zirvDocs

DocsWorkflows and skills

ZIRV.md instruction files

README.md, lines 237–288, 7076–7101View source

Zirv's own native instruction file. Sources, closest scope first:

  1. nested ZIRV.md files between the repository root and the files/worktree scope currently being acted on;
  2. repository ZIRV.md at the repo root, or .zirv/ZIRV.md when the root file is absent — if both exist, the root file wins and .zirv/ZIRV.md is reported shadowed, never merged;
  3. optional operator-global ~/.zirv/ZIRV.md.

The portable AGENTS.md convention is a first-class source alongside it, and existing CLAUDE.md repositories work unmigrated. At the same directory, ZIRV.md outranks AGENTS.md, which outranks CLAUDE.md, which outranks the singular AGENT.md compatibility alias — AGENT.md is only ever a candidate when no AGENTS.md exists in that directory, and always carries a migration diagnostic recommending rename to AGENTS.md. A compatibility file whose content duplicates the winning file (identical text, a symlink resolving to it, or a lone @AGENTS.md-style import of it) is reported as a duplicate consumed once, not as separate shadowed content — the same rules never reach a session twice. zirv ctx optimize's report and zirv context status (see Reviewing your instruction files) list every discovered ZIRV.md/AGENTS.md/CLAUDE.md/AGENT.md surface with its trust class, scope, content hash, and precedence decision (included/shadowed/duplicate/excluded, with a reason). Instructions are context, never permissions: like every native instruction file, ZIRV.md can steer a session's prose but can never change sandboxing, approvals, credentials, provider/account/billing routing, tool grants, workflow policy floors, or settings precedence — see Trust boundary below.

Migration is opt-in and never destructive. zirv context sync --init-zirv-md idempotently writes a starting <repo>/ZIRV.md from the canonical .zirv/context/common.md layer plus any root AGENTS.md/ CLAUDE.md content that is not already zirv-managed; a repeat run with nothing changed is a no-op, and an existing ZIRV.md — including one you have since hand-edited — is never overwritten without --force. Content that looks secret-shaped is skipped and named, never copied. A repository with only AGENTS.md needs no migration at all: zirv context sync --report (the default, read-only mode) offers a one-line compatibility-link plan — a ZIRV.md containing just @AGENTS.md — for anyone who would rather link than duplicate.

Canonical context can drift silently. compile.rs dedupes the canonical .zirv/context/ layer out of a session's prefix only when a managed CLAUDE.md/AGENTS.md byte-for-byte proves it already carries the current render — edit .zirv/context/common.md without regenerating, and that proof fails, so the canonical layer (several KB) is injected twice every session with no error, just a warning on zirv ctx compile --measure. zirv context sync --check is the CI-friendly form of --report: same read-only report, but it also exits non-zero when a managed native file has drifted from the canonical sources it claims to render, so a CI step can catch a forgotten zirv context sync --generate before it merges.

Reviewing your instruction files#

zirv ctx optimize reads the CLAUDE.md hierarchy and the settings layers that steer every session, checks them against recent transcripts and the decision log, and prints a report with proposed edits as unified diffs.

bash
zirv ctx optimize              # full analysis, one cheap model call
zirv ctx optimize --no-model   # deterministic checks only, no model call

It reports four kinds of finding: instructions stated in more than one layer, instructions naming files or hook programs that no longer exist, contradictions between layers, and instruction gaps that correlate with repeated tool failures or user corrections.

It never edits an analysed file. Every proposal is a diff you apply yourself. A finding about a file inside this repository (CLAUDE.md, .claude/settings.json) gets a repo-relative a//b/ header, so git apply works from the repo root. A finding about a file outside the repo (your global CLAUDE.md, ~/.claude/settings.json) gets a plain absolute path with no a//b/ prefix instead, meant for hand application: the report says which is which for every diff it prints. A copy of each report is kept under the state dir, and each run appends to the decision log. When a finished session shows a high tool-failure rate, the Stop hook queues an "optimize recommended" entry and mentions it once in its advisory; it never runs the analysis itself.