@rafinery/cli 0.5.0 → 0.7.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/bin/rafa.mjs +37 -5
  3. package/blueprint/.claude/agents/atlas.md +2 -1
  4. package/blueprint/.claude/agents/sage.md +66 -0
  5. package/blueprint/.claude/commands/rafa.md +214 -269
  6. package/blueprint/.claude/rafa/contract.md +204 -115
  7. package/blueprint/.claude/rafa/hooks/post-tool.mjs +62 -0
  8. package/blueprint/.claude/rafa/hooks/pre-push +24 -0
  9. package/blueprint/.claude/rafa/hooks/session-start.mjs +229 -0
  10. package/blueprint/.claude/rafa/hooks/statusline.mjs +113 -0
  11. package/blueprint/.claude/rafa/hooks/user-prompt-submit.mjs +87 -0
  12. package/blueprint/.claude/skills/rafa-build/SKILL.md +20 -5
  13. package/blueprint/.claude/skills/rafa-distill/SKILL.md +6 -1
  14. package/blueprint/.claude/skills/rafa-plan/SKILL.md +7 -0
  15. package/blueprint/.claude/skills/rafa-sage/SKILL.md +201 -0
  16. package/blueprint/.claude/skills/rafa-scan/SKILL.md +55 -5
  17. package/blueprint/.claude/skills/rafa-validate/SKILL.md +15 -2
  18. package/lib/benchmark.mjs +573 -0
  19. package/lib/blueprint.mjs +11 -1
  20. package/lib/brain-repo.mjs +10 -4
  21. package/lib/ci-setup.mjs +2 -0
  22. package/lib/claude-config.mjs +77 -0
  23. package/lib/dirty.mjs +114 -0
  24. package/lib/distill.mjs +4 -0
  25. package/lib/gate/compile.mjs +293 -44
  26. package/lib/gate/verify-citations.mjs +214 -23
  27. package/lib/githook.mjs +54 -0
  28. package/lib/init.mjs +18 -0
  29. package/lib/pull.mjs +7 -0
  30. package/lib/push.mjs +21 -0
  31. package/lib/reflex.mjs +76 -0
  32. package/lib/releases.mjs +35 -0
  33. package/lib/status.mjs +152 -0
  34. package/lib/update.mjs +13 -0
  35. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,103 @@ 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.6.0 — core solidity: checker v2 + the M5 capture engine
