@bragi-gmbh/codebus 1.4.0 → 1.6.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 (130) hide show
  1. package/dist/ci-hooks/ci-hooks.js +126 -0
  2. package/dist/ci-hooks/ci-hooks.js.map +1 -0
  3. package/dist/commands/agent.js +137 -0
  4. package/dist/commands/agent.js.map +1 -0
  5. package/dist/commands/as.js +1 -1
  6. package/dist/commands/as.js.map +1 -1
  7. package/dist/commands/ask.js +1 -1
  8. package/dist/commands/ask.js.map +1 -1
  9. package/dist/commands/ci-findings.js +129 -0
  10. package/dist/commands/ci-findings.js.map +1 -0
  11. package/dist/commands/ci-reply.js +117 -0
  12. package/dist/commands/ci-reply.js.map +1 -0
  13. package/dist/commands/ci-steer-escalate.js +65 -0
  14. package/dist/commands/ci-steer-escalate.js.map +1 -0
  15. package/dist/commands/cli-mcp-correlation.js +131 -0
  16. package/dist/commands/cli-mcp-correlation.js.map +1 -0
  17. package/dist/commands/connector-attach-detach.js +542 -0
  18. package/dist/commands/connector-attach-detach.js.map +1 -0
  19. package/dist/commands/connector.js +513 -0
  20. package/dist/commands/connector.js.map +1 -0
  21. package/dist/commands/correlation.js +194 -0
  22. package/dist/commands/correlation.js.map +1 -0
  23. package/dist/commands/decision.js +63 -0
  24. package/dist/commands/decision.js.map +1 -1
  25. package/dist/commands/digest.js +14 -3
  26. package/dist/commands/digest.js.map +1 -1
  27. package/dist/commands/do.js +127 -0
  28. package/dist/commands/do.js.map +1 -0
  29. package/dist/commands/factory-attention.js +106 -0
  30. package/dist/commands/factory-attention.js.map +1 -0
  31. package/dist/commands/factory-context-read.js +171 -0
  32. package/dist/commands/factory-context-read.js.map +1 -0
  33. package/dist/commands/factory-interventions.js +102 -0
  34. package/dist/commands/factory-interventions.js.map +1 -0
  35. package/dist/commands/factory.js +187 -0
  36. package/dist/commands/factory.js.map +1 -1
  37. package/dist/commands/graph-pull.js +130 -0
  38. package/dist/commands/graph-pull.js.map +1 -0
  39. package/dist/commands/graph.js +5 -1
  40. package/dist/commands/graph.js.map +1 -1
  41. package/dist/commands/inbox.js +7 -7
  42. package/dist/commands/inbox.js.map +1 -1
  43. package/dist/commands/ingest.js +1 -1
  44. package/dist/commands/ingest.js.map +1 -1
  45. package/dist/commands/install.js +1160 -55
  46. package/dist/commands/install.js.map +1 -1
  47. package/dist/commands/integration-ledger.js +81 -0
  48. package/dist/commands/integration-ledger.js.map +1 -0
  49. package/dist/commands/knowledge.js +178 -0
  50. package/dist/commands/knowledge.js.map +1 -0
  51. package/dist/commands/links.js +1 -1
  52. package/dist/commands/links.js.map +1 -1
  53. package/dist/commands/morning.js +50 -1
  54. package/dist/commands/morning.js.map +1 -1
  55. package/dist/commands/plan-compiler.js +260 -0
  56. package/dist/commands/plan-compiler.js.map +1 -0
  57. package/dist/commands/plan-lint.js +275 -0
  58. package/dist/commands/plan-lint.js.map +1 -0
  59. package/dist/commands/plan-score.js +203 -0
  60. package/dist/commands/plan-score.js.map +1 -0
  61. package/dist/commands/plan.js +481 -15
  62. package/dist/commands/plan.js.map +1 -1
  63. package/dist/commands/product-validity.js +168 -0
  64. package/dist/commands/product-validity.js.map +1 -0
  65. package/dist/commands/question.js +1 -1
  66. package/dist/commands/question.js.map +1 -1
  67. package/dist/commands/read-policy.js +131 -0
  68. package/dist/commands/read-policy.js.map +1 -0
  69. package/dist/commands/read.js +1 -1
  70. package/dist/commands/read.js.map +1 -1
  71. package/dist/commands/repo.js +106 -8
  72. package/dist/commands/repo.js.map +1 -1
  73. package/dist/commands/repository-protection.js +209 -0
  74. package/dist/commands/repository-protection.js.map +1 -0
  75. package/dist/commands/resolve.js +2 -2
  76. package/dist/commands/resolve.js.map +1 -1
  77. package/dist/commands/self-healing.js +26 -0
  78. package/dist/commands/self-healing.js.map +1 -0
  79. package/dist/commands/send.js +1 -1
  80. package/dist/commands/send.js.map +1 -1
  81. package/dist/commands/serial-merge.js +303 -0
  82. package/dist/commands/serial-merge.js.map +1 -0
  83. package/dist/commands/session.js +1 -1
  84. package/dist/commands/session.js.map +1 -1
  85. package/dist/commands/task.js +92 -1
  86. package/dist/commands/task.js.map +1 -1
  87. package/dist/commands/verify.js +77 -0
  88. package/dist/commands/verify.js.map +1 -0
  89. package/dist/config/self-healing-analysis.json +158 -0
  90. package/dist/errors.js +18 -4
  91. package/dist/errors.js.map +1 -1
  92. package/dist/execution/client.js +53 -0
  93. package/dist/execution/client.js.map +1 -0
  94. package/dist/execution/local.js +24 -0
  95. package/dist/execution/local.js.map +1 -0
  96. package/dist/execution/ssh.js +38 -0
  97. package/dist/execution/ssh.js.map +1 -0
  98. package/dist/graph.js +78 -16
  99. package/dist/graph.js.map +1 -1
  100. package/dist/index.js +30 -0
  101. package/dist/index.js.map +1 -1
  102. package/dist/json-lite.js +248 -0
  103. package/dist/json-lite.js.map +1 -0
  104. package/dist/knowledge-drift.js +40 -0
  105. package/dist/knowledge-drift.js.map +1 -0
  106. package/dist/lint/parallelism.js +414 -0
  107. package/dist/lint/parallelism.js.map +1 -0
  108. package/dist/mail-latency.js +11 -1
  109. package/dist/mail-latency.js.map +1 -1
  110. package/dist/mcp-ci-findings.js +31 -0
  111. package/dist/mcp-ci-findings.js.map +1 -0
  112. package/dist/mcp-correlation.js +290 -0
  113. package/dist/mcp-correlation.js.map +1 -0
  114. package/dist/mcp-factory-context-read.js +81 -0
  115. package/dist/mcp-factory-context-read.js.map +1 -0
  116. package/dist/mcp-registry.js +128 -1
  117. package/dist/mcp-registry.js.map +1 -1
  118. package/dist/mcp.js +94 -5
  119. package/dist/mcp.js.map +1 -1
  120. package/dist/openrouter-reservation-guard.js +97 -0
  121. package/dist/openrouter-reservation-guard.js.map +1 -0
  122. package/dist/self-healing-analysis-loader.js +150 -0
  123. package/dist/self-healing-analysis-loader.js.map +1 -0
  124. package/dist/sender.js +11 -9
  125. package/dist/sender.js.map +1 -1
  126. package/dist/toml-lite.js +546 -0
  127. package/dist/toml-lite.js.map +1 -0
  128. package/dist/version-check.js +23 -7
  129. package/dist/version-check.js.map +1 -1
  130. package/package.json +5 -3
