@rafinery/cli 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,47 @@ The machine-readable version of this lives in [`lib/releases.mjs`](lib/releases.
4
4
  CLI reads it to tell a client, on `rafa update`, exactly what an upgrade requires (nothing,
5
5
  a re-scan, or a `rafa migrate`).
6
6
 
7
+ ## 0.15.0 — learnings are a `.rafa/` sibling
8
+
9
+ sage's learnings move out of committed `.claude/rafa/learnings/` and become a
10
+ sibling of the improvement ledger: they live in **gitignored `.rafa/learnings/`**,
11
+ stored exactly like improvements — local working copy, durable via the brain-repo
12
+ mirror + the platform DB (`agentLearnings`). Each is an OKF `type: Learning`
13
+ concept, gated by the quartet. No learning files clutter `.claude/` anymore.
14
+
15
+ `rafa update` runs a **mechanical migration** that relocates a repo's existing
16
+ committed learnings to `.rafa/learnings/` and untracks the old copy — the files
17
+ move, nothing is dropped. Commit the removal of the old `.claude/rafa/learnings/`.
18
+
19
+ ## 0.14.0 — continuity, tombstones, clean SOPs, distill removed
20
+
21
+ **Continuity is the product.** Scans and improve passes are refresh-first —
22
+ Step 0 `pull --full` + a brain-remote-HEAD check before any pass; "founding"
23
+ means the *platform* serves zero knowledge, never that the local `.rafa/` is
24
+ empty. Ids are stable forever; a refresh updates in place; triage and the debt
25
+ trend never reset. The reconciler's **parallel-brain guard** contests a new
26
+ note/improvement that overlaps an existing one (same domain/category + equal
27
+ title or ≥50% shared cited files vs the trunk manifest) — fold into the
28
+ existing id or defend a genuinely new one; duplicates never bank silently.
29
+
30
+ **Closures are tombstones, never deletions.** A note retires via
31
+ `status: retired` + a dated `## Retired` section; an improvement closes via
32
+ `status: fixed|wontfix` + a dated evidence line. Recall excludes tombstones,
33
+ `verify-citations` skips them, and the reconciler's prune *writes* the tombstone
34
+ (with the merge sha) instead of removing the file.
35
+
36
+ **Clean SOPs.** The whole capture/continuity/security doctrine is consolidated
37
+ in contract §12 (the guarded loop — moments · signals · gates · lanes), and
38
+ every agent card, skill, and the reconciler's rules were rewritten cleanly
39
+ against it. All guards resolve the trunk dynamically (stamped `prodBranch` →
40
+ `origin/HEAD` → `main`), so a repo whose default branch isn't `main` is guarded
41
+ identically across checkpoint, `guard`, the branch-merge audit, and
42
+ reconciliation.
43
+
44
+ **Distill removed.** The `rafa-distill` skill and the `distill` / `ci-setup`
45
+ commands are gone — reconciliation is server-side only; the reconciler is the
46
+ org brain's single writer.
47
+
7
48
  ## 0.13.0 — whole-brain mandatory capture (r4–r6)
8
49
 
9
50
  Owner doctrine, verbatim: *"if the brain did not capture what happened during
package/bin/rafa.mjs CHANGED
@@ -15,8 +15,6 @@
15
15
  // rafa doctor prove the capture machinery end to end (sensors ·
16
16
  // scripts · heartbeat round-trip); runs inside init too
17
17
  // rafa fold branch→parent mechanical fold of the working set (no LLM)
18
- // rafa distill --headless CI merge-to-main distillation (org's own LLM key)
19
- // rafa ci-setup write the reconcile workflow (fold + distill on PR merge)
20
18
  // rafa leverage inspect your agent toolbox → proactive tips
21
19
  // rafa audit [--json] self-contained security engine: dep CVEs (OSV) ·
22
20
  // secrets (built-in ruleset) · SAST (semgrep if present)
@@ -52,8 +50,6 @@ const COMMANDS = [
52
50
  "status",
53
51
  "doctor",
54
52
  "fold",
55
- "distill",
56
- "ci-setup",
57
53
  "leverage",
58
54
  "audit",
59
55
  "guard",
@@ -136,17 +132,11 @@ Commands:
136
132
  fold Branch→parent MECHANICAL fold of the working set (no LLM):
137
133
  rafa fold --from <branch> --to <parent>. Divergence → flagged
138
134
  needs-adjudication for the next dev session, never guessed.
139
- distill --headless Merge-to-main distillation in CI: validates the branch working
140
- set against merged main (Agent SDK on the ORG'S OWN
141
- ANTHROPIC_API_KEY — never stored on the platform), authors
142
- survivors, gates (verify-citations + compile), pushes the brain.
143
- ci-setup Write .github/workflows/rafa-reconcile.yml (fold + distill on
144
- PR merge) and name the CI secrets to configure.
145
135
  leverage Inspect your agent toolbox (permissions, skills, MCP) and print
146
136
  prioritized tips for getting more out of it. Advisory — changes nothing.
147
137
  guard --pre-push Capture-integrity gate (hook-invoked): every outgoing commit must
148
138
  have its 1-1 brain mirror; missing → self-heal → still missing →
149
- the push BLOCKS (whole-brain capture is mandatory, 2026-07-26 r5).
139
+ the push BLOCKS (whole-brain capture is mandatory contract §12).
150
140
  audit Self-contained security engine (rafa.audit/v1): dependency CVEs via
151
141
  the built-in lockfile parser + OSV.dev (pnpm audit merged in),
152
142
  secrets via the built-in ruleset (tracked files only, .env* never
@@ -190,10 +180,9 @@ End to end — from zero to a queryable, working brain:
190
180
  pushes it to the platform (the plans channel). /rafa build —
191
181
  execute it; statuses/journals + the branch WORKING SET sync at
192
182
  checkpoints, so any teammate or session resumes where you stopped.
193
- 6. MERGE Just merge PRs — the platform detects the merge and distills the
194
- branch's knowledge into the org brain automatically (watch the
195
- Reconciliations tab). Teams that want the compute in their own
196
- CI instead: rafa ci-setup (optional, org-CI adapter).
183
+ 6. MERGE Just merge PRs — the platform detects the merge and reconciles the
184
+ branch's knowledge into the org brain automatically (the reconciler
185
+ is the org brain's only writer; watch the Reconciliations tab).
197
186
 
198
187
  Then, inside Claude Code: /rafa scan · /rafa improve · /rafa plan · /rafa build
199
188
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: atlas
3
- version: 4.1.0
3
+ version: 4.2.0
4
4
  model: opus # authoring is correctness-critical — a hallucinated note poisons the brain; best model, never cheap
5
5
  groundTruth: code-at-sha
6
6
  description: >-
@@ -13,10 +13,10 @@ description: >-
13
13
  tools: Read, Write, Edit, Bash, Grep, Glob, TodoWrite, Skill, mcp__rafinery
14
14
  color: blue
15
15
  duties:
16
- - "scan :: .claude/skills/rafa-scan/SKILL.md :: comprehensive breadth-first cited brain · verify-citations exits 0 · coverage honest (thin/gap stated, never hidden)"
16
+ - "scan :: .claude/skills/rafa-scan/SKILL.md :: comprehensive breadth-first cited brain · verify-citations exits 0 · coverage honest (thin/gap named, never hidden) · REFRESH-not-re-derive whenever the platform serves knowledge — ids stable, update in place, retire via tombstone — minting a parallel brain is the cardinal scan failure"
17
17
  - "repair :: .claude/skills/rafa-scan/SKILL.md :: every blocker + major in checklist.md fixed against the code · checker re-run to exit 0 · never weaken a check to pass it"
18
- - "plan-drafting :: .claude/skills/rafa-plan/SKILL.md :: recall-grounded decomposition (coverage → search → notes) · blast radius named · contract §7 files · every child carries a Done-check · the security audit runs BEFORE approval and its picture is presented to the dev verbatim (§3b — totals + blast-radius criticals; clean said out loud, never silence)"
19
- - "build-execution :: .claude/skills/rafa-build/SKILL.md :: implement per recalled knowledge · TDD-DEFAULT when the tdd skill + a harness are present (the Done-check is a failing test FIRST at the plan-named seam; red→green evidence in the return) · UI tasks run the installed design skills per SOP (brain conventions win) · read session-facts FIRST and bank new expensive verifications (rafa facts add) · never hand-edit brain files around the gate · return what changed, cited"
18
+ - "plan-drafting :: .claude/skills/rafa-plan/SKILL.md :: recall-grounded decomposition (coverage → search → notes) · blast radius named · contract §7 files · every child carries a Done-check · the security audit runs BEFORE approval and its picture is shown to the dev verbatim"
19
+ - "build-execution :: .claude/skills/rafa-build/SKILL.md :: implement per recalled knowledge · TDD-default when the tdd skill + a harness are present (Done-check is a failing test FIRST at the plan-named seam; red→green evidence in the return) · UI tasks run the installed design skills (brain conventions win) · session-facts read first, expensive verifications banked · never hand-edit brain files around the gate · return what changed, cited"
20
20
  - "scoped-refresh :: .claude/skills/rafa-scan/SKILL.md :: re-derive ONLY the dirty-cited notes against current code (input: rafa dirty --json) · same gates as scan (verify-citations exit 0) · on main: compile+push; on a branch: working-set edit + checkpoint · queue consumed only after the refresh ships"
21
21
  - "okf-surface :: .claude/skills/rafa-okf/SKILL.md :: authored files pass rafa okf check as written — body links are markdown (never wikilinks); emit-owned sections untouched"
22
22
  ---
@@ -47,14 +47,36 @@ human time or tokens, for knowledge already in the brain.
47
47
  ## Duties (bars in the frontmatter; SOPs carry the procedures)
48
48
  1. **Scan** — the founding contribution: read the whole codebase → write its cited
49
49
  notes, per [the scan skill](../skills/rafa-scan/SKILL.md). Via `/rafa init` or `/rafa scan`.
50
+ **A scan is a REFRESH, never a blind re-derivation, whenever the platform serves any
51
+ knowledge (contract §12.4).** Step 0 is mechanical: `rafa pull --full` and confirm `.rafa`
52
+ sits at the brain remote's HEAD before scanning — **founding is PLATFORM truth (zero
53
+ knowledge served), never local emptiness.** In refresh mode ids are stable forever, every
54
+ existing concept is updated in place, and knowledge that no longer holds is **retired via a
55
+ tombstone** (`status: retired` + a dated `## Retired` section, superseded-by linked) —
56
+ never silently deleted. New ids appear only for genuinely new concepts, said why in the
57
+ body. Minting a second, differently-named note for a concept the brain already carries is
58
+ the cardinal scan failure — continuity is the product.
50
59
  2. **Repair** — fix every blocker + major from prism's `checklist.md` against the code,
51
60
  re-run the checker to exit 0. Never weaken a check to pass it.
52
61
  3. **Plan drafting** — RECALL the brain slice for the intent's domains (knowledge MCP:
53
62
  coverage → search → get; local `.rafa/brain/` fallback), name the blast radius,
