opencode-swarm 7.145.0 → 7.145.2

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 (105) hide show
  1. package/.opencode/skills/phase-wrap/SKILL.md +3 -2
  2. package/README.md +5 -1
  3. package/dist/background/workspace-snapshot.d.ts +29 -0
  4. package/dist/cli/{config-doctor-dzsv3pqy.js → config-doctor-j1r33f4q.js} +3 -3
  5. package/dist/cli/{core-qkh9me8x.js → core-c2zrd384.js} +4 -4
  6. package/dist/cli/{curation-policy-5x6346tf.js → curation-policy-xv0j8zyt.js} +6 -6
  7. package/dist/cli/{curator-zssndq5x.js → curator-gk2kmrk1.js} +31 -31
  8. package/dist/cli/{curator-llm-factory-q5p4578g.js → curator-llm-factory-sat3mn5n.js} +31 -31
  9. package/dist/cli/{evidence-summary-service-dqcpapj8.js → evidence-summary-service-0mhx0t0v.js} +14 -14
  10. package/dist/cli/{gate-evidence-bkdqryqg.js → gate-evidence-a5adh55x.js} +9 -9
  11. package/dist/cli/{guardrail-explain-kspf83x5.js → guardrail-explain-r50fery8.js} +32 -32
  12. package/dist/cli/{guardrail-log-qg4sq6gr.js → guardrail-log-p69eys6d.js} +4 -4
  13. package/dist/cli/{hive-promoter-3h7dhnek.js → hive-promoter-ay8a7sct.js} +31 -31
  14. package/dist/cli/{index-wk54ey3h.js → index-0a0asz2s.js} +1 -1
  15. package/dist/cli/{index-2dnqazyr.js → index-1g87esfp.js} +2 -2
  16. package/dist/cli/{index-0pcq32y2.js → index-2vefr1f8.js} +1 -1
  17. package/dist/cli/{index-fp464as8.js → index-4p3qfb05.js} +1 -1
  18. package/dist/cli/{index-77ef8gye.js → index-5e5a1y2r.js} +1 -1
  19. package/dist/cli/{index-0jr9zn34.js → index-612rr70a.js} +2 -2
  20. package/dist/cli/{index-apjdytwx.js → index-673axbjx.js} +3 -3
  21. package/dist/cli/{index-qfawexc8.js → index-6wf75rcm.js} +6 -6
  22. package/dist/cli/{index-k6pdsct6.js → index-7y5akvc9.js} +1 -1
  23. package/dist/cli/{index-hfzcztv6.js → index-9080b3de.js} +34 -34
  24. package/dist/cli/{index-v64kjqvg.js → index-917z76qr.js} +25 -18
  25. package/dist/cli/{index-ffdwj1an.js → index-97psh79d.js} +1 -1
  26. package/dist/cli/{index-kp87kr1a.js → index-9gt8g2qj.js} +4 -4
  27. package/dist/cli/{index-4e5a28h7.js → index-b9kxxd6k.js} +2 -2
  28. package/dist/cli/{index-pa86tpgt.js → index-bghwrr59.js} +1 -1
  29. package/dist/cli/{index-6ezbzd5e.js → index-cb2qtetk.js} +682 -181
  30. package/dist/cli/{index-v3y3qg48.js → index-cpg98bh1.js} +17 -1
  31. package/dist/cli/{index-c13ttmak.js → index-cxn95n7q.js} +180 -32
  32. package/dist/cli/{index-7g276m9m.js → index-czde45km.js} +3 -3
  33. package/dist/cli/{index-zfhe7vbb.js → index-gpnv14kq.js} +2 -2
  34. package/dist/cli/{index-6q3agdmr.js → index-j20fzn0w.js} +2 -2
  35. package/dist/cli/{index-mkks7jwg.js → index-jgb7mq2y.js} +4 -4
  36. package/dist/cli/{index-h4hasck4.js → index-jpppcckq.js} +4 -4
  37. package/dist/cli/{index-4evasm2b.js → index-kggqpefz.js} +5 -5
  38. package/dist/cli/{index-s6cwsnrw.js → index-n55a28zr.js} +254 -36
  39. package/dist/cli/{index-b3xret0a.js → index-ncfjxz9n.js} +5 -5
  40. package/dist/cli/{index-e00wbqw5.js → index-np4ytvvv.js} +2 -2
  41. package/dist/cli/{index-jy9bwa9k.js → index-nsr5b69r.js} +2 -2
  42. package/dist/cli/{index-zz5qsjd1.js → index-qyvjp0bq.js} +66 -38
  43. package/dist/cli/{index-6hqhyb0f.js → index-rk80jhef.js} +19 -5
  44. package/dist/cli/{index-4zwjc9sb.js → index-vav705md.js} +101 -4
  45. package/dist/cli/{index-s72naw1j.js → index-x8pm918t.js} +1 -1
  46. package/dist/cli/{index-b30x236n.js → index-z9yhhk6q.js} +96 -8
  47. package/dist/cli/index.js +32 -32
  48. package/dist/cli/{knowledge-escalator-w1mbaktt.js → knowledge-escalator-22apj3dj.js} +14 -14
  49. package/dist/cli/{knowledge-events-a0dj6gy6.js → knowledge-events-bx8xba9z.js} +12 -12
  50. package/dist/cli/{knowledge-link-mzdjvjsd.js → knowledge-link-82ew2yc4.js} +5 -5
  51. package/dist/cli/{knowledge-store-8kk3rghx.js → knowledge-store-nc71kfsg.js} +6 -6
  52. package/dist/cli/{knowledge-validator-91ym56e0.js → knowledge-validator-g8ne80v6.js} +8 -8
  53. package/dist/cli/model-preflight-7ea00h34.js +170 -0
  54. package/dist/cli/{pending-delegations-6vsrmw5w.js → pending-delegations-kkrczqv7.js} +3 -3
  55. package/dist/cli/{pr-subscriptions-zc3skxde.js → pr-subscriptions-2xn238xt.js} +3 -3
  56. package/dist/cli/{runner-jj32v8bk.js → runner-pqsf809k.js} +6 -6
  57. package/dist/cli/{scan-cursor-12jxwd14.js → scan-cursor-6ksgv514.js} +7 -7
  58. package/dist/cli/{schema-nq9tcz87.js → schema-mpcm7nje.js} +2 -2
  59. package/dist/cli/{scope-persistence-dv6z7n08.js → scope-persistence-mj1w3hqw.js} +11 -8
  60. package/dist/cli/{skill-generator-drscnzq9.js → skill-generator-gsa6qwwt.js} +16 -16
  61. package/dist/cli/{telemetry-z54dgdrh.js → telemetry-t109dhv7.js} +1 -1
  62. package/dist/cli/{workspace-snapshot-q21mgbsh.js → workspace-snapshot-kznz5e13.js} +4 -2
  63. package/dist/cli/{worktree-collision-ownership-rfyyjjct.js → worktree-collision-ownership-2jtg2my1.js} +8 -8
  64. package/dist/cli/{worktree-isolation-4tehtym5.js → worktree-isolation-ajzyp2gm.js} +33 -31
  65. package/dist/config/schema.d.ts +2 -2
  66. package/dist/evidence/task-gate-repair.d.ts +26 -0
  67. package/dist/evidence/task-gate-requirements.d.ts +20 -0
  68. package/dist/gate-evidence.d.ts +7 -0
  69. package/dist/hooks/delegation-gate/worktree-isolation.d.ts +4 -0
  70. package/dist/hooks/knowledge-receipt-ledger-storage.d.ts +2 -0
  71. package/dist/hooks/knowledge-receipt-ledger.d.ts +72 -3
  72. package/dist/hooks/knowledge-receipt-observability.d.ts +1 -1
  73. package/dist/hooks/phase-complete-directive-gate.d.ts +9 -0
  74. package/dist/index.js +566 -546
  75. package/dist/observability/catalog.d.ts +2 -2
  76. package/dist/plan/manager.d.ts +8 -0
  77. package/dist/review/diff-source.d.ts +30 -0
  78. package/dist/review/engine.d.ts +1 -0
  79. package/dist/review/evidence.d.ts +16 -2
  80. package/dist/review/phase-runner.d.ts +1 -0
  81. package/dist/scope/scope-binding.d.ts +16 -0
  82. package/dist/services/model-preflight.d.ts +151 -0
  83. package/dist/services/session-reflection.d.ts +24 -0
  84. package/dist/telemetry.d.ts +12 -1
  85. package/dist/tools/completion-verify.d.ts +2 -0
  86. package/dist/tools/convene-council.d.ts +1 -1
  87. package/dist/tools/index.d.ts +4 -0
  88. package/dist/tools/manifest.d.ts +4 -0
  89. package/dist/tools/phase-complete/gates/final-review-gate.d.ts +3 -3
  90. package/dist/tools/phase-complete/gates/types.d.ts +2 -2
  91. package/dist/tools/phase-complete/preflight-report.d.ts +66 -0
  92. package/dist/tools/phase-complete/snapshot-identity.d.ts +1 -0
  93. package/dist/tools/phase-complete.d.ts +66 -3
  94. package/dist/tools/placeholder-scan.d.ts +64 -0
  95. package/dist/tools/record-directive-override.d.ts +14 -0
  96. package/dist/tools/repair-gate-evidence.d.ts +6 -0
  97. package/dist/tools/repair-knowledge-receipt-ledger.d.ts +27 -0
  98. package/dist/tools/run-phase-review.d.ts +37 -0
  99. package/dist/tools/sast-scan.d.ts +6 -0
  100. package/dist/tools/submit-phase-council-verdicts.d.ts +1 -1
  101. package/dist/tools/tool-metadata.d.ts +32 -16
  102. package/dist/tools/write-final-council-evidence.d.ts +1 -1
  103. package/dist/tools/write-retro.d.ts +2 -0
  104. package/package.json +1 -1
  105. package/dist/cli/{curator-drift-yn5d0mvq.js → curator-drift-r50x1rac.js} +1 -1
