Skip to content
Development
Skill

/vault-sync

Use when you need to validate the Meta-Vault's Markdown frontmatter and wiki-link integrity before closing a session or after vault edits. Runs as a hard gate at session-end Phase 1 — blocks close if any `.md` file fails the Zod frontmatter schema or has dangling

From plugin
session-orchestrator
5144 skills14 agents26 commands10 hooks
+1
Install
$ npx -y skills add Kanevry/session-orchestrator --skill vault-sync --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/vault-sync

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when you need to validate the Meta-Vault's Markdown frontmatter and wiki-link integrity before closing a session or after vault edits. Runs as a hard gate at session-end Phase 1 — blocks close if any `.md` file fails the Zod frontmatter schema or has dangling

SKILL.md

vault-sync.SKILL.md
name: vault-sync
description: >
  Use when you need to validate the Meta-Vault's Markdown frontmatter and wiki-link integrity before
  closing a session or after vault edits. Runs as a hard gate at session-end Phase 1 — blocks close if any
  `.md` file fails the Zod frontmatter schema or has dangling `[[wiki-links]]`. Supports three modes:
  `hard` (blocks on errors), `warn` (reports without blocking), `off` (skip). Reads `vault-sync.*` from
  Session Config; respects per-vault exclude globs from `CLAUDE.md`. Triggers: "vault validation failed at
  session close", "fix vault frontmatter errors", "check vault wiki-links", "why is session-end blocked by
  vault-sync". <example>Context: session-end Phase 1 quality gate, vault-sync.enabled=true,
  vault-sync.mode="hard". user: "/close" assistant: "vault-sync found 2 frontmatter errors in
  vault/40-learnings/ml-notes.md — missing required `id` field. Fixing before close."</example>
model: haiku

Vault Sync Skill

> Project-instruction file resolution: `CLAUDE.md` and `AGENTS.md` (Codex CLI) are transparent aliases — see [skills/_shared/instruction-file-resolution.md](../_shared/instruction-file-resolution.md). The vault-marker check below treats either file as a valid marker (when it carries `## Session Config` + `vault-sync:`); references to `CLAUDE.md` resolve via the SSOT precedence rule.

Status

STATUS: PHASE 1 IMPLEMENTED (2026-04-13). Session-End hard gate (section 3.1) operational. Phase 2 (wave-executor incremental, 3.2) and Phase 3 (evolve advisory, 3.3) not yet implemented.

Implementation

Phase 1 ships a self-contained validator that reads every `.md` file under `VAULT_DIR`, parses YAML frontmatter, validates against the canonical `vaultFrontmatterSchema`, and flags dangling wiki-links as warnings.

Files

  • `validator.mjs` — Node.js ESM validator. Uses `zod` + `yaml` npm packages. Reads `VAULT_DIR` (env or default cwd), walks the tree, skipping `node_modules/`, `.git/`, `.obsidian/`. `90-archive/` is walked but never *checked* (#833): archived notes stay in the link-target register — so an inbound `[[wiki-link]]` to an archived note resolves instead of dangling — while their frontmatter is skipped and counted in `archived_skipped_count`. For each `.md`: parses frontmatter, validates against the inline Zod schema, extracts `[[wiki-links]]`, verifies each target resolves. Emits JSON report on stdout.
  • `validator.sh` — Thin POSIX wrapper. Resolves `VAULT_DIR` from arg 1 or env, self-bootstraps deps via `pnpm install --silent` on first run, execs the Node validator. Session-end and other callers use this entry point.
  • `package.json` — Declares `zod` (`^3.24.0`, matching projects-baseline) and `yaml` (`^2.5.0`) as deps. `pnpm-lock.yaml` is committed; `node_modules/` is gitignored.
  • `tests/validator.bats` — 16 BATS cases covering clean vaults, broken frontmatter, missing required fields, dangling links, no-vault skipping, README-style files, nested directories, and archive/obsidian exclusion.
  • `tests/fixtures/` — Seven fixture vaults matching each test scenario.

Schema source

The inline Zod schema is vendored from the canonical source at `projects-baseline/packages/zod-schemas/src/vault-frontmatter.ts`. The skill is intentionally self-contained (no monorepo workspace dependency), so the schema is duplicated with a header comment pointing at the SSOT. Drift is to be caught by a future smoke test that imports the canonical schema and diffs the shape — NOT YET IMPLEMENTED. Until that test exists, any change to the canonical schema must be mirrored here in the same commit.

Dependencies

`skills/vault-sync/package.json` pins `yaml ^2.5.0` / `zod ^3.24.0` — intentionally NOT the root's `yaml ^2.9.0` / `zod ^3.25.76`. This is not drift to fix:

  • Both CI hosts install this sub-package on its own, independent of the root install (`.gitlab-ci.yml:121` and `.github/workflows/test.yml:93`, both: `(cd skills/vault-sync && npm install --no-audit --no-fund)`).
  • The root `package.json` declares no `workspaces`, so `npm ci` at the root never touches this folder's deps; `skills/vault-sync/node_modules/` is the only place `zod` resolves for this skill (`scripts/lib/vault-archive.mjs:19-21`).
  • The `zod ^3.24.0` pin deliberately tracks the projects-baseline version, not this repo's own (`scripts/release.mjs:488`).

The root's dependency versions are NOT the SSOT for this folder — do not "fix" this pin to match the root.

How session-end invokes it

VAULT_DIR=/path/to/vault bash ~/Projects/session-orchestrator/skills/vault-sync/validator.sh
  • Exit `0` — vault valid (or skipped because no vault exists / no .md files). Warnings may still be present in the JSON report.
  • Exit `1` — one or more validation errors. Session-end surfaces them in the quality gate report and refuses to close.
  • Exit `2` — invalid invocation or infrastructure error. Two cases: (a) `VAULT_DIR` is not set and `cwd` does not look like a Meta-Vault (no `_meta/`, no `.obsidian/`, no `CLAUDE.md` or `AGENTS.md` with `## Session Config` + `vault-sync:` block) — actionable error printed to stderr; (b) infrastructure error (missing `node`, missing `validator.mjs`, cannot bootstrap deps). In both cases no JSON is emitted to stdout.

JSON output shape (stdout):

{
  "status": "ok|invalid|skipped",
  "vault_dir": "...",
  "files_checked": N,
  "files_skipped_no_frontmatter": N,
  "errors": [{"file": "...", "path": "frontmatter.id", "message": "..."}],
  "warnings": [{"file": "...", "type": "dangling-wiki-link", "message": "..."}]
}

Opt-in `--check-expires` flag downgrades expired notes to warnings; default off (Phase 1 leaves freshness for the Phase 3 evolve advisory).

CLI Flags

The validator (both `validator.mjs` and the `validator.sh` wrapper) accepts:

  • `--mode <hard|warn|off>` — gate severity. `hard` (default) exits 1 on any frontmatter/schema error. `warn` exits 0 but still populates the `errors` array in the JSON output
Read more
Ships withsession-orchestrator

Give your agents a working rhythm. You type three commands: /session reads your repository, your open issues and the last session, proposes what to work on, and waits for your correction.

Get the whole plugin

Other skills on session-orchestrator.