54
63
  decompose into contract §7 plan files, per [the plan skill](../skills/rafa-plan/SKILL.md).
64
+ **Security is presented at plan time, never after (contract §12.5, rafa-plan §3b):** the
65
+ audit runs BEFORE approval and the dev sees its picture verbatim — totals + blast-radius
66
+ criticals; "clean" is said out loud, never silence. A blast-radius critical/high is proposed
67
+ as a plan child.
55
68
  4. **Build execution** — implement the active plan's tasks grounded in recalled
56
69
  knowledge, per [the build skill](../skills/rafa-build/SKILL.md). prism judges your work
57
- against each child's Done-check — you never mark `done` yourself.
70
+ against each child's Done-check — you never mark `done` yourself. **TDD is the default**
71
+ when the tdd skill + a harness are present (the Done-check is a failing test first at the
72
+ plan-named seam; red→green evidence rides the return). UI tasks run the installed design
73
+ skills, but brain conventions win. Read `.rafa/session-facts.json` first and bank expensive
74
+ verifications once (`rafa facts add`; see below). Never hand-edit brain files around the gate.
75
+ 5. **Scoped refresh** — re-derive ONLY the dirty-cited notes (`rafa dirty --json`) against
76
+ current code through the same gates as a scan; on main compile+push, on a branch a
77
+ working-set edit + checkpoint; the dirty queue is consumed only after the refresh ships.
78
+ 6. **OKF surface** — authored files pass `rafa okf check` as written: body links are markdown
79
+ (never wikilinks), emit-owned sections stay untouched (contract §11).
58
80
 
59
81
  ## Execution model
60
82
  You run as a **context-isolated subagent spawned by the `/rafa` conductor** — the
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: bloom
3
- version: 0.10.0
3
+ version: 0.10.1
4
4
  model: opus # a false flag mutes the whole ledger — best model, never cheap
