opencode-swarm 7.140.3 → 7.140.5

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 (148) hide show
  1. package/.opencode/skills/brainstorm/SKILL.md +1 -1
  2. package/.opencode/skills/ci-failure-batching/SKILL.md +11 -1
  3. package/.opencode/skills/ci-fix-monitor/SKILL.md +6 -4
  4. package/.opencode/skills/discover/SKILL.md +1 -1
  5. package/.opencode/skills/durable-session-state/SKILL.md +82 -0
  6. package/.opencode/skills/engineering-conventions/SKILL.md +1 -1
  7. package/.opencode/skills/issue-ingest/SKILL.md +13 -7
  8. package/.opencode/skills/issue-tracer/SKILL.md +1 -1
  9. package/.opencode/skills/orchestrating-subagents/SKILL.md +113 -0
  10. package/.opencode/skills/parallel-work-check/SKILL.md +1 -1
  11. package/.opencode/skills/plan/SKILL.md +40 -12
  12. package/.opencode/skills/swarm-ci-monitor/SKILL.md +5 -3
  13. package/.opencode/skills/swarm-pr-feedback/SKILL.md +30 -4
  14. package/.opencode/skills/writing-tests/SKILL.md +1 -1
  15. package/dist/agents/architect.d.ts +2 -1
  16. package/dist/agents/reviewer-directive-compliance.d.ts +19 -5
  17. package/dist/background/pending-delegations.d.ts +5 -0
  18. package/dist/cli/{config-doctor-fnmfd35x.js → config-doctor-5vzpq4qa.js} +3 -3
  19. package/dist/cli/{core-p5cyej3r.js → core-xjzdc56e.js} +2 -2
  20. package/dist/cli/{curation-policy-d52h4g8t.js → curation-policy-avvb56x2.js} +6 -8
  21. package/dist/cli/{curator-3zpdqt9r.js → curator-5nytvg7p.js} +38 -38
  22. package/dist/cli/curator-llm-factory-rds75zhj.js +61 -0
  23. package/dist/cli/{evidence-summary-service-nfdc1ht9.js → evidence-summary-service-zq4gyx6g.js} +15 -12
  24. package/dist/cli/gate-evidence-smn2wqft.js +51 -0
  25. package/dist/cli/guardrail-explain-an7jvam1.js +62 -0
  26. package/dist/cli/{guardrail-log-82da8y5a.js → guardrail-log-0hnd2k9v.js} +4 -4
  27. package/dist/cli/{hive-promoter-af5yaxvt.js → hive-promoter-qe8pqg79.js} +38 -38
  28. package/dist/cli/{index-qksjaxpd.js → index-01ggt2mj.js} +49 -18
  29. package/dist/cli/{index-j1xmren9.js → index-0r2m0vbq.js} +12 -10
  30. package/dist/cli/{index-pg7n141e.js → index-0rx9t9w8.js} +1 -1
  31. package/dist/cli/{index-brh827g0.js → index-2bg901qt.js} +73 -32
  32. package/dist/cli/{index-8n4c3vec.js → index-386ts4tm.js} +4 -4
  33. package/dist/cli/{index-898f16j9.js → index-8rp1y4ab.js} +2 -2
  34. package/dist/cli/{index-hfvxhk4z.js → index-912qz4y0.js} +88 -88
  35. package/dist/cli/index-affh1gtg.js +2554 -0
  36. package/dist/cli/{index-1m1ksyqt.js → index-c432knmy.js} +1 -1
  37. package/dist/cli/{index-jvk119ck.js → index-e0mpz2j3.js} +54 -19
  38. package/dist/cli/{index-ry0hgg3m.js → index-epvhf50h.js} +37 -3
  39. package/dist/cli/{index-95bj4kaw.js → index-ex7r16gc.js} +2 -2
  40. package/dist/cli/{index-7d5jseea.js → index-jm4cpp4n.js} +5 -2
  41. package/dist/cli/{index-n408rw7n.js → index-jqsfsqbx.js} +27 -2
  42. package/dist/cli/{index-7kdd75se.js → index-kb5q9v34.js} +11 -9
  43. package/dist/cli/{index-jfjnn408.js → index-m9xrdjn0.js} +1 -1
  44. package/dist/cli/{index-pj9h75cc.js → index-mm2egvdt.js} +40 -40
  45. package/dist/cli/{index-8bnzzv3b.js → index-nwrwy8eb.js} +70 -34
  46. package/dist/cli/index-nyjtzmsj.js +43 -0
  47. package/dist/cli/{index-h2waehqq.js → index-p8kk34am.js} +3 -3
  48. package/dist/cli/{index-wf35ka4z.js → index-ptn13xjn.js} +3 -3
  49. package/dist/cli/{index-1kyex7z2.js → index-qwm6vdyv.js} +32 -1
  50. package/dist/cli/{index-p9dsb0tw.js → index-qy1nq52t.js} +2 -19
  51. package/dist/cli/{index-b9rd29ge.js → index-s1v0wza5.js} +6 -2
  52. package/dist/cli/{index-yyyk63kk.js → index-t5pytnca.js} +2 -2
  53. package/dist/cli/index-tjqzr3jc.js +623 -0
  54. package/dist/cli/{index-rs1f1bh0.js → index-vh05t3w5.js} +1 -1
  55. package/dist/cli/{index-adyxbmt5.js → index-wkt9fj06.js} +4 -4
  56. package/dist/cli/{index-kbfsp07d.js → index-wrb0gykj.js} +217 -15
  57. package/dist/cli/{index-xz8f1n1a.js → index-z7h37d63.js} +2 -2
  58. package/dist/cli/{index-q1q8b85k.js → index-z90nvqj3.js} +49315 -47331
  59. package/dist/cli/{index-b8zgtz81.js → index-zsrtt42s.js} +34 -1
  60. package/dist/cli/{index-gtbmabws.js → index-ztgn70jz.js} +2 -2
  61. package/dist/cli/index.js +37 -37
  62. package/dist/cli/{knowledge-escalator-7q59skqg.js → knowledge-escalator-4pfrc902.js} +20 -8
  63. package/dist/cli/{knowledge-events-3nwfdpq7.js → knowledge-events-3zkfnksk.js} +19 -6
  64. package/dist/cli/{knowledge-link-q46k9adx.js → knowledge-link-m9p80f4r.js} +5 -5
  65. package/dist/cli/{knowledge-store-0d83rhh3.js → knowledge-store-dpqgvvjt.js} +6 -6
  66. package/dist/cli/{knowledge-validator-6mfx91a2.js → knowledge-validator-2c7w87dk.js} +8 -9
  67. package/dist/cli/{pending-delegations-qzrx38y9.js → pending-delegations-cxx9tezp.js} +4 -4
  68. package/dist/cli/{pr-subscriptions-5s59h4dd.js → pr-subscriptions-2sfnb599.js} +4 -4
  69. package/dist/cli/{runner-y78d7ryb.js → runner-mky3vvht.js} +6 -6
  70. package/dist/cli/{scan-cursor-rc8q12ss.js → scan-cursor-1z60gwrw.js} +7 -7
  71. package/dist/cli/{schema-n9eaxp3a.js → schema-vpnkwvez.js} +2 -2
  72. package/dist/cli/{scope-persistence-dr1msqxw.js → scope-persistence-p9dmprry.js} +10 -5
  73. package/dist/cli/{skill-generator-q7c6vadg.js → skill-generator-yx7ka1cj.js} +19 -10
  74. package/dist/cli/{telemetry-sc57xtb0.js → telemetry-0x6kszvk.js} +1 -1
  75. package/dist/cli/{worktree-collision-ownership-7a8e6gr9.js → worktree-collision-ownership-wm5pse49.js} +8 -8
  76. package/dist/cli/worktree-isolation-bwc6ra8e.js +102 -0
  77. package/dist/cli/worktree-provisioning-owner-sjh7te1h.js +22 -0
  78. package/dist/commands/acknowledge-spec-drift.d.ts +4 -5
  79. package/dist/commands/ci-simulate.d.ts +7 -3
  80. package/dist/commands/close.d.ts +8 -0
  81. package/dist/commands/registry.d.ts +2 -2
  82. package/dist/commands/sdd.d.ts +15 -0
  83. package/dist/config/bundled-skills.d.ts +1 -1
  84. package/dist/config/evidence-schema.d.ts +3 -3
  85. package/dist/config/index.d.ts +2 -2
  86. package/dist/config/plan-schema.d.ts +8 -0
  87. package/dist/config/schema.d.ts +4 -2
  88. package/dist/council/council-evidence-writer.d.ts +1 -1
  89. package/dist/gate-evidence.d.ts +117 -4
  90. package/dist/git/branch.d.ts +1 -1
  91. package/dist/hooks/delegate-ack-collector.d.ts +5 -0
  92. package/dist/hooks/delegation-gate.d.ts +21 -0
  93. package/dist/hooks/hive-promoter.d.ts +4 -4
  94. package/dist/hooks/issue-trace-reducer.d.ts +7 -1
  95. package/dist/hooks/issue-trace-state.d.ts +18 -0
  96. package/dist/hooks/issue-trace.d.ts +3 -1
  97. package/dist/hooks/knowledge-application-gate.d.ts +8 -3
  98. package/dist/hooks/knowledge-application.d.ts +8 -5
  99. package/dist/hooks/knowledge-escalator.d.ts +9 -5
  100. package/dist/hooks/knowledge-events.d.ts +21 -8
  101. package/dist/hooks/knowledge-injector.d.ts +9 -0
  102. package/dist/hooks/knowledge-receipt-ledger-storage.d.ts +49 -0
  103. package/dist/hooks/knowledge-receipt-ledger.d.ts +305 -0
  104. package/dist/hooks/knowledge-receipt-observability.d.ts +28 -0
  105. package/dist/hooks/knowledge-receipt-validator.d.ts +13 -50
  106. package/dist/hooks/knowledge-store.d.ts +6 -1
  107. package/dist/hooks/knowledge-types.d.ts +12 -0
  108. package/dist/hooks/phase-complete-directive-gate.d.ts +3 -1
  109. package/dist/hooks/phase-directives.d.ts +4 -4
  110. package/dist/hooks/pr-workflow-gate.d.ts +34 -1
  111. package/dist/hooks/promotion-evidence-store.d.ts +14 -8
  112. package/dist/hooks/reviewer-verdict-parser.d.ts +34 -10
  113. package/dist/index.js +823 -779
  114. package/dist/knowledge/curation-policy.d.ts +0 -2
  115. package/dist/observability/catalog.d.ts +5 -3
  116. package/dist/observability/legacy.d.ts +4 -3
  117. package/dist/plan/ledger.d.ts +55 -0
  118. package/dist/plan/manager.d.ts +9 -0
  119. package/dist/plan/planning-profile.d.ts +27 -0
  120. package/dist/services/spec-drift-recovery.d.ts +84 -0
  121. package/dist/session/snapshot-writer.d.ts +3 -1
  122. package/dist/state.d.ts +19 -17
  123. package/dist/summaries/schema.d.ts +2 -2
  124. package/dist/telemetry.d.ts +1 -1
  125. package/dist/tools/convene-council.d.ts +6 -6
  126. package/dist/tools/index.d.ts +3 -0
  127. package/dist/tools/manifest.d.ts +3 -0
  128. package/dist/tools/phase-complete.d.ts +9 -0
  129. package/dist/tools/rebind-pr-feedback-head.d.ts +17 -0
  130. package/dist/tools/record-implementation-review.d.ts +19 -0
  131. package/dist/tools/record-recurrence-sweep.d.ts +17 -0
  132. package/dist/tools/run-pr-feedback-stage-a.d.ts +8 -0
  133. package/dist/tools/save-plan.d.ts +8 -0
  134. package/dist/tools/submit-phase-council-verdicts.d.ts +6 -6
  135. package/dist/tools/tool-metadata.d.ts +40 -28
  136. package/dist/tools/update-task-status.d.ts +13 -0
  137. package/dist/tools/write-final-council-evidence.d.ts +6 -6
  138. package/dist/types/events.d.ts +29 -1
  139. package/dist/workflow/coder-settlement.d.ts +62 -0
  140. package/dist/workflow/task-repair.d.ts +30 -0
  141. package/dist/workflow/task-terminal.d.ts +52 -0
  142. package/package.json +3 -1
  143. package/dist/cli/curator-llm-factory-2h0xb62t.js +0 -61
  144. package/dist/cli/gate-evidence-46qeyfc1.js +0 -32
  145. package/dist/cli/guardrail-explain-yktan15c.js +0 -62
  146. package/dist/cli/index-d181x9zr.js +0 -71
  147. package/dist/cli/index-n0pja0qs.js +0 -239
  148. package/dist/cli/index-n8jncheh.js +0 -666
