| name | obsidian-vault-sync |
| description | Audit and maintain an existing Obsidian Vault against the current state of the repository it covers. Runs two parallel read-only scans (codebase + vault), produces a structured audit report across 11 checks (missing coverage, stale notes, dead wikilinks, orphan notes, tag drift, frontmatter drift, ADR staleness, canvas freshness, _AI-CONTEXT.md drift, Dataview query health, plugin recommendations), then applies fixes only after per-item user approval. Global and project-agnostic; pairs with the obsidian-vault creation skill. Trigger when the user says "maintain obsidian vault", "sync obsidian vault", "update obsidian vault", "audit obsidian vault", "obsidian-vault-sync", "vault is out of date", "update vault", "sync vault", or "check vault". SKIP when the user is asking about creating a new vault from scratch (use obsidian-vault instead). |
Obsidian Vault sync / audit
Project-agnostic, global skill. It keeps an Obsidian Vault honest: scans the live
codebase and the vault in parallel, diffs their states across 11 checks, and applies
fixes only after the user approves each finding. The vault is always a mirror of ground
truth — this skill is the sync mechanism that maintains that property over time.
Pairs with $obsidian-vault (which creates the vault). If no vault exists yet, stop
and direct the user there.
Scope flags (parsed from invocation text)
| Flag | Limits audit to |
|---|
--tags | Tag drift and taxonomy checks only |
--content | Note staleness, dead links, orphans, ADR staleness |
--structure | Folder structure, canvas, _AI-CONTEXT.md drift |
--plugins | Plugin/settings recommendations only |
--all | All checks (default when no flag is given) |
Procedure
1. Orient
- Locate the vault root: check
<repo>/.obsidian-vault/ by default; ask if not found.
- If the vault root does not exist: stop, explain, suggest running
$obsidian-vault first.
- Parse any scope flag from the invocation (default
--all).
- Show the user: vault path, scope, and the list of checks that will run. Confirm before
scanning.
2. Scan (two agents in parallel)
Spawn both simultaneously and wait for both to return before proceeding:
Agent A — Codebase scan (read-only subagent):
"Scan this repository and return a structured summary: (1) all top-level
components/modules (folder names, package names from manifests), (2) key file paths
(README, entrypoints, CI config, any architecture docs), (3) recent git activity —
files added, deleted, or renamed in the last 60 commits (run git log --diff-filter=ADR --name-status --oneline -60), (4) any file paths that were deleted or renamed. Return
a structured plain-text report — no file dumps, no code excerpts."
Agent B — Vault scan (vault_scanner custom agent):
Spawn the vault_scanner agent (defined in this repo under
global/codex/agents/vault-scanner.toml)
against the vault root. It returns a structured vault state report covering: all notes
with their frontmatter, wikilinks, and sizes; all tags in use; tags defined in
_TAG-TAXONOMY.md; folder structure; orphan candidates; dead wikilinks; .obsidian/
config contents; template frontmatter schemas; and all Dataview query blocks.
3. Diff → audit report
Cross-reference Agent A and Agent B outputs to evaluate every active check. For each
check, produce a finding entry:
[CHECK NAME] severity: high | medium | low
Summary: <one sentence>
Affected: <list of file paths or note titles>
Action: <add note | update frontmatter | fix wikilink | update canvas | skip | manual>
The 11 checks and their logic:
-
Missing coverage — components in Agent A output with no matching note in
01-Architecture/ or 06-Reference/. Severity: high if component has >5 source files.
-
Stale content — notes containing file paths (from Agent B) that appear in Agent A's
deleted/renamed list. Severity: high if the note is an active ADR or architecture note.
-
Dead wikilinks — wikilinks and related: values from Agent B that don't resolve to
any note path in Agent B's inventory. Severity: medium.
-
Orphan notes — notes from Agent B with no outgoing wikilinks in body and not
referenced by any other note's related: field. Severity: low (may be intentional stubs).
-
Tag drift — two sub-checks:
- Tags used in notes (Agent B) absent from
_TAG-TAXONOMY.md → severity: medium
- Tags in
_TAG-TAXONOMY.md never used in any note → severity: low
-
Frontmatter drift — notes missing fields required by the current template for their
type: value. Derive required fields by reading _templates/TPL-<type>.md frontmatter.
Severity: medium (breaks Dataview queries).
-
ADR staleness — notes with type: adr and status: active that contain file paths
appearing in Agent A's deleted/renamed list. Severity: high.
-
Canvas freshness — compare nodes in Architecture.canvas against components in
Agent A output: nodes for deleted components (remove), missing nodes for new ones (add).
Severity: medium.
-
_AI-CONTEXT.md drift — Agent B's folder list differs from what _AI-CONTEXT.md
describes, or new tag conventions exist that aren't documented there. Severity: medium.
-
Dataview query health — Dataview blocks from Agent B that query a FROM path or
filter on a type:/status: value that doesn't appear in Agent B's folder structure
or note inventory. Severity: medium.
-
Plugin/settings recommendations — compare Agent B's community-plugins.json against
vault usage patterns (e.g., Tasks plugin listed but no task syntax found in notes →
flag as unused). Use WebFetch for one targeted lookup only if clearly useful (e.g.,
checking whether a listed plugin has been deprecated). Severity: low.
4. Present the full audit report
Show all findings before touching anything. Group by severity (high → medium → low).
For each finding, show the check name, severity, affected files, and recommended action.
Finish with a summary: N high / M medium / P low findings. Nothing changed yet.
If no findings: report "vault is fully in sync — nothing to update" and stop.
5. Apply fixes (approval-gated, per section or per item)
Ask the user: approve all high-severity findings, or go item by item?
For each approved finding, apply using this decision tree:
Safe to apply directly (no user content at risk):
- Add missing frontmatter fields to a note (append only; never rewrite existing fields)
- Add missing
#component/<name> tags to _TAG-TAXONOMY.md
- Remove unused taxonomy tags (after confirming none are used)
- Update
Architecture.canvas nodes (add/remove nodes for new/deleted components)
- Fix a dead
related: wikilink if the correct target is unambiguous
- Update
_AI-CONTEXT.md folder list / tag conventions section
Requires diff review before applying:
- Any note whose line count is significantly larger than its template stub — show a
side-by-side diff of proposed changes vs current content; user chooses apply / skip /
manual-merge.
Never apply automatically (always manual):
- ADR body content (user's decision text)
- Session log entries
- Research findings
- Any note with
status: active where the proposed change rewrites meaning, not just metadata
6. Hand off
- List every file changed and every finding skipped.
- If any findings were skipped, offer to save the unresolved list to
<vault-root>/00-Home/_Sync-Backlog.md for follow-up.
- Remind the user that re-running
obsidian-vault-sync on an up-to-date vault should
produce zero findings.
Guardrails
- Never start applying changes before presenting the full audit report (step 4 before 5).
- Never overwrite user-written note content without showing a diff and getting explicit
approval. User content is irreplaceable; vault structure is not.
- Never delete notes — only flag orphans for the user to decide.
- Treat any note larger than ~2× its template stub as user-owned content; use diff review.
- If the vault root is not found, stop immediately — do not create directories or guess paths.
- Never fabricate findings: every reported issue must be traceable to something Agent A or
Agent B actually returned.
- Keep the two scans strictly parallel; do not use one agent's output to guide the other.