From session-orchestrator
Mirrors JSONL session and learning records to Markdown notes in Meta-Vault with vault-compatible frontmatter. Runs conditionally in session-end and evolve phases.
npx claudepluginhub kanevry/session-orchestrator --plugin session-orchestratorThis skill uses the workspace's default tool permissions.
vault-mirror populates the Meta-Vault with machine-generated notes derived from structured JSONL records. It converts entries from `.orchestrator/metrics/sessions.jsonl` and `.orchestrator/metrics/learnings.jsonl` into vault-conformant Markdown files under numeric-prefix subdirectories. This is distinct from vault-sync, which validates the vault — vault-sync validates the vault; vault-mirror po...
Guides strict Test-Driven Development (TDD): write failing tests first for features, bugfixes, refactors before any production code. Enforces red-green-refactor cycle.
Guides systematic root cause investigation for bugs, test failures, unexpected behavior, performance issues, and build failures before proposing fixes.
Guides A/B test setup with mandatory gates for hypothesis validation, metrics definition, sample size calculation, and execution readiness checks.
vault-mirror populates the Meta-Vault with machine-generated notes derived from structured JSONL records. It converts entries from .orchestrator/metrics/sessions.jsonl and .orchestrator/metrics/learnings.jsonl into vault-conformant Markdown files under numeric-prefix subdirectories. This is distinct from vault-sync, which validates the vault — vault-sync validates the vault; vault-mirror populates it. The two skills are complementary: vault-mirror writes notes, vault-sync checks that the vault as a whole remains conformant.
vault-mirror is called in two places:
skills/session-end/session-metrics-write.md) — mirrors the sessions.jsonl entry for the closing session.skills/evolve/SKILL.md) — mirrors all learnings.jsonl entries added during the evolve cycle.Both call sites are conditional: vault-mirror runs only when vault-integration.enabled == true AND vault-integration.mode != "off" in the project's Session Config. When either condition is not met, the call site skips silently and vault-mirror is never invoked.
scripts/vault-mirror.mjs is the implementation. All arguments are required except --dry-run.
| Flag | Type | Required | Description |
|---|---|---|---|
--vault-dir | path | yes | Absolute path to the Meta-Vault root directory. Must exist. |
--source | path | yes | Path to the JSONL file to read (one JSON object per line). Must exist. |
--kind | session or learning | yes | Determines which generator and target path are used. |
--dry-run | flag | no | Parse and resolve paths but do not write any files. Emits action lines as normal. |
Empty lines in the JSONL source are silently skipped.
One JSON line is written to stdout for each non-empty JSONL entry processed. Exit code reflects the run outcome.
action | Meaning |
|---|---|
created | Entry did not exist in the vault; file created. |
updated | Entry existed (generator marker present, same id) with an older updated date; file overwritten. |
skipped-noop | Entry existed, same id, updated date not advanced; file unchanged. |
skipped-handwritten | A file at the target path has no _generator marker (or an unknown generator); left untouched. |
skipped-collision-resolved | A file at the target path has the generator marker but a different id; a disambiguated slug was used instead. |
skipped-invalid | Entry is missing one or more required fields; entry skipped, processing continues. |
{"action":"created","path":"50-sessions/session-2026-04-13.md","kind":"session","id":"session-2026-04-13"}
path is relative to --vault-dir.
| Code | Meaning |
|---|---|
0 | Success (including idempotent no-ops and per-entry skips). |
1 | Malformed JSON on a JSONL line — fatal, processing stops. Also returned when required CLI args are missing. |
2 | Filesystem error: --vault-dir not found, --source not found, or an unexpected write error. |
| Kind | Target |
|---|---|
session | <vault-dir>/50-sessions/<session-id>.md |
learning | <vault-dir>/40-learnings/<slug>.md |
Subdirectories are created automatically with mkdirSync({ recursive: true }) when writing (not in --dry-run mode).
The numeric prefix (50-sessions/, 40-learnings/) follows the vault folder ordering convention so that sessions and learnings appear in the correct position in the vault tree relative to other note types.
Path contract note: Issue #187 proposed <vault>/05-orchestrator/<repo>/ as the target layout. The shipped implementation uses numeric-prefix paths for vault ordering. If you need the issue-text path, file a new issue — do NOT silently change the script.
vault-mirror is safe to run multiple times against the same JSONL source:
_generator marker present, same id, updated date not advanced → skipped-noop, file unchanged._generator marker present, same id, updated date advanced → updated, file overwritten._generator marker → skipped-handwritten, file untouched. The absence of the marker means the file was written by a human and must not be overwritten automatically._generator marker present, different id → slug collision. A disambiguated slug is derived by appending -<first-8-chars-of-entry-uuid> (hyphens stripped from the UUID before taking the prefix). The original file is left unchanged; the new note is written at the disambiguated path with action skipped-collision-resolved.The generator marker value is session-orchestrator-vault-mirror@1 and appears in the YAML frontmatter as _generator: session-orchestrator-vault-mirror@1.
| Condition | Behaviour |
|---|---|
| Entry missing a required field | skipped-invalid emitted on stdout, error written to stderr, exit 0 (processing continues for remaining entries). |
| Malformed JSON on a JSONL line | Error written to stderr, exit 1 (processing stops). |
--vault-dir not found | Error written to stderr, exit 2. |
--source file not found | Error written to stderr, exit 2. |
| Hand-written file at target path | skipped-handwritten emitted on stdout, note written to stderr, file left unchanged. |
Unknown _generator value in existing file | Treated as hand-written: skipped-handwritten, file left unchanged. |
| Unexpected filesystem write error | Error written to stderr, exit 2. |
Mirror the sessions.jsonl for the current project into a vault:
node scripts/vault-mirror.mjs \
--vault-dir ~/Projects/vault \
--source .orchestrator/metrics/sessions.jsonl \
--kind session
Dry-run a learnings mirror to preview actions without writing:
node scripts/vault-mirror.mjs \
--vault-dir ~/Projects/vault \
--source .orchestrator/metrics/learnings.jsonl \
--kind learning \
--dry-run
vault-mirror respects the vault-integration block in the project's Session Config (CLAUDE.md). The script itself does not read Session Config — the calling skill (session-end, evolve) is responsible for reading the config and deciding whether to invoke vault-mirror at all.
| Field | Type | Default | Meaning |
|---|---|---|---|
vault-integration.enabled | boolean | false | When false, the calling skill skips vault-mirror entirely. |
vault-integration.vault-dir | string | — | Absolute or ~-prefixed path to the Meta-Vault root. Passed as --vault-dir. |
vault-integration.mode | strict, warn, or off | warn | When off, the calling skill skips vault-mirror. When warn, mirror failures are surfaced as warnings but do not block session close. When strict, mirror failures block session close. |