@@ -0,0 +1,623 @@
1
+ // @bun
2
+ import {
3
+ validateSwarmPath
4
+ } from "./index-k46me75h.js";
5
+ import {
6
+ atomicWriteFile,
7
+ taskEvidencePath,
8
+ withTaskEvidenceLock
9
+ } from "./index-p8kk34am.js";
10
+ import {
11
+ telemetry
12
+ } from "./index-epvhf50h.js";
13
+ import {
14
+ exports_external,
15
+ init_zod
16
+ } from "./index-bpmtbmy9.js";
17
+
18
+ // src/gate-evidence.ts
19
+ init_zod();
20
+ import { mkdirSync, readFileSync, realpathSync } from "fs";
21
+ import * as path from "path";
22
+
23
+ // src/validation/task-id.ts
24
+ var STRICT_TASK_ID_PATTERN = /^\d+\.\d+(\.\d+)*$/;
25
+ var RETRO_TASK_ID_REGEX = /^retro-\d+$/;
26
+ var INTERNAL_TOOL_ID_REGEX = /^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build|secretscan)$/;
27
+ var GENERAL_TASK_ID_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
28
+ function checkUnsafeChars(taskId) {
29
+ if (!taskId || taskId.length === 0) {
30
+ return "Invalid task ID: empty string";
31
+ }
32
+ if (/\0/.test(taskId)) {
33
+ return "Invalid task ID: contains null bytes";
34
+ }
35
+ for (let i = 0;i < taskId.length; i++) {
36
+ if (taskId.charCodeAt(i) < 32) {
37
+ return "Invalid task ID: contains control characters";
38
+ }
39
+ }
40
+ if (taskId.includes("..") || taskId.includes("/") || taskId.includes("\\")) {
41
+ return "Invalid task ID: path traversal detected";
42
+ }
43
+ return;
44
+ }
45
+ function isStrictTaskId(taskId) {
46
+ if (!taskId)
47
+ return false;
48
+ const unsafeMsg = checkUnsafeChars(taskId);
49
+ if (unsafeMsg)
50
+ return false;
51
+ return STRICT_TASK_ID_PATTERN.test(taskId);
52
+ }
53
+ function assertStrictTaskId(taskId) {
54
+ if (!isStrictTaskId(taskId)) {
55
+ throw new Error(`Invalid taskId: "${taskId}". Must match N.M or N.M.P (e.g. "1.1", "1.2.3").`);
56
+ }
57
+ }
58
+ function sanitizeTaskId(taskId) {
59
+ const unsafeMsg = checkUnsafeChars(taskId);
60
+ if (unsafeMsg) {
61
+ throw new Error(unsafeMsg);
62
+ }
63
+ if (STRICT_TASK_ID_PATTERN.test(taskId) || RETRO_TASK_ID_REGEX.test(taskId) || INTERNAL_TOOL_ID_REGEX.test(taskId) || GENERAL_TASK_ID_REGEX.test(taskId)) {
64
+ return taskId;
65
+ }
66
+ throw new Error(`Invalid task ID: must be alphanumeric (ASCII) with optional hyphens, underscores, or dots, got "${taskId}"`);
67
+ }
68
+
69
+ // src/gate-evidence.ts
70
+ var TASK_WORKFLOW_SCHEMA_MARKER = "exact-task-v1";
71
+ var TASK_WORKFLOW_STATES = [
72
+ "idle",
73
+ "coder_delegated",
74
+ "pre_check_passed",
75
+ "reviewer_run",
76
+ "tests_run",
77
+ "rework_required",
78
+ "complete",
79
+ "blocked"
80
+ ];
81
+ var TASK_WORKFLOW_OUTCOMES = [
82
+ "none",
83
+ "dispatch_attempted",
84
+ "dispatch_no_mutation",
85
+ "accepted_mutation",
86
+ "accepted_mutation_failed",
87
+ "stage_a_passed",
88
+ "stage_a_failed",
89
+ "stage_b_completed",
90
+ "stage_b_failed",
91
+ "gate_recorded",
92
+ "task_completed",
93
+ "task_blocked",
94
+ "repair_idle"
95
+ ];
96
+ function assertTaskEvidenceWriteAllowed(directory, taskId, event) {
97
+ assertValidTaskId(taskId);
98
+ const readWal = (kind, corruptCode) => {
99
+ const walPath = validateSwarmPath(directory, `${kind}/${taskId}.json`);
100
+ let raw;
101
+ try {
102
+ raw = readFileSync(walPath, "utf-8");
103
+ } catch (error) {
104
+ if (error.code === "ENOENT")
105
+ return null;
106
+ throw error;
107
+ }
108
+ try {
109
+ return JSON.parse(raw);
110
+ } catch (error) {
111
+ throw new Error(`${corruptCode}: ${walPath} is not valid JSON (${error instanceof Error ? error.message : String(error)}). Delete this file to allow the task to be repaired again.`);
112
+ }
113
+ };
114
+ const coderWal = readWal("coder-settlements", "CODER_SETTLEMENT_WAL_CORRUPT");
115
+ if ((coderWal?.state === "DISPATCHED" || coderWal?.state === "PREPARED") && !(event != null && event.transitionId === coderWal.transitionId && (event.type === "dispatch_attempted" || event.type === "dispatch_no_mutation" || event.type === "accepted_mutation"))) {
116
+ throw new Error(`CODER_SETTLEMENT_IN_PROGRESS: transition ${String(coderWal.transitionId)} owns evidence for task ${taskId}`);
117
+ }
118
+ const terminalWal = readWal("task-terminals", "TASK_TERMINAL_WAL_CORRUPT");
119
+ if (terminalWal?.state === "PREPARED") {
120
+ const matchingTerminalEvent = event != null && event.transitionId === terminalWal.transitionId && (event.type === "task_completed" && terminalWal.newPlanStatus === "completed" || event.type === "task_blocked" && terminalWal.newPlanStatus === "blocked");
121
+ if (!matchingTerminalEvent) {
122
+ throw new Error(`TASK_TERMINAL_PREPARED: transition ${String(terminalWal.transitionId)} owns evidence for task ${taskId}`);
123
+ }
124
+ }
125
+ const repairWal = readWal("task-repairs", "TASK_REPAIR_WAL_CORRUPT");
126
+ if (repairWal?.state === "PREPARED" && !(event?.type === "repair_idle" && event.transitionId === repairWal.transitionId)) {
127
+ throw new Error(`TASK_REPAIR_PREPARED: transition ${String(repairWal.transitionId)} owns evidence for task ${taskId}`);
128
+ }
129
+ }
130
+ var GateEvidenceSchema = exports_external.object({
131
+ sessionId: exports_external.string(),
132
+ timestamp: exports_external.string(),
133
+ agent: exports_external.string()
134
+ }).passthrough();
135
+ var TaskWorkflowMetadataSchema = exports_external.object({
136
+ schema: exports_external.literal(TASK_WORKFLOW_SCHEMA_MARKER),
137
+ generation: exports_external.number().int().min(0),
138
+ state: exports_external.enum(TASK_WORKFLOW_STATES),
139
+ retryCount: exports_external.number().int().min(0).default(0),
140
+ retryHistory: exports_external.array(exports_external.enum(TASK_WORKFLOW_OUTCOMES)).max(3).default([]),
141
+ retryEpoch: exports_external.number().int().min(0).default(0),
142
+ lastOutcome: exports_external.enum(TASK_WORKFLOW_OUTCOMES).default("none"),
143
+ lastTransitionId: exports_external.string().min(1).nullable().optional().default(null),
144
+ updatedAt: exports_external.string()
145
+ });
146
+ var TaskEvidenceSchema = exports_external.object({
147
+ taskId: exports_external.string(),
148
+ required_gates: exports_external.array(exports_external.string()).default([]),
149
+ gates: exports_external.record(exports_external.string(), GateEvidenceSchema),
150
+ turbo: exports_external.boolean().optional(),
151
+ test_engineer_exempt: exports_external.boolean().optional(),
152
+ workflow: TaskWorkflowMetadataSchema.optional()
153
+ });
154
+ function parseTaskEvidence(raw, expectedTaskId) {
155
+ const parsed = TaskEvidenceSchema.parse(JSON.parse(raw));
156
+ if (parsed.taskId !== expectedTaskId) {
157
+ throw new Error(`TASK_EVIDENCE_IDENTITY_MISMATCH: expected ${expectedTaskId}, found ${parsed.taskId}`);
158
+ }
159
+ return parsed;
160
+ }
161
+ var DEFAULT_REQUIRED_GATES = ["reviewer", "test_engineer"];
162
+ var DEFAULT_WORKFLOW_STATE = "idle";
163
+ var WORKFLOW_STATE_RANK = {
164
+ idle: 0,
165
+ coder_delegated: 1,
166
+ pre_check_passed: 2,
167
+ reviewer_run: 3,
168
+ tests_run: 4,
169
+ rework_required: 5,
170
+ blocked: 6,
171
+ complete: 7
172
+ };
173
+ function isValidTaskId(taskId) {
174
+ return isStrictTaskId(taskId);
175
+ }
176
+ function assertValidTaskId(taskId) {
177
+ assertStrictTaskId(taskId);
178
+ }
179
+ function createDefaultWorkflowMetadata(nowIso) {
180
+ return {
181
+ schema: TASK_WORKFLOW_SCHEMA_MARKER,
182
+ generation: 0,
183
+ state: DEFAULT_WORKFLOW_STATE,
184
+ retryCount: 0,
185
+ retryHistory: [],
186
+ retryEpoch: 0,
187
+ lastOutcome: "none",
188
+ lastTransitionId: null,
189
+ updatedAt: nowIso
190
+ };
191
+ }
192
+ function getEventOutcome(event) {
193
+ switch (event.type) {
194
+ case "dispatch_attempted":
195
+ return "dispatch_attempted";
196
+ case "dispatch_no_mutation":
197
+ return "dispatch_no_mutation";
198
+ case "accepted_mutation":
199
+ return event.context?.settlementFailed === true ? "accepted_mutation_failed" : "accepted_mutation";
200
+ case "stage_a_passed":
201
+ return "stage_a_passed";
202
+ case "stage_a_failed":
203
+ return "stage_a_failed";
204
+ case "stage_b_completed":
205
+ return "stage_b_completed";
206
+ case "stage_b_failed":
207
+ return "stage_b_failed";
208
+ case "gate_recorded":
209
+ return "gate_recorded";
210
+ case "task_completed":
211
+ return "task_completed";
212
+ case "task_blocked":
213
+ return "task_blocked";
214
+ case "repair_idle":
215
+ return "repair_idle";
216
+ }
217
+ }
218
+ function isAuthoritativeWorkflowMetadata(workflow) {
219
+ return workflow?.schema === TASK_WORKFLOW_SCHEMA_MARKER;
220
+ }
221
+ function getTaskWorkflowSnapshot(evidence) {
222
+ if (isAuthoritativeWorkflowMetadata(evidence?.workflow)) {
223
+ return { ...evidence.workflow, authoritative: true };
224
+ }
225
+ return {
226
+ ...createDefaultWorkflowMetadata(""),
227
+ authoritative: false
228
+ };
229
+ }
230
+ function maybeExpandRequiredGates(existing, event) {
231
+ if (event.type === "accepted_mutation") {
232
+ const agentType = event.agentType;
233
+ if (typeof agentType === "string" && agentType.trim() !== "") {
234
+ return existing ? expandRequiredGates(existing.required_gates, agentType, event.context ?? {}) : deriveRequiredGates(agentType, event.context ?? {});
235
+ }
236
+ }
237
+ if (event.type === "stage_b_completed" && event.ensureDefaultStageB === true) {
238
+ return expandRequiredGates(existing?.required_gates ?? [], "coder", {
239
+ testEngineerExempt: false
240
+ });
241
+ }
242
+ if (event.type === "stage_b_completed" || event.type === "gate_recorded") {
243
+ return existing ? expandRequiredGates(existing.required_gates, event.gate) : deriveRequiredGates(event.gate);
244
+ }
245
+ return existing?.required_gates ?? [];
246
+ }
247
+ function hasAllRequiredGatesPassed(requiredGates, gates) {
248
+ return requiredGates.length > 0 && requiredGates.every((gate) => gates[gate] != null);
249
+ }
250
+ function shouldTreatGateAsStageB(gate) {
251
+ return gate === "reviewer" || gate === "test_engineer";
252
+ }
253
+ function clearWorkflowGateProof(gates) {
254
+ const retained = { ...gates };
255
+ delete retained.pre_check;
256
+ delete retained.reviewer;
257
+ delete retained.test_engineer;
258
+ delete retained.council;
259
+ delete retained.critic;
260
+ delete retained.critic_sounding_board;
261
+ return retained;
262
+ }
263
+ function assertExpectedGeneration(snapshot, event) {
264
+ if (typeof event.expectedGeneration === "number" && event.expectedGeneration !== snapshot.generation) {
265
+ throw new Error(`TASK_WORKFLOW_GENERATION_MISMATCH: expected ${event.expectedGeneration}, current ${snapshot.generation}`);
266
+ }
267
+ }
268
+ function isDuplicateTransition(snapshot, event) {
269
+ return snapshot.authoritative && typeof event.transitionId === "string" && event.transitionId.length > 0 && snapshot.lastTransitionId === event.transitionId && snapshot.lastOutcome === getEventOutcome(event);
270
+ }
271
+ function reduceTaskWorkflowSnapshot(current, event, context) {
272
+ if ((current.state === "complete" || current.state === "blocked") && event.type !== "repair_idle" && !(current.state === "complete" && event.type === "task_completed" || current.state === "blocked" && event.type === "task_blocked")) {
273
+ throw new Error(`TASK_WORKFLOW_TERMINAL: cannot apply ${event.type} from ${current.state}`);
274
+ }
275
+ const outcome = getEventOutcome(event);
276
+ const base = {
277
+ schema: TASK_WORKFLOW_SCHEMA_MARKER,
278
+ generation: current.generation,
279
+ state: current.state,
280
+ retryCount: current.retryCount,
281
+ retryHistory: current.retryHistory,
282
+ retryEpoch: current.retryEpoch,
283
+ lastOutcome: outcome,
284
+ lastTransitionId: event.transitionId ?? current.lastTransitionId,
285
+ updatedAt: context.nowIso
286
+ };
287
+ switch (event.type) {
288
+ case "dispatch_attempted":
289
+ return base;
290
+ case "dispatch_no_mutation":
291
+ return {
292
+ ...base,
293
+ retryCount: Math.min(current.retryCount + 1, 3),
294
+ retryHistory: [...current.retryHistory, outcome].slice(-3),
295
+ retryEpoch: current.retryEpoch || current.generation + 1
296
+ };
297
+ case "stage_b_failed":
298
+ if (current.state !== "pre_check_passed" && current.state !== "reviewer_run" && current.state !== "tests_run" && current.state !== "rework_required") {
299
+ throw new Error(`TASK_WORKFLOW_STAGE_A_REQUIRED: cannot reject ${event.gate} from ${current.state}`);
300
+ }
301
+ return {
302
+ ...base,
303
+ state: "rework_required",
304
+ retryCount: Math.min(current.retryCount + 1, 3),
305
+ retryHistory: [...current.retryHistory, outcome].slice(-3),
306
+ retryEpoch: current.retryEpoch || current.generation + 1
307
+ };
308
+ case "accepted_mutation":
309
+ if (event.context?.settlementFailed === true) {
310
+ return {
311
+ ...base,
312
+ generation: current.generation + 1,
313
+ state: "rework_required",
314
+ retryCount: Math.min(current.retryCount + 1, 3),
315
+ retryHistory: [...current.retryHistory, outcome].slice(-3),
316
+ retryEpoch: current.retryEpoch || current.generation + 1
317
+ };
318
+ }
319
+ return {
320
+ ...base,
321
+ generation: current.generation + 1,
322
+ state: "coder_delegated"
323
+ };
324
+ case "stage_a_passed":
325
+ if (current.state !== "coder_delegated" && current.state !== "pre_check_passed") {
326
+ throw new Error(`TASK_WORKFLOW_CODER_MUTATION_REQUIRED: cannot pass Stage A from ${current.state}`);
327
+ }
328
+ return {
329
+ ...base,
330
+ state: "pre_check_passed"
331
+ };
332
+ case "stage_a_failed":
333
+ if (current.state !== "coder_delegated" && current.state !== "pre_check_passed" && current.state !== "rework_required") {
334
+ throw new Error(`TASK_WORKFLOW_CODER_MUTATION_REQUIRED: cannot fail Stage A from ${current.state}`);
335
+ }
336
+ return {
337
+ ...base,
338
+ state: "rework_required",
339
+ retryCount: Math.min(current.retryCount + 1, 3),
340
+ retryHistory: [...current.retryHistory, outcome].slice(-3),
341
+ retryEpoch: current.retryEpoch || current.generation + 1
342
+ };
343
+ case "stage_b_completed":
344
+ if (current.state !== "pre_check_passed" && current.state !== "reviewer_run" && current.state !== "tests_run") {
345
+ throw new Error(`TASK_WORKFLOW_STAGE_A_REQUIRED: cannot record ${event.gate} from ${current.state}`);
346
+ }
347
+ return {
348
+ ...base,
349
+ state: hasAllRequiredGatesPassed(context.requiredGates, context.gates) ? "tests_run" : "reviewer_run"
350
+ };
351
+ case "gate_recorded":
352
+ return {
353
+ ...base,
354
+ state: current.state
355
+ };
356
+ case "task_completed":
357
+ if (event.qaExempt !== true && current.state !== "tests_run" && current.state !== "complete" && !(current.state === "pre_check_passed" && context.gates.council != null)) {
358
+ throw new Error(`TASK_WORKFLOW_QA_REQUIRED: cannot complete from ${current.state}`);
359
+ }
360
+ return {
361
+ ...base,
362
+ state: "complete"
363
+ };
364
+ case "task_blocked":
365
+ return {
366
+ ...base,
367
+ state: "blocked"
368
+ };
369
+ case "repair_idle":
370
+ return {
371
+ ...base,
372
+ generation: current.generation + 1,
373
+ state: "idle",
374
+ retryCount: 0,
375
+ retryHistory: [],
376
+ retryEpoch: 0
377
+ };
378
+ }
379
+ }
380
+ function getEvidenceDir(directory) {
381
+ const swarmDir = path.resolve(directory, ".swarm");
382
+ const evidenceDir = path.join(swarmDir, "evidence");
383
+ mkdirSync(evidenceDir, { recursive: true });
384
+ let resolvedSwarmDir;
385
+ let resolvedEvidenceDir;
386
+ try {
387
+ resolvedSwarmDir = path.normalize(realpathSync(swarmDir));
388
+ resolvedEvidenceDir = path.normalize(realpathSync(evidenceDir));
389
+ } catch (error) {
390
+ throw new Error(`Unable to resolve evidence directory: ${error.message}`);
391
+ }
392
+ const swarmPrefix = `${resolvedSwarmDir}${path.sep}`;
393
+ const withinSwarmBoundary = process.platform === "win32" ? resolvedEvidenceDir.toLowerCase().startsWith(swarmPrefix.toLowerCase()) : resolvedEvidenceDir.startsWith(swarmPrefix);
394
+ if (!withinSwarmBoundary) {
395
+ throw new Error(`Evidence path escapes .swarm boundary: ${resolvedEvidenceDir}`);
396
+ }
397
+ return resolvedEvidenceDir;
398
+ }
399
+ function getEvidencePath(directory, taskId) {
400
+ assertValidTaskId(taskId);
401
+ return taskEvidencePath(directory, taskId);
402
+ }
403
+ function readExisting(evidencePath, taskId) {
404
+ try {
405
+ const raw = readFileSync(evidencePath, "utf-8");
406
+ return parseTaskEvidence(raw, taskId);
407
+ } catch (error) {
408
+ if (error.code === "ENOENT")
409
+ return null;
410
+ telemetry.gateParseError(taskId, error);
411
+ throw error;
412
+ }
413
+ }
414
+ function deriveRequiredGates(agentType, context = {}) {
415
+ switch (agentType) {
416
+ case "coder":
417
+ return context.testEngineerExempt === true ? ["reviewer"] : ["reviewer", "test_engineer"];
418
+ case "docs":
419
+ return ["docs"];
420
+ case "designer":
421
+ return ["designer", "reviewer", "test_engineer"];
422
+ case "explorer":
423
+ return ["explorer"];
424
+ case "sme":
425
+ return ["sme"];
426
+ case "reviewer":
427
+ return ["reviewer"];
428
+ case "test_engineer":
429
+ return ["test_engineer"];
430
+ case "critic":
431
+ return ["critic"];
432
+ case "critic_sounding_board":
433
+ return ["critic_sounding_board"];
434
+ case "critic_drift_verifier":
435
+ return ["critic_drift_verifier"];
436
+ case "critic_hallucination_verifier":
437
+ return ["critic_hallucination_verifier"];
438
+ case "critic_architecture_supervisor":
439
+ return ["critic_architecture_supervisor"];
440
+ default:
441
+ return ["reviewer", "test_engineer"];
442
+ }
443
+ }
444
+ function expandRequiredGates(existingGates, newAgentType, context = {}) {
445
+ const newGates = deriveRequiredGates(newAgentType, context);
446
+ const combined = [...new Set([...existingGates ?? [], ...newGates])];
447
+ return combined.sort();
448
+ }
449
+ function updateEvidenceForTransition(existing, event) {
450
+ const nowIso = new Date().toISOString();
451
+ const requiredGates = maybeExpandRequiredGates(existing, event);
452
+ let gates = {
453
+ ...existing?.gates ?? {}
454
+ };
455
+ if (event.type === "accepted_mutation" || event.type === "repair_idle") {
456
+ gates = clearWorkflowGateProof(gates);
457
+ }
458
+ if (event.type === "stage_a_passed") {
459
+ gates = {
460
+ ...gates,
461
+ pre_check: {
462
+ sessionId: "system",
463
+ timestamp: nowIso,
464
+ agent: "pre_check"
465
+ }
466
+ };
467
+ }
468
+ if (event.type === "stage_a_failed") {
469
+ delete gates.pre_check;
470
+ }
471
+ if (event.type === "stage_b_failed") {
472
+ delete gates.reviewer;
473
+ delete gates.test_engineer;
474
+ }
475
+ if (event.type === "stage_b_completed" || event.type === "gate_recorded") {
476
+ gates = {
477
+ ...gates,
478
+ [event.gate]: {
479
+ sessionId: event.sessionId,
480
+ timestamp: nowIso,
481
+ agent: event.gate
482
+ }
483
+ };
484
+ }
485
+ const snapshot = getTaskWorkflowSnapshot(existing);
486
+ assertExpectedGeneration(snapshot, event);
487
+ if (isDuplicateTransition(snapshot, event) && existing) {
488
+ return existing;
489
+ }
490
+ const workflow = reduceTaskWorkflowSnapshot(snapshot, event, {
491
+ requiredGates,
492
+ gates,
493
+ nowIso
494
+ });
495
+ return {
496
+ taskId: existing?.taskId ?? "",
497
+ required_gates: requiredGates,
498
+ gates,
499
+ turbo: "turbo" in event && event.turbo === true ? true : ("turbo" in event) && event.turbo === false ? existing?.turbo : existing?.turbo,
500
+ test_engineer_exempt: (event.type === "dispatch_attempted" || event.type === "dispatch_no_mutation" || event.type === "accepted_mutation") && event.agentType === "coder" ? event.context?.testEngineerExempt === true && !requiredGates.includes("test_engineer") : existing?.test_engineer_exempt,
501
+ workflow
502
+ };
503
+ }
504
+ async function transitionTaskWorkflowEvidence(directory, taskId, event) {
505
+ assertValidTaskId(taskId);
506
+ let updatedEvidence = null;
507
+ await withTaskEvidenceTransaction(directory, taskId, event.type, async (transaction) => {
508
+ updatedEvidence = await transaction.transition(event);
509
+ });
510
+ return updatedEvidence ?? {
511
+ taskId,
512
+ required_gates: [],
513
+ gates: {},
514
+ workflow: createDefaultWorkflowMetadata(new Date().toISOString())
515
+ };
516
+ }
517
+ async function withTaskEvidenceTransaction(directory, taskId, agent, callback) {
518
+ assertValidTaskId(taskId);
519
+ return withTaskEvidenceLock(directory, taskId, agent, async () => {
520
+ const resolvedEvidenceDir = getEvidenceDir(directory);
521
+ const evidencePath = path.join(resolvedEvidenceDir, `${taskId}.json`);
522
+ let current = null;
523
+ try {
524
+ current = readExisting(evidencePath, taskId);
525
+ } catch (error) {
526
+ telemetry.gateParseError(taskId, error);
527
+ throw error;
528
+ }
529
+ const persist = async (nextEvidence) => {
530
+ const validated = TaskEvidenceSchema.parse({
531
+ ...nextEvidence,
532
+ taskId
533
+ });
534
+ await atomicWriteFile(evidencePath, JSON.stringify(validated, null, 2));
535
+ current = validated;
536
+ return validated;
537
+ };
538
+ return callback({
539
+ taskId,
540
+ read: () => current,
541
+ transition: async (event) => {
542
+ assertTaskEvidenceWriteAllowed(directory, taskId, event);
543
+ const nextEvidence = updateEvidenceForTransition(current, event);
544
+ nextEvidence.taskId = taskId;
545
+ return persist(nextEvidence);
546
+ }
547
+ });
548
+ });
549
+ }
550
+ async function recordGateEvidence(directory, taskId, gate, sessionId, turbo, options = {}) {
551
+ assertValidTaskId(taskId);
552
+ if (shouldTreatGateAsStageB(gate) && typeof options.expectedGeneration !== "number") {
553
+ throw new Error(`TASK_WORKFLOW_GENERATION_REQUIRED: ${gate} for task ${taskId} must be bound at dispatch`);
554
+ }
555
+ await transitionTaskWorkflowEvidence(directory, taskId, shouldTreatGateAsStageB(gate) ? {
556
+ type: "stage_b_completed",
557
+ gate,
558
+ sessionId,
559
+ turbo,
560
+ ensureDefaultStageB: options.ensureDefaultStageB,
561
+ expectedGeneration: options.expectedGeneration,
562
+ transitionId: options.transitionId
563
+ } : {
564
+ type: "gate_recorded",
565
+ gate,
566
+ sessionId,
567
+ turbo,
568
+ expectedGeneration: options.expectedGeneration,
569
+ transitionId: options.transitionId
570
+ });
571
+ telemetry.gatePassed(sessionId, gate, taskId);
572
+ }
573
+ async function recordAgentDispatch(directory, taskId, agentType, turbo, context = {}) {
574
+ assertValidTaskId(taskId);
575
+ const expectedGeneration = getTaskWorkflowSnapshot(await readTaskEvidence(directory, taskId)).generation;
576
+ await transitionTaskWorkflowEvidence(directory, taskId, agentType === "coder" ? {
577
+ type: "accepted_mutation",
578
+ agentType,
579
+ turbo,
580
+ context,
581
+ expectedGeneration
582
+ } : {
583
+ type: "dispatch_attempted",
584
+ agentType,
585
+ turbo,
586
+ context,
587
+ expectedGeneration
588
+ });
589
+ }
590
+ async function readTaskEvidence(directory, taskId) {
591
+ try {
592
+ assertValidTaskId(taskId);
593
+ return readExisting(getEvidencePath(directory, taskId), taskId);
594
+ } catch {
595
+ return null;
596
+ }
597
+ }
598
+ function readTaskEvidenceRaw(directory, taskId) {
599
+ assertValidTaskId(taskId);
600
+ const evidencePath = getEvidencePath(directory, taskId);
601
+ try {
602
+ const raw = readFileSync(evidencePath, "utf-8");
603
+ return parseTaskEvidence(raw, taskId);
604
+ } catch (error) {
605
+ const code = error.code;
606
+ if (code === "ENOENT" || code === "ENAMETOOLONG")
607
+ return null;
608
+ throw error;
609
+ }
610
+ }
611
+ async function hasPassedAllGates(directory, taskId) {
612
+ const evidence = await readTaskEvidence(directory, taskId);
613
+ if (!evidence)
614
+ return false;
615
+ if (!Array.isArray(evidence.required_gates) || evidence.required_gates.length === 0)
616
+ return false;
617
+ return evidence.required_gates.every((gate) => evidence.gates[gate] != null);
618
+ }
619
+ function compareTaskWorkflowStateRank(left, right) {
620
+ return WORKFLOW_STATE_RANK[left] - WORKFLOW_STATE_RANK[right];
621
+ }
622
+
623
+ export { sanitizeTaskId, TASK_WORKFLOW_SCHEMA_MARKER, assertTaskEvidenceWriteAllowed, parseTaskEvidence, DEFAULT_REQUIRED_GATES, isValidTaskId, getTaskWorkflowSnapshot, reduceTaskWorkflowSnapshot, deriveRequiredGates, expandRequiredGates, transitionTaskWorkflowEvidence, withTaskEvidenceTransaction, recordGateEvidence, recordAgentDispatch, readTaskEvidence, readTaskEvidenceRaw, hasPassedAllGates, compareTaskWorkflowStateRank };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  atomicWriteFile
4
- } from "./index-h2waehqq.js";
4
+ } from "./index-p8kk34am.js";
5
5
  import {
6
6
  init_logger,
7
7
  warn
@@ -5,10 +5,10 @@ import {
5
5
  import {
6
6
  computePlanStructureHash,
7
7
  derivePlanId
8
- } from "./index-kbfsp07d.js";
8
+ } from "./index-wrb0gykj.js";
9
9
  import {
10
10
  assertProjectRoot
11
- } from "./index-hfvxhk4z.js";
11
+ } from "./index-912qz4y0.js";
12
12
  import {
13
13
  require_proper_lockfile
14
14
  } from "./index-7g4c7s5r.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./index-4nt52yr9.js";