@@ -2,18 +2,11 @@
2
2
  import {
3
3
  autoCommitDirty,
4
4
  cleanUntrackedFiles
5
- } from "./index-6hqhyb0f.js";
5
+ } from "./index-rk80jhef.js";
6
6
  import {
7
7
  isPathWithinDeclaredScope,
8
8
  unsafePathTextReason
9
9
  } from "./index-556ja8an.js";
10
- import {
11
- validateSwarmPath
12
- } from "./index-w8pgjr75.js";
13
- import {
14
- bunSpawn,
15
- classifySpawnFailure
16
- } from "./index-zj6t9zgx.js";
17
10
  import {
18
11
  init_git_executable,
19
12
  resolveGitExecutable
@@ -22,14 +15,24 @@ import {
22
15
  advisoryWarn,
23
16
  init_warning_buffer
24
17
  } from "./index-4rhhvd1a.js";
18
+ import {
19
+ validateSwarmPath
20
+ } from "./index-w8pgjr75.js";
21
+ import {
22
+ bunSpawn,
23
+ classifySpawnFailure
24
+ } from "./index-zj6t9zgx.js";
25
25
  import {
26
26
  atomicWriteFile,
27
27
  taskEvidencePath,
28
28
  withTaskEvidenceLock
29
- } from "./index-6q3agdmr.js";
29
+ } from "./index-j20fzn0w.js";
30
+ import {
31
+ assertProjectRoot
32
+ } from "./index-bghwrr59.js";
30
33
  import {
31
34
  telemetry
32
- } from "./index-zz5qsjd1.js";
35
+ } from "./index-qyvjp0bq.js";
33
36
  import {
34
37
  exports_external,
35
38
  init_zod
@@ -40,8 +43,214 @@ import {
40
43
 
41
44
  // src/gate-evidence.ts
42
45
  init_zod();
43
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, realpathSync } from "fs";
44
- import * as path2 from "path";
46
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
47
+ import * as path3 from "path";
48
+
49
+ // src/evidence/task-gate-requirements.ts
50
+ init_zod();
51
+ import { createHash } from "crypto";
52
+ import * as fs from "fs";
53
+ import * as path from "path";
54
+ var MAX_TASK_GATE_REQUIREMENTS_BYTES = 256 * 1024;
55
+ var TaskGateRequirementsReceiptSchema = exports_external.object({
56
+ schemaVersion: exports_external.literal(1),
57
+ taskId: exports_external.string().min(1).max(120),
58
+ generation: exports_external.number().int().min(0),
59
+ normalizedRole: exports_external.string().min(1).max(120),
60
+ testEngineerExempt: exports_external.boolean().nullable(),
61
+ requiredGates: exports_external.array(exports_external.string()).min(1).max(16),
62
+ sourceEvent: exports_external.string().min(1).max(120),
63
+ sourceTransitionId: exports_external.string().min(1).max(200).nullable(),
64
+ recordedAt: exports_external.string().min(1).max(128),
65
+ previousChainHash: exports_external.string().regex(/^[a-f0-9]{64}$/).nullable(),
66
+ chainHash: exports_external.string().regex(/^[a-f0-9]{64}$/)
67
+ }).strict();
68
+ function samePath(left, right) {
69
+ const normalize = (value) => process.platform === "win32" ? path.resolve(value).toLowerCase() : path.resolve(value);
70
+ return normalize(left) === normalize(right);
71
+ }
72
+ function assertSafeRequirementsParent(directory, create) {
73
+ assertProjectRoot(directory, undefined, "task gate requirements");
74
+ const rootStat = fs.lstatSync(directory);
75
+ if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
76
+ throw new Error("TASK_GATE_REQUIREMENTS_UNREADABLE: project root is not a regular directory");
77
+ }
78
+ const canonicalRoot = fs.realpathSync(directory);
79
+ const segments = [".swarm", "evidence", "task-gate-requirements"];
80
+ let current = canonicalRoot;
81
+ for (const segment of segments) {
82
+ current = path.join(current, segment);
83
+ let info;
84
+ try {
85
+ info = fs.lstatSync(current);
86
+ } catch (error) {
87
+ if (error.code === "ENOENT") {
88
+ if (!create)
89
+ return current;
90
+ try {
91
+ fs.mkdirSync(current);
92
+ } catch (mkdirError) {
93
+ if (mkdirError.code !== "EEXIST") {
94
+ throw mkdirError;
95
+ }
96
+ }
97
+ info = fs.lstatSync(current);
98
+ } else {
99
+ throw error;
100
+ }
101
+ }
102
+ if (info.isSymbolicLink() || !info.isDirectory()) {
103
+ throw new Error("TASK_GATE_REQUIREMENTS_UNREADABLE: receipt parent is redirected or not a directory");
104
+ }
105
+ const canonicalCurrent = fs.realpathSync(current);
106
+ if (!samePath(canonicalCurrent, current)) {
107
+ throw new Error("TASK_GATE_REQUIREMENTS_UNREADABLE: receipt parent escaped the project root");
108
+ }
109
+ }
110
+ return current;
111
+ }
112
+ function safeTaskGateRequirementsReceiptPath(directory, taskId, createParent) {
113
+ const parent = assertSafeRequirementsParent(directory, createParent);
114
+ return path.join(parent, `${taskId}.jsonl`);
115
+ }
116
+ function sha256(value) {
117
+ return createHash("sha256").update(value).digest("hex");
118
+ }
119
+ function canonicalReceiptPayload(receipt) {
120
+ return JSON.stringify({
121
+ ...receipt,
122
+ requiredGates: [...receipt.requiredGates]
123
+ });
124
+ }
125
+ function computeChainHash(receipt) {
126
+ return sha256(canonicalReceiptPayload(receipt));
127
+ }
128
+ function readBoundedTextFile(filePath) {
129
+ let pathStat;
130
+ try {
131
+ pathStat = fs.lstatSync(filePath);
132
+ } catch (error) {
133
+ if (error.code === "ENOENT")
134
+ return null;
135
+ throw error;
136
+ }
137
+ if (pathStat.isSymbolicLink() || !pathStat.isFile()) {
138
+ throw new Error("TASK_GATE_REQUIREMENTS_UNREADABLE: receipt path is not a regular file");
139
+ }
140
+ if (pathStat.size > MAX_TASK_GATE_REQUIREMENTS_BYTES) {
141
+ throw new Error(`TASK_GATE_REQUIREMENTS_OVERSIZED: ${pathStat.size} bytes exceeds ${MAX_TASK_GATE_REQUIREMENTS_BYTES}`);
142
+ }
143
+ const descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
144
+ try {
145
+ const openedStat = fs.fstatSync(descriptor);
146
+ if (!openedStat.isFile() || openedStat.dev !== pathStat.dev || openedStat.ino !== pathStat.ino) {
147
+ throw new Error("TASK_GATE_REQUIREMENTS_UNREADABLE: receipt changed while being opened");
148
+ }
149
+ if (openedStat.size > MAX_TASK_GATE_REQUIREMENTS_BYTES) {
150
+ throw new Error(`TASK_GATE_REQUIREMENTS_OVERSIZED: ${openedStat.size} bytes exceeds ${MAX_TASK_GATE_REQUIREMENTS_BYTES}`);
151
+ }
152
+ return fs.readFileSync(descriptor, "utf-8");
153
+ } finally {
154
+ fs.closeSync(descriptor);
155
+ }
156
+ }
157
+ async function readTaskGateRequirementsReceipts(directory, taskId) {
158
+ const filePath = safeTaskGateRequirementsReceiptPath(directory, taskId, false);
159
+ const text = readBoundedTextFile(filePath);
160
+ if (text === null)
161
+ return [];
162
+ const receipts = [];
163
+ for (const line of text.split(`
164
+ `)) {
165
+ if (!line.trim())
166
+ continue;
167
+ const parsed = TaskGateRequirementsReceiptSchema.parse(JSON.parse(line));
168
+ if (parsed.taskId !== taskId) {
169
+ throw new Error(`TASK_GATE_REQUIREMENTS_IDENTITY_MISMATCH: expected ${taskId}, found ${parsed.taskId}`);
170
+ }
171
+ const { chainHash, ...withoutChainHash } = parsed;
172
+ const expectedHash = computeChainHash(withoutChainHash);
173
+ if (expectedHash !== chainHash) {
174
+ throw new Error(`TASK_GATE_REQUIREMENTS_CHAIN_MISMATCH: receipt for ${taskId} failed hash validation`);
175
+ }
176
+ const previousChainHash = receipts.at(-1)?.chainHash ?? null;
177
+ if (parsed.previousChainHash !== previousChainHash) {
178
+ throw new Error(`TASK_GATE_REQUIREMENTS_CHAIN_MISMATCH: receipt for ${taskId} failed linkage validation`);
179
+ }
180
+ receipts.push(parsed);
181
+ }
182
+ return receipts;
183
+ }
184
+ function deriveReceiptRole(event) {
185
+ switch (event.type) {
186
+ case "accepted_mutation":
187
+ case "dispatch_attempted":
188
+ case "dispatch_no_mutation":
189
+ if (typeof event.agentType === "string" && event.agentType.trim().length > 0) {
190
+ return {
191
+ normalizedRole: event.agentType.trim(),
192
+ testEngineerExempt: event.agentType === "coder" ? event.context?.testEngineerExempt === true : null
193
+ };
194
+ }
195
+ return null;
196
+ case "stage_b_completed":
197
+ case "gate_recorded":
198
+ return {
199
+ normalizedRole: event.gate,
200
+ testEngineerExempt: null
201
+ };
202
+ default:
203
+ return null;
204
+ }
205
+ }
206
+ function shouldAppendReceipt(current, next, role) {
207
+ if (next.required_gates.length === 0)
208
+ return false;
209
+ const currentGeneration = current?.workflow?.generation ?? -1;
210
+ const nextGeneration = next.workflow?.generation ?? -1;
211
+ if (current === null)
212
+ return true;
213
+ if (JSON.stringify(current.required_gates) !== JSON.stringify(next.required_gates)) {
214
+ return true;
215
+ }
216
+ if ((current.test_engineer_exempt ?? null) !== role.testEngineerExempt) {
217
+ return true;
218
+ }
219
+ return currentGeneration !== nextGeneration;
220
+ }
221
+ async function appendTaskGateRequirementsReceiptIfNeeded(directory, taskId, current, next, event) {
222
+ const role = deriveReceiptRole(event);
223
+ if (!role || !shouldAppendReceipt(current, next, role))
224
+ return;
225
+ const filePath = safeTaskGateRequirementsReceiptPath(directory, taskId, true);
226
+ const receipts = await readTaskGateRequirementsReceipts(directory, taskId);
227
+ const latest = receipts.at(-1);
228
+ const baseReceipt = {
229
+ schemaVersion: 1,
230
+ taskId,
231
+ generation: next.workflow?.generation ?? 0,
232
+ normalizedRole: role.normalizedRole,
233
+ testEngineerExempt: role.testEngineerExempt,
234
+ requiredGates: [...next.required_gates],
235
+ sourceEvent: event.type,
236
+ sourceTransitionId: event.transitionId ?? null,
237
+ recordedAt: new Date().toISOString(),
238
+ previousChainHash: latest?.chainHash ?? null
239
+ };
240
+ const receipt = {
241
+ ...baseReceipt,
242
+ chainHash: computeChainHash(baseReceipt)
243
+ };
244
+ if (latest && latest.generation === receipt.generation && latest.normalizedRole === receipt.normalizedRole && latest.testEngineerExempt === receipt.testEngineerExempt && JSON.stringify(latest.requiredGates) === JSON.stringify(receipt.requiredGates) && latest.sourceTransitionId === receipt.sourceTransitionId) {
245
+ return;
246
+ }
247
+ const lines = [...receipts, receipt].map((entry) => JSON.stringify(entry));
248
+ assertSafeRequirementsParent(directory, false);
249
+ await atomicWriteFile(filePath, `${lines.join(`
250
+ `)}
251
+ `);
252
+ assertSafeRequirementsParent(directory, false);
253
+ }
45
254
 