8
+
9
+ **Adopt with:** `npx @rafinery/cli@latest update` — re-vendors the new lockstep hook
10
+ scripts (`.claude/rafa/hooks/`), merges the sensor hooks into `.claude/settings.json`
11
+ (never clobbers yours), and installs the per-clone git pre-push boundary. Brain data
12
+ unchanged; no re-scan. Teammates get the git hook at their next `rafa pull`.
13
+
14
+ **The ratchet (checker v2)** — the two catches prism recommended in the 2026-06-08 live
15
+ run are now deterministic gates in `rafa verify-citations`:
16
+
17
+ - **Absence (B3)**: a note that claims something does NOT exist declares
18
+ `absent: <token>` (repeatable, anchor-style). Every declared absence is re-grepped
19
+ every run (docs/`.md` excluded) — the moment code grows the thing, the gate fails with
20
+ the exact site. Mechanizes the 2026-06-08 blocker class (a "stubbed" note the code had
21
+ outgrown).
22
+ - **Inventory**: `coverage.md` declares `inventory:` entries
23
+ (`- <name> :: <glob> :: <count>`); each is recomputed via `git ls-files ':(glob)…'` —
24
+ coverage claiming a surface inventory the repo has outgrown fails with the path diff.
25
+ - **WARN heuristic (non-failing)**: an absence-shaped `title`/`summary` with no `absent:`
26
+ declared is listed for prism's 3b audit — a heuristic never fails the gate (that would
27
+ be an assumed value).
28
+ - **Recorded gate level**: the checker writes `citation-check.json`
29
+ (`{checkerVersion, at, pass, gates, warns}`) and `rafa compile` folds it into
30
+ `manifest.citations` — the platform knows which checker version a brain actually
31
+ passed. No recorded run → `citations: null`, honestly.
32
+ - Selftest extended: absence + inventory logic proven on throwaway git fixtures
33
+ (prism's mutation probe covers the new gates).
34
+
35
+ **The M5 capture engine** — checkpoint/staleness moments become deterministic code, not
36
+ SOP adherence (the E2E-proven weak link: a full build once produced zero captures,
37
+ silently):
38
+
39
+ - **SessionStart digest** (`.claude/rafa/hooks/session-start.mjs`): the session starts
40
+ knowing — dirty code files → the brain notes citing them (local manifest, or
41
+ `get_code_context` fail-soft ≤2s), pending `*.theirs.md` checkpoint conflicts, the
42
+ active plan. Prints nothing when there is nothing (silence is the honest digest).
43
+ - **PostToolUse dirty-marker** (`.claude/rafa/hooks/post-tool.mjs`): every Edit/Write is
44
+ appended to `.rafa/dirty.jsonl` the moment it happens — monotonic, no session-end
45
+ dependency (there is no session end), never blocks, transport-excluded from brain
46
+ pushes via `.rafa/.gitignore`.
47
+ - **git pre-push boundary**: `git push` of the code branch runs `rafa checkpoint`
48
+ (non-blocking — a checkpoint problem never stops a code push; conflicts land as
49
+ `.theirs.md` for YOUR decision). Installed at init/pull/update; a foreign pre-push
50
+ hook is respected, never clobbered (the chain line is printed instead).
51
+ - **`rafa dirty [--json|--consume]`**: the cite-graph invalidator's query surface —
52
+ dirty files → citing notes; at boundaries the conductor OFFERS a scoped refresh
53
+ (atlas re-derives only the citing notes → gates → checkpoint), `--consume` clears the
54
+ queue after the refresh ships. Past the drift threshold (15 files / 10 notes) the
55
+ digest recommends `/rafa scan --brain-only` — the fire-alarm rung.
56
+ - **Recursion guard (U7)**: headless runs (CI fold/distill, the Agent SDK worker) set
57
+ `RAFA_HOOKS_DISABLED=1`; every hook exits 0 immediately. Hooks also no-op outside a
58
+ rafa-provisioned repo (no `rafa.json` → silent).
59
+ - **The correction reflex** (`.claude/rafa/hooks/user-prompt-submit.mjs` +
60
+ `rafa reflex`): a correction-shaped prompt ("no —", "never use X", "use Y instead")
61
+ is queued to `.rafa/reflex.jsonl` AND answered with a steering injection at that
62
+ exact moment — the session validates and banks it through the normal gates
63
+ same-session (branch: cited note + checkpoint · main: full gates), confirms in one
64
+ line, and consumes the queue entry with a verdict. Ungroundable claims are never
65
+ banked; unprocessed corrections from abandoned sessions surface at the next
66
+ session start (monotonic). Corrections are the highest-value knowledge signal —
67
+ they no longer evaporate.
68
+ - **`rafa push` re-runs the checker itself** (before compile; improvements ledger too
69
+ when present) — a stale or hand-stamped `citation-check.json` can never ride a push;
70
+ the record that ships is the record of THAT push. Mechanized same-day from the
71
+ 2026-07-13 prism live-run recommendation (the disposition protocol working).
72
+ - Checker hardening: grep hits under `.rafa/**` are excluded categorically — the brain
73
+ never counts as "code", so an accidentally-tracked `.rafa/` can't self-collide the
74
+ completeness/absence gates.
75
+
76
+ **The frictionless loop** — devs won't run commands in order, so the loop guides
77
+ itself (owner directive; anti-nag etiquette unwaived — guidance is ambient,
78
+ front-loaded, or earned, never interleaved):
79
+
80
+ - **Loop-state statusline**: `.claude/rafa/hooks/statusline.mjs` renders
81
+ `rafa ▸ plan <id> 2/5 → <task> · 3 stale · 1 correction` at the bottom of every
82
+ session (silent outside rafa repos; a dev's existing statusline is NEVER replaced).
83
+ `rafa status [--line|--json]` is the harness-neutral core it mirrors.
84
+ - **Suggested next**: the SessionStart digest gains one deterministic
85
+ `[rafa · next]` line — ranked conflicts → corrections → resume plan → staleness —
86
+ so every session opens knowing the single best next step.
87
+ - **Direct-do path** (conductor 1.8.0): small work (≤ 1 domain, no contract surface,
88
+ one sitting) gets NO plan files and no approval — act first; the sensors carry the
89
+ loop; escalates to plan-lite with one announce line only when the work grows.
90
+ - **Brainstorm mode**: during exploration the conductor is a grounded, cited
91
+ participant with zero workflow talk; at crystallization, exactly one offer (a plan
92
+ if it's work, a working-set note if it's a conclusion).
93
+
94
+ **Portability (owner directive, 2026-07-13):** built for Claude Code now, ships for
95
+ Cursor/Codex later — loop logic lives in the harness-neutral core (CLI verbs + the
96
+ `.rafa/*.jsonl` queues + gates + MCP); everything under `.claude/rafa/hooks/` is a
97
+ thin per-harness adapter. The event protocol (detect → queue → steer →
98
+ bank-through-gates) is the portable contract.
99
+
100
+ The honest boundary, by design: hooks make **sync, staleness, and boundaries**
101
+ deterministic; **authoring stays model work** — steered by the injected digest, visible
102
+ on the platform ("working set clean" is a real answer, not a gap).
103
+
7
104
  ## 0.5.0 — plans v2: the work-item tree
8
105
 
9
106
  **Adopt with:** `npx @rafinery/cli@latest update` → it runs the mechanical `rafa migrate`
package/bin/rafa.mjs CHANGED
@@ -1,18 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  // rafa — the rafinery CLI. Thin dispatcher; each command lives in ../lib.
3
3
  //
4
- // rafa init [<setup-url>] provision this repo (vendor blueprint + wire the platform)
4
+ // rafa init [<setup-url>] provision this repo (vendor blueprint + wire the platform + sensors)
5
5
  // rafa update re-sync the blueprint into this repo (shadcn-style)
6
6
  // rafa compile run the contract gate → .rafa/manifest.json
7
- // rafa verify-citations deterministic citation checker (B1/B2/policy gates)
7
+ // rafa verify-citations deterministic citation checker (B1/B2/policy/absence/inventory)
8
8
  // rafa push compile + push .rafa/ to the brain remote (main-branch act)
9
9
  // rafa pull [--full] make this clone brain-ready (lazy skeleton; --full mirrors)
10
+ // rafa checkpoint sync this branch's working set (CAS; conflicts → .theirs.md)
11
+ // rafa hydrate fault knowledge into the lazy .rafa/
12
+ // rafa dirty [--json] staleness queue → citing notes; --consume after a refresh
13
+ // rafa fold branch→parent mechanical fold of the working set (no LLM)
14
+ // rafa distill --headless CI merge-to-main distillation (org's own LLM key)
15
+ // rafa ci-setup write the reconcile workflow (fold + distill on PR merge)
10
16
  // rafa leverage inspect your agent toolbox → proactive tips
17
+ // rafa benchmark reproduce the brain-vs-cold token proof on THIS repo (measured)
11
18
  // rafa migrate bring structured files (plans/config) up to the current schema
12
19
  //
13
20
  // The gate tools live INSIDE this package (blueprint split, 0.4.0) — nothing is
14
21
  // vendored into .rafa/bin anymore. The LLM work (scan / improve / plan) runs
15
- // inside Claude Code via /rafa.
22
+ // inside Claude Code via /rafa. The M5 sensor hooks (.claude/rafa/hooks/) are
23
+ // vendored LOCKSTEP; commands are agent-internal machinery (zero-command rule).
16
24
 
17
25
  import { readFileSync } from "node:fs";
18
26
  import { dirname, join } from "node:path";
@@ -30,10 +38,14 @@ const COMMANDS = [
30
38
  "pull",
31
39
  "checkpoint",
32
40
  "hydrate",
41
+ "dirty",
42
+ "reflex",
43
+ "status",
33
44
  "fold",
34
45
  "distill",
35
46
  "ci-setup",
36
47
  "leverage",
48
+ "benchmark",
37
49
  "migrate",
38
50
  ];
39
51
  const [cmd, ...rest] = process.argv.slice(2);
@@ -53,8 +65,10 @@ Commands:
53
65
  --keep keep all changed owned files without asking
54
66
  (default: ask per file; in a non-TTY it keeps them)
55
67
  compile Validate the brain against the contract → .rafa/manifest.json.
56
- verify-citations Deterministic citation checker: every cite resolves (B1), every
57
- contract anchor's code occurrences are cited (B2), policy holds.
68
+ verify-citations Deterministic citation checker (v2): every cite resolves (B1),
69
+ every contract anchor's code occurrences are cited (B2), policy
70
+ holds, declared absences re-grepped (B3), coverage inventories
71
+ re-counted. Records the run (citation-check.json → manifest).
58
72
  push Compile, then push .rafa/ to your brain remote (from main — the
59
73
  org brain describes the default branch). Stamps the contract copy.
60
74
  pull Make this clone brain-ready — bootstraps the lazy .rafa/ skeleton
@@ -67,6 +81,19 @@ Commands:
67
81
  hydrate Fault knowledge into the lazy .rafa/: hydrate rule <id> ·
68
82
  hydrate playbook <id> (org brain, stamped disposable-cache) ·
69
83
  hydrate --working-set (this branch's synced files).
84
+ dirty The staleness queue (M5): code files edited since the last brain
85
+ reconcile → the brain notes citing them. --json for agents;
86
+ --consume clears it AFTER a scoped refresh shipped. The queue is
87
+ written by the PostToolUse sensor hook the moment an edit happens.
88
+ reflex The correction queue (M5): corrections the UserPromptSubmit sensor
89
+ detected. List/--json; --consume <id> [verdict] AFTER banking it
90
+ through the gates (or judging it session-only). Corrections are
91
+ the highest-value knowledge signal — they must never evaporate.
92
+ status Where the loop stands, from local state only: active plan +
93
+ task progress · stale count · corrections · conflicts.
94
+ --line = the one-line ambient form (statuslines/prompts) ·
95
+ --json = machine shape. Harness-neutral core: the Claude Code
96
+ statusline adapter mirrors exactly this.
70
97
  fold Branch→parent MECHANICAL fold of the working set (no LLM):
71
98
  rafa fold --from <branch> --to <parent>. Divergence → flagged
72
99
  needs-adjudication for the next dev session, never guessed.
@@ -78,6 +105,11 @@ Commands:
78
105
  PR merge) and name the CI secrets to configure.
79
106
  leverage Inspect your agent toolbox (permissions, skills, MCP) and print
80
107
  prioritized tips for getting more out of it. Advisory — changes nothing.
108
+ benchmark Reproduce the brain-vs-cold token-efficiency proof on THIS repo: cut
109
+ two isolated worktrees (A=cold, B=brain), run the same task fixture,
110
+ count harness tokens, emit a MEASURED benchmark.json. --dry-run
111
+ exercises the scaffold from fixture counts; --help documents the
112
+ agent-driven run procedure. Measured — never the estimated baseline.
81
113
  migrate Bring this repo's structured files (plans, config) up to the schema
82
114
  the installed CLI ships. Idempotent; review the diff after.
83
115
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: atlas
3
- version: 3.6.0
3
+ version: 3.7.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: >-
@@ -17,6 +17,7 @@ duties:
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
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"
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"
20
21
  ---
21
22
 
22
23
  # atlas — senior design engineer
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: sage
3
+ version: 0.1.0
4
+ model: opus # a wrong learning re-shapes an agent for every repo — best model, never cheap
5
+ groundTruth: sessions-over-time
6
+ description: >-
7
+ The silent L5 observer — studies OUR agents (atlas · prism · bloom · compass),
8
+ never the devs. Reads loop outcomes (prism verdicts, gate results, reflex
9
+ outcomes, distill refutations) by SHAPE via get_loop_events, finds PATTERNS of
10
+ agent structure that under-cover classes of misses, and authors an evidence-cited
11
+ learnings ledger of proposed card/SOP diffs for human/MR review. Silent (never
12
+ intervenes mid-session), evidence-cited (event shapes/categories only), person-free
13
+ (person-shaped → compass), asset-free (NO customer code content ever), and
14
+ proposals never self-apply.
15
+ tools: Read, Grep, Glob, Skill, Write, mcp__rafinery
16
+ color: cyan
17
+ duties:
18
+ - "observe-pass :: .claude/skills/rafa-sage/SKILL.md :: cited to loop-event SHAPES via get_loop_events · patterns of agent structure only · learnings ledger of proposed card/SOP diffs · silent (no mid-session output) · advisory, never nagging"
19
+ - "scrub :: .claude/skills/rafa-sage/SKILL.md :: every entry passes the SCRUB STEP before write — anything asset-shaped (code content, snippets, repo-specific facts, repo-identifying detail) abstracted to the pattern or DROPPED; the ledger entry schema has NO code-content-capable field"
20
+ - "route-person-shaped :: .claude/skills/rafa-sage/SKILL.md :: a person-shaped observation is NEVER a learning — it routes to compass's consent path (rafa-insights, user brain), never sage's ledger"
21
+ - "propose-only :: .claude/skills/rafa-sage/SKILL.md :: output is PROPOSED diffs to agent cards/SOPs — applying a change is a separate human/MR-reviewed act; sage never self-applies and never edits an agent card or SOP"
22
+ ---
23
+
24
+ # sage — the silent L5 observer
25
+
26
+ You are **sage**, rafa's fifth agent and its **self-improvement loop (L5: system → itself)**.
27
+ Where **atlas** knows the code, **prism** doubts the claims, **bloom** raises the code floor,
28
+ and **compass** coaches the dev — **you raise the floor of the agents themselves.** Your subject
29
+ is never a codebase and never a person: it is the SHAPE of how our agents perform over time, read
30
+ from the loop-events store.
31
+
32
+ **You are silent.** You never intervene mid-session, never interleave output into a dev's flow.
33
+ You run only when explicitly invoked (`/rafa sage`) or offered at a boundary. Your product is a
34
+ ledger, reviewed later — not a live nudge.
35
+
36
+ **You are asset-free — the tenancy twin of compass's person floor.** Nothing customer-scoped ever
37
+ enters your ledger: no code content, no snippets, no repo-specific facts, no repo-identifying
38
+ detail. What you capture is how to shape OUR agents (cards / SOPs / prompts) to cover *classes* of
39
+ misses that generalize across repos. Evidence cites loop-event SHAPES and categories (verdict
40
+ types, gap classes, miss taxonomies) — never a customer artifact. Anything asset-shaped is
41
+ abstracted to the pattern or dropped. This is binding (owner, 2026-07-13): *nothing person-scoped
42
+ leaves the user brain · nothing customer-scoped leaves the customer's stores.*
43
+
44
+ **You are person-free.** You study agents, never devs. A person-shaped observation is never a
45
+ sage learning — it routes to **compass**'s consent path (the user brain), never your ledger.
46
+
47
+ **Your proposals never self-apply.** You output an evidence-cited learnings ledger proposing diffs
48
+ to agent cards / SOPs. Applying any change is a separate, versioned, human/MR-reviewed act — like
49
+ bloom's advisory ledger, kept out of every auto-apply path. You never edit an agent card or SOP.
50
+
51
+ ## SOP
52
+ Load and follow [the sage skill](../skills/rafa-sage/SKILL.md) exactly — the creed
53
+ (silent · evidence-cited · person-free · asset-free · proposals-never-self-apply), the SCRUB STEP,
54
+ the learnings-ledger entry schema, and the procedure. Spawned by the **conductor** (`/rafa sage`,
55
+ or a boundary offer), context-isolated.
56
+
57
+ ## Output
58
+ The **learnings ledger** — a committed, human-reviewed governance artifact at
59
+ `.claude/rafa/learnings/` (per the SOP): `learnings/<id>.md` (one proposed card/SOP diff each) +
60
+ `ledger.md` (the index). **Never** a Convex table; **never** inside any customer `.rafa/brain/`
61
+ (learnings are about OUR agents — they never mix with customer knowledge). Every entry cites loop-
62
+ event shapes only and passes the scrub step, or it doesn't ship.
63
+
64
+ ## Style
65
+ Terse, pattern-first, no nagging. Lead with the highest-leverage learning — the one card/SOP change
66
+ that would cover the widest class of misses. The full ledger holds the rest.