npx skills add ...
npx skills add davidlee/doctrine --skill close
Use to formally close a slice once its phases are complete, audited, and reconciled — confirm the rollup, verify spec-coherence, harvest durable findings, reconcile lifecycle status, and land a clean final commit. Routed to from /reconcile.
npx skills add davidlee/doctrine --skill close
You are executing formal closure, not just marking work done.
Inputs:
## Reconciliation Outcome recorded (see /reconcile)Pre-check:
EX-) and verification (VT-) are met. Confirm the
rollup: doctrine slice list should show the slice as X/X complete with
no !N blocked, no ?N anomalous, no — untracked./reconcile is done (via /audit → /reconcile): the RV ledger is resolved,
every governance/spec finding is dispositioned, and the RV carries a
## Reconciliation Outcome section. If the reconciliation brief was empty
(no-op), the outcome confirms that explicitly.lib:reference/harvest.md before
closure — or consciously rejected. A clean slice may harvest nothing;
the conscious-rejection gate is what closure checks.doctrine check gate is green.Spec-coherence gate — confirm reconciliation is complete before done:
Before the terminal transition, verify every item from the audit's
reconciliation brief is resolved through one of four paths:
done REV
(revision status REV-N done). The REV rationale (revision-NNN.md)
carries the reconcile narrative.design via the
design back-edge (reconcile → design).
Additionally:design.md /
slice-NNN.md and recorded in the ## Reconciliation Outcome.done · await=none): every finding terminal
and the pass concluded (review conclude RV-NNN --basis …). A ledger
whose findings are all terminal — a zero-finding ledger included — reads
active · await=raiser until the raiser concludes it; conclude it, do not
raise a token finding. The absence of unresolved blockers is what gates the
transition, never the status string (a display summary, never a gate).## Reconciliation Outcome).
No free-floating "rejected" disposition is permitted — every finding
must land in one of the terminal states above.
If any item is unresolved, refuse close and return to /reconcile.
(The structural closure seam is the mechanical backstop; this gate is the
substantive check — the verb enforces; the skill verifies.)Commit cleanly: land .doctrine/** workflow artefacts in small, clean
conventional commits scoped with the slice id, rather than letting them
accumulate. Code and workflow edits go together or separately, whichever
commits cleanly first.
Stage the slug symlink.
*/newverbs lay out<kind>/NNN/and a sibling slug symlink<kind>/NNN-slug -> NNN(slice, review, revision, rec, …). A path-scopedgit add <kind>/NNN/stages the dir but misses the symlink, stranding it uncommitted. Stage both —git add <kind>/NNN*— or add the symlink explicitly. Checkgit statusfor a danglingNNN-slugbefore the final commit. 3a. Dispatched slice — integrate the admitted OID (post-audit only). If the slice was driven by/dispatch, project the audited units now:
When a candidate workflow is active this targets the immutable admitted
close_target OID (and --edge the admitted review_surface OID) under a
fast-forward-only CAS row — never a raw phase/*/review/* tip or the
mutable candidate ref, and never a close-time merge. A moved trunk refuses
(admit a superseding close-target candidate on the new base). This is the
only place --integrate runs — never at /dispatch conclude, only here,
post-audit.
Verify (tree-true). After --integrate --trunk, both checks
below must pass — do not proceed to step 4 unless they do:
(a) is the phantom-reverse-diff detector — the whole tracked tree, not
path-limited (a phantom reverse-diff can span any file the slice projected,
not just src/).
(b) reads the trunk row's planned_new_oid from the committed dispatch/<N>
journal — a tree-read, stable from this checkout — and diffs it against
the resolved trunk delivery ref (doctrine dispatch deliver-to, default
refs/heads/main); a difference means trunk does not hold the projected tip, so
integration did not land.
3b. Split lineage — the payload reached trunk out-of-band
(--record-integration). See lib:reference/dispatch-mechanics.md §
Split lineage — record an already-landed payload, don't advance trunk.
The close gate still refuses done ("dispatched but no
trunk row"). Record the earned row instead of hand-editing journal.toml:
Per lib:reference/dispatch-mechanics.md § Split lineage,
--record-integration asserts the payload is already an ancestor of trunk
and commits a single Verified trunk row. Then slice status <N> done reads
that row and passes. This is the
sanctioned replacement for a hand-written journal row; land the payload
out-of-band as git merge --no-ff phase/<N>-NN (or
the admitted candidate), not review/<N>.
reconcile (flip it with
doctrine slice status <id> reconcile if /audit didn't), then
doctrine slice status <id> done (<id> is the bare number, e.g. 40).
The closure seam enforces the order and refuses while an RV targeting the
slice carries an unresolved blocker. Re-run doctrine slice list and confirm
the ⚠ divergence marker is gone — authored status now agrees with the
rollup. (The terminal set is {done, abandoned}; closure here is the done
path — abandoning a slice is a separate decision, not this skill.)doctrine backlog edit <ID> --status resolved --resolution fixed (or the resolution that fits). A closed
slice with its origin still open is hygiene debt./reconcile. If closure depends on tolerated drift with material
tradeoffs, /consult before normalising around it.When slice status <id> done refuses with undischarged residual drift, each
flagged requirement needs an accept REC owned by the closing slice that
satisfies all three clauses:
move = accept — an affirm, not revise/redesign.[[status_delta]] naming the requirement whose to equals its
current authored status (the status the refusal prints).[[evidence_ref]] set ⊇ every distinct coverage key feeding
that requirement's composite, so fresh contradictory evidence cannot be excused
by a stale REC.Author it, then hand-edit the two tables:
Full predicate, rationale, and a worked example:
doctrine memory show mem.pattern.doctrine.close-drift-discharge-rec.
done, with the rollup in agreement.