opencode-swarm 7.184.11 → 7.184.12

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 (100) hide show
  1. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  2. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  3. package/dist/background/delegation-lifecycle.d.ts +6 -2
  4. package/dist/background/pending-delegations.d.ts +23 -1
  5. package/dist/cli/auto-checkpoint-7y3x5cv2.js +183 -0
  6. package/dist/cli/checkpoint-j39f718z.js +51 -0
  7. package/dist/cli/{coder-settlement-6mhw6b36.js → coder-settlement-12ytzqvs.js} +13 -11
  8. package/dist/cli/{config-doctor-tbaswv40.js → config-doctor-vphp4shw.js} +2 -2
  9. package/dist/cli/{core-4389fcpc.js → core-5a1awn37.js} +3 -3
  10. package/dist/cli/{curation-policy-xe77n9zj.js → curation-policy-1rzheh1x.js} +6 -5
  11. package/dist/cli/{curator-drift-nnge4dkk.js → curator-drift-ex0qxt9p.js} +9 -9
  12. package/dist/cli/curator-llm-factory-ktkat73z.js +81 -0
  13. package/dist/cli/{curator-asqb0cm7.js → curator-x2hxjdac.js} +48 -42
  14. package/dist/cli/{dispatch-cv89p2y1.js → dispatch-0ejzwb45.js} +2 -1
  15. package/dist/cli/{evidence-summary-service-cdrwfdyp.js → evidence-summary-service-pfksvp16.js} +24 -19
  16. package/dist/cli/{gate-evidence-xbn83jeh.js → gate-evidence-8n8kb8tb.js} +8 -6
  17. package/dist/cli/guardrail-explain-px94swcz.js +82 -0
  18. package/dist/cli/{guardrail-log-b6ef00v7.js → guardrail-log-xevw9xht.js} +7 -7
  19. package/dist/cli/{guardrail-reset-77r7jfn2.js → guardrail-reset-18wvqbga.js} +48 -42
  20. package/dist/cli/hive-promoter-5r35f3ap.js +96 -0
  21. package/dist/cli/{index-7kmxy1rb.js → index-27wzbb3n.js} +4 -4
  22. package/dist/cli/{index-kaay5kmx.js → index-2cbt4b7t.js} +2 -2
  23. package/dist/cli/{index-w0jbrttk.js → index-2p1an48j.js} +3 -3
  24. package/dist/cli/index-2y9b45jj.js +24 -0
  25. package/dist/cli/index-34ysgky0.js +954 -0
  26. package/dist/cli/{index-ejpxkrp6.js → index-39ng38sp.js} +1 -1
  27. package/dist/cli/{index-hk0eh9qb.js → index-4g4sr4ah.js} +1 -1
  28. package/dist/cli/{index-cn67bp4y.js → index-53fy0aq2.js} +52 -46
  29. package/dist/cli/{index-5cawm255.js → index-5w404j07.js} +8 -6
  30. package/dist/cli/index-5y1qxw0x.js +963 -0
  31. package/dist/cli/{index-35cdceqf.js → index-6cjpmvpa.js} +2 -20
  32. package/dist/cli/{index-jhk62dp4.js → index-74e43s33.js} +4 -4
  33. package/dist/cli/index-7bxssqaf.js +2676 -0
  34. package/dist/cli/index-7pmbnjvj.js +11 -0
  35. package/dist/cli/{index-j4efx148.js → index-7r3pkgma.js} +5 -5
  36. package/dist/cli/{index-kg2mb1m5.js → index-7rzgdcvc.js} +2 -2
  37. package/dist/cli/{index-hamqvzqn.js → index-9nyqt3kb.js} +10 -2682
  38. package/dist/cli/{index-6z53ry5f.js → index-a53f5t61.js} +2 -2
  39. package/dist/cli/{index-e0rrj9kk.js → index-azyhws0s.js} +9 -9
  40. package/dist/cli/{index-0mj7hc2z.js → index-bntwj2tp.js} +5 -5
  41. package/dist/cli/{index-aae38s4x.js → index-cftva3pa.js} +2 -11
  42. package/dist/cli/{index-c0dahh34.js → index-cvam011t.js} +1 -1
  43. package/dist/cli/{index-gqj1k2y6.js → index-d42kjvwy.js} +2 -2
  44. package/dist/cli/{index-gnryhmak.js → index-dftztz4y.js} +1 -1
  45. package/dist/cli/{index-zz5rryxj.js → index-dze05t9h.js} +7 -7
  46. package/dist/cli/{index-tamg9rve.js → index-eqfmabtd.js} +2 -2
  47. package/dist/cli/{index-hwjr3xyg.js → index-fbp7dqfe.js} +10 -38
  48. package/dist/cli/{index-0ajyhjht.js → index-fxf3zhtq.js} +1 -1
  49. package/dist/cli/index-g4fs6z4e.js +37 -0
  50. package/dist/cli/{index-9xfxsx8y.js → index-hfs97j0c.js} +1 -1
  51. package/dist/cli/{index-nh5fxxc9.js → index-jtg0zsnx.js} +4 -2
  52. package/dist/cli/{index-pbwfwc0v.js → index-kcbkce43.js} +48 -42
  53. package/dist/cli/{index-07fqfseh.js → index-m1pqenq9.js} +2 -2
  54. package/dist/cli/{index-be5h97z8.js → index-mfqge140.js} +1 -1
  55. package/dist/cli/{index-3w96sd7p.js → index-n572fdtf.js} +2969 -3838
  56. package/dist/cli/{index-5m1b70z3.js → index-pwcbtbhd.js} +4 -4
  57. package/dist/cli/{index-xpcvwzdq.js → index-rbvndg2d.js} +3 -3
  58. package/dist/cli/{index-8gs8qkjs.js → index-ryafwy2b.js} +1 -1
  59. package/dist/cli/{index-vx0wjfc1.js → index-s7rap90y.js} +7 -7
  60. package/dist/cli/{index-q7q00ppx.js → index-tyzmjw2s.js} +7 -7
  61. package/dist/cli/{index-7k4ksbqd.js → index-vk49btd6.js} +1 -1
  62. package/dist/cli/{index-89nqyqxs.js → index-w33zgxn6.js} +3 -3
  63. package/dist/cli/{index-x1gyqgze.js → index-w6w6ny06.js} +2 -2
  64. package/dist/cli/{index-ygdj73xq.js → index-x0jybm74.js} +3 -3
  65. package/dist/cli/{index-xw8xdcrf.js → index-ymhs7hng.js} +5 -5
  66. package/dist/cli/{index-645ckyxy.js → index-yvmvsej2.js} +55 -971
  67. package/dist/cli/{index-x119gdak.js → index-yx5z4200.js} +2 -2
  68. package/dist/cli/{index-dqpq8m9w.js → index-yydv4jfy.js} +2 -2
  69. package/dist/cli/{index-5njp971j.js → index-zmtpnyff.js} +8 -8
  70. package/dist/cli/{index-908zxswj.js → index-zzebc1td.js} +44 -16
  71. package/dist/cli/index.js +49 -43
  72. package/dist/cli/{knowledge-escalator-8cc6jcw0.js → knowledge-escalator-z5qb6y6s.js} +13 -12
  73. package/dist/cli/{knowledge-events-b5g6ky4h.js → knowledge-events-gv173j4d.js} +11 -10
  74. package/dist/cli/{knowledge-link-8tetyje0.js → knowledge-link-vvyfhhmr.js} +5 -4
  75. package/dist/cli/{knowledge-store-1w60j5xm.js → knowledge-store-g4sjhep5.js} +6 -5
  76. package/dist/cli/{knowledge-validator-sd88rjcy.js → knowledge-validator-8whkrsrb.js} +8 -7
  77. package/dist/cli/{mcp-3052r65q.js → mcp-x25b3q1g.js} +1 -1
  78. package/dist/cli/{model-preflight-m0nwfsx8.js → model-preflight-b21njmda.js} +48 -42
  79. package/dist/cli/{pending-delegations-5nx22evh.js → pending-delegations-f6rmrqzn.js} +16 -12
  80. package/dist/cli/{pr-subscriptions-kas44ty9.js → pr-subscriptions-nmbme4kp.js} +14 -12
  81. package/dist/cli/{pr-workflow-gate-pmggnw1j.js → pr-workflow-gate-mtzfsmkg.js} +48 -42
  82. package/dist/cli/{runner-ff0bj9w0.js → runner-cwmgb9rw.js} +6 -5
  83. package/dist/cli/{scan-cursor-yw12hvtc.js → scan-cursor-gmpjsr3a.js} +7 -6
  84. package/dist/cli/{schema-1g1y1d5q.js → schema-rvxnxp4n.js} +1 -1
  85. package/dist/cli/{scope-persistence-de472fxy.js → scope-persistence-fqenprq7.js} +17 -15
  86. package/dist/cli/{server-1n00bga4.js → server-ws1my2dz.js} +62 -54
  87. package/dist/cli/{skill-generator-c5wbbjqx.js → skill-generator-pt1epeer.js} +15 -14
  88. package/dist/cli/{snapshot-coordination-init-gwj594hc.js → snapshot-coordination-init-9zrktnh5.js} +48 -42
  89. package/dist/cli/{speckit-checkoff-hc479v4r.js → speckit-checkoff-k13zhgh5.js} +4 -4
  90. package/dist/cli/{telemetry-39zmx4fp.js → telemetry-n6y2sjhg.js} +1 -1
  91. package/dist/cli/{workspace-snapshot-nrbvjh1c.js → workspace-snapshot-gnwak61t.js} +3 -3
  92. package/dist/cli/{worktree-collision-ownership-jvgxxnf9.js → worktree-collision-ownership-mw3rkc4v.js} +18 -16
  93. package/dist/cli/{worktree-isolation-r9hr23r8.js → worktree-isolation-0rtrpf0b.js} +48 -42
  94. package/dist/index.js +541 -541
  95. package/dist/plan/auto-checkpoint.d.ts +56 -0
  96. package/dist/plan/manager.d.ts +8 -12
  97. package/package.json +1 -1
  98. package/dist/cli/curator-llm-factory-1gjzcafw.js +0 -75
  99. package/dist/cli/guardrail-explain-xtyxjmyz.js +0 -76
  100. package/dist/cli/hive-promoter-dsrj2ar2.js +0 -90