46
255
  // src/validation/task-id.ts
47
256
  var STRICT_TASK_ID_PATTERN = /^\d+\.\d+(\.\d+)*$/;
@@ -90,7 +299,7 @@ function sanitizeTaskId(taskId) {
90
299
  }
91
300
 
92
301
  // src/workflow/workflow-wal-file.ts
93
- import * as fs2 from "fs";
302
+ import * as fs3 from "fs";
94
303
  import { mkdir, open } from "fs/promises";
95
304
  import { dirname } from "path";
96
305
 
@@ -98,11 +307,11 @@ import { dirname } from "path";
98
307
  init_warning_buffer();
99
308
 
100
309
  // src/turbo/lean/recovery.ts
101
- import * as fs from "fs";
102
- import * as path from "path";
310
+ import * as fs2 from "fs";
311
+ import * as path2 from "path";
103
312
  var RECOVERY_DIR_NAME = "recovery";
104
313
  function recoveryDir(directory) {
105
- return path.join(directory, ".swarm", RECOVERY_DIR_NAME);
314
+ return path2.join(directory, ".swarm", RECOVERY_DIR_NAME);
106
315
  }
107
316
  function isRecoveryRecord(value) {
108
317
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
@@ -116,11 +325,11 @@ function readRecoveryRecords(directory) {
116
325
  const dir = recoveryDir(directory);
117
326
  let entries;
118
327
  try {
119
- entries = fs.readdirSync(dir, { withFileTypes: true });
328
+ entries = fs2.readdirSync(dir, { withFileTypes: true });
120
329
  } catch {
121
330
  return {
122
331
  records: [],
123
- errored: fs.existsSync(dir)
332
+ errored: fs2.existsSync(dir)
124
333
  };
125
334
  }
126
335
  const records = [];
@@ -128,9 +337,9 @@ function readRecoveryRecords(directory) {
128
337
  for (const entry of entries) {
129
338
  if (!entry.isFile() || !entry.name.endsWith(".json"))
130
339
  continue;
131
- const full = path.join(dir, entry.name);
340
+ const full = path2.join(dir, entry.name);
132
341
  try {
133
- const parsed = JSON.parse(fs.readFileSync(full, "utf-8"));
342
+ const parsed = JSON.parse(fs2.readFileSync(full, "utf-8"));
134
343
  if (isRecoveryRecord(parsed)) {
135
344
  records.push(parsed);
136
345
  } else {
@@ -189,7 +398,7 @@ init_git_executable();
189
398
  var _internals = {
190
399
  bunSpawn,
191
400
  platform: process.platform,
192
- sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
401
+ sleep: (ms) => new Promise((resolve2) => setTimeout(resolve2, ms)),
193
402
  cleanupOrphanedBranches,
194
403
  startupOrphanRecovery,
195
404
  extractSessionId,
@@ -763,9 +972,9 @@ var SMALL_WORKFLOW_WAL_MAX_BYTES = 1024 * 1024;
763
972
  var CHUNK_BYTES = 64 * 1024;
764
973
  var _internals2 = {
765
974
  openFile: open,
766
- openFileSync: fs2.openSync,
767
- readFileSync: fs2.readSync,
768
- closeFileSync: fs2.closeSync
975
+ openFileSync: fs3.openSync,
976
+ readFileSync: fs3.readSync,
977
+ closeFileSync: fs3.closeSync
769
978
  };
770
979
  function maxBytesFor(kind) {
771
980
  return kind === "coder-settlement" ? CODER_SETTLEMENT_MAX_BYTES : SMALL_WORKFLOW_WAL_MAX_BYTES;
@@ -1017,8 +1226,14 @@ var TaskEvidenceSchema = exports_external.object({
1017
1226
  required_gates: exports_external.array(exports_external.string()).default([]),
1018
1227
  gates: exports_external.record(exports_external.string(), GateEvidenceSchema),
1019
1228
  turbo: exports_external.boolean().optional(),
1229
+ requirements_state: exports_external.enum(["known", "unknown"]).optional(),
1020
1230
  test_engineer_exempt: exports_external.boolean().optional(),
1021
- workflow: TaskWorkflowMetadataSchema.optional()
1231
+ workflow: TaskWorkflowMetadataSchema.optional(),
1232
+ repair_provenance: exports_external.object({
1233
+ source_sha256: exports_external.string().regex(/^[a-f0-9]{64}$/).nullable(),
1234
+ source_generation: exports_external.number().int().min(0).nullable(),
1235
+ requirements_receipt_hash: exports_external.string().regex(/^[a-f0-9]{64}$/).nullable()
1236
+ }).optional()
1022
1237
  });
1023
1238
  function parseTaskEvidence(raw, expectedTaskId) {
1024
1239
  const parsed = TaskEvidenceSchema.parse(JSON.parse(raw));
@@ -1259,18 +1474,18 @@ function reduceTaskWorkflowSnapshot(current, event, context) {
1259
1474
  }
1260
1475
  }
1261
1476
  function getEvidenceDir(directory) {
1262
- const swarmDir = path2.resolve(directory, ".swarm");
1263
- const evidenceDir = path2.join(swarmDir, "evidence");
1264
- mkdirSync2(evidenceDir, { recursive: true });
1477
+ const swarmDir = path3.resolve(directory, ".swarm");
1478
+ const evidenceDir = path3.join(swarmDir, "evidence");
1479
+ mkdirSync3(evidenceDir, { recursive: true });
1265
1480
  let resolvedSwarmDir;
1266
1481
  let resolvedEvidenceDir;
1267
1482
  try {
1268
- resolvedSwarmDir = path2.normalize(realpathSync(swarmDir));
1269
- resolvedEvidenceDir = path2.normalize(realpathSync(evidenceDir));
1483
+ resolvedSwarmDir = path3.normalize(realpathSync2(swarmDir));
1484
+ resolvedEvidenceDir = path3.normalize(realpathSync2(evidenceDir));
1270
1485
  } catch (error) {
1271
1486
  throw new Error(`Unable to resolve evidence directory: ${error.message}`);
1272
1487
  }
1273
- const swarmPrefix = `${resolvedSwarmDir}${path2.sep}`;
1488
+ const swarmPrefix = `${resolvedSwarmDir}${path3.sep}`;
1274
1489
  const withinSwarmBoundary = process.platform === "win32" ? resolvedEvidenceDir.toLowerCase().startsWith(swarmPrefix.toLowerCase()) : resolvedEvidenceDir.startsWith(swarmPrefix);
1275
1490
  if (!withinSwarmBoundary) {
1276
1491
  throw new Error(`Evidence path escapes .swarm boundary: ${resolvedEvidenceDir}`);
@@ -1283,7 +1498,7 @@ function getEvidencePath(directory, taskId) {
1283
1498
  }
1284
1499
  function readExisting(evidencePath, taskId) {
1285
1500
  try {
1286
- const raw = readFileSync2(evidencePath, "utf-8");
1501
+ const raw = readFileSync3(evidencePath, "utf-8");
1287
1502
  return parseTaskEvidence(raw, taskId);
1288
1503
  } catch (error) {
1289
1504
  if (error.code === "ENOENT")
@@ -1399,7 +1614,7 @@ async function withTaskEvidenceTransaction(directory, taskId, agent, callback) {
1399
1614
  assertValidTaskId(taskId);
1400
1615
  return withTaskEvidenceLock(directory, taskId, agent, async () => {
1401
1616
  const resolvedEvidenceDir = getEvidenceDir(directory);
1402
- const evidencePath = path2.join(resolvedEvidenceDir, `${taskId}.json`);
1617
+ const evidencePath = path3.join(resolvedEvidenceDir, `${taskId}.json`);
1403
1618
  let current = null;
1404
1619
  try {
1405
1620
  current = readExisting(evidencePath, taskId);
@@ -1407,12 +1622,15 @@ async function withTaskEvidenceTransaction(directory, taskId, agent, callback) {
1407
1622
  telemetry.gateParseError(taskId, error);
1408
1623
  throw error;
1409
1624
  }
1410
- const persist = async (nextEvidence) => {
1625
+ const persist = async (nextEvidence, event) => {
1411
1626
  const validated = TaskEvidenceSchema.parse({
1412
1627
  ...nextEvidence,
1413
1628
  taskId
1414
1629
  });
1415
1630
  await atomicWriteFile(evidencePath, JSON.stringify(validated, null, 2));
1631
+ if (event) {
1632
+ await appendTaskGateRequirementsReceiptIfNeeded(directory, taskId, current, validated, event);
1633
+ }
1416
1634
  current = validated;
1417
1635
  return validated;
1418
1636
  };
@@ -1423,7 +1641,7 @@ async function withTaskEvidenceTransaction(directory, taskId, agent, callback) {
1423
1641
  assertTaskEvidenceWriteAllowed(directory, taskId, event);
1424
1642
  const nextEvidence = updateEvidenceForTransition(current, event);
1425
1643
  nextEvidence.taskId = taskId;
1426
- return persist(nextEvidence);
1644
+ return persist(nextEvidence, event);
1427
1645
  }
1428
1646
  });
1429
1647
  });
@@ -1480,7 +1698,7 @@ function readTaskEvidenceRaw(directory, taskId) {
1480
1698
  assertValidTaskId(taskId);
1481
1699
  const evidencePath = getEvidencePath(directory, taskId);
1482
1700
  try {
1483
- const raw = readFileSync2(evidencePath, "utf-8");
1701
+ const raw = readFileSync3(evidencePath, "utf-8");
1484
1702
  return parseTaskEvidence(raw, taskId);
1485
1703
  } catch (error) {
1486
1704
  const code = error.code;
@@ -6,12 +6,12 @@ import {
6
6
  resolveSwarmKnowledgePath,
7
7
  transactKnowledge,
8
8
  wordBigrams
9
- } from "./index-qfawexc8.js";
9
+ } from "./index-6wf75rcm.js";
10
10
  import {
11
11
  queryHistoricalOutcomes,
12
12
  readKnowledgeEvents,
13
13
  recordKnowledgeEvent
14
- } from "./index-c13ttmak.js";
14
+ } from "./index-cxn95n7q.js";
15
15
  import {
16
16
  init_knowledge_types,
17
17
  isActiveStatus
@@ -224,11 +224,11 @@ async function maybeQuarantineOnContradiction(directory, entryId, threshold, win
224
224
  alreadyInactive: true
225
225
  };
226
226
  }
227
- const { quarantineEntry } = await import("./knowledge-validator-91ym56e0.js");
227
+ const { quarantineEntry } = await import("./knowledge-validator-g8ne80v6.js");
228
228
  let policyConfig;
229
229
  try {
230
- const { KnowledgeConfigSchema } = await import("./schema-nq9tcz87.js");
231
- const { loadPluginConfigWithMeta } = await import("./index-kp87kr1a.js");
230
+ const { KnowledgeConfigSchema } = await import("./schema-mpcm7nje.js");
231
+ const { loadPluginConfigWithMeta } = await import("./index-9gt8g2qj.js");
232
232
  const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
233
233
  policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
234
234
  } catch {
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  readKnowledge,
4
4
  transactKnowledge
5
- } from "./index-qfawexc8.js";
5
+ } from "./index-6wf75rcm.js";
6
6
  import {
7
7
  init_git_executable,
8
8
  resolveGitExecutableAsync
9
9
  } from "./index-9e6fdz2h.js";
10
10
  import {
11
11
  resolveKnowledgeStoreDir
12
- } from "./index-s72naw1j.js";
12
+ } from "./index-x8pm918t.js";
13
13
  import {
14
14
  init_knowledge_types,
15
15
  isActiveStatus
@@ -9,11 +9,11 @@ import {
9
9
  } from "./index-y8552snf.js";
10
10
  import {
11
11
  atomicWriteFile
12
- } from "./index-6q3agdmr.js";
12
+ } from "./index-j20fzn0w.js";
13
13
  import {
14
14
  assertProjectRoot,
15
15
  withEvidenceLock
16
- } from "./index-pa86tpgt.js";
16
+ } from "./index-bghwrr59.js";
17
17
  import {
18
18
  exports_external,
19
19
  init_zod