@rafinery/cli 0.10.0 → 0.12.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 +49 -0
- package/bin/rafa.mjs +10 -0
- package/blueprint/.claude/agents/atlas.md +2 -2
- package/blueprint/.claude/agents/bloom.md +3 -2
- package/blueprint/.claude/commands/rafa.md +1 -1
- package/blueprint/.claude/rafa/contract.md +27 -4
- package/blueprint/.claude/skills/rafa-build/SKILL.md +5 -1
- package/blueprint/.claude/skills/rafa-commit/SKILL.md +22 -0
- package/blueprint/.claude/skills/rafa-distill/SKILL.md +37 -4
- package/blueprint/.claude/skills/rafa-improve/SKILL.md +17 -6
- package/blueprint/.claude/skills/rafa-okf/SKILL.md +1 -1
- package/blueprint/.claude/skills/rafa-plan/SKILL.md +14 -1
- package/blueprint/.claude/skills/rafa-scan/SKILL.md +9 -1
- package/blueprint/.claude/skills/rafa-security/SKILL.md +96 -0
- package/lib/audit/core.mjs +488 -0
- package/lib/audit.mjs +279 -0
- package/lib/blueprint.mjs +1 -0
- package/lib/checkpoint.mjs +14 -5
- package/lib/distill.mjs +56 -3
- package/lib/distiller/doctrine.mjs +4 -4
- package/lib/distiller/schema-ladder.mjs +186 -0
- package/lib/doctor.mjs +16 -0
- package/lib/gate/compile.mjs +17 -13
- package/lib/init.mjs +3 -2
- package/lib/manifest.mjs +2 -1
- package/lib/mcp-client.mjs +10 -2
- package/lib/push.mjs +9 -3
- package/lib/releases.mjs +27 -0
- package/lib/stamp.mjs +24 -0
- package/lib/working-set.mjs +3 -2
- package/package.json +1 -1
- package/skills-bundle/skills-manifest.json +1 -1
package/lib/gate/compile.mjs
CHANGED
|
@@ -268,22 +268,26 @@ export function runCompile(argv = []) {
|
|
|
268
268
|
"leverage",
|
|
269
269
|
"required · { impact, effort } ∈ low|medium|high",
|
|
270
270
|
);
|
|
271
|
+
// `category` is canonical; `lens` is the pre-2026-07-26 name, accepted
|
|
272
|
+
// as a deprecated alias so already-authored ledgers keep compiling.
|
|
273
|
+
const category = reqEnum(
|
|
274
|
+
{ category: data.category ?? data.lens },
|
|
275
|
+
"category",
|
|
276
|
+
[
|
|
277
|
+
"security",
|
|
278
|
+
"correctness",
|
|
279
|
+
"performance",
|
|
280
|
+
"architecture",
|
|
281
|
+
"product",
|
|
282
|
+
"ops",
|
|
283
|
+
],
|
|
284
|
+
path,
|
|
285
|
+
);
|
|
271
286
|
out.push({
|
|
272
287
|
id,
|
|
273
288
|
priority: reqEnum(data, "priority", ["P0", "P1", "P2", "P3"], path),
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
"lens",
|
|
277
|
-
[
|
|
278
|
-
"security",
|
|
279
|
-
"correctness",
|
|
280
|
-
"performance",
|
|
281
|
-
"architecture",
|
|
282
|
-
"product",
|
|
283
|
-
"ops",
|
|
284
|
-
],
|
|
285
|
-
path,
|
|
286
|
-
),
|
|
289
|
+
category,
|
|
290
|
+
lens: category, // transitional dual-key — dropped with the backfill arc
|
|
287
291
|
status: reqEnum(
|
|
288
292
|
data,
|
|
289
293
|
"status",
|
package/lib/init.mjs
CHANGED
|
@@ -183,8 +183,9 @@ export default async function init(args) {
|
|
|
183
183
|
);
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
// Reconciliation runs on the PLATFORM (App-only era, owner call 2026-07-18
|
|
187
|
-
// merged PRs are detected and
|
|
186
|
+
// Reconciliation runs on the PLATFORM (App-only era, owner call 2026-07-18;
|
|
187
|
+
// agent-native since 2026-07-21): merged PRs are detected and reconciled by
|
|
188
|
+
// the server-side LangGraph agent — no
|
|
188
189
|
// CI workflow, no repo secrets, nothing to wire here. The org-CI adapter
|
|
189
190
|
// stays available as an explicit opt-out for teams that want the compute in
|
|
190
191
|
// their own CI: `rafa ci-setup`. Init no longer asks — one fewer question,
|
package/lib/manifest.mjs
CHANGED
|
@@ -165,7 +165,8 @@ export default async function manifest() {
|
|
|
165
165
|
return {
|
|
166
166
|
id,
|
|
167
167
|
priority: PRIORITIES.has(d.priority) ? d.priority : "P2",
|
|
168
|
-
|
|
168
|
+
category: str(d.category ?? d.lens, "general"),
|
|
169
|
+
lens: str(d.category ?? d.lens, "general"), // transitional mirror of category
|
|
169
170
|
status: IMP_STATUSES.has(d.status) ? d.status : "open",
|
|
170
171
|
title: str(d.title, id),
|
|
171
172
|
summary: str(d.summary),
|
package/lib/mcp-client.mjs
CHANGED
|
@@ -18,12 +18,20 @@ import { CLI_VERSION } from "./releases.mjs";
|
|
|
18
18
|
|
|
19
19
|
// The CLI's own actor envelope for state-plane writes (wave 5: REQUIRED on every
|
|
20
20
|
// loop event — strict, no legacy path). model is the explicit "mechanical"
|
|
21
|
-
// sentinel: no LLM ruled here, and the split stays grep-able for sage.
|
|
21
|
+
// sentinel: no LLM ruled here, and the split stays grep-able for sage. The
|
|
22
|
+
// runner honors RAFA_ACTOR_RUNNER first (platform tiers export it —
|
|
23
|
+
// sandbox|ci|session; "sandbox" is a legacy wire value kept for historical
|
|
24
|
+
// rows), else CI env, else session.
|
|
22
25
|
export function cliActorMeta() {
|
|
26
|
+
const declared = process.env.RAFA_ACTOR_RUNNER;
|
|
23
27
|
return {
|
|
24
28
|
model: "mechanical",
|
|
25
29
|
agent: `cli@${CLI_VERSION}`,
|
|
26
|
-
runner:
|
|
30
|
+
runner: ["sandbox", "ci", "session"].includes(declared)
|
|
31
|
+
? declared
|
|
32
|
+
: process.env.CI
|
|
33
|
+
? "ci"
|
|
34
|
+
: "session",
|
|
27
35
|
};
|
|
28
36
|
}
|
|
29
37
|
|
package/lib/push.mjs
CHANGED
|
@@ -189,6 +189,11 @@ export default async function push(args = []) {
|
|
|
189
189
|
// on it.
|
|
190
190
|
const verbArg = args.find((a) => a.startsWith("--verb="));
|
|
191
191
|
const verb = verbArg ? verbArg.slice("--verb=".length) : "update";
|
|
192
|
+
// Custom subject (owner 2026-07-26: reconciliation commits are DESCRIPTIVE):
|
|
193
|
+
// --message="…" replaces the generic manifest-derived subject; the brain-for
|
|
194
|
+
// trailer machinery below is untouched — provenance consumers keep their key.
|
|
195
|
+
const msgArg = args.find((a) => a.startsWith("--message="));
|
|
196
|
+
const customSubject = msgArg ? msgArg.slice("--message=".length).trim().replace(/"/g, "'") : null;
|
|
192
197
|
const subjectParts = [];
|
|
193
198
|
try {
|
|
194
199
|
const m = JSON.parse(readFileSync(join(rafaDir, "manifest.json"), "utf8"));
|
|
@@ -214,9 +219,10 @@ export default async function push(args = []) {
|
|
|
214
219
|
} catch {
|
|
215
220
|
/* stat is garnish */
|
|
216
221
|
}
|
|
217
|
-
const subject =
|
|
218
|
-
|
|
219
|
-
|
|
222
|
+
const subject = (
|
|
223
|
+
customSubject ??
|
|
224
|
+
`brain(${verb}): ${subjectParts.length ? subjectParts.join(" · ") : "state sync"} · brain-for: ${codeSha}`
|
|
225
|
+
).replace(/"/g, "'");
|
|
220
226
|
try {
|
|
221
227
|
inRafa(
|
|
222
228
|
`git commit -m "${subject}" -m "brain-for: ${codeSha}${stagedStat ? ` · ${stagedStat}` : ""} · cli: ${CLI_VERSION}"`,
|
package/lib/releases.mjs
CHANGED
|
@@ -382,6 +382,33 @@ export const RELEASES = [
|
|
|
382
382
|
"--json` carries the harness-neutral agentSkills + skillDeps blocks; " +
|
|
383
383
|
"doctor gains a capabilities section.",
|
|
384
384
|
},
|
|
385
|
+
{
|
|
386
|
+
version: "0.11.0",
|
|
387
|
+
contract: 1,
|
|
388
|
+
plans: 2,
|
|
389
|
+
requires: "update",
|
|
390
|
+
summary:
|
|
391
|
+
"SCHEMA-AWARE RECONCILIATION (owner's 4-case doctrine): distillation " +
|
|
392
|
+
"resolves the version lattice BEFORE judging — target below source → " +
|
|
393
|
+
"full target rewrite onto the newer schema (rides the run's gates + " +
|
|
394
|
+
"push); source below target → incoming candidates lift before judging; " +
|
|
395
|
+
"equal-but-old → the merged target rewrites onto the runner's latest; " +
|
|
396
|
+
"equal-and-current → plain diff (today). Either side newer than the " +
|
|
397
|
+
"runner aborts LOUDLY (update the runner; knowledge is never " +
|
|
398
|
+
"downgraded); transforms are registered per step and a missing step " +
|
|
399
|
+
"fails loudly — the ladder never guesses a schema. Also in this " +
|
|
400
|
+
"release (missed 0.10.0's publish): distill-refutation emits carry the " +
|
|
401
|
+
"required actor envelope + dedupeKey (a re-run counts once); " +
|
|
402
|
+
"cliActorMeta honors RAFA_ACTOR_RUNNER (sandbox|ci|session); dependsOn " +
|
|
403
|
+
"invalidation documented NOT transitive with breadth-as-conservative " +
|
|
404
|
+
"taught at facts add/help/prism's card (pinned by test). DESCRIPTIVE " +
|
|
405
|
+
"COMMITS: reconciliation pushes compose reconcile(<branch>): N banked " +
|
|
406
|
+
"· M refuted · K adjudication (rafa push --message= override); the " +
|
|
407
|
+
"commit contract requires an agent-readable body on dev commits. The " +
|
|
408
|
+
"configurable prod branch reaches the CLI: trunkBranchOf (stamp → " +
|
|
409
|
+
"origin/HEAD → main) drives the checkpoint trunk guard + CI distill " +
|
|
410
|
+
"target.",
|
|
411
|
+
},
|
|
385
412
|
];
|
|
386
413
|
|
|
387
414
|
// The release this CLI build ships (last entry).
|
package/lib/stamp.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// stamp against what the running CLI ships to know what changed and what to migrate FROM.
|
|
4
4
|
// (Also holds platform identity fields when the repo was provisioned via a setup URL.)
|
|
5
5
|
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
6
7
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
8
|
import { join } from "node:path";
|
|
8
9
|
import { CURRENT, CLI_VERSION, RELEASES } from "./releases.mjs";
|
|
@@ -34,6 +35,29 @@ export function writeStamp(cwd, patch = {}) {
|
|
|
34
35
|
return next;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
// The code repo's canonical (prod) branch (owner 2026-07-26: configurable,
|
|
39
|
+
// never hardcoded). Resolution chain: the rafa.json stamp's `prodBranch`
|
|
40
|
+
// (mirrors the platform's per-repo setting — carried down so the CLI's trunk
|
|
41
|
+
// guards agree with the platform's routing) → git's own origin/HEAD symref
|
|
42
|
+
// (the repo's actual default) → "main".
|
|
43
|
+
export function trunkBranchOf(cwd) {
|
|
44
|
+
const s = readStamp(cwd);
|
|
45
|
+
if (typeof s.prodBranch === "string" && s.prodBranch.trim() !== "")
|
|
46
|
+
return s.prodBranch.trim();
|
|
47
|
+
try {
|
|
48
|
+
const out = execSync("git symbolic-ref refs/remotes/origin/HEAD", {
|
|
49
|
+
cwd,
|
|
50
|
+
encoding: "utf8",
|
|
51
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
52
|
+
}).trim();
|
|
53
|
+
const m = out.match(/refs\/remotes\/origin\/(.+)$/);
|
|
54
|
+
if (m) return m[1];
|
|
55
|
+
} catch {
|
|
56
|
+
/* no remote / no symref — fall through */
|
|
57
|
+
}
|
|
58
|
+
return "main";
|
|
59
|
+
}
|
|
60
|
+
|
|
37
61
|
// The versions this repo was last stamped at. Un-stamped repos predate the stamp (added in
|
|
38
62
|
// 0.2.0), so default to the FIRST release's schema — never raise a false migration alarm.
|
|
39
63
|
export function stampedVersions(cwd) {
|
package/lib/working-set.mjs
CHANGED
|
@@ -160,15 +160,16 @@ export function materializeImprovement(cwd, data, brainForSha) {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
// Deterministic ledger-file writer for hydrated improvements — mirrors the shape
|
|
163
|
-
// bloom authors (see any improve/improvements/*.md): priority ·
|
|
163
|
+
// bloom authors (see any improve/improvements/*.md): priority · category · status ·
|
|
164
164
|
// fix · leverage · blast_radius · cites, then the prose body.
|
|
165
165
|
export function renderImprovement(d) {
|
|
166
|
+
const category = d.category ?? d.lens;
|
|
166
167
|
const lines = [
|
|
167
168
|
"---",
|
|
168
169
|
"schemaVersion: 1",
|
|
169
170
|
`id: ${d.id}`,
|
|
170
171
|
`priority: ${d.priority}`,
|
|
171
|
-
...(
|
|
172
|
+
...(category ? [`category: ${category}`] : []),
|
|
172
173
|
`status: ${d.status}`,
|
|
173
174
|
`title: ${q(d.title)}`,
|
|
174
175
|
...(d.summary ? [`summary: ${q(d.summary)}`] : []),
|
package/package.json
CHANGED