@@ -0,0 +1,260 @@
1
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { join, relative, resolve } from "node:path";
3
+ import { CodebusError } from "../errors.js";
4
+ /** Stable format marker for generated plan files. */
5
+ export const PLAN_COMPILER_VERSION = "codebus-plan/1";
6
+ /** The bounded retry proposal from CB-DOC-000003 D4. */
7
+ export const LUNA_RETRY_LIMIT = 2;
8
+ function row(value, label) {
9
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
10
+ throw new CodebusError(`plan compile: ledger is missing ${label}`);
11
+ }
12
+ return value;
13
+ }
14
+ function text(value, fallback = "") {
15
+ return typeof value === "string" ? value : value == null ? fallback : String(value);
16
+ }
17
+ function bool(value) {
18
+ return value === true;
19
+ }
20
+ function list(value) {
21
+ if (!Array.isArray(value))
22
+ return [];
23
+ return value.filter((item) => typeof item === "string");
24
+ }
25
+ function safeSegment(value, fallback) {
26
+ const segment = value
27
+ .replace(/[^a-zA-Z0-9._-]+/g, "-")
28
+ .replace(/^-+|-+$/g, "");
29
+ return segment && segment !== "." && segment !== ".." ? segment : fallback;
30
+ }
31
+ function yamlScalar(value) {
32
+ return JSON.stringify(value);
33
+ }
34
+ function findingId(finding) {
35
+ return text(finding.finding_id ?? finding.id);
36
+ }
37
+ function workItemId(item) {
38
+ return text(item.work_item_id ?? item.finding_id ?? item.id);
39
+ }
40
+ function dependencyIds(item) {
41
+ const self = workItemId(item);
42
+ // plan_ledger_work_items starts each recursive closure at the work item
43
+ // itself, so dependency_ids intentionally includes that anchor. It is not
44
+ // a real prerequisite and must not make every item look cyclic.
45
+ return [...new Set(list(item.dependency_ids ?? item.dependencies ?? item.depends_on))]
46
+ .filter((id) => id !== self);
47
+ }
48
+ function evidenceLines(finding) {
49
+ if (!Array.isArray(finding.evidence))
50
+ return ["- (none recorded)"];
51
+ const lines = finding.evidence.map((entry) => {
52
+ const evidence = row(entry, "finding evidence");
53
+ const kind = text(evidence.kind, "UNKNOWN");
54
+ const ref = text(evidence.ref, "(missing ref)");
55
+ const excerpt = text(evidence.excerpt);
56
+ return `- ${kind}: ${ref}${excerpt ? ` — ${excerpt}` : ""}`;
57
+ });
58
+ return lines.length ? lines : ["- (none recorded)"];
59
+ }
60
+ function affectedFiles(finding) {
61
+ const files = list(finding.affected_files);
62
+ return files.length ? files.map((file) => `- \`${file}\``) : ["- (not specified)"];
63
+ }
64
+ function renderWorkItem(task, finding, item, ordinal) {
65
+ const taskId = text(task.id);
66
+ const taskDisplayId = text(task.display_id, taskId);
67
+ const id = findingId(finding);
68
+ const deps = dependencyIds(item);
69
+ const claim = text(finding.claim ?? item.claim, "(requirement claim missing)").trim();
70
+ const epoch = text(finding.epoch ?? item.epoch, "unknown");
71
+ const severity = text(finding.severity, "unspecified");
72
+ const type = text(finding.finding_type ?? finding.type, "REQUIREMENT");
73
+ return `<!-- generated by ${PLAN_COMPILER_VERSION}; do not edit in place -->
74
+ ---
75
+ compiler: ${yamlScalar(PLAN_COMPILER_VERSION)}
76
+ task_id: ${yamlScalar(taskId)}
77
+ task_display_id: ${yamlScalar(taskDisplayId)}
78
+ finding_id: ${yamlScalar(id)}
79
+ ordinal: ${ordinal}
80
+ retry_limit: ${LUNA_RETRY_LIMIT}
81
+ ---
82
+
83
+ # Work item ${ordinal}: ${claim}
84
+
85
+ This file is a generated execution artifact for **${taskDisplayId}**. The
86
+ CodeBus ledger is the source of truth; change the finding and recompile rather
87
+ than editing this file in place.
88
+
89
+ ## Requirement
90
+
91
+ ${claim}
92
+
93
+ ## Ledger back-references
94
+
95
+ - Finding: \`${id}\`
96
+ - Type: \`${type}\`
97
+ - Discovery epoch: \`${epoch}\`
98
+ - Severity: \`${severity}\`
99
+ - Dependencies: ${deps.length ? deps.map((dep) => `\`${dep}\``).join(", ") : "(none)"}
100
+
101
+ ### Affected files
102
+
103
+ ${affectedFiles(finding).join("\n")}
104
+
105
+ ### Evidence
106
+
107
+ ${evidenceLines(finding).join("\n")}
108
+
109
+ ## Execution contract
110
+
111
+ - Treat this requirement as one Luna-sized work item in an isolated worktree.
112
+ - Preserve the finding ID above in the implementation/PR evidence so the
113
+ result remains traceable to the accepted ledger event.
114
+ - Report the commit, tests, and any typed evidence back to CodeBus.
115
+
116
+ ## Failure routing
117
+
118
+ - A failed execution may use at most **${LUNA_RETRY_LIMIT} bounded Luna retries**;
119
+ never turn this artifact into an unbounded retry loop.
120
+ - If the bounded retries fail, re-enter the ledger with a new finding rather
121
+ than editing this file or marking the requirement successful. The new
122
+ \`finding.propose\` must include \`TEST_RESULT\` evidence for the failed attempt,
123
+ the original finding ID (\`${id}\`), the attempt count, and the failure summary.
124
+ - A subsequent ledger resolution/recompilation is the only supported way to
125
+ change this work item.
126
+ `;
127
+ }
128
+ function topologicalOrder(items, edges) {
129
+ const ids = new Set(items.map(workItemId));
130
+ const byId = new Map(items.map((item) => [workItemId(item), item]));
131
+ const dependencies = new Map(items.map((item) => [workItemId(item), new Set(dependencyIds(item).filter((id) => ids.has(id)))]));
132
+ // plan_ledger_edges is directed from an item to what it depends on. Add the
133
+ // projected edges too: they are the canonical source when a dependency was
134
+ // derived through a Finding relation rather than a payload field.
135
+ for (const edge of edges) {
136
+ const source = text(edge.source_finding_id);
137
+ const target = text(edge.target_finding_id);
138
+ if (ids.has(source) && ids.has(target) && source !== target) {
139
+ dependencies.get(source).add(target);
140
+ }
141
+ }
142
+ const ready = [...items]
143
+ .filter((item) => dependencies.get(workItemId(item)).size === 0)
144
+ .map(workItemId)
145
+ .sort();
146
+ const ordered = [];
147
+ while (ready.length) {
148
+ const id = ready.shift();
149
+ ordered.push(byId.get(id));
150
+ for (const [candidate, deps] of dependencies) {
151
+ if (!deps.delete(id) || deps.size !== 0)
152
+ continue;
153
+ ready.push(candidate);
154
+ ready.sort();
155
+ }
156
+ }
157
+ if (ordered.length !== items.length) {
158
+ const cycle = [...dependencies.entries()]
159
+ .filter(([, deps]) => deps.size > 0)
160
+ .map(([id]) => id)
161
+ .sort()
162
+ .join(", ");
163
+ throw new CodebusError(`plan compile: dependency cycle prevents compilation (${cycle})`);
164
+ }
165
+ return ordered;
166
+ }
167
+ async function removePreviousGeneratedFiles(taskDir) {
168
+ const manifestPath = join(taskDir, ".codebus-manifest.json");
169
+ try {
170
+ const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
171
+ if (!Array.isArray(manifest.files))
172
+ return;
173
+ for (const file of manifest.files) {
174
+ if (typeof file !== "string" || file.includes("/") || file.includes("\\") || file === "..")
175
+ continue;
176
+ await rm(join(taskDir, file), { force: true });
177
+ }
178
+ }
179
+ catch {
180
+ // A first compile, or a missing/corrupt manifest, never deletes unknown
181
+ // files. Only paths previously recorded by this compiler are recyclable.
182
+ }
183
+ }
184
+ /**
185
+ * Compile one plan_ledger_status result into deterministic plan artifacts.
186
+ * This function performs no semantic normalization and no ledger writes: the
187
+ * accepted Finding event and plan_ledger_status projection are authoritative.
188
+ */
189
+ export async function compilePlanLedger(ledgerValue, outDir = "plan") {
190
+ const ledger = row(ledgerValue, "ledger result");
191
+ const task = row(ledger.task, "task");
192
+ const findings = Array.isArray(ledger.findings) ? ledger.findings.map((value) => row(value, "finding")) : [];
193
+ const workItems = Array.isArray(ledger.work_items)
194
+ ? ledger.work_items.map((value) => row(value, "work item"))
195
+ : [];
196
+ const edges = Array.isArray(ledger.edges) ? ledger.edges.map((value) => row(value, "edge")) : [];
197
+ const findingsById = new Map(findings.map((finding) => [findingId(finding), finding]));
198
+ const compilable = [];
199
+ const skipped = [];
200
+ for (const item of workItems) {
201
+ const id = workItemId(item);
202
+ if (bool(item.compilable)) {
203
+ const finding = findingsById.get(id);
204
+ if (!finding)
205
+ throw new CodebusError(`plan compile: compilable work item ${id} has no Finding projection`);
206
+ const type = text(finding.finding_type ?? finding.type).toUpperCase();
207
+ const status = text(finding.status).toUpperCase();
208
+ if (type !== "REQUIREMENT" || status !== "ACCEPTED") {
209
+ throw new CodebusError(`plan compile: work item ${id} is marked compilable without an accepted REQUIREMENT`);
210
+ }
211
+ compilable.push(item);
212
+ }
213
+ else {
214
+ skipped.push({ finding_id: id, hold_reason: item.hold_reason == null ? null : text(item.hold_reason) });
215
+ }
216
+ }
217
+ if (compilable.length === 0) {
218
+ throw new CodebusError("plan compile: no compilable accepted REQUIREMENT work items");
219
+ }
220
+ const ordered = topologicalOrder(compilable, edges);
221
+ const taskId = text(task.id);
222
+ if (!taskId)
223
+ throw new CodebusError("plan compile: task projection has no id");
224
+ const taskDisplayId = text(task.display_id, taskId);
225
+ const outputRoot = resolve(outDir);
226
+ // Display IDs are workspace-scoped, not global. Include the immutable task
227
+ // UUID so two workspaces can compile CB-TASK-000001 into the same output
228
+ // root without one manifest deleting the other's artifacts.
229
+ const taskKey = `${taskDisplayId}-${taskId}`;
230
+ const taskDir = join(outputRoot, safeSegment(taskKey, safeSegment(taskId, "task")));
231
+ await mkdir(taskDir, { recursive: true });
232
+ await removePreviousGeneratedFiles(taskDir);
233
+ const files = [];
234
+ for (const [index, item] of ordered.entries()) {
235
+ const id = workItemId(item);
236
+ const finding = findingsById.get(id);
237
+ const ordinal = index + 1;
238
+ const filename = `${String(ordinal).padStart(3, "0")}-${safeSegment(id, `finding-${ordinal}`)}.md`;
239
+ await writeFile(join(taskDir, filename), renderWorkItem(task, finding, item, ordinal), {
240
+ encoding: "utf8", mode: 0o600,
241
+ });
242
+ files.push({ path: relative(process.cwd(), join(taskDir, filename)), finding_id: id, ordinal });
243
+ }
244
+ await writeFile(join(taskDir, ".codebus-manifest.json"), JSON.stringify({
245
+ compiler: PLAN_COMPILER_VERSION,
246
+ task_id: taskId,
247
+ task_display_id: taskDisplayId,
248
+ files: files.map((file) => file.path.split(/[\\/]/).pop()),
249
+ }, null, 2) + "\n", { encoding: "utf8", mode: 0o600 });
250
+ return {
251
+ compiler: PLAN_COMPILER_VERSION,
252
+ task_id: taskId,
253
+ task_display_id: taskDisplayId,
254
+ output_dir: relative(process.cwd(), taskDir),
255
+ files,
256
+ skipped,
257
+ retry_limit: LUNA_RETRY_LIMIT,
258
+ };
259
+ }
260
+ //# sourceMappingURL=plan-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-compiler.js","sourceRoot":"","sources":["../../src/commands/plan-compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,275 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { parse, YAMLParseError } from "yaml";
3
+ import { CodebusError } from "../errors.js";
4
+ import { makeCtx, workspaceId } from "../client.js";
5
+ import { resolveConfig } from "../config.js";
6
+ const finding = (findings, code, message, path) => {
7
+ findings.push({ code, message, ...(path ? { path } : {}) });
8
+ };
9
+ const text = (value) => typeof value === "string" ? value : "";
10
+ const list = (value) => Array.isArray(value) ? value : [];
11
+ const object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
12
+ export const DEFAULT_PLAN_CAPS = {
13
+ max_budget_usd: 150, max_stages: 12, max_children_per_stage: null, source: "default",
14
+ };
15
+ /** Refusals must name the authority: the caps decision id, or "default". */
16
+ export function planCapsLabel(caps) {
17
+ return caps.source === "decision"
18
+ ? `caps decision ${caps.decision_display_id ?? caps.decision_id ?? "unknown"}`
19
+ : "default caps; no approved plan-caps decision";
20
+ }
21
+ /** Offline fallback: caps declared on the plan object itself (lintPlanFile). */
22
+ export function planCapsFromObject(source) {
23
+ const caps = object(object(source).caps);
24
+ const positiveInt = (value) => typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : null;
25
+ const budget = typeof caps.max_budget_usd === "number" && caps.max_budget_usd > 0
26
+ ? caps.max_budget_usd : DEFAULT_PLAN_CAPS.max_budget_usd;
27
+ const stages = positiveInt(caps.max_stages) ?? DEFAULT_PLAN_CAPS.max_stages;
28
+ const children = positiveInt(caps.max_children_per_stage);
29
+ const decision = text(caps.decision) || null;
30
+ return {
31
+ max_budget_usd: budget, max_stages: stages, max_children_per_stage: children,
32
+ decision_display_id: decision, source: decision ? "decision" : "default",
33
+ };
34
+ }
35
+ /** Caps-only findings (L005/L006), shared by lint and the import pre-check. */
36
+ export function planCapsFindings(source, caps) {
37
+ const findings = [];
38
+ const plan = object(source);
39
+ const stages = list(plan.stages).map(object);
40
+ const workflow = stages.length > 0 && stages.some((stage) => "agent" in stage || "prompt" in stage);
41
+ const label = planCapsLabel(caps);
42
+ if (typeof plan.budget_usd !== "number" || plan.budget_usd > caps.max_budget_usd || plan.budget_usd < 0) {
43
+ finding(findings, "L005", `budget_usd must be between 0 and ${caps.max_budget_usd} (${label})`, "budget_usd");
44
+ }
45
+ if (stages.length < 1 || (!workflow && stages.length > caps.max_stages)) {
46
+ finding(findings, "L006", `stages must contain between 1 and ${caps.max_stages} stages (${label})`, "stages");
47
+ }
48
+ if (!workflow && caps.max_children_per_stage != null) {
49
+ const ids = stages.map((stage) => text(stage.id));
50
+ for (const [index, stage] of stages.entries()) {
51
+ const children = stages.filter((other) => list(other.depends_on).map(text).includes(ids[index])).length;
52
+ if (children > caps.max_children_per_stage) {
53
+ finding(findings, "L006", `stage ${ids[index]} has ${children} dependent stages; max_children_per_stage is ${caps.max_children_per_stage} (${label})`, `stages[${index}]`);
54
+ }
55
+ }
56
+ }
57
+ return findings;
58
+ }
59
+ export function lintPlan(source, caps) {
60
+ const findings = [];
61
+ const plan = object(source);
62
+ const stages = list(plan.stages).map(object);
63
+ const workflow = stages.length > 0 && stages.some((stage) => "agent" in stage || "prompt" in stage);
64
+ if (typeof source !== "object" || source === null || Array.isArray(source)) {
65
+ finding(findings, "L001", "plan must be a YAML object");
66
+ return findings;
67
+ }
68
+ const required = workflow ? ["name", "budget_usd", "stages"] : ["name", "budget_usd", "repo", "roles", "stages"];
69
+ for (const key of required)
70
+ if (!(key in plan))
71
+ finding(findings, "L002", `missing required property: ${key}`, key);
72
+ if (workflow && !text(plan.workdir))
73
+ finding(findings, "L020", "workflow workdir is required", "workdir");
74
+ if (!workflow) {
75
+ const roles = object(plan.roles);
76
+ const owner = object(roles.owner);
77
+ if (owner.kind !== "person" || !text(owner.id))
78
+ finding(findings, "L003", "roles.owner must be exactly one human person", "roles.owner");
79
+ for (const role of ["driver", "reviewer", "approver"]) {
80
+ const principal = object(roles[role]);
81
+ if (!text(principal.id) || !["person", "agent"].includes(text(principal.kind)))
82
+ finding(findings, "L004", `roles.${role} is missing or invalid`, `roles.${role}`);
83
+ }
84
+ const executors = list(roles.executor);
85
+ if (executors.length === 0 || executors.some((entry) => !text(object(entry).id)))
86
+ finding(findings, "L004", "roles.executor must contain at least one principal", "roles.executor");
87
+ const reviewer = text(object(roles.reviewer).id);
88
+ if (reviewer && executors.some((entry) => text(object(entry).id) === reviewer))
89
+ finding(findings, "L010", "reviewer must not also be an executor", "roles.reviewer");
90
+ const repo = object(plan.repo);
91
+ if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(text(repo.slug)) || !/^[0-9a-f]{40,64}$/.test(text(repo.base_sha)))
92
+ finding(findings, "L020", "repo.slug and repo.base_sha are invalid", "repo");
93
+ }
94
+ const effectiveCaps = caps ?? planCapsFromObject(source);
95
+ findings.push(...planCapsFindings(source, effectiveCaps));
96
+ const ids = stages.map((stage) => text(stage.id));
97
+ if (ids.some((id) => !/^[a-z][a-z0-9_-]*$/.test(id)) || new Set(ids).size !== ids.length)
98
+ finding(findings, "L006", "stage ids must be unique identifiers", "stages");
99
+ const idSet = new Set(ids);
100
+ for (const [index, stage] of stages.entries()) {
101
+ const prefix = `stages[${index}]`;
102
+ const max = stage.max_minutes;
103
+ if (typeof max !== "number" || !Number.isInteger(max) || max < 1 || max > 75)
104
+ finding(findings, "L007", "max_minutes must be an integer from 1 to 75", `${prefix}.max_minutes`);
105
+ const deps = list(stage.depends_on).map(text);
106
+ for (const dep of deps)
107
+ if (!idSet.has(dep))
108
+ finding(findings, "L008", `unknown dependency: ${dep}`, `${prefix}.depends_on`);
109
+ if (!workflow && text(stage.agent_role) === "")
110
+ finding(findings, "L006", "stage.agent_role is required", `${prefix}.agent_role`);
111
+ if (workflow) {
112
+ if (text(stage.agent) === "" || !text(stage.prompt) || !text(stage.done_when))
113
+ finding(findings, "L006", "workflow stages require agent, prompt, and done_when", prefix);
114
+ if (!["none", "human"].includes(text(stage.gate)))
115
+ finding(findings, "L020", "workflow stage.gate is invalid", `${prefix}.gate`);
116
+ if (!/^(?:stop|continue|retry:[1-9][0-9]*)$/.test(text(stage.on_fail)))
117
+ finding(findings, "L020", "workflow stage.on_fail is invalid", `${prefix}.on_fail`);
118
+ }
119
+ if (!workflow) {
120
+ if (!text(stage.goal) || !text(stage.metric) || !text(stage.done_when) || !text(stage.prompt_ref))
121
+ finding(findings, "L020", "stage goal, metric, done_when, and prompt_ref are required", prefix);
122
+ if (!["build", "plan", "reason", "research", "executor"].includes(text(stage.agent_role)))
123
+ finding(findings, "L020", "stage.agent_role is invalid", `${prefix}.agent_role`);
124
+ if (!["none", "human"].includes(text(stage.gate)))
125
+ finding(findings, "L020", "stage.gate is invalid", `${prefix}.gate`);
126
+ if (!/^(?:stop|continue|retry:[1-9][0-9]*)$/.test(text(stage.on_fail)))
127
+ finding(findings, "L020", "stage.on_fail is invalid", `${prefix}.on_fail`);
128
+ }
129
+ }
130
+ const edges = new Map(ids.map((id) => [id, list(stages[ids.indexOf(id)].depends_on).map(text)]));
131
+ const visiting = new Set();
132
+ const visited = new Set();
133
+ const visit = (id) => {
134
+ if (visiting.has(id))
135
+ return true;
136
+ if (visited.has(id))
137
+ return false;
138
+ visiting.add(id);
139
+ const cycle = (edges.get(id) ?? []).some(visit);
140
+ visiting.delete(id);
141
+ visited.add(id);
142
+ return cycle;
143
+ };
144
+ if (ids.some(visit))
145
+ finding(findings, "L009", "stage dependencies contain a cycle", "stages");
146
+ // Only done_when is executable predicate text. Prompts may discuss forbidden
147
+ // examples while documenting why a policy exists.
148
+ const predicates = stages.map((stage) => text(stage.done_when)).join("\n");
149
+ const policy = (code, pattern, message) => {
150
+ if (pattern.test(predicates))
151
+ finding(findings, code, message, "stages[].done_when");
152
+ };
153
+ policy("L012", /\bgrep\s+(?:-[A-Za-z]*R[A-Za-z]*|--recursive)\b[^\n]*\bsrc\//i, "predicates must not source-grep src/ for defaults");
154
+ policy("L013", /\bgit\s+log\s+-1\b/i, "predicates must not use mutable git log -1");
155
+ policy("L014", /(?:monitor-)?self[-_ ]?test|live\s+(?:test|check)|curl\s+https?:/i, "predicates must not run live self-tests or probes");
156
+ policy("L015", /\bgrep\s+(?:-w|--word-regexp|-F|--fixed-strings)\b/i, "predicates must not use literal-word grep");
157
+ policy("L016", /https?:\/\/[^\s'"\)]+/i, "predicates must not use hosted URLs");
158
+ policy("L017", /(?:stale[ _-]+digest|digest[ _-]+(?:age|current|now)|digest(?:_age|_at)\s*[<>=])/i, "predicates must not rely on stale or time-varying digests");
159
+ if (!/git[^\n]*merge-base\s+--is-ancestor[^\n]*origin\/main/i.test(predicates))
160
+ finding(findings, "L018", "predicates must include origin/main ancestry evidence", "stages[].done_when");
161
+ if (!/ci-green(?:\.sh)?[^\n]*--required/i.test(predicates))
162
+ finding(findings, "L019", "predicates must require green CI evidence", "stages[].done_when");
163
+ let humanGateSeen = false;
164
+ for (const [index, stage] of stages.entries()) {
165
+ if (stage.gate === "human")
166
+ humanGateSeen = true;
167
+ const irreversible = list(stage.irreversible_tags).length > 0 || stage.irreversible === true;
168
+ if (irreversible && stage.gate !== "human" && !humanGateSeen)
169
+ finding(findings, "L011", "irreversible work requires a preceding human gate", `stages[${index}]`);
170
+ }
171
+ if (!workflow && list(plan.stages).some((stage) => {
172
+ const paths = list(object(stage).allowed_paths);
173
+ return paths.length === 0 || paths.some((path) => typeof path !== "string" || path.length === 0) || new Set(paths).size !== paths.length;
174
+ }))
175
+ finding(findings, "L020", "each stage must declare unique non-empty allowed_paths", "stages[].allowed_paths");
176
+ return findings;
177
+ }
178
+ export function lintPlanFile(path, caps) {
179
+ const findings = [];
180
+ let source;
181
+ try {
182
+ source = parse(readFileSync(path, "utf8"));
183
+ }
184
+ catch (error) {
185
+ finding(findings, "L001", error instanceof YAMLParseError ? `invalid YAML: ${error.message}` : `cannot read YAML: ${String(error)}`);
186
+ return { verdict: "fail", findings, path };
187
+ }
188
+ findings.push(...lintPlan(source, caps));
189
+ return { verdict: findings.length === 0 ? "pass" : "fail", findings, path };
190
+ }
191
+ export async function lintPlanOnline(ctx, planRef, revisionDigest) {
192
+ const ws = await workspaceId(ctx);
193
+ const key = /^CB-PLAN-/i.test(planRef) ? "display_id" : "id";
194
+ const { data: plan, error: planError } = await ctx.supabase.from("plan_list_v1").select("*")
195
+ .eq("workspace_id", ws).eq(key, key === "display_id" ? planRef.toUpperCase() : planRef).single();
196
+ if (planError || !plan || plan.revision_digest !== revisionDigest || !plan.latest_revision_id) {
197
+ throw new CodebusError("plan lint requires the exact latest revision digest");
198
+ }
199
+ const { data: revision, error: revisionError } = await ctx.supabase.from("plan_revisions")
200
+ .select("document").eq("id", plan.latest_revision_id).single();
201
+ if (revisionError || !revision?.document)
202
+ throw new CodebusError("plan revision source is unavailable");
203
+ // Admission caps are owner decisions: read the effective caps for this plan
204
+ // from plan_caps_effective_v1 (0111); fall back to defaults when absent.
205
+ const { data: capsRow, error: capsError } = await ctx.supabase.from("plan_caps_effective_v1")
206
+ .select("*").eq("plan_id", plan.id).maybeSingle();
207
+ if (capsError)
208
+ throw new CodebusError(capsError.message);
209
+ const caps = capsRow
210
+ ? {
211
+ max_budget_usd: Number(capsRow.max_budget_usd),
212
+ max_stages: Number(capsRow.max_stages),
213
+ max_children_per_stage: capsRow.max_children_per_stage == null ? null : Number(capsRow.max_children_per_stage),
214
+ decision_id: capsRow.decision_id ?? null,
215
+ decision_display_id: capsRow.decision_display_id ?? null,
216
+ source: capsRow.source === "decision" ? "decision" : "default",
217
+ }
218
+ : DEFAULT_PLAN_CAPS;
219
+ const findings = lintPlan(revision.document, caps);
220
+ const result = {
221
+ verdict: findings.length === 0 ? "pass" : "fail", findings, path: String(plan.source_ref ?? planRef),
222
+ };
223
+ const { error } = await ctx.supabase.rpc("plan_lint_report_record", {
224
+ p_revision_id: plan.latest_revision_id,
225
+ p_revision_digest: revisionDigest,
226
+ p_verdict: result.verdict,
227
+ p_report: { ruleset: "L001-L020", caps: { ...caps, label: planCapsLabel(caps) }, findings },
228
+ });
229
+ if (error)
230
+ throw new CodebusError(error.message);
231
+ return result;
232
+ }
233
+ export function registerPlanLint(plan) {
234
+ plan.command("lint").argument("<path-or-plan>")
235
+ .option("--offline", "perform deterministic local linting only")
236
+ .option("--revision <digest>", "exact immutable revision digest for online evidence")
237
+ .option("--json", "JSON output")
238
+ .action(async (path, options, command) => {
239
+ if (!options.offline && !options.revision)
240
+ throw new CodebusError("plan lint requires --offline or --revision");
241
+ const result = options.offline
242
+ ? lintPlanFile(path)
243
+ : await lintPlanOnline(await makeCtx(resolveConfig(command.optsWithGlobals())), path, options.revision);
244
+ console.log(options.json ? JSON.stringify(result, null, 2) : `${result.verdict}: ${result.findings.map((item) => item.code).join(", ") || "no findings"}`);
245
+ if (result.verdict === "fail")
246
+ throw new CodebusError(`plan lint failed: ${result.findings.map((item) => item.code).join(", ")}`);
247
+ });
248
+ // ADR 0008: plans execute as multi-agent DAGs, never as chains. This is the hermetic
249
+ // parallelism check over an execution manifest (tracks[].stages[].children[]), ported from
250
+ // phase2-triage/check-parallelism.py. Offline and deterministic — no DB, no network.
251
+ // The check module is imported lazily so unrelated CLI subprocess spawns never load it —
252
+ // the merged coverage gate (vitest in-process + c8 subprocess) would otherwise measure
253
+ // it as loaded-but-unexecuted in every spawned process and double-count it half-covered.
254
+ plan.command("lint-parallelism").argument("<manifest>", "execution manifest YAML (tracks[].stages[].children[])")
255
+ .option("--json", "JSON output")
256
+ .action(async (manifestPath, options) => {
257
+ const { formatParallelism, lintParallelismFile } = await import("../lint/parallelism.js");
258
+ const result = lintParallelismFile(manifestPath);
259
+ if (options.json) {
260
+ console.log(JSON.stringify(result, null, 2));
261
+ }
262
+ else {
263
+ console.log(formatParallelism(result));
264
+ for (const item of result.findings)
265
+ console.log(`${item.code}: ${item.message}`);
266
+ if (result.overridden)
267
+ console.log(`override: thresholds waived — ${result.overrideReason}`);
268
+ console.log(`PARALLELISM ${result.verdict.toUpperCase()}`);
269
+ }
270
+ if (result.verdict === "fail") {
271
+ throw new CodebusError(`plan lint-parallelism failed: ${result.findings.map((item) => item.code).join(", ")}`);
272
+ }
273
+ });
274
+ }
275
+ //# sourceMappingURL=plan-lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-lint.js","sourceRoot":"","sources":["../../src/commands/plan-lint.ts"],"names":[],"mappings":"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"}