@.doctrine/state/boot.md
# jail
if `/workspace` exists, you're in a bubblewrap jail with the system defined in flake.nix,
including some additional readonly repos mounted ro at `/workspace` plus my ro
`~/.cargo/bin/doctrine` - if you need a rw doctrine use the build target.
If you need something else that's missing, STOP and ask the User.
# bootstrap doctrine
**Start EVERY substantive task with `/route`** — it chooses the governing skill
before you inspect files, run commands, or write code. The routing table, core
process, and guardrails ride the boot snapshot (`@.doctrine/state/boot.md`,
inlined above), so they are not recited here.
The CLI is the source of truth for command shapes — `doctrine --help` (dev:
`./target/debug/doctrine --help`, off-PATH after `cargo build`). Don't guess
ids or flags; ask the CLI. Durable knowledge lives in doctrine's own memory
(`doctrine memory record|find|retrieve`), not Claude's — the index is in the
snapshot's Memory section; `/record-memory` and `/retrieve-memory` wrap it.
---
## layout
```
.doctrine/slice/nnn/
slice-nnn.toml metadata, relations, lifecycle status
slice-nnn.md scope document
design.md canonical technical design
plan.toml authored phase plan (objectives, EN/EX/VT criteria, links)
plan.md plan prose — rationale & sequencing (no queried data: storage rule)
notes.md durable implementation notes (on-demand)
handover.md disposable agent context — GITIGNORED
audit.md verification / code-review / drift findings (hand-made; no scaffold yet)
phases -> symlink into the runtime state tree (GITIGNORED)
.doctrine/adr/nnn/ adr-nnn.{toml,md} + nnn-slug symlink — project-global ADRs (authored)
.doctrine/state/slice/nnn/phases/ runtime phase tracking (phase-NN.{toml,md}) — GITIGNORED
.doctrine/governance.md user-owned governance pointer layer — projected into the boot snapshot
doc/* evergreen, authoritative specs. not yet structurally supported by doctrine
.doctrine/memory/items/nnn/ memory store — memory.toml + memory.md per item;
mem.<key> symlink alias. Query via `doctrine memory find|retrieve`.
install/ sources copied to .doctrine by the installer; plugins/skills handled special
src/ rust code (incl. src/git.rs — the impure born-frame capture seam,
forgettable's forget.remote.v1/forget.checkout.v1 reproduced byte-for-byte;
src/boot.rs — the cache-friendly governance snapshot, SL-011)
```
## storage model (the storage rule)
Three tiers — know which one you're writing:
- **authored** (`*.toml` + `*.md` under `slice/nnn/` and `adr/nnn/`): committed,
diffable, reviewed. Structured data in TOML; prose in MD; **never queried/derived
data in prose.** ADRs are authored entities too — status lives in `adr-nnn.toml`.
- **runtime state** (`.doctrine/state/`, the `phases` symlink, `handover.md`,
`boot.md`): GITIGNORED, disposable, `rm -rf`-able. Progress lives here, never in
authored files.
- **derived**: regenerable indexes/caches — gitignored.
## conventions
(`/route`'s digest already carries: no code without an approved plan; use the
CLI, don't guess; immutable `PHASE-NN` / `EN-/EX-/VT-` ids; TDD red/green/refactor.
These are the project-specific additions.)
- **frequent conventional commits**; scope with the slice id, e.g.
`fix(SL-004): …`, `doc(SL-005): …`, `plan(SL-005): …`. Commit on `main`.
- **reference form** — cite entities by their prefixed canonical id everywhere
(prose, commits, comments): `SL-020`, `ADR-004`, `PRD-010`, `REQ-060`,
`RSK-004`, `ASM-001`. The id is identity; the slug is never authoritative. Cite
the **durable** id, never a mobile membership label (`FR-`/`NF-` move per spec —
use the `REQ-NNN` they label).
- **ask, don't infer.** correctness comes first and last.
- **pure/imperative split** (slices-spec § Architecture): no clock, rng, git, or disk
in the pure layer — pass them in as inputs (the date/uid pattern). Impurity lives in
the thin shell.
- **behaviour-preservation gate**: when changing shared machinery (the entity engine),
the existing suites are the proof — they must stay green unchanged.
- **lint as you go** — `cargo clippy` zero warnings; `just gate` before every commit
(`just check` is the fast inner-loop variant — root package only, skips the cordage
workspace crate; `gate` runs `--workspace`). (The gate runs plain `cargo clippy` —
bins/lib only; do NOT use `--all-targets`, which lights up
`unwrap_used`/`expect_used` denials in test code.)
- **no parallel implementation** — ride existing seams; find duplication before writing.
## known CLI gaps (todo as the tooling surface expands)
- **review/audit ledger — SHIPPED (SL-040).** The RV kind (`RV-NNN`, ADR-007) is the
structured audit substrate `audit.md` lacked: `doctrine review new --facet
reconciliation --target SL-NNN`, then append-only `raise`/`dispose`/`verify`/
`contest`/`withdraw` under a turn-based baton + per-review lock (D-C4a), with a
warm-cache `prime`. `/audit` is rewired onto it — `audit.md` retired for new audits
(existing files stay valid; no migration). Remaining review skills (`/inquisition`,
`/code-review`, reconciliation) not yet rewired — IMP-023.
- **slice status rollup — SHIPPED (SL-009).** `slice list` now derives `X/Y complete`
per slice from the phase state tree (`!N` blocked, `?N` anomalous, `—` untracked)
and flags `⚠` when the hand-edited status and the rollup diverge. Read-only — it
*reveals* divergence; the lifecycle-transition verb below reconciles it.
- **slice lifecycle transition — SHIPPED (SL-040 / ADR-009).** `doctrine slice status
<id> <state>` classifies and writes the move (advance / back-edge / skip / abandon)
across `proposed→design→plan→ready→started→audit→reconcile→done`; refuses the closure
seam out of order (`→reconcile` only from `audit`, `→done` only from `reconcile`) and
refuses leaving a terminal status (`done`/`abandoned`). The closure seam enforces the
D-C9b close-gate — refuses `→reconcile`/`→done` while an RV targeting the slice carries
an unresolved `blocker`. Resolves the SL-009 rollup divergence. (`<id>` is the bare
number, e.g. `40`, not `SL-040`.)
- **no standalone plan validation** — a malformed `plan.toml` only surfaces when
`slice phases` parses it.
- **memory retrieval — SHIPPED.** `record/show/list` (SL-005); SL-007 producer
(`record` scope+git-anchor capture, `verify`, `src/git.rs` seam); SL-008 reader
(scope-aware `find`/`retrieve`, 9-key ranking, git staleness, the `retrieve`
trust holdback). No retrieval gap remains. Producer follow-up still open: `record`
has no `--trust`/`--severity` flag (audit A-3) — the risk axes are TOML-only.
- **boot snapshot — SHIPPED (SL-011).** `doctrine boot` regenerates the cache-friendly
governance snapshot; `boot install` wires the `@`-import + SessionStart hook;
`boot --check` is the disk sentry (stale / unpopulated). In-session edits lag ≤2
sessions — `/canon` carries the regenerate-THEN-`/clear` freshen-now ritual.
- **candidate / admission workflow — SHIPPED (SL-068 / ADR-012 candidate clauses).**
`review/*` and `phase/*` from `dispatch sync --prepare-review` are immutable
EVIDENCE refs — never edited or landed in place (R2). To review, repair, or land
dispatched work, publish a **candidate interaction branch**: `doctrine dispatch
candidate create --slice N --role review_surface|close_target --base <trunk>
[--source <ref>] [--worktree]` (a Doctrine no-ff 3-way merge recording immutable
source/base/merge OIDs); `… candidate status --slice N` lists evidence vs
candidates separately and prints the safe next verb; `… candidate admit --slice N
--role <role> --candidate <ref> [--review RV-NNN]` validates provenance +
merge-ancestry, refuses a moved ref, and pins an immutable `admitted_oid`. `/close`
then runs `dispatch sync --integrate`, which targets the admitted OID via an
ff-only CAS row (never a close-time merge or a mutable ref; a moved target refuses
— admit a superseding candidate). Orchestrator-classed; `create`/`admit` refuse
under worker-mode and from a raw-evidence worktree. Remaining `/audit` +
`/code-review` candidate-surface rewiring is deferred (IMP-042); freeform
candidate-workflow orientation masters are SL-069's to author (CHR-009).
## environment
nixos; bubblewrap jails (mounted into /workspace/*).
- Always use READ tool *before* writing any substantial edit (e.g.
filling a template, writing `handover.md`) to avoid expensive write
failure. `cot`, etc do NOT count!
- default reviewer: codex mcp - use default (GPT-5.5) for external
adversarial reviews. Opus sub-agent is also useful for variety on
subsequent passes.