karlorz/llm-wiki · Archived

wiki-sync

Safely sync vault git with a lockfile and lint guards. Use to push or pull wiki changes across sessions.

First seen Jul 27, 2026

Installation

$ npx skills add karlorz/llm-wiki --skill wiki-sync

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from karlorz/llm-wiki · top by installs.

npx skills add karlorz/llm-wiki

Browse all from karlorz/llm-wiki

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 3
Default branch main
Open issues 1
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 13,809 B
  • docs SUMMARY.md 121 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

wiki-sync

When This Skill Activates

  • User wants to push local vault changes to the remote.
  • User wants to pull remote changes into their local vault.
  • User asks about vault sync status, git state, or multi-device coordination.
  • Multiple Claude Code sessions targeting the same vault.
  • Periodic maintenance before or after editing sessions.

Pre-orientation reads

Standard four reads.

Steps

  1. Resolve vault: skillwiki path (record source for context).

Pre-flight peer check (multi-session safe)

Before any git stash or pull/push operation, check for peer sessions:

  1. Run skillwiki sync peers <vault> to detect other sessions with active locks or recent wiki-sync:* stashes.
  2. If any non-self peer is present (locked or has stashes newer than 5 minutes):

- Surface the peer's session_id, PID, and summary to the user - Ask the user to wait for the peer to finish, or pass --force to proceed anyway - If --force is not given and peer is detected, abort and exit

  1. Acquire an advisory lock: skillwiki sync lock <vault> --summary "wiki-sync <op>" (where <op> is "pull" or "push")

- If lock is held (exit code 48), surface the holder (session_id, PID, summary) and abort

  1. Always pair with unlock on exit (success or error):

- skillwiki sync unlock <vault> in a finally block or error handler

Stash backlog warning

On every invocation, count wiki-sync:* stashes older than 24 hours via skillwiki sync peers:

  • If any old stashes exist, warn the user: "Found N wiki-sync stash(es) older than 24h — audit and clean before proceeding"
  • Do not auto-drop old stashes — the user audits each one

Sync workflow

  1. Run skillwiki sync status <vault>. Read the JSON output.

- Exit code 0: vault is clean (nothing to sync). - Exit code 22: warnings — dirty/ahead/behind (needs action).

  1. Present the current state: status, dirty, ahead, behind, last_commit.
  2. Ask the user which operation they want: push, pull, or both (pull then push).

Push workflow

  1. If vault is dirty, ask the user to review uncommitted changes before proceeding.
  2. Run skillwiki sync lint-delta <vault> --base-ref origin/main. Block only when new_errors > 0. Report full/base/new/resolved. Malformed delta evidence fails closed — do not push.
  3. If lint-delta allows (new_errors = 0), stage and commit:

- git -C <vault> add -A - git -C <vault> commit -m "sync: vault update $(date -u +%Y-%m-%dT%H:%MZ)"

  1. Run git -C <vault> push origin HEAD. Report result.
  2. Append one log.md entry summarizing: files pushed, lint result, commit hash.

Pull workflow

  1. Run skillwiki sync status <vault> --include-stashes to check for untracked file collisions (see Untracked file fingerprint below).
  2. If vault is dirty, stash first with the identifiable name format:

``bash VAULT="<vault>" SESSIONID="$(echo $CLAUDESESSIONID)" # or fallback to PID/hostname CWDHASH="$(echo -n "$VAULT" | sha256sum | cut -c1-8)" ISOTS="$(date -u +%Y-%m-%dT%H:%MZ)" MSG="wiki-sync:${SESSIONID}:${CWDHASH}:${ISOTS}:pre-pull" git -C "$VAULT" stash push -m "$MSG" ``

  1. Prefer the canonical pull helper (wiki-pull-with-auto-resolve.sh / vault-presync --execute) so stale-clean rebase state uses recovery-ref + rebase --quit, active rebases fail closed, and only fully materialized commits are dropped. If invoking git directly: git -C <vault> pull --rebase origin HEAD. Report result.
  2. If a stash was created, pop it: git -C <vault> stash pop.
  3. If conflicts occur during stash pop, identify them and present to the user for resolution (see Conflict Resolution below).
  4. Run skillwiki lint <vault> after pull to verify vault integrity.
  5. Append one log.md entry summarizing: commits pulled, lint result, any conflicts.

Pull-then-push workflow

  1. Execute the pull workflow (steps 9-14) first.
  2. Then execute the push workflow (steps 4-8).

Stash naming convention

