@rafinery/cli 0.8.16 → 0.10.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 +81 -0
- package/bin/rafa.mjs +11 -0
- package/blueprint/.claude/agents/atlas.md +21 -3
- package/blueprint/.claude/agents/bloom.md +2 -2
- package/blueprint/.claude/agents/prism.md +42 -3
- package/blueprint/.claude/agents/sage.md +1 -1
- package/blueprint/.claude/commands/rafa.md +24 -13
- package/blueprint/.claude/rafa/contract.md +6 -0
- package/blueprint/.claude/rafa/hooks/brain-commit.mjs +4 -0
- package/blueprint/.claude/rafa/hooks/session-start.mjs +66 -0
- package/blueprint/.claude/skills/rafa-build/SKILL.md +111 -20
- package/blueprint/.claude/skills/rafa-improve/SKILL.md +22 -0
- package/blueprint/.claude/skills/rafa-leverage/SKILL.md +6 -1
- package/blueprint/.claude/skills/rafa-plan/SKILL.md +36 -1
- package/blueprint/.claude/skills/rafa-review/SKILL.md +16 -2
- package/blueprint/.claude/skills/rafa-sage/SKILL.md +8 -2
- package/blueprint/.claude/skills/rafa-scan/SKILL.md +4 -1
- package/lib/brain-repo.mjs +1 -1
- package/lib/checkpoint.mjs +12 -10
- package/lib/distiller/doctrine.mjs +5 -16
- package/lib/doctor.mjs +19 -1
- package/lib/facts.mjs +130 -0
- package/lib/gate/compile.mjs +12 -0
- package/lib/gate/verify-citations.mjs +78 -1
- package/lib/hydrate.mjs +45 -0
- package/lib/init.mjs +9 -1
- package/lib/leverage/engine.mjs +32 -3
- package/lib/leverage.mjs +11 -2
- package/lib/loop-cache.mjs +67 -0
- package/lib/mcp-client.mjs +12 -0
- package/lib/push.mjs +9 -1
- package/lib/reflex.mjs +5 -1
- package/lib/releases.mjs +51 -0
- package/lib/review.mjs +32 -6
- package/lib/session-facts.mjs +108 -0
- package/lib/skill-deps.mjs +377 -0
- package/lib/update.mjs +9 -0
- package/package.json +3 -2
- package/skills-bundle/frontend-design/LICENSE.txt +177 -0
- package/skills-bundle/frontend-design/SKILL.md +55 -0
- package/{LICENSE → skills-bundle/grill-me/LICENSE} +6 -6
- package/skills-bundle/grill-me/SKILL.md +7 -0
- package/skills-bundle/grill-me/agents/openai.yaml +5 -0
- package/skills-bundle/grilling/SKILL.md +53 -0
- package/skills-bundle/improve-codebase-architecture/HTML-REPORT.md +123 -0
- package/skills-bundle/improve-codebase-architecture/LICENSE +21 -0
- package/skills-bundle/improve-codebase-architecture/SKILL.md +71 -0
- package/skills-bundle/improve-codebase-architecture/agents/openai.yaml +5 -0
- package/skills-bundle/requesting-code-review/LICENSE +21 -0
- package/skills-bundle/requesting-code-review/SKILL.md +95 -0
- package/skills-bundle/requesting-code-review/code-reviewer.md +172 -0
- package/skills-bundle/skills-manifest.json +72 -0
- package/skills-bundle/tdd/LICENSE +21 -0
- package/skills-bundle/tdd/SKILL.md +36 -0
- package/skills-bundle/tdd/agents/openai.yaml +3 -0
- package/skills-bundle/tdd/mocking.md +59 -0
- package/skills-bundle/tdd/tests.md +77 -0
- package/skills-bundle/vercel-composition-patterns/AGENTS.md +946 -0
- package/skills-bundle/vercel-composition-patterns/README.md +60 -0
- package/skills-bundle/vercel-composition-patterns/SKILL.md +89 -0
- package/skills-bundle/vercel-composition-patterns/metadata.json +11 -0
- package/skills-bundle/vercel-composition-patterns/rules/_sections.md +29 -0
- package/skills-bundle/vercel-composition-patterns/rules/_template.md +24 -0
- package/skills-bundle/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills-bundle/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills-bundle/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills-bundle/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills-bundle/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills-bundle/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/skills-bundle/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills-bundle/vercel-composition-patterns/rules/state-lift-state.md +125 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,87 @@ 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.10.0 — wave 6: the capability arc (skill dependencies + agent upgrades)
|
|
8
|
+
|
|
9
|
+
rafa's agents get materially better at engineering — and the mechanism is the
|
|
10
|
+
owner's design: rafa **declares** third-party skill dependencies and installs
|
|
11
|
+
them **with your consent**, package-manager style, so the agents adopt YOUR
|
|
12
|
+
toolbox instead of hardcoding one.
|
|
13
|
+
|
|
14
|
+
- **The skill installer.** `rafa update`/`init` offers 7 declared skills (tdd,
|
|
15
|
+
frontend-design, vercel-composition-patterns, requesting-code-review,
|
|
16
|
+
improve-codebase-architecture, grill-me, and rafa's own grilling procedure)
|
|
17
|
+
with one-line reasons; on yes it installs them one at a time into the
|
|
18
|
+
**harness-neutral `.agents/skills/`** (one convention Claude Code, Codex,
|
|
19
|
+
and Cursor all read — Codex manifests ride along), verifies each
|
|
20
|
+
(frontmatter parses · sha256s match the tarball's own manifest · license
|
|
21
|
+
files present), and stamps `rafa.json`. Declining is remembered — re-offer
|
|
22
|
+
with `rafa update --skills`; `--yes` for CI; non-TTY without `--yes` skips
|
|
23
|
+
and stamps nothing. A declined set degrades gracefully, never breaks:
|
|
24
|
+
vendored cards never reference `.agents/` (pinned by test).
|
|
25
|
+
- **TDD by default** (atlas 4.0.0): eligible code tasks (tdd installed + a
|
|
26
|
+
harness detected) build red→green — the Done-check IS a failing test
|
|
27
|
+
authored first at a seam the dev approved at plan time; evidence (red
|
|
28
|
+
exit≠0 before green exit 0) rides the structured return; prism re-runs
|
|
29
|
+
green live and verifies red per validation tier. Refactor defers to review.
|
|
30
|
+
- **The design method**: UI tasks invoke frontend-design (token system,
|
|
31
|
+
signature element, critique-before-code) and consult Vercel's composition
|
|
32
|
+
rules (React-19-gated) — with the brain's design-system notes as the brief.
|
|
33
|
+
- **The grill gate** (prism 0.9.0): plans get a tier-bounded adversarial
|
|
34
|
+
interview before approval — grounding, unstated dependencies, VACUOUS
|
|
35
|
+
Done-checks (tautological tests caught), YAGNI. Devs also get `/grill-me`.
|
|
36
|
+
- **Severity-labeled findings** everywhere prism/review rule: Critical ·
|
|
37
|
+
Important · Minor — Minor never flips a verdict.
|
|
38
|
+
- **bloom's architecture method** (0.9.0): git-log heat scoping, the deletion
|
|
39
|
+
test, Confidence-lined candidates, first-slice-or-backlog — never big-bang.
|
|
40
|
+
- **Toolbox surfaces**: conductor 2.2.0 recalls `.agents/skills` in every
|
|
41
|
+
spawn slice; `rafa leverage --json` carries top-level `agentSkills` +
|
|
42
|
+
`skillDeps`; `rafa doctor` verifies installed skills against the bundle.
|
|
43
|
+
|
|
44
|
+
Adopt with `rafa update` — the skills prompt runs first, then the blueprint
|
|
45
|
+
sync. All licenses confirmed and vendored (MIT ×5, Apache-2.0 frontend-design).
|
|
46
|
+
|
|
47
|
+
## 0.9.0 — wave 5: trust plane + transport economics
|
|
48
|
+
|
|
49
|
+
The research-canvas QA dogfood session (2026-07-25) produced a P0–P3 bottleneck
|
|
50
|
+
backlog; its root causes converged with sage's first two learnings on the same
|
|
51
|
+
seam. This release lands the whole wave:
|
|
52
|
+
|
|
53
|
+
- **Strict loop events, no legacy path.** `report_loop_event` requires the
|
|
54
|
+
actor envelope (`model` · `agent` · `runner ∈ sandbox|ci|session`; mechanical
|
|
55
|
+
CLI emits stamp `model:"mechanical"`) and `verification {method: static|live,
|
|
56
|
+
tool?, evidence?}` on verdict/gate categories — the static-vs-executed
|
|
57
|
+
distinction is structural, so a fabricated "tests passed" can't survive the
|
|
58
|
+
schema. `dedupeKey` makes every emit idempotent; `tier` records the
|
|
59
|
+
validation tier the ruling ran at. Pre-0.9.0 emits are rejected server-side
|
|
60
|
+
(pre-launch: old CLIs discarded). Both sage learnings flipped accepted.
|
|
61
|
+
- **One beat per task boundary.** `patch_plan_item` patches ONE item's fields
|
|
62
|
+
(structure stays `push_plan`-only); `checkpoint_task` lands the item patch +
|
|
63
|
+
the prism-verdict loop event + decision records in ONE transaction,
|
|
64
|
+
idempotent on retry. A task boundary went from ~6 platform calls + a
|
|
65
|
+
full-tree resend to 2 beats.
|
|
66
|
+
- **Self-healing citations.** `verify-citations --fix` rewrites a drifted cite
|
|
67
|
+
when its token still lives at exactly ONE grep site (gone/ambiguous stay
|
|
68
|
+
failing — the checker never guesses), then re-runs clean. `rafa hydrate`
|
|
69
|
+
re-bases served cites against the local checkout on arrival.
|
|
70
|
+
- **`rafa facts` — the session-facts plane.** Bank a verified fact once (claim
|
|
71
|
+
+ the command/exit that proved it + dependsOn paths, sha-anchored); agents
|
|
72
|
+
read first and cite `SF-n unchanged`. Staleness is mechanical (dependsOn ∩
|
|
73
|
+
git diff since the verifying sha, working tree included).
|
|
74
|
+
- **The sage-due bridge.** `rafa checkpoint` caches loop-event shapes locally;
|
|
75
|
+
the SessionStart digest prints "sage due: N" with zero added platform calls,
|
|
76
|
+
and the conductor card makes honoring it a MUST — sage's trigger is
|
|
77
|
+
mechanical instead of discretionary.
|
|
78
|
+
- **`validation_tier` on plan tasks** (light|standard|full): bounds prism's
|
|
79
|
+
re-derivation depth only — the Done-check gate never relaxes.
|
|
80
|
+
- Cards/SOPs re-vendored: prism 0.8.0 (tool-authenticity rule · structured
|
|
81
|
+
return · bounded invariant citation) · atlas 3.9.0 (structured return ·
|
|
82
|
+
facts duty) · sage 0.4.0 (verification/actor/tier analysis dimensions) ·
|
|
83
|
+
conductor 2.1.0 (mechanical sage trigger). Review summary counts dedupe by
|
|
84
|
+
note id.
|
|
85
|
+
|
|
86
|
+
Adopt with `rafa update` (re-vendors hooks, cards, SOPs, contract).
|
|
87
|
+
|
|
7
88
|
## 0.8.16 — the session tail never strands (both planes, one beat)
|
|
8
89
|
|
|
9
90
|
Live-catch (2026-07-24, research-canvas): brain notes authored AFTER the last code
|
package/bin/rafa.mjs
CHANGED
|
@@ -46,6 +46,7 @@ const COMMANDS = [
|
|
|
46
46
|
"hydrate",
|
|
47
47
|
"dirty",
|
|
48
48
|
"reflex",
|
|
49
|
+
"facts",
|
|
49
50
|
"status",
|
|
50
51
|
"doctor",
|
|
51
52
|
"fold",
|
|
@@ -73,6 +74,8 @@ Commands:
|
|
|
73
74
|
Flags (init/update): --overwrite replace changed owned files without asking
|
|
74
75
|
--keep keep all changed owned files without asking
|
|
75
76
|
(default: ask per file; in a non-TTY it keeps them)
|
|
77
|
+
--skills re-offer declared skill dependencies (incl. declined)
|
|
78
|
+
--yes install all skill dependencies unprompted (CI)
|
|
76
79
|
compile Validate the brain against the contract → .rafa/manifest.json.
|
|
77
80
|
manifest The BRANCH manifest (lenient snapshot — WIP files land under
|
|
78
81
|
drafts, never fail). You never need to run this: the post-commit
|
|
@@ -113,6 +116,14 @@ Commands:
|
|
|
113
116
|
detected. List/--json; --consume <id> [verdict] AFTER banking it
|
|
114
117
|
through the gates (or judging it session-only). Corrections are
|
|
115
118
|
the highest-value knowledge signal — they must never evaporate.
|
|
119
|
+
facts The session-facts plane (wave 5.4 — memoized verification): bank a
|
|
120
|
+
VERIFIED fact once (claim + the command/exit that proved it +
|
|
121
|
+
dependsOn paths, sha-anchored); agents read first and cite
|
|
122
|
+
"SF-n unchanged" instead of re-deriving. Staleness is mechanical
|
|
123
|
+
(dependsOn ∩ git diff since the verifying sha) and NOT transitive —
|
|
124
|
+
declare the enclosing directory for subsystem-spanning facts
|
|
125
|
+
(breadth is the conservative move). add · invalidate ·
|
|
126
|
+
prune --stale · --json.
|
|
116
127
|
status Where the loop stands, from local state only: active plan +
|
|
117
128
|
task progress · stale count · corrections · conflicts.
|
|
118
129
|
--line = the one-line ambient form (statuslines/prompts) ·
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: atlas
|
|
3
|
-
version:
|
|
3
|
+
version: 4.0.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: >-
|
|
@@ -16,7 +16,7 @@ duties:
|
|
|
16
16
|
- "scan :: .claude/skills/rafa-scan/SKILL.md :: comprehensive breadth-first cited brain · verify-citations exits 0 · coverage honest (thin/gap stated, never hidden)"
|
|
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
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"
|
|
19
|
-
- "build-execution :: .claude/skills/rafa-build/SKILL.md :: implement per recalled knowledge · never hand-edit brain files around the gate · return what changed, cited"
|
|
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"
|
|
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
|
---
|
|
@@ -62,6 +62,22 @@ whole-codebase read happens in *your* window, not the conductor's, so the main s
|
|
|
62
62
|
stays lean. You **never spawn** other agents — subagents can't nest, so the conductor owns
|
|
63
63
|
the loop. Return summaries + on-disk artifacts, not the raw reads.
|
|
64
64
|
|
|
65
|
+
**Structured return (wave 5).** A build-execution report ends with the machine
|
|
66
|
+
block the conductor assembles Logs from — never re-paraphrased prose:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{ "filesChanged": ["path", "…"], "commitSha": "…",
|
|
70
|
+
"notes": "one-paragraph what/why",
|
|
71
|
+
"factsDiscovered": ["SF-n banked: <claim>", "…"] }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Session facts (wave 5 — read first, bank once).** Before re-deriving any
|
|
75
|
+
environment/tooling fact, read `.rafa/session-facts.json` (`rafa facts`) and
|
|
76
|
+
cite `SF-<n> unchanged` when it holds. When YOU verify something expensive
|
|
77
|
+
(a harness exists, an install works, an env constraint), bank it once:
|
|
78
|
+
`rafa facts add --claim="…" --command="…" --exit=N [--depends=a,b]` — the next
|
|
79
|
+
spawn inherits it instead of re-learning it.
|
|
80
|
+
|
|
65
81
|
## The brain is your index, once it exists
|
|
66
82
|
Generic at provision-time, repo-aware after the scan: **if a brain exists at
|
|
67
83
|
`.rafa/brain/`, consult it as your index before re-reading code** — route via its cited
|
|
@@ -91,7 +107,9 @@ Never act cold; never over-load.
|
|
|
91
107
|
*name* is a contract; its *value* is a secret. If a note genuinely needs a value, stop and ask
|
|
92
108
|
the dev — don't harvest it. (Enforced in [the scan skill](../skills/rafa-scan/SKILL.md) step 4.)
|
|
93
109
|
- **Toolbox-first execution (automatic — never an offer).** Before implementing any
|
|
94
|
-
task step, CHECK the repo's installed toolbox — committed `.claude/skills/`,
|
|
110
|
+
task step, CHECK the repo's installed toolbox — committed `.claude/skills/`, the
|
|
111
|
+
**harness-neutral `.agents/skills/`** (consent-installed skill dependencies —
|
|
112
|
+
tdd, frontend-design, vercel-composition-patterns are yours to INVOKE),
|
|
95
113
|
`.mcp.json` servers, commands — for a capability that already does it, and INVOKE
|
|
96
114
|
it (Skill tool / MCP) instead of hand-rolling. The conductor passes the matching
|
|
97
115
|
inventory slice in your spawn prompt; consult it first. Only what is actually
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bloom
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.9.0
|
|
4
4
|
model: opus # a false flag mutes the whole ledger — best model, never cheap
|
|
5
5
|
groundTruth: code-trend
|
|
6
6
|
description: >-
|
|
@@ -13,7 +13,7 @@ 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 · leverage-ranked · cite-checked (unresolved dropped) · ledger + debt trend regenerated"
|
|
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"
|
|
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
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"
|
|
19
19
|
- "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"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prism
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.9.0
|
|
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: >-
|
|
@@ -14,8 +14,8 @@ tools: Read, Grep, Glob, Bash, Write, mcp__rafinery
|
|
|
14
14
|
color: orange
|
|
15
15
|
duties:
|
|
16
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)"
|
|
17
|
-
- "plan-gate :: .claude/skills/rafa-plan/SKILL.md :: PASS = every task grounded in brain + code (none hallucinated) · every child
|
|
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; FAIL returns cited reasons to the producer"
|
|
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
|
+
- "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
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"
|
|
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
|
---
|
|
@@ -37,6 +37,45 @@ brain as a trusted index, whatever you are validating is the thing on trial —
|
|
|
37
37
|
against the code (ground truth) and the stated acceptance criteria. Trust nothing in
|
|
38
38
|
it until you've confirmed it.
|
|
39
39
|
|
|
40
|
+
**Tool authenticity (wave 5 — the npx-placeholder trap).** A tool result is
|
|
41
|
+
evidence ONLY if the tool actually ran: name the binary (path or resolved
|
|
42
|
+
command) and the REAL exit code. `npx <name>` can silently resolve a joke/
|
|
43
|
+
placeholder package and "pass" — a class that already produced one fabricated
|
|
44
|
+
verdict in the field. If you cannot execute the check (no keys, no deps, no
|
|
45
|
+
env), the claim is `method: "static"` — say so in the same breath, never
|
|
46
|
+
smooth it into an unqualified PASS. Fabricating a `live` result is the one
|
|
47
|
+
unforgivable failure: the whole trust model prices from it.
|
|
48
|
+
|
|
49
|
+
**Structured return (wave 5).** Your report ends with the machine block the
|
|
50
|
+
conductor assembles Logs and loop events from — never re-paraphrased prose:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{ "verdict": "PASS|ITERATE",
|
|
54
|
+
"evidence": [{ "claim": "…", "method": "static|live", "tool": "…", "exitCode": 0 }],
|
|
55
|
+
"residualRisk": "what was NOT proven, named — or the explicit empty string" }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The `evidence` entries feed `report_loop_event.verification` verbatim; the
|
|
59
|
+
static-vs-live split is structural, not prose discipline.
|
|
60
|
+
|
|
61
|
+
**Bounded invariant citation (wave 5 — no-redundant-reverification).** An
|
|
62
|
+
invariant YOU (or a prior prism pass this plan) verified once is citable as
|
|
63
|
+
`SF-<n> unchanged` **iff** `.rafa/session-facts.json` shows its `dependsOn`
|
|
64
|
+
untouched since its verifying sha (the session-start digest surfaces staleness;
|
|
65
|
+
`rafa facts` lists it). Re-deriving an unchanged, evidence-backed fact is waste,
|
|
66
|
+
not rigor. The bound is hard: anything NOT in the facts file — and everything
|
|
67
|
+
about the artifact under test itself — stays trust-nothing. **Invalidation is
|
|
68
|
+
NOT transitive** (dependsOn is intersected with the diff, imports are never
|
|
69
|
+
walked — pinned by test): trust a fact only as far as its declared breadth, and
|
|
70
|
+
when a fact you rely on spans a subsystem whose dependsOn names single files,
|
|
71
|
+
treat it as under-declared — re-verify instead of citing it.
|
|
72
|
+
|
|
73
|
+
**Validation tier (wave 5).** A task's `validation_tier` (plan §7) bounds your
|
|
74
|
+
RE-DERIVATION DEPTH — how much surrounding context you re-read and re-prove:
|
|
75
|
+
light = the Done-check itself + direct evidence · standard = + the touched
|
|
76
|
+
files' immediate seams · full = unbounded re-derivation. The Done-check gate
|
|
77
|
+
NEVER relaxes at any tier, and your emitted loop event carries the tier it ran at.
|
|
78
|
+
|
|
40
79
|
## Duties (each duty's bar is in the frontmatter; the SOP carries the procedure)
|
|
41
80
|
1. **Scan validation** — judge the brain in `.rafa/brain/` against the repo per
|
|
42
81
|
[the validate skill](../skills/rafa-validate/SKILL.md). Verdict + score + severity-
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
version: 2.0
|
|
2
|
+
version: 2.2.0
|
|
3
3
|
description: rafa — the repo's engineering SOP. Use whenever the dev wants to plan a feature or change, build/execute against the active plan, improve code health, or ground work in the repo's brain — intent counts, the dev does NOT need to type /rafa. Also explicit: /rafa <init|scan|improve|plan|build|push|leverage|migrate|update|help> [--brain-only]. Admin verbs (init/scan/push/migrate/update) run ONLY when explicitly invoked.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -59,10 +59,15 @@ MCP tools, checkpoints, pushes, decisions logging — is AGENT-INTERNAL machiner
|
|
|
59
59
|
dev speaks intent; YOU run the machinery. Never instruct the dev to run a command you
|
|
60
60
|
can run yourself. The only human acts: init (provision) · `npx rafa pull` (once per
|
|
61
61
|
clone) · ci-setup approval · npm publish. **Toolbox is a recall surface:** at bootstrap,
|
|
62
|
-
load the committed toolbox
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
load the committed toolbox — `.claude/skills/` (this harness) **and
|
|
63
|
+
`.agents/skills/` (the HARNESS-NEUTRAL third-party skills — one convention
|
|
64
|
+
Claude Code · Codex · Cursor all read; installed by `rafa update` with
|
|
65
|
+
consent, wave 6)** — plus `.mcp.json` and commands, alongside brain status
|
|
66
|
+
(`rafa leverage --json` is the deterministic read); pass the matching slice
|
|
67
|
+
into every atlas/bloom spawn prompt — agents USE the fit capability instead of
|
|
68
|
+
hand-rolling (only what's installed, never guessed; a DECLINED skill dep means
|
|
69
|
+
the SOP's fallback path, never a nag; personal `~/.claude/` stays
|
|
70
|
+
live-recommend-only). **Actor envelope:** stamp `actorMeta {model,
|
|
66
71
|
agent, runner: "session"}` on every state-plane write (checkpoints, plan pushes,
|
|
67
72
|
decisions, reports) and export `RAFA_ACTOR_MODEL` before CLI calls — the platform records
|
|
68
73
|
WHO/WHAT executed; "unreported" when unknown, never guessed.
|
|
@@ -240,14 +245,20 @@ explicitly typed; an ACCEPTED boundary offer counts as the explicit invocation.
|
|
|
240
245
|
|
|
241
246
|
## sage — the silent L5 observer (runs IMPLICITLY, zero-command; owner 2026-07-13)
|
|
242
247
|
|
|
243
|
-
Devs never type `/rafa sage`. **Trigger
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
Devs never type `/rafa sage`. **Trigger — MECHANICAL as of wave 5 (owner
|
|
249
|
+
2026-07-25):** the SessionStart digest computes it — a `[rafa · sage] sage due:
|
|
250
|
+
N loop events…` line (the checkpoint-written loop-event cache vs the learnings
|
|
251
|
+
ledger, compared locally). **When that line is present, spawning sage at the
|
|
252
|
+
next completion boundary — build final-verify · distill close · bootstrap — is
|
|
253
|
+
a MUST, not a judgment call**: the line IS the trigger condition already
|
|
254
|
+
evaluated; a discretionary trigger is how sage never fired organically. Spawn
|
|
255
|
+
per [rafa-sage](../skills/rafa-sage/SKILL.md); announce ONE line, proceed; its
|
|
256
|
+
proposals ride the NEXT bootstrap digest. No digest line = not due (skip
|
|
257
|
+
silently). Writing proposals is the just-do rung; the consent moment is
|
|
258
|
+
ACCEPTING one (accepted = a versioned, MR-reviewed card/SOP edit — proposals
|
|
259
|
+
never self-apply). `/rafa sage` is the explicit override. Full mechanics
|
|
260
|
+
(≥10-event threshold, `get_loop_events` shape read, scrub step, ledger schema,
|
|
261
|
+
the person-free/asset-free creed) live in the skill.
|
|
251
262
|
|
|
252
263
|
## migrate · update — brain-side schema migration (no skill; the intelligence-only half)
|
|
253
264
|
|
|
@@ -382,6 +382,7 @@ blocked_by: [payments-c2] # optional · item ids this waits on — a dependency
|
|
|
382
382
|
blocked_reason: "vendor sandbox access" # optional · external blocks (no dependency id to point at)
|
|
383
383
|
priority: 2 # optional · 0 none · 1 urgent · 2 high · 3 medium · 4 low (Linear scale)
|
|
384
384
|
estimate: 3 # optional · points (Linear estimate / Jira story points)
|
|
385
|
+
validation_tier: standard # optional · light|standard|full — bounds prism's re-derivation DEPTH only (wave 5); the Done-check gate itself never relaxes. Planner assigns from blast radius: contract/state/graph surface → full · types/docs/leaf-UI → light · default standard
|
|
385
386
|
branch: feat/webhooks # optional · ↔ Linear branchName
|
|
386
387
|
baseSha: abc123 # optional · commit it was cut from
|
|
387
388
|
domains: [payments] # optional · EPIC only · the blast radius — the brain link
|
|
@@ -573,12 +574,17 @@ state**, marked by `envelope.plane: "state"`:
|
|
|
573
574
|
| `resolve_working_file` | branch working set | `distilled` / `refuted` (+ cited note) at merge-to-main distillation; `keep-current` for adjudication decisions; CAS on status — a racing distill fails loudly |
|
|
574
575
|
| `fold_working_set` | branch working set | branch→parent-branch MECHANICAL fold (no LLM, no prism — rigor only at main): absent → re-keyed · identical → merged · divergent → `needs-adjudication` on the parent row |
|
|
575
576
|
| `push_plan` / `list_plans` / `update_plan_status` / `set_active_plan` / `log_decision` | **plans** — (repo) work objects | the push-on-approval channel (§7 v2): approval pushes the whole work-item TREE (items[], bodies stored); `list_plans` = names only; statuses push back (5-value enum — blocked is derived); `log_decision` records the deliberation trail (paraphrase + pivotal quotes); the active pointer is explicit, never inferred |
|
|
577
|
+
| `patch_plan_item` | plans (one item) | wave 5.2 — field-level patch on ONE item (no full-tree resend): provided fields replace, absent stay; CLEARING a field and any STRUCTURE change (kind/parent/add/remove/domains/external/merged) remain `push_plan`-only, so "a vanished optional field must not survive" keeps holding at tree granularity; snapshot-before-change rides noteRevisions like a re-push |
|
|
578
|
+
| `checkpoint_task` | plans + loopEvents + planDecisions (**ONE transaction**) | wave 5.2 — the ONE-beat boundary write: optional item patch + the loop-event ruling + decision records land atomically (all-or-nothing; `mcp.call` is an action, so composing the separate tools can never be atomic — this is one internalMutation). Idempotent end-to-end (patch no-ops on same values · loop event dedupes on `dedupeKey` · decisions dedupe on client-stable ids). The embedded loopEvent obeys `report_loop_event`'s exact rules — one rulebook, no side door. `checkpoint_sync` stays separate: per-file CAS partial-accept is a different failure model than an atomic beat |
|
|
576
579
|
| `report_improvement_status` | **events only** — no store | a LIVE session signal (bloom's fixed-in-passing during build). The improvement ledger row is untouched — it has ONE writer, the ingest (K1); the platform overlays the report as pending-reconciliation until the next brain push confirms it |
|
|
577
580
|
| `reconcile_claim` | **reconciliations queue** — (repo) run rows | executor claim (`plane:"state"`): ACID no-running-sibling assert → returns the attempt token; delegates to `reconciliations.claim`; stamps the actor envelope `{model, agent, runner}` (runner ∈ `sandbox`\|`ci`\|`session`, enum-checked at the boundary) on the row |
|
|
578
581
|
| `reconcile_heartbeat` | reconciliations queue | extends the wall-clock lease + sets the phase; **attempt-fenced** (a non-current attempt is rejected, nothing written); actor envelope re-stamped |
|
|
579
582
|
| `reconcile_log_append` | **reconciliationLogs** — the run log tail | batched chunks, **secret-screened PER LINE** (the same `looksLikeSecret` screen — a credential chunk is rejected by chunk/line index, nothing stored or echoed) + **attempt-fenced**; `seq`-ordered; UNLOGGED (emits its own `reconcile.log` event, counts only) |
|
|
580
583
|
| `reconcile_report` | reconciliations queue (+ knowledge node on success) | terminal outcome + node delta + meter; **attempt-fenced**; success COMPOSES the pointer advance atomically (insert node + move pointer, one mutation); refutation/deletion ride the success outcomes; actor envelope stamped |
|
|
581
584
|
| `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 |
|
|
585
|
+
| `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 |
|
|
586
|
+
| `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 |
|
|
587
|
+
| `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 |
|
|
582
588
|
|
|
583
589
|
State tools work with or without an ingested brain (a working set can exist —
|
|
584
590
|
and a plan can be pushed — before the first scan) and are exempt from the
|
|
@@ -181,6 +181,10 @@ try {
|
|
|
181
181
|
// rafa review's scored-ranges artifact (wave 2.3) — regenerated per
|
|
182
182
|
// review, machine state like distill-verdicts; never brain knowledge.
|
|
183
183
|
"review.json",
|
|
184
|
+
// wave 5: session-scoped machine state — memoized verification + the
|
|
185
|
+
// checkpoint-written loop-event cache the sage-due digest reads.
|
|
186
|
+
"session-facts.json",
|
|
187
|
+
"loop-events-tail.json",
|
|
184
188
|
];
|
|
185
189
|
const gi = join(rafa, ".gitignore");
|
|
186
190
|
const cur = existsSync(gi) ? readFileSync(gi, "utf8") : "";
|
|
@@ -300,6 +300,72 @@ try {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
// Session facts (wave 5.4 — memoized verification): banked verified facts +
|
|
304
|
+
// mechanical staleness (dependsOn ∩ git diff since the verifying sha, working
|
|
305
|
+
// tree included). Spawned agents read the file FIRST and cite "SF-n unchanged"
|
|
306
|
+
// instead of re-deriving. Local reads only — no platform call.
|
|
307
|
+
{
|
|
308
|
+
const doc = readJson(join(rafaDir, "session-facts.json"));
|
|
309
|
+
if (doc?.schemaVersion === 1 && Array.isArray(doc.facts) && doc.facts.length) {
|
|
310
|
+
let stale = 0;
|
|
311
|
+
for (const f of doc.facts) {
|
|
312
|
+
try {
|
|
313
|
+
const changed = execSync(`git diff --name-only ${f.verifiedAtSha}`, {
|
|
314
|
+
cwd: root,
|
|
315
|
+
encoding: "utf8",
|
|
316
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
317
|
+
})
|
|
318
|
+
.split("\n")
|
|
319
|
+
.filter(Boolean);
|
|
320
|
+
if (
|
|
321
|
+
(f.dependsOn ?? []).some((p) =>
|
|
322
|
+
changed.some((c) => c === p || c.startsWith(p.endsWith("/") ? p : p + "/")),
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
stale++;
|
|
326
|
+
} catch {
|
|
327
|
+
stale++; // unknown sha — fail-honest, count it stale
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
lines.push(
|
|
331
|
+
`[rafa · facts] ${doc.facts.length} session fact(s) banked (.rafa/session-facts.json — spawned agents read it FIRST and cite "SF-n unchanged" instead of re-deriving)` +
|
|
332
|
+
(stale ? ` · ${stale} STALE — re-verify or \`rafa facts prune --stale\`` : ""),
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Sage-due bridge (wave 5.5 — mechanical detection): the checkpoint-written
|
|
338
|
+
// loop-event cache vs the learnings ledger, compared LOCALLY (zero platform
|
|
339
|
+
// calls). Sage's trigger was a discretionary end-of-session SOP step and
|
|
340
|
+
// never fired organically — detection now lands front-of-session where
|
|
341
|
+
// reminders get obeyed; only the SPAWN stays with the conductor.
|
|
342
|
+
{
|
|
343
|
+
const cache = readJson(join(rafaDir, "loop-events-tail.json"));
|
|
344
|
+
if (cache?.schemaVersion === 1 && Array.isArray(cache.events)) {
|
|
345
|
+
let ledgerAt = null;
|
|
346
|
+
const ledgerPath = join(root, ".claude", "rafa", "learnings", "ledger.md");
|
|
347
|
+
if (existsSync(ledgerPath)) {
|
|
348
|
+
const m = readFileSync(ledgerPath, "utf8").match(
|
|
349
|
+
/^-\s*Generated:\s*([0-9]{4}-[0-9]{2}-[0-9]{2}(?:[T ][0-9:.Z+-]+)?)/m,
|
|
350
|
+
);
|
|
351
|
+
if (m) {
|
|
352
|
+
const t = Date.parse(m[1]);
|
|
353
|
+
if (Number.isFinite(t)) ledgerAt = t;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const fresh =
|
|
357
|
+
ledgerAt == null
|
|
358
|
+
? cache.events
|
|
359
|
+
: cache.events.filter((e) => Number.isFinite(e.at) && e.at > ledgerAt);
|
|
360
|
+
if (fresh.length >= 10)
|
|
361
|
+
lines.push(
|
|
362
|
+
`[rafa · sage] sage due: ${fresh.length} loop events since the last learnings pass` +
|
|
363
|
+
(ledgerAt == null ? " (no ledger yet — sage has never run here)" : "") +
|
|
364
|
+
` — spawn sage at the next completion boundary (zero-command; this line is the trigger, not a suggestion).`,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
303
369
|
// Benchmark liveness (harness-arc: the proof engine is workflow-woven, never a
|
|
304
370
|
// dev-typed command) — a scanned brain with no MEASURED benchmark is a gap the
|
|
305
371
|
// scan SOP's Prove-it step closes. Absence sensor only; never a nag mid-flow.
|
|
@@ -17,7 +17,7 @@ platform MCP (one read path — the same surface any third-party agent uses).
|
|
|
17
17
|
| Role | Agent | Job per task |
|
|
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
|
-
| **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). 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) |
|
|
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
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 |
|
|
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
|
|
|
@@ -47,22 +47,33 @@ platform MCP (one read path — the same surface any third-party agent uses).
|
|
|
47
47
|
**and append a dated entry to the child's `## Log`** (body links: markdown,
|
|
48
48
|
per [rafa-okf](../rafa-okf/SKILL.md)) — what was done, what was
|
|
49
49
|
decided, what surprised (body prose: displayed verbatim on the platform, never
|
|
50
|
-
parsed; the plan files at `.rafa/plans/<plan>/` ARE the local cache) →
|
|
51
|
-
task-done CHECKPOINT
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
parsed; the plan files at `.rafa/plans/<plan>/` ARE the local cache) → the
|
|
51
|
+
task-done CHECKPOINT is **ONE beat (wave 5), two calls total**, under the
|
|
52
|
+
session consent:
|
|
53
|
+
**(a) `checkpoint_task`** — the atomic boundary write (all-or-nothing,
|
|
54
|
+
idempotent on retry) carrying together: `patch: {status, body}` (the item's
|
|
55
|
+
new status + its full body with the fresh `## Log` entry — never a
|
|
56
|
+
whole-tree `push_plan` for one task); `loopEvent: {category:
|
|
57
|
+
"prism-verdict", outcome: PASS|ITERATE, subject: <task id>, tier: <the
|
|
58
|
+
task's validation_tier>, verification: <prism's evidence entry — method
|
|
59
|
+
static|live + tool + exit code, straight from its structured return>,
|
|
60
|
+
actorMeta: {model: <ruling model>, agent: "prism@<card ver>", runner:
|
|
61
|
+
"session"}, dedupeKey: "<task-id>·v<attempt>"}` (the emit rides the ruling's
|
|
62
|
+
OWN moment, never a session-end sweep; the dedupeKey makes a retried beat
|
|
63
|
+
count ONCE — the non-idempotent-emit learning, closed); and `decisions:
|
|
64
|
+
[...]` — each deliberation since the last beat with a CLIENT-STABLE id
|
|
65
|
+
(`<task-id>·d1`, `·d2` …): what came up, what was considered, what the DEV
|
|
66
|
+
chose, why (actor = the dev for steering, the agent for its own proposals;
|
|
67
|
+
PARAPHRASE + short verbatim quotes only where the wording carries the
|
|
68
|
+
decision — transcripts never land in shared stores; mirror each into the
|
|
69
|
+
item's `## Decisions` section).
|
|
70
|
+
**(b) `rafa checkpoint`** — the branch working set + sensor heartbeat +
|
|
71
|
+
brain mirror (the CLI beat; it also refreshes the loop-event cache the
|
|
72
|
+
sage-due digest reads).
|
|
73
|
+
`push_plan` remains for CREATION and structure changes only;
|
|
74
|
+
`update_plan_status`/`log_decision` stay valid but the one-beat call
|
|
75
|
+
replaces them at task boundaries. Checkpoint moments: task done · plan
|
|
63
76
|
approved · explicit ask · cadence · git push/pull — never session-end. The
|
|
64
|
-
loop-event emits ride the SAME checkpoint beats — one per outcome as it
|
|
65
|
-
occurs, monotonic, NEVER a session-end sweep. The
|
|
66
77
|
git-push boundary is MECHANICAL (M5): the pre-push hook runs `rafa checkpoint`
|
|
67
78
|
itself, non-blocking — the session still owns the task-done/plan-approved
|
|
68
79
|
moments. A checkpoint CONFLICT (a teammate's newer copy of the same file) is
|
|
@@ -71,10 +82,11 @@ platform MCP (one read path — the same surface any third-party agent uses).
|
|
|
71
82
|
3. **Brain changes mid-build — WHERE you are decides WHERE it goes.**
|
|
72
83
|
- **On the default branch (main):** run a full `/rafa scan` (regenerate →
|
|
73
84
|
prism → compile → push); the brain re-stamps at the new sha, so
|
|
74
|
-
`brain = f(code@sha)` stays exact.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
85
|
+
`brain = f(code@sha)` stays exact. gate-result loop events are
|
|
86
|
+
**MECHANICAL** (wave 5): the push gates emit them CLI-stamped — actor
|
|
87
|
+
envelope, `method: "live"` verification with the real exit code, and a
|
|
88
|
+
`(gate·sha·outcome)` dedupeKey. The session never hand-emits gate-result;
|
|
89
|
+
the double-emit class died with the non-idempotent-emit learning.
|
|
78
90
|
- **On any other branch:** the org brain is NEVER written from a branch —
|
|
79
91
|
it describes main, and a branch-state scan would poison it for everyone.
|
|
80
92
|
Invalidated/learned knowledge → the branch **working set**: hydrate the
|
|
@@ -106,6 +118,85 @@ platform MCP (one read path — the same surface any third-party agent uses).
|
|
|
106
118
|
scoped-refresh offer NOW (on main: refresh → gates → push; on a branch:
|
|
107
119
|
working-set edit → checkpoint), and `rafa dirty --consume` only after it ships.
|
|
108
120
|
|
|
121
|
+
## TDD-default (wave 6 — code tasks build red → green)
|
|
122
|
+
|
|
123
|
+
**Eligibility gate (deterministic, decided once per session):** the `tdd` skill
|
|
124
|
+
is installed (`.agents/skills/tdd/` — the toolbox slice says so) AND the repo
|
|
125
|
+
has a test harness — checklist, first hit wins: `package.json` `test` script ·
|
|
126
|
+
`vitest.config.*`/`jest.config.*` · `pytest.ini`/`pyproject [tool.pytest]` ·
|
|
127
|
+
`go.mod` with `*_test.go` · `Cargo.toml`. Bank the answer as a session fact
|
|
128
|
+
(`rafa facts add --claim="test harness: <runner>" --command="<detect>" --exit=0
|
|
129
|
+
--depends=package.json`) so no later spawn re-derives it. Not eligible → the
|
|
130
|
+
pre-wave path below, unchanged, plus a `factsDiscovered: ["tdd unavailable:
|
|
131
|
+
<reason>"]` note in atlas's return — bloom may later surface a tooling-fit
|
|
132
|
+
improvement; NEVER a mid-build nag.
|
|
133
|
+
|
|
134
|
+
**The loop (per the installed tdd skill — atlas INVOKES it; its anti-patterns
|
|
135
|
+
are prism's criteria):**
|
|
136
|
+
1. **Red** — atlas authors the failing test FIRST, at the seam the plan's
|
|
137
|
+
Done-check names (the seam was dev-confirmed at approval — never invented
|
|
138
|
+
here). Run it; it must FAIL for the right reason. Commit
|
|
139
|
+
`[<task-id>] test: red — <seam>` (full tier prefers the split commit; at
|
|
140
|
+
standard tier the evidence object below is the durable proof and red+green
|
|
141
|
+
may land as one commit).
|
|
142
|
+
2. **Green** — implement the minimal slice to exit 0. One seam, one test, one
|
|
143
|
+
vertical slice per cycle — never all-tests-then-all-code.
|
|
144
|
+
3. **Refactor is NOT part of the loop** — it belongs to the review stage
|
|
145
|
+
(tdd SKILL.md's own rule + the [rafa-review](../rafa-review/SKILL.md) gate;
|
|
146
|
+
bloom's no-big-bang directive is the same law).
|
|
147
|
+
Evidence rides atlas's structured return —
|
|
148
|
+
`evidence: [{claim: "red", tool: "<runner>", exitCode: 1}, {claim: "green",
|
|
149
|
+
tool: "<runner>", exitCode: 0}]` + `skillsUsed: ["tdd"]` — and
|
|
150
|
+
`how: via the tdd skill` lands in the item's `approach`.
|
|
151
|
+
|
|
152
|
+
**prism's verification, tier-scaled:** green is ALWAYS re-run live (tool
|
|
153
|
+
authenticity: binary + real exit code). Red at **standard** = attested from
|
|
154
|
+
atlas's evidence, labeled `method: "static"`; at **full** = re-run at the red
|
|
155
|
+
commit in a throwaway worktree (`git worktree add`), labeled `method: "live"`.
|
|
156
|
+
Mock discipline is a finding class: mocks only at system boundaries, never the
|
|
157
|
+
repo's own collaborators (the tdd skill's mocking reference is the criteria).
|
|
158
|
+
|
|
159
|
+
## UI tasks — the design method (wave 6)
|
|
160
|
+
|
|
161
|
+
**Trigger:** the task's epic `domains:` include a UI domain, or its target
|
|
162
|
+
files land in the app's component/route surfaces — the BRAIN's domain map
|
|
163
|
+
decides, never a hardcoded path list.
|
|
164
|
+
|
|
165
|
+
**Method (when the skills are installed — the toolbox slice says):** atlas
|
|
166
|
+
**INVOKES** `frontend-design` (Skill tool) for the two-pass plan — token
|
|
167
|
+
system (Color 4–6 named values · Type roles · Layout · the ONE signature
|
|
168
|
+
element), then self-critique against the brief before any code — and CONSULTS
|
|
169
|
+
`vercel-composition-patterns` for component structure (no boolean-prop
|
|
170
|
+
sprawl · compound components · state/actions/meta context · children over
|
|
171
|
+
render props), gating the `react19-*` rules on the repo's actual React version
|
|
172
|
+
(a React ≤18 repo skips them, stated in the return).
|
|
173
|
+
|
|
174
|
+
**Adherence vs distinctive — the brain decides:** when the brain documents a
|
|
175
|
+
design system (theme tokens, component conventions), those notes ARE the
|
|
176
|
+
brief and the skill's own "the brief's own words always win" rule applies —
|
|
177
|
+
adherence mode, distinctiveness spent within the system. No design-system
|
|
178
|
+
notes (greenfield/marketing surface) → distinctive mode, full method. Record
|
|
179
|
+
`how: via the frontend-design skill` (+ vercel-composition-patterns when
|
|
180
|
+
consulted). Skills declined → the pre-wave path + a `factsDiscovered` note.
|
|
181
|
+
|
|
182
|
+
## Spawn-prompt discipline (wave 5 — pay once, cite after)
|
|
183
|
+
|
|
184
|
+
- **Session facts first.** Every atlas/prism spawn prompt begins by pointing at
|
|
185
|
+
`.rafa/session-facts.json` (read first; cite `SF-n unchanged` where it holds;
|
|
186
|
+
bank new expensive verifications via `rafa facts add`). Six agents
|
|
187
|
+
re-deriving one environment fact was the QA session's headline waste.
|
|
188
|
+
- **Never restate card doctrine.** The card already binds the agent's creed
|
|
189
|
+
(prism's skepticism, atlas's toolbox-first) — a spawn prompt carries ONLY the
|
|
190
|
+
task-specific grounding: the task file, the exact target files/patterns, the
|
|
191
|
+
`validation_tier`, the facts pointer. Re-explaining the card in every prompt
|
|
192
|
+
is conductor inefficiency, not rigor.
|
|
193
|
+
- **Compact agent-to-agent register.** A subagent's primary reader is the
|
|
194
|
+
CONDUCTOR: terse-with-citations by default, ending in the structured return
|
|
195
|
+
(prism: `{verdict, evidence[], residualRisk}` · atlas: `{filesChanged,
|
|
196
|
+
commitSha, notes, factsDiscovered}`) — Logs and loop events assemble from
|
|
197
|
+
FIELDS, never re-paraphrased prose. Expand to full prose only on ITERATE or
|
|
198
|
+
when the human will read it directly.
|
|
199
|
+
|
|
109
200
|
**Lite plans** (single-child, from plan-lite) run the same per-task loop — the
|
|
110
201
|
Done-check gate never relaxes; only the ceremony around it shrinks (no bloom nudge,
|
|
111
202
|
single checkpoint + plan push at the end).
|