@rafinery/cli 0.2.2 → 0.4.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 (45) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +17 -7
  3. package/bin/rafa.mjs +78 -8
  4. package/blueprint/.claude/agents/atlas.md +28 -20
  5. package/blueprint/.claude/agents/bloom.md +15 -8
  6. package/blueprint/.claude/agents/compass.md +46 -0
  7. package/blueprint/.claude/agents/prism.md +42 -25
  8. package/blueprint/.claude/commands/rafa.md +190 -13
  9. package/blueprint/.claude/rafa/contract.md +482 -0
  10. package/blueprint/.claude/skills/rafa-build/SKILL.md +76 -0
  11. package/blueprint/.claude/skills/rafa-distill/SKILL.md +87 -0
  12. package/blueprint/{.rafa/capabilities/improve.md → .claude/skills/rafa-improve/SKILL.md} +10 -5
  13. package/blueprint/.claude/skills/rafa-insights/SKILL.md +71 -0
  14. package/blueprint/{.rafa/capabilities/leverage.md → .claude/skills/rafa-leverage/SKILL.md} +9 -4
  15. package/blueprint/.claude/skills/rafa-plan/SKILL.md +74 -0
  16. package/blueprint/{.rafa/capabilities/scan.md → .claude/skills/rafa-scan/SKILL.md} +14 -9
  17. package/blueprint/{.rafa/capabilities/validate.md → .claude/skills/rafa-validate/SKILL.md} +14 -5
  18. package/lib/blueprint.mjs +22 -12
  19. package/lib/brain-repo.mjs +100 -0
  20. package/lib/checkpoint.mjs +138 -0
  21. package/lib/ci-setup.mjs +109 -0
  22. package/lib/claude-config.mjs +5 -5
  23. package/lib/compile.mjs +6 -21
  24. package/lib/distill.mjs +237 -0
  25. package/lib/fold.mjs +53 -0
  26. package/lib/gate/compile.mjs +549 -0
  27. package/lib/gate/verify-citations.mjs +156 -0
  28. package/lib/hydrate.mjs +96 -0
  29. package/lib/init.mjs +69 -35
  30. package/lib/leverage/adapters/claude-code.mjs +5 -4
  31. package/lib/mcp-client.mjs +97 -0
  32. package/lib/mcp-config.mjs +93 -0
  33. package/lib/migrations/index.mjs +39 -3
  34. package/lib/pull.mjs +129 -0
  35. package/lib/push.mjs +93 -14
  36. package/lib/releases.mjs +36 -0
  37. package/lib/verify-citations.mjs +9 -0
  38. package/lib/working-set.mjs +113 -0
  39. package/package.json +2 -2
  40. package/blueprint/.rafa/bin/rafa-compile.mjs +0 -390
  41. package/blueprint/.rafa/bin/rafa-push.mjs +0 -75
  42. package/blueprint/.rafa/bin/verify-citations.mjs +0 -153
  43. package/blueprint/.rafa/capabilities/build.md +0 -38
  44. package/blueprint/.rafa/capabilities/plan.md +0 -38
  45. package/blueprint/.rafa/contract.md +0 -303
