Skip to content
Development
Skill

/vault-mirror

Use when you need to populate the Meta-Vault with machine-generated notes derived from session-orchestrator JSONL records. Converts entries from `.orchestrator/metrics/sessions.jsonl` and `.orchestrator/metrics/learnings.jsonl` into vault-conformant Markdown under `50-sessions/`

From plugin
session-orchestrator
5044 skills14 agents26 commands10 hooks
+1
Install
$ npx -y skills add Kanevry/session-orchestrator --skill vault-mirror --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-mirror

Context preview

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

Use when you need to populate the Meta-Vault with machine-generated notes derived from session-orchestrator JSONL records. Converts entries from `.orchestrator/metrics/sessions.jsonl` and `.orchestrator/metrics/learnings.jsonl` into vault-conformant Markdown under `50-sessions/`

SKILL.md

vault-mirror.SKILL.md
name: vault-mirror
description: >
  Use when you need to populate the Meta-Vault with machine-generated notes derived from
  session-orchestrator JSONL records. Converts entries from `.orchestrator/metrics/sessions.jsonl` and
  `.orchestrator/metrics/learnings.jsonl` into vault-conformant Markdown under `50-sessions/` and
  `40-learnings/`. Called automatically at session-end Phase 3.7 and after evolve Phase 3.5 — only when
  `vault-integration.enabled=true` and `vault-integration.mode != "off"`. Idempotent: re-runs safely;
  skips hand-authored notes. Triggers: "mirror to vault", "sync session notes to vault", "write learning
  notes to vault", "vault-mirror failed at session close". <example>Context: session-end is finalizing,
  vault-integration.mode is "warn". user: "/close" assistant: "Running vault-mirror to write
  50-sessions/session-2026-05-17.md from the closing session record — 1 created, 0 skipped."</example>
model: haiku

Vault Mirror 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). When this skill mentions Session Config in `CLAUDE.md`, the alias rule applies.

Purpose

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.

When Invoked

vault-mirror is called in two places:

  • **Phase 3.7 of session-end** (`skills/session-end/session-metrics-write.md`) — mirrors the sessions.jsonl entry for the closing session.
  • **Phase 3.5 of evolve** (`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.

Inputs

`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.

Outputs

One JSON line is written to stdout for each non-empty JSONL entry processed. Exit code reflects the run outcome.

Action values

| `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. | | `skipped-quality-low` | Entry failed the quality gate (PRD F1.2): learning `confidence` below `vault-mirror.quality.min-confidence` (CLI: `--quality-min-confidence`, default `0.5`), or session rendered-narrative length below `vault-mirror.quality.min-narrative-chars` (CLI: `--quality-min-narrative-chars`, default `400`). The emitted JSON line includes a `reason` field describing the violated threshold and `path: null` (no file was created). The quality gate runs **before** `--force`; `--force` does not bypass it. |

Output line shape

{"action":"created","path":"50-sessions/session-orchestrator/session-2026-04-13.md","kind":"session","id":"session-2026-04-13"}

`path` is relative to `--vault-dir`.

Exit codes

| 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. |

Target Paths

| Kind | Target | |---|---| | `session` | `<vault-dir>/50-sessions/<repo>/<session-id>.md` | | `learning` | `<vault-dir>/40-learnings/<repo>/<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.

**Per-project namespacing (#660).** New writes are namespaced under a per-repo subdirectory `<repo>/`, so a single shared vault can hold notes from multiple projects without cross-repo slug/id collisions. `<repo>` is resolved by `resolveRepoNamespace()` (`scripts/lib/vault-mirror/namespace.mjs`): the optional `vault-integration.vault-name` Session Config key (CLI: `--vault-name`) when set, else the git-origin repo slug via `deriveRepo()`, sanitised to a single kebab segment. Owner-privacy leaks (personal home path / private project slug / personal name) are redacted to `redacted-re

Read more
Ships withsession-orchestrator

Give your agents a working rhythm. Plan the work. Run it in checked waves. Pick up where you left off. Session Orchestrator is a free, MIT-licensed workflow plugin for Claude Code, Codex CLI, Cursor IDE, or Pi.

Get the whole plugin

Other skills on session-orchestrator.