When wiki-sync creates a stash, use the identifiable message format:

wiki-sync:{session_id}:{cwd_hash}:{iso8601_timestamp}:{summary}
  • sessionid: prefer $CLAUDESESSION_ID env var if set, else $$ (shell PID), else unknown
  • cwd_hash: first 8 chars of sha256($VAULT path)
  • iso8601_timestamp: e.g., 2026-05-23T03:25:00Z (UTC)
  • summary: short label like pre-pull, pre-push, or custom reason

This allows any session to list git stash list and identify which stash came from which session/working directory.

Untracked file fingerprint (pre-pull)

Before git pull --rebase, check for untracked files that exist on the remote and may collide:

for f in $(git -C "$VAULT" ls-files --others --exclude-standard); do
  if git -C "$VAULT" cat-file -e "origin/main:$f" 2>/dev/null; then
    # File exists on remote; check if identical
    if diff -q <(git -C "$VAULT" show "origin/main:$f") "$VAULT/$f" >/dev/null 2>&1; then
      # Byte-identical — safe to remove (presync artifact)
      rm "$VAULT/$f"
    else
      # DIFFERENT — surface to user, DO NOT silently --include-untracked
      echo "UNTRACKED COLLISION: $f differs from origin/main — surface to user for resolution"
    fi
  fi
  # If file does not exist on remote, leave it alone (pull won't touch it)
done

If collisions are found (different content), ask the user to resolve manually before pulling.

Conflict Resolution

When merge conflicts are detected:

Frontmatter conflicts

  • For updated: fields: always take the newer timestamp (compare both sides, keep the later one).
  • For all other frontmatter fields: present both versions to the user and ask which to keep.

Body conflicts

  • Do not auto-resolve body conflicts.
  • Mark unresolved regions with ??? on a line by itself between the conflicting versions, so the user can see both sides and decide.
  • Example:
Content from local version
???
Content from remote version
  • After resolving conflicts, run skillwiki lint <vault> to verify before committing.

Modify/delete conflicts

When git pull --rebase reports CONFLICT (modify/delete):

  1. Identify the commit that deleted the file:

``bash git -C "$VAULT" log --diff-filter=D --pretty=oneline -- <path> ``

  1. Read the commit message and any retro / log entry referencing it to determine if the deletion was intentional or accidental.
  2. Decide:

- git -C "$VAULT" rm <path> — accept the deletion (rebase continues) - git -C "$VAULT" add <path> — keep the local restoration (rebase continues)

  1. git -C "$VAULT" rebase --continue.

Rebase conflict storm (archive commits × snapshot stream)

When many local archive-only commits (e.g., archive: moved X to archive/) are rebased over an origin/main that receives frequent snapshot commits (e.g., sg01 Snapshot YYYYMMDDHHMMSS), every archive commit re-triggers the same content conflicts on shared files (log.md, knowledge.md, spec.md). This is predictable and can be resolved systematically.

Detection: 3+ consecutive rebase stops on commits whose message matches ^archive: moved.

Resolution: For each archive commit during the storm:

# Apply --ours to all conflicting files (keep HEAD = origin/main + snapshots)
for f in $(git -C "$VAULT" diff --name-only --diff-filter=U); do
  git -C "$VAULT" checkout --ours "$f" && git -C "$VAULT" add "$f"
done
git -C "$VAULT" rebase --continue

After the storm passes (non-archive commits or clean rebase), pop the stash and handle any remaining conflicts per the normal Conflict Resolution sections above.

Prevention:

  • Sync more frequently — don't let local fall >5 commits behind origin/main
  • Prefer smaller, attended exact-target archive operations and sync promptly; there is no batch raw-archive apply mode.
  • For vaults with snapshot cron, prefer smaller, more frequent syncs over large batch rebases

See concepts/wiki-sync-rebase-conflict-storm-pattern.md for detailed analysis.

Multi-device coordination

When the user mentions editing from Obsidian desktop and Claude Code on a server (or any two-device setup):

  • Recommend pulling before every editing session on each device.
  • Recommend pushing after every editing session on each device.
  • If both devices edit the same page between syncs, conflicts are inevitable — the Conflict Resolution section handles this.
  • Suggest enabling auto-commit in Obsidian (Community Plugins: obsidian-git) to reduce dirty-state drift.

Host-aware write and promotion authority

Resolve the live vault with skillwiki path first. Then choose the host role:

Host role Live vault Authoring surface Promotion to GitHub
Authorized Git-backed leaf (e.g. macOS) Git vault from skillwiki path Managed SkillWiki publishers against that vault skillwiki sync push "$VAULT" after lint-delta
Protected snapshotter (sg01) /root/wiki (rclone FUSE; not a Git repo) Managed SkillWiki publishers against /root/wiki S3 → wiki-snapshot.timer (default) → protected /root/wiki-git pipeline → GitHub

High-signal safety rule:

Do not author, copy, edit, stage, commit, pull, reset, or push agent changes
in /root/wiki-git.

Protected snapshotter rules (sg01)

  • Author only via managed commands against the live vault (skillwiki path → usually /root/wiki).
  • Do not run skillwiki sync push /root/wiki (not a Git repo) or skillwiki sync push /root/wiki-git (blocked as protected snapshot worktree).
  • Do not cd into /root/wiki-git or ~/wiki-git for ordinary authoring.
  • Do not rsync, copy, or edit files into the snapshot worktree as an agent/operator workflow.
  • Do not run git reset --hard, direct commits, or manual snapshot scripts to "fix" divergence.
  • Promotion is owned by wiki-snapshot.timer by default. Publishers never start systemd units.
  • skillwiki work-complete may finish with committed=false on sg01; later snapshot promotion owns the Git commit/push.
  • .skillwiki/work-complete/*.env journals are local retry hygiene, not GitHub SSOT. Do not treat them as publishable. Prefer last-op pathspecs over a raw git add -A when staging a managed completion. Vault .gitignore and rclone push filters must exclude work-complete/ and last-op.json.

Authorized Git leaf rules

  • Use managed publication (skillwiki page publish, skillwiki project-page publish, etc.) against the resolved Git vault.
  • Then use this skill's push workflow (skillwiki sync status → lint-delta → commit → skillwiki sync push / git push as documented above).
  • Never treat a snapshot worktree mirror as a substitute for the live vault.

Historical rationale (not executable)

Some older deployments separated a cloud-backed live vault from a Git snapshot worktree. That architecture still exists on protected snapshotters, but the snapshot worktree is pipeline-internal. Historical recipes that rsync into the worktree, reset it hard to origin/main, or run snapshot shell scripts by hand are obsolete and must not be copied.

Stop conditions

  • skillwiki sync status reports notarepo — the vault is not a git repository. On protected snapshotters this is expected for the FUSE live path; do not switch to /root/wiki-git to force a push.
  • Lint errors are found before a push — do not push until resolved.
  • git push or git pull fails with a network error — report and stop.
  • Peer lock is held or peer stashes exist — abort and ask the user to wait or pass --force.
  • Untracked file collision detected on pull — surface to user for manual resolution.
  • Host is a protected snapshotter and the requested operation would author or push via /root/wiki-git — refuse and use managed live-vault publication + timer promotion instead.

Forbidden

  • Pushing when lint errors exist.
  • Auto-resolving body conflicts without user review.
  • Force-pushing (git push --force).
  • Rewriting raw content/frontmatter to resolve conflicts. Preserve-moves must stay under raw/ (normally raw/archived/ or raw/duplicates/) and require an attended approved structural command; scheduled/headless sync remains report-only.
  • Stashing without the wiki-sync:... name format (breaks peer detection).
  • Force-deleting a peer's lockfile (use --force only if peer is confirmed dead).
  • Authoring, copying, editing, staging, committing, pulling, resetting, or pushing agent changes in /root/wiki-git (or any configured snapshot worktree).
  • Running skillwiki sync push against a protected snapshot worktree or against a non-Git FUSE live vault.
  • Invoking snapshot services/scripts or git reset --hard in the snapshot worktree as a recovery shortcut.

Convergence safeguards (2026-07-11)

Rebase-state classification

  • stale-clean: recovery ref at tip + git rebase --quit (preserves advanced tip; never abort-reset to orig-head).
  • active (REBASE_HEAD / UU paths): leave untouched; fail closed.
  • Recovery refs live under refs/vault-sync/recovery/<UTC timestamp>.

Materialized-commit proof

Drop a local commit from rebase only when every path is proven present on the target ref (exact blobs; byte-identical added ## log sections). Partial/raw/rename mismatches retain or stop.

Lint-delta fail-closed

  • Fingerprints: <bucket>\0<page>\0<normalized-detail>
  • CLI: skillwiki sync lint-delta <vault> --base-ref origin/main
  • Block publication only when new_errors > 0; inherited full debt remains visible.
  • Missing/malformed delta evidence blocks (never silent lint skip).