@@ -1,38 +0,0 @@
1
- # plan — brain-grounded ADR decomposition (DRAFT · capability #3)
2
-
3
- > Status: **draft / spec.** The first *consumer* of the stores — where the brain starts to pay
4
- > off. Depends on: brain (#1), ledger (#2). Built after the stores are proven in real use.
5
-
6
- Turn an intent into an approval-gated **ADR plan**, *grounded* in the brain (don't re-derive)
7
- and *aware* of the ledger (fold improvement into the work). Invoke via `/plan <intent>`.
8
-
9
- ## Why plan fits the mission (the integration)
10
-
11
- plan is the first place knowledge + improvement meet real work, all keyed on **domain**:
12
-
13
- - **RECALL** — load the brain slice for the domains the intent touches: conventions,
14
- contracts, flows, and **non-exemplars** (don't copy the grandfathered demo — the audit's
15
- exact lesson). The plan starts from known ground, not a cold read. *This is the 100×.*
16
- - **BLAST RADIUS** — name the domains/nodes the change touches (from the brain's map), so risk
17
- is known up front and `build` can recall/nudge per task.
18
- - **NUDGE** — query the improve ledger for open improvements in that blast radius; surface the
19
- **top-leverage** ones as optional *"while-you're-here"* tasks (leverage-ranked, dismissible).
20
- - **LEVERAGE (orchestrate, don't bury)** — match the intent against available capabilities
21
- (committed skills/agents/MCP **+** the dev's personal ones, discovered live) and recommend the
22
- best-fit to the host: *"there's a `tdd-workflow` skill for this — use it."* Never plan to
23
- hand-roll what a capability already does; flag config that would help. Recommend; the host
24
- orchestrates (a hook can't auto-invoke).
25
-
26
- ## Procedure (draft)
27
- 1. **Recall** the brain slice for the intent's domains (notes + contracts + non-exemplars).
28
- 2. **Decompose** ADR: decision + rationale + alternatives + tradeoffs + risk surface + non-goals.
29
- 3. **Tasks** — each bound to domains/nodes (so `build` can recall + nudge per task) with a done-check.
30
- 4. **Ledger nudge** — surface open improvements in the blast radius as optional, leverage-ranked tasks.
31
- 4b. **Leverage-match** — recommend the existing skills/tools/MCP that fit the tasks; flag tooling-fit
32
- improvements. Don't plan to reinvent a present capability.
33
- 5. **Approval gate** (ExitPlanMode). Materialize `.rafa/plans/<id>.md` + `active.md → {plan, task:1}`.
34
-
35
- ## Deferred / open
36
- - Capture-back of plan-time decisions → brain (prism-validated) — needs the capture engine (hooks).
37
- - Pivot detection (conversation-as-steering; mark superseded, the path is data).
38
- - Plan lifecycle + tiering (cap, archive→remote, restore) — designed in `.arohi/architecture.md`.
@@ -1,303 +0,0 @@
1
- # rafa brain contract — v1
2
-
3
- The strict protocol every brain file obeys, and the `manifest.json` the platform
4
- ingests. This is the **single source of truth** shared by the writers (atlas, bloom,
5
- prism) and the reader (the platform ingest). If a file violates this, the compile
6
- step **fails loudly** and the authoring agent must correct it — the platform never
7
- guesses, never assumes a value.
8
-
9
- Pipeline:
10
-
11
- ```
12
- agents write .md (frontmatter per this contract)
13
- → rafa compile (deterministic: parse frontmatter, VALIDATE, fail loudly)
14
- ├ FAIL → structured error (file · field · rule) → author agent fixes → retry
15
- └ PASS → emit manifest.json
16
- → git push → webhook → INGEST = JSON.parse(manifest) + shape-check → Convex
17
- → query APIs (per repo+branch) → platform renders
18
- ```
19
-
20
- Two enforcement points: **compile-time** (structure — this contract) and **prism**
21
- (semantics — truth of the content). Structure is validated *before* semantics.
22
-
23
- ---
24
-
25
- ## File-type registry — every `.rafa` file has a declared class
26
-
27
- No consumer ever guesses. **Every** file type is classified here; a `structured` type has
28
- a schema (parse it), a `verbatim` type is prose (display it, never parse for data), a
29
- `generated` type is machine-written by a named tool. If a file matching a `structured` path
30
- doesn't validate, compile fails.
31
-
32
- | Type | Path glob | Class | Schema | Author |
33
- |---|---|---|---|---|
34
- | rule | `brain/rules/*.md` | **structured** | §2 | atlas |
35
- | playbook | `brain/playbooks/*.md` | **structured** | §2 | atlas |
36
- | health | `brain/checklist.md` | **structured** | §4 | prism |
37
- | coverage | `brain/coverage.md` | **structured** | §6 | atlas |
38
- | improvement | `improve/improvements/*.md` | **structured** | §3 | bloom |
39
- | ledger | `improve/ledger.md` | **structured** | §5 | bloom |
40
- | plan | `plans/**/*.md` | **structured** | §7 *(wired: Slice 4)* | plan/build |
41
- | log | `brain/log.md` | **verbatim** | — (prose trail) | conductor |
42
- | citation-check | `**/citation-check.md` | **generated** | — (by `verify-citations`) | tool |
43
- | active pointer | `active.md` | **generated** | — (`# <plan-id>` or "No active plan") | conductor |
44
- | blueprint | `capabilities/*`, `bin/*`, `contract.md` | **verbatim** | — (shipped SOPs/tools) | rafa |
45
-
46
- `structured` types are compiled into `manifest.json` (§1) — that JSON is the ONLY thing the
47
- platform ingests. `verbatim`/`generated` files are shown as-is in the file browser (fetched
48
- lazily), never parsed. A file under a `structured` path that isn't in this table → compile
49
- error (no rogue unschema'd data files).
50
-
51
- ---
52
-
53
- ## 0. Global rules
54
-
55
- - **Frontmatter is the only machine-read surface.** The markdown **body is prose**
56
- and is NEVER parsed for data. Every value the platform shows comes from frontmatter
57
- (via the compiled manifest), or from the body rendered *verbatim* (never scraped).
58
- - **`schemaVersion` is required** on every file and in the manifest. Unknown version
59
- → ingest reports an error, does not guess.
60
- - **`id` is required and stable.** It MUST equal the filename stem (`foo.md` → `foo`).
61
- Renames are safe because rows are keyed by `id`, not path.
62
- - **Required fields are required.** Missing/empty required field = compile failure.
63
- The validator **never fills a default for a required field** — that would be
64
- assuming. Optional fields have documented defaults.
65
- - **Enums are closed.** A value outside the enum = compile failure (not coerced).
66
-
67
- ### Frontmatter grammar (strict subset — the only shapes allowed)
68
-
69
- Frontmatter is a leading `---` … `---` block. Within it, only these forms are legal;
70
- anything else is a compile error:
71
-
72
- ```yaml
73
- key: scalar # string | number | true | false
74
- key: "quoted string" # quotes stripped
75
- key: [a, b, c] # flow list of scalars
76
- key: { a: x, b: y } # flow map of scalars
77
- key: # block list …
78
- - item
79
- - item
80
- ```
81
-
82
- No nested block maps, no multiline scalars, no anchors. Deterministic to parse.
83
-
84
- ### cites DSL
85
-
86
- Each cite is one string: `` `<path>:<line> :: <token>` ``
87
-
88
- - split on the **first** ` :: ` → (`left`, `token`)
89
- - in `left`, split on the **last** `:` → (`path`, `line`)
90
- - `line` is digits (`"42"`) or a range (`"14-18"`)
91
-
92
- Compile parses each into `{ file, line, token }`. A cite that doesn't match → error.
93
-
94
- ---
95
-
96
- ## 1. manifest.json — the ingestion contract
97
-
98
- Machine-generated by `rafa compile`, committed to the brain repo, read by ingest as
99
- JSON. This is the exact shape the platform binds to.
100
-
101
- ```jsonc
102
- {
103
- "schemaVersion": 1,
104
- "generatedAt": "2026-07-03T10:00:00Z", // ISO-8601, stamped by compile
105
- "repo": "owner/repo", // CODE repo full_name (identity)
106
- "branch": "main", // code branch this brain reflects
107
- "codeSha": "abc123…", // code commit the brain was built for
108
-
109
- "health": { // from brain/checklist.md — or null
110
- "verdict": "PASS", // "PASS" | "ITERATE"
111
- "score": 95, // 0–100
112
- "gates": { "fidelity": "pass", "coverage": "pass" },
113
- "counts": { "blockers": 0, "majors": 0, "minors": 2 }
114
- },
115
-
116
- "ledger": { // from improve/ledger.md — or null
117
- "open": 7,
118
- "debtScore": 13,
119
- "byPriority": { "P0": 0, "P1": 1, "P2": 3, "P3": 3 }
120
- },
121
-
122
- "coverage": { // from brain/coverage.md — or null
123
- "domains": [ // one row per domain, its scan status
124
- { "domain": "design-system", "status": "mapped" },
125
- { "domain": "external-integrations", "status": "thin" }
126
- ]
127
- },
128
-
129
- "notes": [
130
- {
131
- "id": "agent-name-contract",
132
- "kind": "rule", // "rule" | "playbook" (from directory)
133
- "type": "contract", // contract | convention | flow | how-to
134
- "domain": "web-agent-bridge",
135
- "title": "…",
136
- "summary": "…",
137
- "links": ["other-note-id"], // [] if none
138
- "failure": "silent", // "silent" | "loud" | omitted
139
- "cites": [{ "file": "src/x.tsx", "line": "42", "token": "research_agent" }],
140
- "path": "brain/rules/agent-name-contract.md" // prose body (lazy fetch)
141
- }
142
- ],
143
-
144
- "improvements": [
145
- {
146
- "id": "dead-model-options-google-crewai",
147
- "priority": "P1", // P0 | P1 | P2 | P3
148
- "lens": "product", // security|correctness|performance|architecture|product|ops
149
- "status": "open", // open | backlog | fixed | wontfix
150
- "title": "…",
151
- "summary": "…",
152
- "fix": "…",
153
- "leverage": { "impact": "high", "effort": "low" }, // impact/effort ∈ low|medium|high
154
- "blastRadius": ["web-agent-bridge"], // [] if none
155
- "cites": [{ "file": "…", "line": "25", "token": "…" }],
156
- "path": "improve/improvements/dead-model-options-google-crewai.md"
157
- }
158
- ],
159
-
160
- "plans": [] // v1: may be empty; shape in §6
161
- }
162
- ```
163
-
164
- Ingest is `JSON.parse` + a shape-check against this schema. Any mismatch (missing
165
- key, wrong enum, wrong type, unknown `schemaVersion`) → a **surfaced ingest error**
166
- on the platform, never a guessed value.
167
-
168
- ---
169
-
170
- ## 2. Note files — `brain/rules/*.md`, `brain/playbooks/*.md`
171
-
172
- `kind` is derived from the directory (`rules/` → `rule`, `playbooks/` → `playbook`).
173
-
174
- ```yaml
175
- ---
176
- schemaVersion: 1
177
- id: agent-name-contract # required · == filename stem
178
- type: contract # required · contract | convention | flow | how-to
179
- domain: web-agent-bridge # required · non-empty
180
- title: The agent name is a cross-process contract # required
181
- summary: Only "research_agent" is fully wired end to end # required
182
- links: [copilotkit-runtime-route-convention] # optional · default []
183
- failure: silent # optional · silent | loud
184
- cites: # required · ≥ 1
185
- - src/lib/model-selector-provider.tsx:42 :: research_agent
186
- - agents/python/main.py:20 :: research_agent
187
- ---
188
- (prose body — rendered verbatim, never parsed)
189
- ```
190
-
191
- ---
192
-
193
- ## 3. Improvement files — `improve/improvements/*.md`
194
-
195
- ```yaml
196
- ---
197
- schemaVersion: 1
198
- id: dead-model-options-google-crewai # required · == filename stem
199
- priority: P1 # required · P0 | P1 | P2 | P3
200
- lens: product # required · security|correctness|performance|architecture|product|ops
201
- status: open # required · open | backlog | fixed | wontfix
202
- title: Two of the four model options are dead and fail silently # required
203
- summary: google_genai and crewai route to unwired agents # required
204
- fix: Wire both agents in main.py, or remove them from the picker # required
205
- leverage: { impact: high, effort: low } # required · impact/effort ∈ low|medium|high
206
- blast_radius: [web-agent-bridge, external-integrations] # optional · default []
207
- cites: # required · ≥ 1
208
- - src/components/ModelSelector.tsx:25 :: google_genai
209
- found: 2026-07-02 # optional · ISO date
210
- ---
211
- (prose body)
212
- ```
213
-
214
- Note: `title`, `summary`, `fix` are now **required frontmatter** — previously scraped
215
- from prose. That scraping is gone; these are authored values.
216
-
217
- ---
218
-
219
- ## 4. Health file — `brain/checklist.md`
220
-
221
- ```yaml
222
- ---
223
- schemaVersion: 1
224
- verdict: PASS # required · PASS | ITERATE
225
- score: 95 # required · 0–100
226
- gates: { fidelity: pass, coverage: pass } # required · each pass | fail
227
- counts: { blockers: 0, majors: 0, minors: 2 } # required · non-negative ints
228
- ---
229
- (prism report body)
230
- ```
231
-
232
- ---
233
-
234
- ## 5. Ledger file — `improve/ledger.md`
235
-
236
- The debt figure is **authored in frontmatter** (bloom's number), not parsed from a
237
- table. `open`/`by_priority` are cross-checked against the improvement rows at ingest.
238
- Flat keys only — no nesting (compile maps `debt_score`→`debtScore`, `by_priority`→`byPriority`).
239
-
240
- ```yaml
241
- ---
242
- schemaVersion: 1
243
- open: 7
244
- debt_score: 13
245
- by_priority: { P0: 0, P1: 1, P2: 3, P3: 3 }
246
- ---
247
- (human-readable trend/tables in the body)
248
- ```
249
-
250
- ---
251
-
252
- ## 6. Coverage file — `brain/coverage.md`
253
-
254
- The scan's breadth report. `domains` is a **flow map** of `domain: status`, one entry per
255
- domain found (compile emits it as `[{ domain, status }]` in the manifest). Status enum:
256
- `mapped | thin | stubbed | empty`. The body holds the human per-criterion PASS/FAIL narrative.
257
-
258
- ```yaml
259
- ---
260
- schemaVersion: 1
261
- domains: { design-system: mapped, components: mapped, api: thin, external-integrations: empty }
262
- ---
263
- (per-criterion PASS/FAIL narrative in the body)
264
- ```
265
-
266
- ---
267
-
268
- ## 7. Plan files — `plans/**/*.md` (Slice 4)
269
-
270
- Each child owns exactly one file (so merges never conflict; parent progress is
271
- derived by counting).
272
-
273
- ```yaml
274
- ---
275
- schemaVersion: 1
276
- id: c1-schema # required · == filename stem
277
- plan: multitenant # required · the parent plan id
278
- parent: null # required · parent plan id, or null for the root
279
- kind: parent | child # required
280
- title: … # required
281
- status: todo | in-progress | done | blocked # required (child); parent may omit
282
- branch: feat/mt-c1 # optional · the branch this executes on
283
- baseSha: abc123 # optional · commit it was cut from
284
- ---
285
- ```
286
-
287
- Parent progress is `count(children where status == done) / count(children)` —
288
- derived, never stored.
289
-
290
- ---
291
-
292
- ## 8. Versioning & the validate-and-correct loop
293
-
294
- - **`schemaVersion`** bumps when this contract changes incompatibly. Ingest refuses
295
- an unknown version (surfaced error) rather than mis-reading it.
296
- - **Validate-and-correct:** `rafa compile` validates every file. On failure it emits
297
- a structured error — `path · field · rule` — to the **authoring agent** (atlas for
298
- notes, bloom for improvements/ledger, prism for checklist). The agent edits the
299
- file and compile re-runs. Bounded retries; if it can't converge, a **hard failure**
300
- blocks the push (better than a silently-wrong brain).
301
- - The validator **reports, never auto-fills** a required value.
302
-
303
- This contract is the thing to test against.