@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.
- package/CHANGELOG.md +105 -0
- package/README.md +17 -7
- package/bin/rafa.mjs +78 -8
- package/blueprint/.claude/agents/atlas.md +28 -20
- package/blueprint/.claude/agents/bloom.md +15 -8
- package/blueprint/.claude/agents/compass.md +46 -0
- package/blueprint/.claude/agents/prism.md +42 -25
- package/blueprint/.claude/commands/rafa.md +190 -13
- package/blueprint/.claude/rafa/contract.md +482 -0
- package/blueprint/.claude/skills/rafa-build/SKILL.md +76 -0
- package/blueprint/.claude/skills/rafa-distill/SKILL.md +87 -0
- package/blueprint/{.rafa/capabilities/improve.md → .claude/skills/rafa-improve/SKILL.md} +10 -5
- package/blueprint/.claude/skills/rafa-insights/SKILL.md +71 -0
- package/blueprint/{.rafa/capabilities/leverage.md → .claude/skills/rafa-leverage/SKILL.md} +9 -4
- package/blueprint/.claude/skills/rafa-plan/SKILL.md +74 -0
- package/blueprint/{.rafa/capabilities/scan.md → .claude/skills/rafa-scan/SKILL.md} +14 -9
- package/blueprint/{.rafa/capabilities/validate.md → .claude/skills/rafa-validate/SKILL.md} +14 -5
- package/lib/blueprint.mjs +22 -12
- package/lib/brain-repo.mjs +100 -0
- package/lib/checkpoint.mjs +138 -0
- package/lib/ci-setup.mjs +109 -0
- package/lib/claude-config.mjs +5 -5
- package/lib/compile.mjs +6 -21
- package/lib/distill.mjs +237 -0
- package/lib/fold.mjs +53 -0
- package/lib/gate/compile.mjs +549 -0
- package/lib/gate/verify-citations.mjs +156 -0
- package/lib/hydrate.mjs +96 -0
- package/lib/init.mjs +69 -35
- package/lib/leverage/adapters/claude-code.mjs +5 -4
- package/lib/mcp-client.mjs +97 -0
- package/lib/mcp-config.mjs +93 -0
- package/lib/migrations/index.mjs +39 -3
- package/lib/pull.mjs +129 -0
- package/lib/push.mjs +93 -14
- package/lib/releases.mjs +36 -0
- package/lib/verify-citations.mjs +9 -0
- package/lib/working-set.mjs +113 -0
- package/package.json +2 -2
- package/blueprint/.rafa/bin/rafa-compile.mjs +0 -390
- package/blueprint/.rafa/bin/rafa-push.mjs +0 -75
- package/blueprint/.rafa/bin/verify-citations.mjs +0 -153
- package/blueprint/.rafa/capabilities/build.md +0 -38
- package/blueprint/.rafa/capabilities/plan.md +0 -38
- 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.
|