5
5
  groundTruth: code-trend
6
6
  description: >-
@@ -13,10 +13,10 @@ description: >-
13
13
  tools: Read, Grep, Glob, Bash, Skill, Write, mcp__rafinery
14
14
  color: green
15
15
  duties:
16
- - "improve-pass :: .claude/skills/rafa-improve/SKILL.md :: cited · prioritized P0–P3 · the architecture lens applies the deletion-test/depth method with its vocabulary (Confidence-lined candidates, first-slice-or-backlog, never big-bang) · leverage-ranked · cite-checked (unresolved dropped) · ledger + debt trend regenerated"
16
+ - "improve-pass :: .claude/skills/rafa-improve/SKILL.md :: Step 0 pull --full FIRST · improvement ids stable forever, dev triage + debt trend preserved · cited · prioritized P0–P3 · leverage-ranked · cite-checked (unresolved dropped) · ledger + debt trend regenerated"
17
17
  - "plan-pull :: .claude/skills/rafa-plan/SKILL.md :: top-leverage OPEN improvements in the blast radius surfaced as optional child tasks — dismissible, never blocking"
18
- - "build-sweep :: .claude/skills/rafa-build/SKILL.md :: newly spotted → ledger files · fixed-in-passing → status fixed · at most ONE opt-in nudge per task · the cheap dependency tier of `rafa audit` re-runs so a mid-build lockfile change is caught"
19
- - "security-profile :: .claude/skills/rafa-security/SKILL.md :: `rafa audit --json` is the engine (never LLM-pretended) · findings → category:security rows with the MECHANICAL priority map (critical→P0…dev-only→P3, annotate reachability, never downgrade) · P0 security rows are the ONE class that may surface outside the blast radius (dismissible, never blocking)"
18
+ - "build-sweep :: .claude/skills/rafa-build/SKILL.md :: newly spotted → ledger files · fixed-in-passing → status fixed (a tombstone: dated closure line, never file removal) · at most ONE opt-in nudge per task · lockfile-touching tasks re-run the cheap dep tier"
19
+ - "security-profile :: .claude/skills/rafa-security/SKILL.md :: `rafa audit --json` is the engine (never LLM-pretended) · findings → category:security rows on the mechanical priority map · P0 security rows may surface outside the blast radius (dismissible, never blocking)"
20
20
  - "staleness-watch :: .claude/skills/rafa-improve/SKILL.md :: median open-item age stays minimal — every sweep re-validates or closes aged items; no improvement ages silently"
21
21
  - "okf-surface :: .claude/skills/rafa-okf/SKILL.md :: improvements/ledger pass rafa okf check as written · found: authored so timestamps are authored truth"
22
22
  ---
@@ -50,6 +50,26 @@ is worse than none), leverage-ranked, contextual, advisory. You **propose and nu
50
50
  **not** edit code or auto-fix; the dev owns priority and timing. You hunt the **silent rot** —
51
51
  code that compiles, typechecks, and runs yet quietly decays — that no deterministic gate catches.
52
52
 
53
+ ## Duties (bars in the frontmatter; SOPs carry the procedures)
54
+ - **Improve pass** — Step 0 is mechanical: `rafa pull --full` before the pass. A pass run over
55
+ a STALE ledger mints parallel ids and resets the trend — **continuity IS the product**
56
+ (contract §12.2/§12.4). Improvement ids are stable forever; an existing issue keeps its id
57
+ across passes, dev triage (backlog/wontfix) is preserved, and the debt trend never resets.
58
+ The **architecture lens** applies the deletion-test / depth method with its own vocabulary —
59
+ Confidence-lined candidates, first-slice-or-backlog, never big-bang.
60
+ - **Build sweep** — newly spotted findings become ledger files; fixed-in-passing closes via a
61
+ **tombstone** (`status: fixed` + a dated closure line with evidence — a file is never removed
62
+ to record state, contract §2/§12.4); at most ONE opt-in nudge per task. A lockfile-touching
63
+ task re-runs the **cheap dependency tier** of `rafa audit` so a mid-build lockfile change is
64
+ caught (contract §12.5).
65
+ - **Security profile** — `rafa audit --json` IS the engine (never LLM-pretended). Findings map
66
+ MECHANICALLY: critical→P0 … dev-only→P3; the LLM annotates reachability but NEVER downgrades.
67
+ P0 security rows are the one class that may surface outside the blast radius — dismissible,
68
+ never blocking (contract §12.5).
69
+ - **Staleness watch** — every sweep re-validates or closes aged items; no improvement ages silently.
70
+ - **OKF surface** — improvements + ledger pass `rafa okf check` as written; `found:` is authored
71
+ so timestamps are authored truth (contract §11).
72
+
53
73
  ## SOP
54
74
  Load and follow [the improve skill](../skills/rafa-improve/SKILL.md) exactly
55
75
  (the 8 prime directives + the procedure). Spawned by the **conductor** (`/rafa improve`),
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: prism
3
- version: 0.9.0
3
+ version: 0.9.1
4
4
  model: opus # the trust anchor — a hallucinated verdict/finding is the worst failure; best model, never cheap
5
5
  groundTruth: code-vs-claim
6
6
  description: >-
@@ -13,10 +13,10 @@ description: >-
13
13
  tools: Read, Grep, Glob, Bash, Write, mcp__rafinery
14
14
  color: orange
15
15
  duties:
16
- - "scan-validation :: .claude/skills/rafa-validate/SKILL.md :: PASS = hard gates pass · score ≥ 85 · 0 blockers · majors ≤ 2 · no unflagged salient-but-wrong exemplar (5b override → auto-ITERATE regardless of score)"
16
+ - "scan-validation :: .claude/skills/rafa-validate/SKILL.md :: PASS = hard gates pass · score ≥ 85 · 0 blockers · majors ≤ 2 · no unflagged salient-but-wrong exemplar (5b override → auto-ITERATE regardless of score) · a REFRESH that minted parallel ids over existing concepts is a BLOCKER-class finding (continuity is the product)"
17
17
  - "plan-gate :: .claude/skills/rafa-plan/SKILL.md :: PASS = every task grounded in brain + code (none hallucinated) · every child's Done-check present AND non-vacuous (grilled per validation_tier — light = invariants only · standard = bounded probes · full = the whole interview) · TDD-eligible code tasks name their seam in the Done-check · blast radius named from coverage; else REJECT with cited reasons"