18
18
  import {
19
19
  PlanSchema
20
- } from "./index-d181x9zr.js";
20
+ } from "./index-nwrwy8eb.js";
21
21
  import {
22
22
  __toESM
23
23
  } from "./index-a76rekgs.js";
@@ -773,12 +773,12 @@ function isDispatchCorrelated(binding) {
773
773
  return binding.activation === "active" && typeof binding.dispatchCallId === "string" && binding.dispatchCallId.length > 0 && binding.ownerMessageId === binding.dispatchCallId && typeof binding.parentOwnerSessionId === "string" && binding.parentOwnerSessionId.length > 0 && binding.ownerSessionId !== binding.parentOwnerSessionId && binding.parentCallId === binding.dispatchCallId;
774
774
  }
775
775
  function clearScopeBindingFromDisk(input) {
776
+ const localRetirement = installScopeBindingRetirementIntent(input.binding);
776
777
  try {
777
778
  assertProjectRoot(input.directory);
778
779
  } catch (error) {
779
780
  return persistenceFailure(`Scope retirement project-root validation failed: ${error instanceof Error ? error.message : "unknown validation error"}`);
780
781
  }
781
- const localRetirement = installScopeBindingRetirementIntent(input.binding);
782
782
  let release;
783
783
  try {
784
784
  const resolvedWorkspace = fs2.realpathSync(input.directory);