@@ -0,0 +1,954 @@
1
+ // @bun
2
+ import {
3
+ EvaluationRunV1Schema,
4
+ GateAuditResultV1Schema,
5
+ getProtectedEvaluationRunIds
6
+ } from "./index-jtg0zsnx.js";
7
+ import {
8
+ TASK_WORKFLOW_SCHEMA_MARKER,
9
+ deriveApplicableGateSet,
10
+ isValidTaskId,
11
+ readCurrentTaskDeclaredFiles,
12
+ readTaskEvidence,
13
+ readTaskEvidenceRaw,
14
+ sanitizeTaskId
15
+ } from "./index-fbp7dqfe.js";
16
+ import {
17
+ readSwarmFileAsync,
18
+ validateSwarmPath
19
+ } from "./index-dftztz4y.js";
20
+ import {
21
+ bunWrite
22
+ } from "./index-2s7dvzff.js";
23
+ import {
24
+ EVIDENCE_MAX_JSON_BYTES,
25
+ EvidenceBundleSchema,
26
+ EvidenceSchema
27
+ } from "./index-frcemc0b.js";
28
+ import {
29
+ withEvidenceLock
30
+ } from "./index-6cjpmvpa.js";
31
+ import {
32
+ assertProjectRoot
33
+ } from "./index-t7hmqgjy.js";
34
+ import {
35
+ invalidateCachedArtifact
36
+ } from "./index-bntwj2tp.js";
37
+ import {
38
+ ZodError,
39
+ init_zod
40
+ } from "./index-gknz3bv1.js";
41
+ import {
42
+ warn
43
+ } from "./index-zgwm4ryv.js";
44
+
45
+ // src/evidence/manager.ts
46
+ init_zod();
47
+ import {
48
+ mkdirSync,
49
+ readdirSync,
50
+ realpathSync,
51
+ renameSync,
52
+ rmSync,
53
+ statSync
54
+ } from "fs";
55
+ import * as fs3 from "fs/promises";
56
+ import * as path2 from "path";
57
+
58
+ // src/evaluation/retention.ts
59
+ import * as fs from "fs/promises";
60
+ import * as path from "path";
61
+ function artifactKey(artifact) {
62
+ return `${artifact.namespace}/${artifact.id}`;
63
+ }
64
+ function validId(value) {
65
+ return /^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/.test(value);
66
+ }
67
+ async function evaluationRunCandidates(directory) {
68
+ const root = path.join(directory, ".swarm", "evolution", "runs");
69
+ let entries = [];
70
+ try {
71
+ entries = await fs.readdir(root, { withFileTypes: true });
72
+ } catch (error) {
73
+ if (error.code === "ENOENT") {
74
+ return { candidates: [], corrupt: [] };
75
+ }
76
+ throw error;
77
+ }
78
+ const candidates = [];
79
+ const corrupt = [];
80
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
81
+ if (!entry.isFile() || !entry.name.endsWith(".json"))
82
+ continue;
83
+ const id = entry.name.slice(0, -".json".length);
84
+ if (!validId(id))
85
+ continue;
86
+ const artifact = { namespace: "evaluation-run", id };
87
+ const target = path.join(root, entry.name);
88
+ try {
89
+ const run = EvaluationRunV1Schema.parse(JSON.parse(await fs.readFile(target, "utf8")));
90
+ if (run.runId !== id)
91
+ throw new Error("run id/path mismatch");
92
+ candidates.push({
93
+ artifact,
94
+ createdAt: run.createdAt,
95
+ target,
96
+ kind: "file"
97
+ });
98
+ } catch {
99
+ corrupt.push(artifact);
100
+ }
101
+ }
102
+ return { candidates, corrupt };
103
+ }
104
+ async function gateAuditCandidates(directory) {
105
+ const root = path.join(directory, ".swarm", "evidence", "gate-audit");
106
+ let entries = [];
107
+ try {
108
+ entries = await fs.readdir(root, { withFileTypes: true });
109
+ } catch (error) {
110
+ if (error.code === "ENOENT") {
111
+ return { candidates: [], corrupt: [] };
112
+ }
113
+ throw error;
114
+ }
115
+ const candidates = [];
116
+ const corrupt = [];
117
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
118
+ if (!entry.isDirectory() || !validId(entry.name))
119
+ continue;
120
+ const artifact = { namespace: "gate-audit", id: entry.name };
121
+ const target = path.join(root, entry.name);
122
+ try {
123
+ const result = GateAuditResultV1Schema.parse(JSON.parse(await fs.readFile(path.join(target, "results.json"), "utf8")));
124
+ if (result.runId !== entry.name)
125
+ throw new Error("run id/path mismatch");
126
+ candidates.push({
127
+ artifact,
128
+ createdAt: result.createdAt,
129
+ target,
130
+ kind: "directory"
131
+ });
132
+ } catch {
133
+ corrupt.push(artifact);
134
+ }
135
+ }
136
+ return { candidates, corrupt };
137
+ }
138
+ async function retentionCandidates(directory) {
139
+ const [runs, audits] = await Promise.all([
140
+ evaluationRunCandidates(directory),
141
+ gateAuditCandidates(directory)
142
+ ]);
143
+ return {
144
+ candidates: [...runs.candidates, ...audits.candidates].sort((a, b) => artifactKey(a.artifact).localeCompare(artifactKey(b.artifact))),
145
+ corrupt: [...runs.corrupt, ...audits.corrupt].sort((a, b) => artifactKey(a).localeCompare(artifactKey(b)))
146
+ };
147
+ }
148
+ async function protectedArtifacts(directory) {
149
+ const ids = await getProtectedEvaluationRunIds(directory);
150
+ return new Set([...ids].map((id) => `evaluation-run/${id}`));
151
+ }
152
+ async function removeCandidate(candidate) {
153
+ if (candidate.kind === "directory") {
154
+ await fs.rm(candidate.target, { recursive: true, force: true });
155
+ return;
156
+ }
157
+ await fs.unlink(candidate.target);
158
+ }
159
+ var _retentionInternals = {
160
+ protectedArtifacts,
161
+ removeCandidate
162
+ };
163
+ async function archiveEvaluationArtifacts(args) {
164
+ assertProjectRoot(args.directory);
165
+ return withEvidenceLock(args.directory, path.join("evolution", "retention-index"), "evaluation-retention", "archive", async () => {
166
+ const inventory = await retentionCandidates(args.directory);
167
+ let protectedKeys = await _retentionInternals.protectedArtifacts(args.directory);
168
+ const protectedRefs = inventory.candidates.filter((candidate) => protectedKeys.has(artifactKey(candidate.artifact))).map((candidate) => candidate.artifact);
169
+ const eligible = inventory.candidates.filter((candidate) => !protectedKeys.has(artifactKey(candidate.artifact)));
170
+ const now = args.now ?? new Date;
171
+ const cutoff = new Date(now.getTime() - args.maxAgeDays * 86400000).toISOString();
172
+ const selectedKeys = new Set(eligible.filter((candidate) => candidate.createdAt < cutoff).map((candidate) => artifactKey(candidate.artifact)));
173
+ const remaining = eligible.filter((candidate) => !selectedKeys.has(artifactKey(candidate.artifact))).sort((a, b) => a.createdAt === b.createdAt ? artifactKey(a.artifact).localeCompare(artifactKey(b.artifact)) : a.createdAt.localeCompare(b.createdAt));
174
+ if (args.maxBundles !== undefined && remaining.length > args.maxBundles) {
175
+ for (const candidate of remaining.slice(0, remaining.length - args.maxBundles)) {
176
+ selectedKeys.add(artifactKey(candidate.artifact));
177
+ }
178
+ }
179
+ const selectedCandidates = eligible.filter((candidate) => selectedKeys.has(artifactKey(candidate.artifact))).sort((a, b) => artifactKey(a.artifact).localeCompare(artifactKey(b.artifact)));
180
+ const archived = [];
181
+ const failed = [];
182
+ if (!args.dryRun) {
183
+ for (const candidate of selectedCandidates) {
184
+ protectedKeys = await _retentionInternals.protectedArtifacts(args.directory);
185
+ if (protectedKeys.has(artifactKey(candidate.artifact))) {
186
+ protectedRefs.push(candidate.artifact);
187
+ continue;
188
+ }
189
+ try {
190
+ await _retentionInternals.removeCandidate(candidate);
191
+ archived.push(candidate.artifact);
192
+ } catch (error) {
193
+ failed.push({
194
+ artifact: candidate.artifact,
195
+ error: error instanceof Error ? error.message : String(error)
196
+ });
197
+ }
198
+ }
199
+ }
200
+ return {
201
+ inventory: inventory.candidates.map((candidate) => candidate.artifact),
202
+ selected: selectedCandidates.map((candidate) => candidate.artifact),
203
+ archived,
204
+ corrupt: inventory.corrupt,
205
+ protected: [
206
+ ...new Map(protectedRefs.map((artifact) => [artifactKey(artifact), artifact])).values()
207
+ ].sort((a, b) => artifactKey(a).localeCompare(artifactKey(b))),
208
+ failed
209
+ };
210
+ });
211
+ }
212
+
213
+ // src/evidence/documents-retention.ts
214
+ import * as fs2 from "fs";
215
+ import * as fsp from "fs/promises";
216
+ import * as readline from "readline";
217
+ var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
218
+ var MAX_READ_BYTES = 100 * 1024 * 1024;
219
+ var RENAME_MAX_ATTEMPTS = 5;
220
+ var RENAME_BACKOFF_MS = 10;
221
+ var RENAME_RETRY_CODES = new Set(["EPERM", "EBUSY", "ENOTEMPTY", "EACCES"]);
222
+ var _internals = {
223
+ stat: (p) => fsp.stat(p),
224
+ createReadStream: (p, options) => fs2.createReadStream(p, options),
225
+ openSync: (p, flags) => fs2.openSync(p, flags),
226
+ writeSync: (fd, data, position) => fs2.writeSync(fd, data, position),
227
+ fsyncSync: (fd) => fs2.fsyncSync(fd),
228
+ closeSync: (fd) => fs2.closeSync(fd),
229
+ renameWithRetry: atomicRenameWithRetry,
230
+ unlink: (p) => fsp.unlink(p)
231
+ };
232
+ async function atomicRenameWithRetry(src, dst, renameFn = fsp.rename) {
233
+ let lastErr;
234
+ for (let attempt = 0;attempt < RENAME_MAX_ATTEMPTS; attempt++) {
235
+ try {
236
+ await renameFn(src, dst);
237
+ return;
238
+ } catch (err) {
239
+ lastErr = err;
240
+ const code = err?.code;
241
+ if (!code || !RENAME_RETRY_CODES.has(code)) {
242
+ throw err;
243
+ }
244
+ if (attempt < RENAME_MAX_ATTEMPTS - 1) {
245
+ await new Promise((resolve) => setTimeout(resolve, RENAME_BACKOFF_MS));
246
+ }
247
+ }
248
+ }
249
+ throw lastErr;
250
+ }
251
+ function emptyResult(dryRun) {
252
+ return {
253
+ inventory: 0,
254
+ selected: 0,
255
+ archived: 0,
256
+ corrupt: 0,
257
+ bytesBefore: 0,
258
+ bytesAfter: 0,
259
+ dryRun,
260
+ aborted: false
261
+ };
262
+ }
263
+ async function readCacheRows(filePath) {
264
+ const stat2 = await _internals.stat(filePath);
265
+ const bytesBefore = stat2.size;
266
+ const stream = _internals.createReadStream(filePath, {
267
+ encoding: "utf8",
268
+ highWaterMark: 64 * 1024
269
+ });
270
+ const rl = readline.createInterface({
271
+ input: stream,
272
+ crlfDelay: Infinity
273
+ });
274
+ const rows = [];
275
+ let corrupt = 0;
276
+ let bytesRead = 0;
277
+ let aborted = false;
278
+ try {
279
+ for await (const line of rl) {
280
+ const lineBytes = Buffer.byteLength(line, "utf8") + 1;
281
+ bytesRead += lineBytes;
282
+ if (bytesRead > MAX_READ_BYTES) {
283
+ aborted = true;
284
+ break;
285
+ }
286
+ if (line.length === 0)
287
+ continue;
288
+ let record = null;
289
+ try {
290
+ const parsed = JSON.parse(line);
291
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
292
+ record = parsed;
293
+ } else {
294
+ corrupt++;
295
+ continue;
296
+ }
297
+ } catch {
298
+ corrupt++;
299
+ continue;
300
+ }
301
+ rows.push({ raw: line, bytes: lineBytes, record });
302
+ }
303
+ } finally {
304
+ rl.close();
305
+ stream.destroy();
306
+ }
307
+ return { rows, corrupt, aborted, bytesBefore };
308
+ }
309
+ function oldestFirst(a, b) {
310
+ const at = typeof a.record?.capturedAt === "string" ? a.record.capturedAt : "";
311
+ const bt = typeof b.record?.capturedAt === "string" ? b.record.capturedAt : "";
312
+ if (at === bt)
313
+ return a.raw.localeCompare(b.raw);
314
+ return at.localeCompare(bt);
315
+ }
316
+ function selectSurvivors(rows, maxRecords, maxBytes) {
317
+ const ordered = [...rows].sort(oldestFirst);
318
+ let keepFrom = 0;
319
+ if (typeof maxRecords === "number" && ordered.length > maxRecords) {
320
+ keepFrom = ordered.length - maxRecords;
321
+ }
322
+ if (typeof maxBytes === "number" && maxBytes > 0) {
323
+ let total = 0;
324
+ for (let i = keepFrom;i < ordered.length; i++) {
325
+ total += ordered[i].bytes;
326
+ }
327
+ while (keepFrom < ordered.length && total > maxBytes) {
328
+ total -= ordered[keepFrom].bytes;
329
+ keepFrom++;
330
+ }
331
+ }
332
+ const survivors = ordered.slice(keepFrom);
333
+ const selected = rows.length - survivors.length;
334
+ return { survivors, selected };
335
+ }
336
+ async function rewriteAtomic(filePath, survivors) {
337
+ const tmpPath = `${filePath}.tmp.${Date.now()}.${process.pid}`;
338
+ const payload = survivors.length > 0 ? `${survivors.map((row) => row.raw).join(`
339
+ `)}
340
+ ` : "";
341
+ let succeeded = false;
342
+ const fd = _internals.openSync(tmpPath, "w");
343
+ try {
344
+ _internals.writeSync(fd, payload, 0);
345
+ _internals.fsyncSync(fd);
346
+ _internals.closeSync(fd);
347
+ await _internals.renameWithRetry(tmpPath, filePath);
348
+ succeeded = true;
349
+ } catch (err) {
350
+ try {
351
+ _internals.closeSync(fd);
352
+ } catch {}
353
+ const msg = err instanceof Error ? err.message : String(err);
354
+ throw new Error(`documents-cache rewrite failed: ${msg}`);
355
+ } finally {
356
+ if (!succeeded) {
357
+ try {
358
+ await _internals.unlink(tmpPath);
359
+ } catch {}
360
+ }
361
+ }
362
+ return Buffer.byteLength(payload, "utf8");
363
+ }
364
+ async function pruneEvidenceDocuments(args) {
365
+ assertProjectRoot(args.directory);
366
+ const dryRun = args.dryRun === true;
367
+ const capsUnset = (typeof args.maxBytes !== "number" || args.maxBytes <= 0) && (typeof args.maxRecords !== "number" || args.maxRecords <= 0);
368
+ const filePath = validateSwarmPath(args.directory, EVIDENCE_CACHE_FILE);
369
+ let stat2;
370
+ try {
371
+ stat2 = await _internals.stat(filePath);
372
+ } catch (err) {
373
+ const code = err?.code;
374
+ if (code === "ENOENT")
375
+ return emptyResult(dryRun);
376
+ throw err;
377
+ }
378
+ if (capsUnset) {
379
+ return {
380
+ inventory: 0,
381
+ selected: 0,
382
+ archived: 0,
383
+ corrupt: 0,
384
+ bytesBefore: stat2.size,
385
+ bytesAfter: stat2.size,
386
+ dryRun,
387
+ aborted: false
388
+ };
389
+ }
390
+ let readResult;
391
+ try {
392
+ readResult = await readCacheRows(filePath);
393
+ } catch (err) {
394
+ const msg = err instanceof Error ? err.message : String(err);
395
+ warn(`documents-cache prune: read failed: ${msg}`);
396
+ throw err;
397
+ }
398
+ if (readResult.aborted) {
399
+ warn(`documents-cache prune: aborted, file exceeds ${MAX_READ_BYTES} bytes; left untouched`);
400
+ return {
401
+ inventory: readResult.rows.length,
402
+ selected: 0,
403
+ archived: 0,
404
+ corrupt: readResult.corrupt,
405
+ bytesBefore: readResult.bytesBefore,
406
+ bytesAfter: readResult.bytesBefore,
407
+ dryRun,
408
+ aborted: true
409
+ };
410
+ }
411
+ const { survivors, selected } = selectSurvivors(readResult.rows, args.maxRecords, args.maxBytes);
412
+ if (dryRun) {
413
+ const bytesAfter2 = survivors.reduce((sum, row) => sum + row.bytes, 0);
414
+ return {
415
+ inventory: readResult.rows.length,
416
+ selected,
417
+ archived: 0,
418
+ corrupt: readResult.corrupt,
419
+ bytesBefore: readResult.bytesBefore,
420
+ bytesAfter: bytesAfter2,
421
+ dryRun: true,
422
+ aborted: false
423
+ };
424
+ }
425
+ if (selected === 0 && readResult.corrupt === 0) {
426
+ return {
427
+ inventory: readResult.rows.length,
428
+ selected: 0,
429
+ archived: 0,
430
+ corrupt: 0,
431
+ bytesBefore: readResult.bytesBefore,
432
+ bytesAfter: readResult.bytesBefore,
433
+ dryRun: false,
434
+ aborted: false
435
+ };
436
+ }
437
+ const bytesAfter = await rewriteAtomic(filePath, survivors);
438
+ return {
439
+ inventory: readResult.rows.length,
440
+ selected,
441
+ archived: selected,
442
+ corrupt: readResult.corrupt,
443
+ bytesBefore: readResult.bytesBefore,
444
+ bytesAfter,
445
+ dryRun: false,
446
+ aborted: false
447
+ };
448
+ }
449
+
450
+ // src/evidence/manager.ts
451
+ var VALID_EVIDENCE_TYPES = [
452
+ "review",
453
+ "test",
454
+ "diff",
455
+ "approval",
456
+ "note",
457
+ "retrospective",
458
+ "syntax",
459
+ "placeholder",
460
+ "sast",
461
+ "sbom",
462
+ "build",
463
+ "quality_budget",
464
+ "secretscan"
465
+ ];
466
+ function isValidEvidenceType(type) {
467
+ return VALID_EVIDENCE_TYPES.includes(type);
468
+ }
469
+ function isSecretscanEvidence(evidence) {
470
+ return evidence.type === "secretscan";
471
+ }
472
+ var sanitizeTaskId2 = sanitizeTaskId;
473
+ function validateProjectRoot(directory) {
474
+ assertProjectRoot(directory, {
475
+ realpathSync: _internals2.realpathSync,
476
+ statSync: _internals2.statSync
477
+ }, "evidence");
478
+ }
479
+ async function saveEvidence(directory, taskId, evidence, abortSignal) {
480
+ abortSignal?.throwIfAborted();
481
+ _internals2.validateProjectRoot(directory);
482
+ const sanitizedTaskId = sanitizeTaskId2(taskId);
483
+ const relativePath = path2.join("evidence", sanitizedTaskId, "evidence.json");
484
+ validateSwarmPath(directory, relativePath);
485
+ _internals2.validateEvidence(evidence);
486
+ return withEvidenceLock(directory, relativePath, "evidence-manager", sanitizedTaskId, async () => {
487
+ abortSignal?.throwIfAborted();
488
+ const evidencePath = validateSwarmPath(directory, relativePath);
489
+ const evidenceDir = path2.dirname(evidencePath);
490
+ let bundle;
491
+ const existingContent = await readSwarmFileAsync(directory, relativePath);
492
+ abortSignal?.throwIfAborted();
493
+ if (existingContent !== null) {
494
+ try {
495
+ const parsed = JSON.parse(existingContent);
496
+ bundle = EvidenceBundleSchema.parse(parsed);
497
+ } catch (error) {
498
+ warn(`Existing evidence bundle invalid for task ${sanitizedTaskId}, creating new: ${error instanceof Error ? error.message : String(error)}`);
499
+ const now = new Date().toISOString();
500
+ bundle = {
501
+ schema_version: "1.0.0",
502
+ task_id: sanitizedTaskId,
503
+ entries: [],
504
+ created_at: now,
505
+ updated_at: now
506
+ };
507
+ }
508
+ } else {
509
+ const now = new Date().toISOString();
510
+ bundle = {
511
+ schema_version: "1.0.0",
512
+ task_id: sanitizedTaskId,
513
+ entries: [],
514
+ created_at: now,
515
+ updated_at: now
516
+ };
517
+ }
518
+ const MAX_BUNDLE_ENTRIES = 100;
519
+ let entries = [...bundle.entries, evidence];
520
+ if (entries.length > MAX_BUNDLE_ENTRIES) {
521
+ entries = entries.slice(entries.length - MAX_BUNDLE_ENTRIES);
522
+ }
523
+ const updatedBundle = {
524
+ ...bundle,
525
+ entries,
526
+ updated_at: new Date().toISOString()
527
+ };
528
+ const bundleJson = JSON.stringify(updatedBundle);
529
+ if (bundleJson.length > EVIDENCE_MAX_JSON_BYTES) {
530
+ throw new Error(`Evidence bundle size (${bundleJson.length} bytes) exceeds maximum (${EVIDENCE_MAX_JSON_BYTES} bytes)`);
531
+ }
532
+ mkdirSync(evidenceDir, { recursive: true });
533
+ const tempPath = path2.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
534
+ try {
535
+ await bunWrite(tempPath, bundleJson);
536
+ abortSignal?.throwIfAborted();
537
+ renameSync(tempPath, evidencePath);
538
+ } catch (error) {
539
+ try {
540
+ rmSync(tempPath, { force: true });
541
+ } catch {}
542
+ throw error;
543
+ }
544
+ invalidateCachedArtifact(evidencePath);
545
+ return updatedBundle;
546
+ });
547
+ }
548
+ function isFlatRetrospective(parsed) {
549
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && parsed.type === "retrospective" && !parsed.schema_version;
550
+ }
551
+ var LEGACY_TASK_COMPLEXITY_MAP = {
552
+ low: "simple",
553
+ medium: "moderate",
554
+ high: "complex"
555
+ };
556
+ function remapLegacyTaskComplexity(entry) {
557
+ const taskComplexity = entry.task_complexity;
558
+ if (typeof taskComplexity === "string" && taskComplexity in LEGACY_TASK_COMPLEXITY_MAP) {
559
+ return {
560
+ ...entry,
561
+ task_complexity: LEGACY_TASK_COMPLEXITY_MAP[taskComplexity]
562
+ };
563
+ }
564
+ return entry;
565
+ }
566
+ function wrapFlatRetrospective(flatEntry, taskId) {
567
+ const now = new Date().toISOString();
568
+ const remappedEntry = remapLegacyTaskComplexity(flatEntry);
569
+ return {
570
+ schema_version: "1.0.0",
571
+ task_id: remappedEntry.task_id ?? taskId,
572
+ created_at: remappedEntry.timestamp ?? now,
573
+ updated_at: remappedEntry.timestamp ?? now,
574
+ entries: [remappedEntry]
575
+ };
576
+ }
577
+ async function loadEvidence(directory, taskId, options) {
578
+ const sanitizedTaskId = sanitizeTaskId2(taskId);
579
+ const relativePath = path2.join("evidence", sanitizedTaskId, "evidence.json");
580
+ if (relativePath.length > 4096) {
581
+ return { status: "not_found" };
582
+ }
583
+ const evidencePath = validateSwarmPath(directory, relativePath);
584
+ const content = await readSwarmFileAsync(directory, relativePath);
585
+ if (content === null) {
586
+ return { status: "not_found" };
587
+ }
588
+ let parsed;
589
+ try {
590
+ parsed = JSON.parse(content);
591
+ } catch {
592
+ return { status: "invalid_schema", errors: ["Invalid JSON"] };
593
+ }
594
+ if (isFlatRetrospective(parsed)) {
595
+ const wrappedBundle = _internals2.wrapFlatRetrospective(parsed, sanitizedTaskId);
596
+ try {
597
+ const validated = EvidenceBundleSchema.parse(wrappedBundle);
598
+ if (options?.migrate === false) {
599
+ return { status: "found", bundle: validated };
600
+ }
601
+ try {
602
+ validateProjectRoot(directory);
603
+ await withEvidenceLock(directory, relativePath, "evidence-loader", sanitizedTaskId, async () => {
604
+ const evidenceDir = path2.dirname(evidencePath);
605
+ const bundleJson = JSON.stringify(validated);
606
+ const tempPath = path2.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
607
+ try {
608
+ await bunWrite(tempPath, bundleJson);
609
+ await fs3.rename(tempPath, evidencePath);
610
+ invalidateCachedArtifact(evidencePath);
611
+ } catch (writeError) {
612
+ try {
613
+ rmSync(tempPath, { force: true });
614
+ } catch {}
615
+ warn(`Failed to persist repaired flat retrospective for task ${sanitizedTaskId}: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
616
+ }
617
+ });
618
+ } catch (lockErr) {
619
+ warn(`Evidence lock failed during flat-retrospective write-back for task ${sanitizedTaskId}: ${lockErr instanceof Error ? lockErr.message : String(lockErr)}`);
620
+ }
621
+ return { status: "found", bundle: validated };
622
+ } catch (error) {
623
+ warn(`Wrapped flat retrospective failed validation for task ${sanitizedTaskId}: ${error instanceof Error ? error.message : String(error)}`);
624
+ const errors = error instanceof ZodError ? error.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [error instanceof Error ? error.message : String(error)];
625
+ return { status: "invalid_schema", errors };
626
+ }
627
+ }
628
+ try {
629
+ const validated = EvidenceBundleSchema.parse(parsed);
630
+ return { status: "found", bundle: validated };
631
+ } catch (error) {
632
+ warn(`Evidence bundle validation failed for task ${sanitizedTaskId}: ${error instanceof Error ? error.message : String(error)}`);
633
+ const errors = error instanceof ZodError ? error.issues.map((e) => `${e.path.join(".")}: ${e.message}`) : [error instanceof Error ? error.message : String(error)];
634
+ return { status: "invalid_schema", errors };
635
+ }
636
+ }
637
+ async function listEvidenceTaskIds(directory) {
638
+ const evidenceBasePath = validateSwarmPath(directory, "evidence");
639
+ try {
640
+ statSync(evidenceBasePath);
641
+ } catch {
642
+ return [];
643
+ }
644
+ let entries;
645
+ try {
646
+ entries = readdirSync(evidenceBasePath);
647
+ } catch {
648
+ return [];
649
+ }
650
+ const taskIds = [];
651
+ for (const entry of entries) {
652
+ const entryPath = path2.join(evidenceBasePath, entry);
653
+ try {
654
+ const stats = statSync(entryPath);
655
+ if (!stats.isDirectory()) {
656
+ continue;
657
+ }
658
+ sanitizeTaskId2(entry);
659
+ taskIds.push(entry);
660
+ } catch (error) {
661
+ if (error instanceof Error && !error.message.startsWith("Invalid task ID")) {
662
+ warn(`Error reading evidence entry '${entry}': ${error.message}`);
663
+ }
664
+ }
665
+ }
666
+ return taskIds.sort();
667
+ }
668
+ async function deleteEvidence(directory, taskId) {
669
+ const sanitizedTaskId = sanitizeTaskId2(taskId);
670
+ try {
671
+ validateProjectRoot(directory);
672
+ } catch {
673
+ return false;
674
+ }
675
+ const relativePath = path2.join("evidence", sanitizedTaskId);
676
+ const evidenceDir = validateSwarmPath(directory, relativePath);
677
+ try {
678
+ statSync(evidenceDir);
679
+ } catch {
680
+ return false;
681
+ }
682
+ try {
683
+ rmSync(evidenceDir, { recursive: true, force: true });
684
+ return true;
685
+ } catch (error) {
686
+ warn(`Failed to delete evidence for task ${sanitizedTaskId}: ${error instanceof Error ? error.message : String(error)}`);
687
+ return false;
688
+ }
689
+ }
690
+ async function checkRequirementCoverage(phase, directory) {
691
+ const relativePath = path2.join("evidence", `req-coverage-phase-${phase}.json`);
692
+ const absolutePath = path2.resolve(directory, ".swarm", relativePath);
693
+ try {
694
+ await fs3.access(absolutePath);
695
+ return { exists: true, path: absolutePath };
696
+ } catch {
697
+ return { exists: false, path: absolutePath };
698
+ }
699
+ }
700
+ async function archiveEvidence(directory, maxAgeDays, maxBundles, options) {
701
+ const taskIds = await _internals2.listEvidenceTaskIds(directory);
702
+ const cutoffDate = options?.now ? new Date(options.now) : _internals2.now();
703
+ cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);
704
+ const cutoffIso = cutoffDate.toISOString();
705
+ const selected = new Set;
706
+ const selectedByAge = new Set;
707
+ const selectedByCount = new Set;
708
+ const archived = [];
709
+ const failed = [];
710
+ const remainingBundles = [];
711
+ for (const taskId of taskIds) {
712
+ let result;
713
+ try {
714
+ result = await _internals2.loadEvidence(directory, taskId);
715
+ } catch {
716
+ warn("archive: skipping corrupt or unreadable evidence for task", taskId);
717
+ continue;
718
+ }
719
+ if (result.status !== "found") {
720
+ continue;
721
+ }
722
+ if (result.bundle.updated_at < cutoffIso) {
723
+ selected.add(taskId);
724
+ selectedByAge.add(taskId);
725
+ } else {
726
+ remainingBundles.push({
727
+ taskId,
728
+ updatedAt: result.bundle.updated_at
729
+ });
730
+ }
731
+ }
732
+ if (maxBundles !== undefined && remainingBundles.length > maxBundles) {
733
+ remainingBundles.sort((a, b) => a.updatedAt.localeCompare(b.updatedAt));
734
+ const toDelete = remainingBundles.length - maxBundles;
735
+ for (let i = 0;i < toDelete; i++) {
736
+ selected.add(remainingBundles[i].taskId);
737
+ selectedByCount.add(remainingBundles[i].taskId);
738
+ }
739
+ }
740
+ if (!options?.dryRun) {
741
+ for (const taskId of [...selected].sort()) {
742
+ const deleted = await _internals2.deleteEvidence(directory, taskId);
743
+ if (deleted)
744
+ archived.push(taskId);
745
+ else
746
+ failed.push(taskId);
747
+ }
748
+ }
749
+ const evaluation = await archiveEvaluationArtifacts({
750
+ directory,
751
+ maxAgeDays,
752
+ maxBundles,
753
+ dryRun: options?.dryRun,
754
+ now: options?.now
755
+ });
756
+ let documentsCache = {
757
+ inventory: 0,
758
+ selected: 0,
759
+ archived: 0,
760
+ corrupt: 0,
761
+ bytesBefore: 0,
762
+ bytesAfter: 0,
763
+ dryRun: options?.dryRun === true,
764
+ aborted: false
765
+ };
766
+ if (typeof options?.cacheMaxBytes === "number" && options.cacheMaxBytes > 0 || typeof options?.cacheMaxRecords === "number" && options.cacheMaxRecords > 0) {
767
+ try {
768
+ documentsCache = await _internals2.pruneEvidenceDocuments({
769
+ directory,
770
+ maxBytes: options?.cacheMaxBytes,
771
+ maxRecords: options?.cacheMaxRecords,
772
+ dryRun: options?.dryRun
773
+ });
774
+ } catch (error) {
775
+ const msg = error instanceof Error ? error.message : String(error);
776
+ warn(`archiveEvidence: documents-cache prune failed (fail-open): ${msg}`);
777
+ }
778
+ }
779
+ if (options?.report) {
780
+ return {
781
+ inventoryEvidence: [...taskIds].sort(),
782
+ selectedEvidence: [...selected].sort(),
783
+ selectedEvidenceByAge: [...selectedByAge].sort(),
784
+ selectedEvidenceByCount: [...selectedByCount].sort(),
785
+ archivedEvidence: archived.sort(),
786
+ failedEvidence: failed.sort(),
787
+ evaluation,
788
+ documentsCache
789
+ };
790
+ }
791
+ return archived.sort();
792
+ }
793
+ function validateEvidence(evidence) {
794
+ return EvidenceSchema.parse(evidence);
795
+ }
796
+ var _internals2 = {
797
+ wrapFlatRetrospective,
798
+ loadEvidence,
799
+ listEvidenceTaskIds,
800
+ validateProjectRoot,
801
+ validateEvidence,
802
+ saveEvidence,
803
+ deleteEvidence,
804
+ pruneEvidenceDocuments,
805
+ realpathSync,
806
+ statSync,
807
+ now: () => new Date
808
+ };
809
+
810
+ // src/evidence/gate-bridge.ts
811
+ var GATE_EVIDENCE_TYPE_BY_GATE = {
812
+ reviewer: "review",
813
+ test_engineer: "test"
814
+ };
815
+ async function readDurableGateEvidence(directory, taskId) {
816
+ try {
817
+ return await readTaskEvidence(directory, taskId);
818
+ } catch {
819
+ return null;
820
+ }
821
+ }
822
+ function getDurableGateEvidenceStatus(evidence) {
823
+ if (!evidence?.gates || typeof evidence.gates !== "object") {
824
+ return {
825
+ isComplete: false,
826
+ missingGates: [],
827
+ evidenceExists: evidence != null,
828
+ invalid: false
829
+ };
830
+ }
831
+ if (!Array.isArray(evidence.required_gates)) {
832
+ return {
833
+ isComplete: false,
834
+ missingGates: ["required_gates"],
835
+ evidenceExists: true,
836
+ invalid: false
837
+ };
838
+ }
839
+ const derivedGates = deriveApplicableGateSet(evidence);
840
+ return {
841
+ isComplete: derivedGates.missingGates.length === 0,
842
+ missingGates: derivedGates.missingGates,
843
+ evidenceExists: true,
844
+ invalid: false
845
+ };
846
+ }
847
+ async function getDurableGateEvidenceStatusForTask(directory, taskId) {
848
+ if (!isValidTaskId(taskId)) {
849
+ return {
850
+ isComplete: false,
851
+ missingGates: [],
852
+ evidenceExists: false,
853
+ invalid: false
854
+ };
855
+ }
856
+ try {
857
+ return getDurableGateEvidenceStatusWithCurrentScope(readTaskEvidenceRaw(directory, taskId), directory, taskId);
858
+ } catch {
859
+ return {
860
+ isComplete: false,
861
+ missingGates: ["invalid_gate_evidence"],
862
+ evidenceExists: true,
863
+ invalid: true
864
+ };
865
+ }
866
+ }
867
+ function getDurableGateEvidenceStatusWithCurrentScope(evidence, directory, taskId) {
868
+ if (!evidence?.gates || typeof evidence.gates !== "object") {
869
+ return getDurableGateEvidenceStatus(evidence);
870
+ }
871
+ if (!Array.isArray(evidence.required_gates)) {
872
+ return getDurableGateEvidenceStatus(evidence);
873
+ }
874
+ if (!evidence.workflow || evidence.workflow.schema !== TASK_WORKFLOW_SCHEMA_MARKER) {
875
+ if (evidence.required_gates.length === 0) {
876
+ return {
877
+ isComplete: false,
878
+ missingGates: ["required_gates"],
879
+ evidenceExists: true,
880
+ invalid: false
881
+ };
882
+ }
883
+ const missingGates = evidence.required_gates.filter((gate) => evidence.gates[gate] == null);
884
+ return {
885
+ isComplete: missingGates.length === 0,
886
+ missingGates,
887
+ evidenceExists: true,
888
+ invalid: false
889
+ };
890
+ }
891
+ const derivedGates = deriveApplicableGateSet(evidence, {
892
+ currentDeclaredFiles: readCurrentTaskDeclaredFiles(directory, taskId)
893
+ });
894
+ return {
895
+ isComplete: derivedGates.missingGates.length === 0,
896
+ missingGates: derivedGates.missingGates,
897
+ evidenceExists: true,
898
+ invalid: false
899
+ };
900
+ }
901
+ function gateEvidenceToEntry(taskId, gate, type, evidence) {
902
+ const gateRecord = evidence.gates[gate];
903
+ if (!gateRecord) {
904
+ return null;
905
+ }
906
+ const base = {
907
+ task_id: taskId,
908
+ timestamp: gateRecord.timestamp,
909
+ agent: gateRecord.agent || gate,
910
+ verdict: "pass",
911
+ summary: `Gate evidence recorded by ${gate}`,
912
+ metadata: { source: "durable_gate_evidence", gate }
913
+ };
914
+ if (type === "review") {
915
+ return {
916
+ ...base,
917
+ type,
918
+ risk: "low",
919
+ issues: []
920
+ };
921
+ }
922
+ if (type === "approval") {
923
+ return {
924
+ ...base,
925
+ type
926
+ };
927
+ }
928
+ return {
929
+ ...base,
930
+ type,
931
+ tests_passed: 0,
932
+ tests_failed: 0,
933
+ failures: []
934
+ };
935
+ }
936
+ function mergeDurableGateEntriesFromEvidence(taskId, entries, evidence) {
937
+ if (!evidence?.gates) {
938
+ return entries;
939
+ }
940
+ const merged = [...entries];
941
+ for (const gate of Object.keys(evidence.gates).sort()) {
942
+ const type = GATE_EVIDENCE_TYPE_BY_GATE[gate] ?? "approval";
943
+ if ((type === "review" || type === "test") && merged.some((entry2) => entry2.type === type)) {
944
+ continue;
945
+ }
946
+ const entry = gateEvidenceToEntry(taskId, gate, type, evidence);
947
+ if (entry) {
948
+ merged.push(entry);
949
+ }
950
+ }
951
+ return merged;
952
+ }
953
+
954
+ export { isValidEvidenceType, isSecretscanEvidence, sanitizeTaskId2 as sanitizeTaskId, validateProjectRoot, saveEvidence, loadEvidence, listEvidenceTaskIds, checkRequirementCoverage, archiveEvidence, _internals2 as _internals, readDurableGateEvidence, getDurableGateEvidenceStatusForTask, mergeDurableGateEntriesFromEvidence };