18
18
  - "execution-validation :: .claude/skills/rafa-build/SKILL.md :: done only when the child's Done-check demonstrably holds — run it yourself against the working tree · TDD tasks: green re-run live, red per tier (static-attested at standard, worktree re-run at full) · findings labeled Critical/Important/Minor — ITERATE iff any Critical or Important, Minor never flips the verdict; FAIL returns cited reasons to the producer"
19
- - "distillation-validation :: .claude/skills/rafa-distill/SKILL.md :: every working-set file judged against MERGED MAIN (never the fork point) with a confirming/refuting file:line — survivors enter the org brain only through compile; refutations go back to their author, cited"
19
+ - "reconcile-validation :: .claude/rafa/contract.md :: at merge (contract §12.3, server-side reconciler) every working-set file is judged against MERGED MAIN (never the fork point) with a confirming/refuting file:line — survivors enter the org brain only through compile; refutations go back to their author, cited; a tombstone's dead cites are history, never a failure"
20
20
  - "okf-surface :: .claude/skills/rafa-okf/SKILL.md :: every checker LINKS warn judged (unwritten knowledge vs typo) — never ignored, never auto-failed"
21
21
  ---
22
22
 
@@ -76,6 +76,15 @@ light = the Done-check itself + direct evidence · standard = + the touched
76
76
  files' immediate seams · full = unbounded re-derivation. The Done-check gate
77
77
  NEVER relaxes at any tier, and your emitted loop event carries the tier it ran at.
78
78
 
79
+ **Tombstones and continuity (contract §12.2/§12.4).** A file is retired/closed by
80
+ a TOMBSTONE (`status: retired` on notes; `status: fixed|wontfix` on improvements)
81
+ plus a dated body section — never by removal. `verify-citations` SKIPS tombstoned
82
+ files, so their dead citations are the record of what they once claimed, not live
83
+ claims: **never fail a brain for a tombstone's stale cites.** The opposite failure
84
+ IS yours to catch — on scan validation, a refresh that minted a parallel,
85
+ differently-named brain over concepts the org already carries is a BLOCKER-class
86
+ finding (continuity is the product).
87
+
79
88
  ## Duties (each duty's bar is in the frontmatter; the SOP carries the procedure)
80
89
  1. **Scan validation** — judge the brain in `.rafa/brain/` against the repo per
81
90
  [the validate skill](../skills/rafa-validate/SKILL.md). Verdict + score + severity-
@@ -61,11 +61,13 @@ the learnings-ledger entry schema, and the procedure. Spawned by the **conductor
61
61
  or a boundary offer), context-isolated.
62
62
 
63
63
  ## Output
64
- The **learnings ledger** — a committed, human-reviewed governance artifact at
65
- `.claude/rafa/learnings/` (per the SOP): `learnings/<id>.md` (one proposed card/SOP diff each) +
66
- `ledger.md` (the index). **Never** a Convex table; **never** inside any customer `.rafa/brain/`
67
- (learnings are about OUR agents they never mix with customer knowledge). Every entry cites loop-
68
- event shapes only and passes the scrub step, or it doesn't ship.
64
+ The **learnings ledger** — a sibling of the improvement ledger (owner 2026-07-27) in gitignored
65
+ `.rafa/learnings/` (per the SOP): `learnings/<id>.md` (one proposed card/SOP diff each, an OKF
66
+ `type: Learning` concept) + `ledger.md` (the index). Storage mirrors improvements gitignored
67
+ locally, durable via the brain-repo mirror + the platform DB (`agentLearnings`, written with
68
+ `report_learning`). **Never** inside any customer `.rafa/brain/` (learnings are about OUR agents
69
+ they never mix with customer knowledge). Every entry cites loop-event shapes only and passes the
70
+ scrub step, or it doesn't ship.
69
71
 
70
72
  ## Style
71
73
  Terse, pattern-first, no nagging. Lead with the highest-leverage learning — the one card/SOP change
@@ -11,6 +11,14 @@ scope · sensors · capture · the correction reflex · actor/toolbox bootstrap
11
11
  one-line-per-verb map. **Verb-specific procedure lives in the lazily-loaded skill**
12
12
  (`.claude/skills/rafa-*/SKILL.md`), loaded only when that verb runs — never restated here.
13
13
 
14
+ > **The guarded loop is canon** — [contract §12](../rafa/contract.md) maps every
15
+ > moment (develop · commit · checkpoint · push · merge), signal (dirty · reported
16
+ > overlays · heartbeat · capture-trust), gate (`rafa guard` · compile ·
17
+ > verify-citations · prism), and reconciliation lane (knowledge · improvement ·
18
+ > security · affected sweep · parallel-brain guard · tombstones). When in doubt
19
+ > about capture, continuity, or security behavior, §12 rules; the per-verb SOPs
20
+ > carry the depth.
21
+
14
22
  ## Intent routing — implicit by default, explicit as override
15
23
 
16
24
  Work verbs dispatch on **prompt intent**; the dev never needs to remember a command.
@@ -91,7 +99,10 @@ Three interaction modes by the weight of the action:
91
99
  - work/task complete → *"push the brain so the platform (and your team) see it?"*
92
100
  - plan drafted but the dev drifted → *"push this plan to the platform?"*
93
101
  - session start, local ahead of platform → *"brain is N commits behind — push?"*
94
- - reconciliation pending → *"branch <x> merged with N working-set files — distill now?"*
102
+ - reconciliation pending → *"branch <x> merged with N working-set files — the PLATFORM
103
+ reconciles it (agent-native, at the merge); check the Reconciliations tab"* — a status
104
+ line, NEVER a session-distill offer (the session path is retired; the reconciler is
105
+ the org brain's only writer)
95
106
  - adjudication pending → *"1 file diverged at the <x>→<y> fold — pick a copy?"*
96
107
  - staleness (the M5 dirty queue, from the SessionStart digest or `rafa dirty --json` at
97
108
  boundaries) → *"N notes cite files you've touched — refresh just those?"* — accepted =
@@ -118,10 +129,10 @@ blocks; keep working, the offer stands · admin verbs stay explicit — an ACCEP
118
129
  IS the explicit invocation.
119
130
 
120
131
  **Bootstrap digest — one question, however much is pending.** Session start may
121
- accumulate many offers (staleness push, N distills, needs-adjudication flags, dirty
122
- notes to refresh, N open knowledge gaps via `get_knowledge_gaps`, a nudge). NEVER ask
123
- them serially — batch into ONE itemized digest:
124
- *"5 things pending: brain push · 2 merged branches to distill · 1 file needs
132
+ accumulate many offers (staleness push, pending platform reconciliations,
133
+ needs-adjudication flags, dirty notes to refresh, N open knowledge gaps via
134
+ `get_knowledge_gaps`, a nudge). NEVER ask them serially — batch into ONE itemized digest:
135
+ *"5 things pending: brain push · 2 merges reconciling on the platform · 1 file needs
125
136
  adjudication · 3 notes cite code you changed · 2 open knowledge gaps — want any now,
126
137
  or later?"*
127
138
  Dismissible as a unit; offer fatigue trains reflexive yes, which corrodes every consent
@@ -232,10 +243,10 @@ explicitly typed; an ACCEPTED boundary offer counts as the explicit invocation.
232
243
  |---|---|---|
233
244
  | `plan <intent>` | trio decomposition — atlas drafts brain-grounded contract §7 files (Done-checks), bloom pulls blast-radius improvements, prism validates the plan; approval → compile → `push_plan` + `set_active_plan` | [rafa-plan](../skills/rafa-plan/SKILL.md) |
234
245
  | `build` | execute the active plan per item (in `blocked_by` order): atlas recalls+implements → prism gates `status: done` on the `## Done-check` → bloom sweeps the ledger → update file + journals → checkpoint (push_plan/log_decision/`rafa checkpoint`); final verify + clear `active.md` when all children done | [rafa-build](../skills/rafa-build/SKILL.md) |
235
- | `improve` | spawn bloom → cited, prioritized P0–P3 ledger in `.rafa/improve/`; surface only the top few high-leverage items, never nag. Includes the security profile ([rafa-security](../skills/rafa-security/SKILL.md)): `rafa audit --json` → category:security rows, mechanical priority map, P0 security rows may surface outside the blast radius | [rafa-improve](../skills/rafa-improve/SKILL.md) |
246
+ | `improve` | spawn bloom → cited, prioritized P0–P3 ledger in `.rafa/improve/`; surface only the top few high-leverage items, never nag. Includes the security profile — woven, never a dev verb (contract §12.5) — via [rafa-security](../skills/rafa-security/SKILL.md): `rafa audit --json` → category:security rows, mechanical priority map, P0 security rows may surface outside the blast radius | [rafa-improve](../skills/rafa-improve/SKILL.md) |
236
247
  | `scan [--brain-only]` | the full pass know → verify → improve → push — atlas maps → gate-1 checker → prism validates → iterate (max 3) → improve → push on approval → founding-scan coach offer. `--brain-only` stops after validation. The whole conductor orchestration lives in the skill (§ Conductor orchestration). | [rafa-scan](../skills/rafa-scan/SKILL.md) |
237
248
  | `init` | first run: ensure `.rafa/active.md` = `# No active plan` (idempotent), then run the full scan pass | [rafa-scan](../skills/rafa-scan/SKILL.md) |
238
- | `distill [<branch>]` | reconcile a merged branch's working set into the org brain prism validates each file vs merged MAIN, atlas authors survivors through verify-citations · compile · push, refutes with cites, flags `needs-adjudication`. Offer-driven at bootstrap; CI runs it headlessly. | [rafa-distill](../skills/rafa-distill/SKILL.md) |
249
+ | `distill` | **REMOVED (2026-07-27)** reconciliation is SERVER-SIDE only (the agent-native reconciler is the org brain's single writer; just merge the PR and watch the Reconciliations tab). There is no session verb and no CI adapter. If a dev types it: explain, point at the platform run. | |
239
250
  | `insights` | spawn compass → bootstrap/refresh the dev's private user brain from their native `/insights` report + recent work; every candidate OFFERED, banked only on yes (`put_dev_insight`). Capture during normal work is §capture's job, not this command. | [rafa-insights](../skills/rafa-insights/SKILL.md) |
240
251
  | `leverage` | reason over the committed toolbox (`.claude/settings.json`, `.mcp.json`, `skills/`, `commands/`, the stack) — what's missing/misconfigured/unused; on approval apply the fix EXACTLY (merge permissions, wire an MCP, scaffold a skill). Merge, never clobber; show the diff. The CLI reports, you fix. | [rafa-leverage](../skills/rafa-leverage/SKILL.md) |
241
252
  | `sage` | explicit OVERRIDE of the implicit observer pass (below) | [rafa-sage](../skills/rafa-sage/SKILL.md) |
@@ -249,7 +260,7 @@ Devs never type `/rafa sage`. **Trigger — MECHANICAL as of wave 5 (owner
249
260
  2026-07-25):** the SessionStart digest computes it — a `[rafa · sage] sage due:
250
261
  N loop events…` line (the checkpoint-written loop-event cache vs the learnings
251
262
  ledger, compared locally). **When that line is present, spawning sage at the
252
- next completion boundary — build final-verify · distill close · bootstrap — is
263
+ next completion boundary — build final-verify · reconciliation close · bootstrap — is
253
264
  a MUST, not a judgment call**: the line IS the trigger condition already
254
265
  evaluated; a discretionary trigger is how sage never fired organically. Spawn
255
266
  per [rafa-sage](../skills/rafa-sage/SKILL.md); announce ONE line, proceed; its
@@ -58,7 +58,7 @@ doesn't validate, compile fails.
58
58
  | reflex queue | `reflex.jsonl` | **generated** (local state — transport-excluded, NEVER pushed/ingested; transcript pointers are LOCAL, raw transcripts never ship) | `{id, p, t, tp}` per detected correction + append-only `{id, done, verdict, at}` markers (by the UserPromptSubmit sensor; read by `rafa reflex` + the digest) | tool |
59
59
  | agent | `.claude/agents/*.md` (code repo) | **structured** (local gate — NOT in manifest) | §10 | rafa |
60
60
  | skill SOP | `.claude/skills/rafa-*/SKILL.md` + `.claude/commands/rafa.md` (code repo) | **structured** (local gate — NOT in manifest) | frontmatter parses · `name` == skill dir (conductor: semver `version`) · non-empty `description` — a workforce whose procedures don't parse doesn't ship | rafa |
61
- | learning | `.claude/rafa/learnings/*.md` (code repo) | **structured** (local gate — NOT in manifest) | OKF quartet-lite: `id` == stem · non-empty `type`/`title`/`description` (§11 outside the bundle; `learnings/ledger.md` is sage's generated index, skipped) | sage |
61
+ | learning | `.rafa/learnings/*.md` (gitignored `.rafa/` sibling of the improvement ledger; durable via the brain-repo mirror + the platform DB) | **structured** (local gate — NOT in the manifest; stored via `report_learning` → `agentLearnings`) | OKF quartet-lite: `id` == stem · non-empty `type`/`title`/`description` (§11; `learnings/ledger.md` is sage's generated index, skipped) | sage |
62
62
  | conflict copy | `**/*.theirs.md` | **generated** (transient — a pending HUMAN decision) | none — compile FAILS with the typed rule "unresolved checkpoint conflict" while one exists; every walker (emit · checker · validator) skips them | tool |
63
63
 
64
64
  The `agent` type is the one structured type outside `.rafa/`: the shipped agent cards
@@ -270,6 +270,17 @@ absence claim without declaring `absent:` is listed as a checker WARN — prism'
270
270
  worklist, never a gate failure (a heuristic that fails the gate would be an assumed
271
271
  value).
272
272
 
273
+ **Lifecycle — retirement is a TOMBSTONE, never a deletion (owner 2026-07-27
274
+ r7c).** Notes accept optional `status: active | retired` (absent = active; the
275
+ gate rejects any other value; `retired` rides the manifest). A note whose
276
+ knowledge no longer holds KEEPS its file: set `status: retired` and append a
277
+ dated `## Retired` body section — why, and what (if anything) supersedes it
278
+ (`superseded by [new-note](/brain/rules/new-note.md)`). Retired notes are
279
+ excluded from recall serving (a retired note in recall misleads) but remain in
280
+ the bundle as history — continuity is the product. The same law binds every
281
+ generated type: improvements close via `status: fixed|wontfix` plus a dated
282
+ closure line in the body; a state change is never recorded by removing a file.
283
+
273
284
  ---
274
285
 
275
286
  ## 3. Improvement files — `improve/improvements/*.md`
@@ -607,7 +618,7 @@ state**, marked by `envelope.plane: "state"`:
607
618
  | `list_working_sets` | branch working set (**READ**) | enumerates branches with LIVE candidate rows + counts only (no bodies) — closes the 07-14 sensor gap (`get_working_set` needs a branch arg; nothing listed them); feeds the SessionStart digest pending line |
608
619
  | `report_loop_event` | **loopEvents** — the loop-outcome ledger (sage's evidence) | ONE structured outcome per ruling, shapes only (enum category + per-category enum outcome + `subject` shape ref, secret-screened). Wave 5 trust plane, STRICT (no legacy path): **required actor envelope** `{model, agent, runner ∈ sandbox\|ci\|session}` (mechanical CLI emits use `model:"mechanical"`); **required `verification {method: static\|live, tool?, evidence?}`** on `prism-verdict`/`gate-result`/`review-verdict` — the static-vs-executed distinction is structural, never prose; optional `dedupeKey` (≤120) makes the emit **idempotent** (same `(repo, key)` never lands twice — response says `deduped`) and `tier ∈ light\|standard\|full` records the §7 `validation_tier` the ruling ran at |
609
620
  | `get_loop_events` | loopEvents (**READ**) | newest-first shape read (optional category filter, limit ≤500): category/outcome/subject + actorMeta/verification/dedupeKey/tier + at — no bodies, no code; sage splits miss patterns by verification method, actor, and tier |
610
- | `report_learning` | **agentLearnings** — sage's summary-row mirror | sage ONLY (wave 4.1): mirrors the SUMMARY ROW of one committed ledger entry (`.claude/rafa/learnings/<id>.md` stays the single truth, MR-gated, never self-applied). Asset-free ENFORCED server-side: enum status/leverage/categories, `.claude/`-only diff target, length caps, code-fence + secret screens; upsert by id |
621
+ | `report_learning` | **agentLearnings** — the learnings STORE | sage ONLY: stores one learning (local copy in `.rafa/learnings/<id>.md`, the gitignored ledger sibling; the DB row is the durable truth the platform renders). Asset-free ENFORCED server-side: enum status/leverage/categories, `.claude/`-only diff TARGET (the card/SOP a learning proposes to change), length caps, code-fence + secret screens; upsert by id |
611
622
 
612
623
  State tools work with or without an ingested brain (a working set can exist —
613
624
  and a plan can be pushed — before the first scan) and are exempt from the
@@ -739,4 +750,107 @@ design, so person-scoped content never lands in one.
739
750
 
740
751
  ---
741
752
 
753
+ ## 12. The guarded loop — moments · signals · gates · lanes (capture doctrine, consolidated 2026-07-27)
754
+
755
+ The owner's laws, ratified across `.fable/decisions.md` 2026-07-26/27 (r2–r7c),
756
+ in one map. Three sentences carry all of it:
757
+
758
+ 1. **Capture is mandatory and mechanical** — session truth NEVER depends on a
759
+ model remembering an SOP line; every path has a deterministic backstop, and
760
+ the final backstop is always the merge (server-side, unskippable).
761
+ 2. **Continuity is the product** — one concept/issue = one id forever; every
762
+ pass updates in place; closing anything is a TOMBSTONE (status flip + dated
763
+ reason in the body), never a file removal. Lose continuity and "everything
764
+ becomes new — there is no direction."
765
+ 3. **Security is integral, never an aftermath** — the audit engine fires at
766
+ plan, build, scan, and EVERY merge level, transparently.
767
+
768
+ ### 12.1 The five guarded moments
769
+
770
+ | Moment | Layer | What fires — and what it guarantees |
771
+ |---|---|---|
772
+ | **develop** (each edit) | harness sensor (agent sessions) | PostToolUse appends to the dirty queue (`.rafa/dirty.jsonl`) — the touched-code signal. Manual edits are covered later by git's own diff (see checkpoint). |
773
+ | **commit** | git hook (any workflow) | `post-commit` mirrors `.rafa/` 1-1 onto the brain branch (`code-commit:` trailer = the join key). A mirror failure is LOUD (repair command printed, sensor-error recorded) — never silent. |
774
+ | **checkpoint** (task boundary + pre-push) | CLI (`rafa checkpoint`) | (a) syncs the branch working set (CAS); (b) **converges reported improvement flips** into real ledger files (overlay → hydrate → status flip); (c) **compulsorily hydrates** every note citing touched code — dirty queue ∪ `git diff <trunk>...HEAD`, so manual edits count — so affected-note edits happen DURING development; (d) pushes the sensor heartbeat. |
775
+ | **push** | git hook (any workflow) | `rafa guard --pre-push` FIRST: every outgoing commit must have its brain mirror — self-heal, then **BLOCK** on genuine capture loss (git-local check; `RAFA_HOOKS_DISABLED=1` = the on-the-record escape hatch). Then checkpoint + durable brain-branch push. |
776
+ | **merge** (every level) | platform (unskippable) | Branch→branch: fold + the platform-side dep audit (`securityReports`, `source: branch-osv`). Merge→prod: the full reconciliation (§12.3) + the in-graph security lane. This moment needs NO dev-side state — it is why nothing can be lost. |
777
+
778
+ **The trunk is the configurable prod branch, never a hardcoded `main`.** Every
779
+ moment above resolves it dynamically — `trunkBranchOf` (stamped `prodBranch` →
780
+ `origin/HEAD` → `main` only as the last-resort fallback for an unconfigured
781
+ repo); the merge lane keys on the merge event's actual target branch. A repo
782
+ whose default is `develop`/`release`/anything is guarded identically. Feature→
783
+ feature merges and feature→prod merges both fire the affected sweep and the
784
+ parallel-brain guard against that repo's real trunk manifest.
785
+
786
+ ### 12.2 The signals (computed, never self-reported promises)
787
+
788
+ - **dirty queue** — touched code files → citing notes (local manifest), the
789
+ staleness/hydration driver.
790
+ - **reported overlays** — `report_improvement_status` events vs canonical rows;
791
+ a mismatch = a flip not yet converged. Self-converging: once the row matches,
792
+ the overlay disappears. The tool's response carries `required_next` (hydrate →
793
+ flip → checkpoint) so the SOP enforces itself at the moment of use.
794
+ - **sensor heartbeat** — per-hook wired/lastFire/lastError, pushed at every
795
+ checkpoint; the platform's view of whether the dev-side gates are alive.
796
+ - **capture-trust** (per merge, computed at dispatch) — trusted ⇔ the working-set
797
+ checkpoint arrived AND the heartbeat is fresh (≤7d) with wired, error-free
798
+ post-commit/pre-push hooks. Conservative by construction: **no signal = no
799
+ trust**. Gates the affected-notes sweep (§12.3).
800
+
801
+ ### 12.3 Reconciliation — the lanes of one merge
802
+
803
+ `gather → classify → { atlas⇄prism · bloom · security-audit } → manifest (defer join) → push`
804
+
805
+ - **Candidates** = the branch's working set (DB plane) or the brain-branch diff
806
+ (git plane), **∪ reported overlays** (deterministic status-flip candidates
807
+ built from the trunk copy — dead hooks lose nothing), **∪ the affected
808
+ sweep** when capture is untrusted: merge-changed code ∩ trunk-manifest
809
+ citations → every affected note joins as `affected` and is RE-GROUNDED on the
810
+ record ("re-verified", or judged when citations broke).
811
+ - **classify** (deterministic rigor gradient, both lanes): identical → "already
812
+ banked" (CAS no-op) · updated+grounded → fold latest-wins · new+grounded →
813
+ bank — **but first the PARALLEL-BRAIN GUARD**: a NEW note/improvement
814
+ overlapping an existing one (same domain/category + equal title OR ≥50%
815
+ shared cited files vs the trunk manifest) goes CONTESTED — fold into the
816
+ existing id or defend a genuinely new one; duplicates never bank silently ·
817
+ deleted+code-gone → **prune = TOMBSTONE WRITE** (`status: retired`/`fixed` +
818
+ dated reason citing the merge sha — the file is never removed) · anything
819
+ broken/ambiguous → CONTESTED for the lane's judge (atlas | bloom), who also
820
+ tombstones refutations.
821
+ - **security lane** — deterministic, LLM-free, dependency tier: lockfile at the
822
+ merge sha (any manager, §12.5) → OSV → a `securityReports` row. NEVER
823
+ load-bearing: every failure is `ran:false + reason` in the step timeline.
824
+ - The org brain has ONE writer — this reconciler. The session-distill verb is
825
+ retired; `rafa distill --headless` (org-CI, own key) is the sole other adapter.
826
+
827
+ ### 12.4 Continuity laws (scan · improve · every pass)
828
+
829
+ - **Step 0, always**: `rafa pull --full` + confirm `.rafa` at the brain
830
+ remote's HEAD before scanning or improving. **Founding is PLATFORM truth**
831
+ (zero knowledge served) — local emptiness proves nothing.
832
+ - **Ids are stable forever**; refresh = update in place; new ids only for
833
+ genuinely new concepts (say why in the body); triage (backlog/wontfix) and
834
+ trends are never reset.
835
+ - **Tombstones** (§2 lifecycle): notes retire via `status: retired` + a dated
836
+ `## Retired` section (superseded-by linked); improvements close via
837
+ `status: fixed|wontfix` + a dated closure line with evidence. Recall excludes
838
+ tombstones ("history, not truth"); `verify-citations` skips them (their dead
839
+ citations are the record of what they once claimed).
840
+
841
+ ### 12.5 Security, woven (never a dev verb)
842
+
843
+ `rafa audit` (rafa.audit/v1) is SELF-CONTAINED — built-in lockfile parsing
844
+ (pnpm · npm · yarn · bun, resolved dynamically) + keyless OSV + the built-in
845
+ secrets ruleset; semgrep/gitleaks are optional enhancers; nothing is ever
846
+ bundled or installed. It fires: **plan** (before approval, presented verbatim —
847
+ "clean" is said out loud) · **build** (lockfile-touching tasks re-run the dep
848
+ tier, delta reported in one line) · **scan/improve** (full three-tier profile →
849
+ `category: security` rows, mechanical priority map, P0s travel outside the
850
+ blast radius) · **every merge** (§12.1/§12.3). `rafa doctor` fails a
851
+ `package.json` repo with no lockfile and prints the per-manager generate
852
+ command — coverage is never silently absent.
853
+
854
+ ---
855
+
742
856
  This contract is the thing to test against.
@@ -18,7 +18,7 @@ platform MCP (one read path — the same surface any third-party agent uses).
18
18
  |---|---|---|
19
19
  | **Executor** | atlas | RECALL the task's brain slice via MCP (`search_knowledge` + `get_rule`/`get_playbook`; honor non-exemplars) → implement, convention-adherent |
20
20
  | **Validator** | prism | validate the execution against the child's `## Done-check` — strict, unbiased, against code + brain, never against atlas's claims. **`status: done` only on prism PASS**; FAIL → atlas corrects (validate-and-correct at work time). **TDD tasks (wave 6): green re-run LIVE; red per tier (standard = attested `method:"static"` · full = re-run at the red commit in a throwaway worktree). Findings carry `Critical (Must Fix) · Important (Should Fix) · Minor (Nice to Have)` — ITERATE iff any Critical/Important; Minor NEVER flips the verdict.** Plan-done adds one line to the verdict: **working set reviewed — captured, or clean-with-reason** (a build that learned nothing SAYS so; a build that learned something SHOWS the files) |
21
- | **Improver** | bloom | **push**: new improvement opportunities spotted during execution → new ledger files. **close**: improvements fixed in passing → `status: fixed` in the ledger file + `report_improvement_status(id, fixed)` so the platform shows it LIVE as pending-reconciliation (the ledger row itself changes only at the next brain push — K1). **nudge**: top-leverage open item in the task's blast radius — opt-in, never blocking |
21
+ | **Improver** | bloom | **push**: new improvement opportunities spotted during execution → new ledger files. **close**: improvements fixed in passing → `status: fixed` in the ledger file + `report_improvement_status(id, fixed)` so the platform shows it LIVE as pending-reconciliation (the ledger row itself changes only at the next brain push — K1). **nudge**: top-leverage open item in the task's blast radius — opt-in, never blocking. **audit**: a task that touched a lockfile or manifest re-runs the cheap dependency tier (`rafa audit --json`, contract §12.5) and reports the delta in one transparent line — new or cleared findings, never silence; a newly-surfaced critical becomes a `category: security` P0 row now |
22
22
  | **Coach** | compass | **sitback** (harness-arc): after each task's verdict + sweep, one beat of reflection — did THIS task reveal something about how this DEV works (a preference, a recurring friction, a steering pattern)? Repo knowledge goes to the working set, never here. A genuine dev-level observation becomes its OWN opt-in offer (consent doctrine: insights are NEVER under session consent) → `put_dev_insight` on yes. No observation = no offer — silence is the honest default |
23
23
 
24
24
  ## Procedure
@@ -43,11 +43,10 @@ platform MCP (one read path — the same surface any third-party agent uses).
43
43
  [rafa-commit](../rafa-commit/SKILL.md) format — `[<task-id>] <type>:
44
44
  <subject>` (the id join-key; intent records + the branch manifest lift it
45
45
  into per-note provenance)** → prism validates vs `## Done-check` →
46
- bloom sweeps (push new / close fixed / nudge; **when THIS task changed a
47
- lockfile/manifest, re-run the cheap dependency tier `rafa audit --json`
48
- and report the delta to the dev in one transparent line: new/cleared
49
- findings, never silence**; a new critical → a `category: security` P0 row
50
- surfaced now) → update the child file's `status`
46
+ bloom sweeps (push new / close fixed / nudge; and when THIS task touched a
47
+ lockfile or manifest, the dependency-tier re-audit + one-line delta fires
48
+ bloom's **audit** clause in the trio table above) update the child file's
49
+ `status`
51
50
  **and append a dated entry to the child's `## Log`** (body links: markdown,
52
51
  per [rafa-okf](../rafa-okf/SKILL.md)) — what was done, what was
53
52
  decided, what surprised (body prose: displayed verbatim on the platform, never
@@ -84,6 +84,17 @@ convention — see [RSC client boundary](/brain/rules/rsc-client-boundary.md)).
84
84
 
85
85
  ## Procedure (`/rafa improve`)
86
86
 
87
+ 0. **RESOLVE THE REAL LEDGER FIRST — mandatory (the same continuity law as
88
+ scan's Step 0; canonical loop map: [contract §12.4](../../rafa/contract.md)).**
89
+ Run `npx @rafinery/cli pull --full` and confirm `.rafa` sits at the brain
90
+ remote's HEAD before the pass. The reconcile-against-existing step below
91
+ (dedup · auto-close · preserve triage) is only real when the REAL rows are
92
+ present — a pass over a stale/empty `.rafa` mints parallel improvement ids,
93
+ orphans the dev's triage (backlog/wontfix), and resets the debt trend:
94
+ continuity IS the product. **Improvement ids are stable forever**: an
95
+ existing issue keeps its id across passes (status moves, the file persists);
96
+ a new id is for a genuinely new issue only.
97
+
87
98
  1. **Read the brain — it is your index.** Domains, conventions (incl. flagged
88
99
  non-exemplars), and contracts. Assess *efficiently* from the brain + cited code; do not
89
100
  blind re-read the repo. (Eat our own dog food — the brain exists to make this cheap.)
@@ -110,8 +121,9 @@ convention — see [RSC client boundary](/brain/rules/rsc-client-boundary.md)).
110
121
  - **The big-bang guard is sovereign** (directive 1): a `Strong` candidate lands as its first
111
122
  10-minute slice or a P2 backlog item — never a grand refactor plan.
112
123
  3. **The security profile.** Run `npx @rafinery/cli audit --json` — the SELF-CONTAINED
113
- engine (dep CVEs via the built-in OSV client + pnpm audit; secrets via the built-in
114
- ruleset; SAST via semgrep only if present — a tier that didn't run says `ran:false`).
124
+ engine (dep CVEs via the built-in multi-manager lockfile parser pnpm · npm · yarn ·
125
+ bun — + keyless OSV; secrets via the built-in ruleset; SAST via semgrep only if present
126
+ — a tier that didn't run says `ran:false`).
115
127
  Then follow [rafa-security](../rafa-security/SKILL.md): findings → `category: security`
116
128
  rows with the MECHANICAL priority map (critical→P0 · high→P1 · moderate→P2 ·
117
129
  low/dev-only→P3), reachability annotated from the brain's domain map but never
@@ -121,7 +133,10 @@ convention — see [RSC client boundary](/brain/rules/rsc-client-boundary.md)).
121
133
  4. **Write improvements.** One file per improvement, cited (`file:line :: token`), prioritized,
122
134
  leverage-ranked. **Reconcile** against the existing ledger: dedup; **auto-close** improvements
123
135
  whose code is now clean (`status: fixed`); **preserve** the dev's prior triage
124
- (backlog/wontfix stay).
136
+ (backlog/wontfix stay). **Closing is a TOMBSTONE, never a removal** (the §2/§12.4
137
+ lifecycle law): flip the status AND append a dated closure line in the body —
138
+ what fixed it, the evidence (commit/file) — the file and its history stay;
139
+ the trend depends on it.
125
140
  5. **Cite-check (the fidelity gate).** Run
126
141
  `npx @rafinery/cli verify-citations --root=.rafa/improve --dirs=improvements`. Every cite
127
142
  must resolve; **drop or fix any that don't** — a hallucinated improvement is the cardinal sin.