opencode-swarm 7.145.1 → 7.146.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/phase-wrap/SKILL.md +3 -2
- package/README.md +5 -1
- package/dist/cli/{config-doctor-96jmxr7s.js → config-doctor-vs6hvbew.js} +3 -3
- package/dist/cli/{core-w78pc1hh.js → core-jvvm935f.js} +2 -2
- package/dist/cli/{curation-policy-smyc2mrm.js → curation-policy-xv0j8zyt.js} +6 -6
- package/dist/cli/{curator-59hzdxrv.js → curator-5bxh1djq.js} +28 -28
- package/dist/cli/{curator-llm-factory-g794pv51.js → curator-llm-factory-pe6skby4.js} +28 -28
- package/dist/cli/{evidence-summary-service-41m0cna6.js → evidence-summary-service-6m9jmzk8.js} +12 -12
- package/dist/cli/{gate-evidence-7aywx7qa.js → gate-evidence-84sfx6g8.js} +7 -7
- package/dist/cli/{guardrail-explain-j88dhm6w.js → guardrail-explain-jhbxq8yb.js} +29 -29
- package/dist/cli/{guardrail-log-xcb3ke8s.js → guardrail-log-vpbp3rm4.js} +4 -4
- package/dist/cli/{hive-promoter-nnnx5692.js → hive-promoter-mmmfszv8.js} +28 -28
- package/dist/cli/{index-34tawmyx.js → index-0a0asz2s.js} +1 -1
- package/dist/cli/{index-2qrd8mfa.js → index-4p3qfb05.js} +1 -1
- package/dist/cli/{index-gey2257h.js → index-5e5a1y2r.js} +1 -1
- package/dist/cli/{index-17e73wac.js → index-5qwmpamg.js} +1 -1
- package/dist/cli/{index-41t3hgaa.js → index-92cxd0r1.js} +247 -29
- package/dist/cli/{index-rtkttser.js → index-97psh79d.js} +1 -1
- package/dist/cli/{index-gf03198s.js → index-bghwrr59.js} +1 -1
- package/dist/cli/{index-tw8ck794.js → index-bma2wrqx.js} +2 -2
- package/dist/cli/{index-v3y3qg48.js → index-cpg98bh1.js} +17 -1
- package/dist/cli/{index-kxzgnz2h.js → index-d4e6wpkg.js} +14 -7
- package/dist/cli/{index-sfemjcb8.js → index-f17j50dx.js} +5 -5
- package/dist/cli/{index-7axx11dt.js → index-fay8h6v8.js} +25 -5
- package/dist/cli/{index-19v4tccw.js → index-fyr2wbvz.js} +2 -2
- package/dist/cli/{index-cqfp05jb.js → index-fzqhn96z.js} +3 -3
- package/dist/cli/{index-mrkgxfeh.js → index-g3xt1d16.js} +4 -4
- package/dist/cli/{index-evpgszmp.js → index-gxbhp7sx.js} +2 -2
- package/dist/cli/{index-mpf01swm.js → index-j20fzn0w.js} +2 -2
- package/dist/cli/{index-xz4x17z0.js → index-j43qndgc.js} +30 -30
- package/dist/cli/{index-neh8azwc.js → index-jfcgnvg6.js} +3 -3
- package/dist/cli/{index-qpke2x5h.js → index-kfmee1cr.js} +6 -6
- package/dist/cli/{index-4evasm2b.js → index-kggqpefz.js} +5 -5
- package/dist/cli/{index-90w06fqr.js → index-kwxp0z0n.js} +4 -4
- package/dist/cli/{index-b7ntt9cw.js → index-n6ke10ck.js} +4 -4
- package/dist/cli/{index-fwnhh6s7.js → index-nsr5b69r.js} +2 -2
- package/dist/cli/{index-bst6epnr.js → index-pz2py5v7.js} +1876 -1065
- package/dist/cli/{index-8ef23wex.js → index-q2mvacjr.js} +4 -4
- package/dist/cli/{index-dppzthm9.js → index-qyvjp0bq.js} +2 -2
- package/dist/cli/{index-tm0bezd9.js → index-s8qyaqs2.js} +1 -1
- package/dist/cli/{index-ymyke19q.js → index-vk15nbh4.js} +2 -2
- package/dist/cli/{index-dzan8czb.js → index-x8pm918t.js} +1 -1
- package/dist/cli/{index-ff66fbjt.js → index-zd1mfygt.js} +177 -29
- package/dist/cli/{index-zpp507z0.js → index-zsmsy1dh.js} +2 -2
- package/dist/cli/index.js +28 -28
- package/dist/cli/{knowledge-escalator-s6acdpwj.js → knowledge-escalator-c9p3w12b.js} +12 -12
- package/dist/cli/{knowledge-events-jprkz49t.js → knowledge-events-d201414m.js} +10 -10
- package/dist/cli/{knowledge-link-zvtmj756.js → knowledge-link-82ew2yc4.js} +5 -5
- package/dist/cli/{knowledge-store-mc4awds4.js → knowledge-store-ds45k9th.js} +6 -6
- package/dist/cli/{knowledge-validator-pe4ncrvj.js → knowledge-validator-707vsncy.js} +8 -8
- package/dist/cli/{model-preflight-77dwxfv5.js → model-preflight-7ea00h34.js} +1 -1
- package/dist/cli/{pending-delegations-epzht3d7.js → pending-delegations-kkrczqv7.js} +3 -3
- package/dist/cli/{pr-subscriptions-2ahy8g87.js → pr-subscriptions-2xn238xt.js} +3 -3
- package/dist/cli/{runner-ra9pjhp2.js → runner-pqsf809k.js} +6 -6
- package/dist/cli/{scan-cursor-hdzhqwzj.js → scan-cursor-znhqb8xa.js} +7 -7
- package/dist/cli/{schema-pg85z06v.js → schema-dnnm0p40.js} +2 -2
- package/dist/cli/{scope-persistence-v8we8ja7.js → scope-persistence-4n24a1e2.js} +8 -8
- package/dist/cli/{skill-generator-ctskfct2.js → skill-generator-5s0p3y8k.js} +14 -14
- package/dist/cli/{telemetry-c21dgffc.js → telemetry-t109dhv7.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-f7se4wbf.js → worktree-collision-ownership-2jtg2my1.js} +3 -3
- package/dist/cli/{worktree-isolation-j4qb7mgb.js → worktree-isolation-1v2mythh.js} +28 -28
- package/dist/commands/memory.d.ts +8 -0
- package/dist/commands/registry.d.ts +8 -0
- package/dist/config/schema.d.ts +16 -2
- package/dist/evidence/task-gate-repair.d.ts +26 -0
- package/dist/evidence/task-gate-requirements.d.ts +20 -0
- package/dist/gate-evidence.d.ts +7 -0
- package/dist/hooks/knowledge-receipt-ledger-storage.d.ts +2 -0
- package/dist/hooks/knowledge-receipt-ledger.d.ts +72 -3
- package/dist/hooks/knowledge-receipt-observability.d.ts +1 -1
- package/dist/hooks/phase-complete-directive-gate.d.ts +9 -0
- package/dist/index.js +593 -537
- package/dist/memory/config.d.ts +20 -0
- package/dist/memory/errors.d.ts +14 -0
- package/dist/memory/gateway.d.ts +32 -0
- package/dist/memory/index.d.ts +3 -2
- package/dist/memory/pii.d.ts +66 -0
- package/dist/memory/prompt-block.d.ts +1 -1
- package/dist/memory/provider.d.ts +15 -0
- package/dist/memory/redaction.d.ts +31 -8
- package/dist/memory/schema.d.ts +18 -0
- package/dist/memory/sentinel.d.ts +12 -0
- package/dist/memory/sqlite-provider.d.ts +93 -0
- package/dist/memory/types.d.ts +9 -0
- package/dist/plan/manager.d.ts +8 -0
- package/dist/review/diff-source.d.ts +30 -0
- package/dist/review/engine.d.ts +1 -0
- package/dist/review/evidence.d.ts +16 -2
- package/dist/review/phase-runner.d.ts +1 -0
- package/dist/tools/completion-verify.d.ts +2 -0
- package/dist/tools/convene-council.d.ts +1 -1
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/manifest.d.ts +4 -0
- package/dist/tools/phase-complete/gates/final-review-gate.d.ts +3 -3
- package/dist/tools/phase-complete/gates/types.d.ts +2 -2
- package/dist/tools/phase-complete/preflight-report.d.ts +66 -0
- package/dist/tools/phase-complete/snapshot-identity.d.ts +1 -0
- package/dist/tools/phase-complete.d.ts +66 -3
- package/dist/tools/record-directive-override.d.ts +14 -0
- package/dist/tools/repair-gate-evidence.d.ts +6 -0
- package/dist/tools/repair-knowledge-receipt-ledger.d.ts +27 -0
- package/dist/tools/run-phase-review.d.ts +37 -0
- package/dist/tools/submit-phase-council-verdicts.d.ts +1 -1
- package/dist/tools/tool-metadata.d.ts +32 -16
- package/dist/tools/write-final-council-evidence.d.ts +1 -1
- package/dist/tools/write-retro.d.ts +2 -0
- package/package.json +12 -2
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
autoCommitDirty,
|
|
4
4
|
cleanUntrackedFiles
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-zsmsy1dh.js";
|
|
6
6
|
import {
|
|
7
7
|
isPathWithinDeclaredScope,
|
|
8
8
|
unsafePathTextReason
|
|
@@ -26,10 +26,13 @@ import {
|
|
|
26
26
|
atomicWriteFile,
|
|
27
27
|
taskEvidencePath,
|
|
28
28
|
withTaskEvidenceLock
|
|
29
|
-
} from "./index-
|
|
29
|
+
} from "./index-j20fzn0w.js";
|
|
30
|
+
import {
|
|
31
|
+
assertProjectRoot
|
|
32
|
+
} from "./index-bghwrr59.js";
|
|
30
33
|
import {
|
|
31
34
|
telemetry
|
|
32
|
-
} from "./index-
|
|
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
|
|
44
|
-
import * as
|
|
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
|
|
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
|
|
102
|
-
import * as
|
|
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
|
|
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 =
|
|
328
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
120
329
|
} catch {
|
|
121
330
|
return {
|
|
122
331
|
records: [],
|
|
123
|
-
errored:
|
|
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 =
|
|
340
|
+
const full = path2.join(dir, entry.name);
|
|
132
341
|
try {
|
|
133
|
-
const parsed = JSON.parse(
|
|
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((
|
|
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:
|
|
767
|
-
readFileSync:
|
|
768
|
-
closeFileSync:
|
|
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 =
|
|
1263
|
-
const evidenceDir =
|
|
1264
|
-
|
|
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 =
|
|
1269
|
-
resolvedEvidenceDir =
|
|
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}${
|
|
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 =
|
|
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 =
|
|
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 =
|
|
1701
|
+
const raw = readFileSync3(evidencePath, "utf-8");
|
|
1484
1702
|
return parseTaskEvidence(raw, taskId);
|
|
1485
1703
|
} catch (error) {
|
|
1486
1704
|
const code = error.code;
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
PluginConfigSchema,
|
|
7
7
|
init_schema,
|
|
8
8
|
stripKnownSwarmPrefix
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-fay8h6v8.js";
|
|
10
10
|
import {
|
|
11
11
|
ALL_AGENT_NAMES,
|
|
12
12
|
init_constants
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-cpg98bh1.js";
|
|
14
14
|
import {
|
|
15
15
|
log
|
|
16
16
|
} from "./index-zgwm4ryv.js";
|
|
@@ -435,7 +435,23 @@ var init_tool_metadata = __esm(() => {
|
|
|
435
435
|
]
|
|
436
436
|
},
|
|
437
437
|
phase_complete: {
|
|
438
|
-
description: "
|
|
438
|
+
description: "preflight every applicable phase gate, report all blockers, and atomically commit a current passing snapshot",
|
|
439
|
+
agents: ["architect"]
|
|
440
|
+
},
|
|
441
|
+
run_phase_review: {
|
|
442
|
+
description: "run the bounded phase-final review engine and persist complete content-addressed review evidence",
|
|
443
|
+
agents: ["architect"]
|
|
444
|
+
},
|
|
445
|
+
repair_gate_evidence: {
|
|
446
|
+
description: "quarantine corrupt exact-task gate evidence and install a fresh blocked generation that requires every gate to rerun",
|
|
447
|
+
agents: ["architect"]
|
|
448
|
+
},
|
|
449
|
+
repair_knowledge_receipt_ledger: {
|
|
450
|
+
description: "validate or repair authoritative knowledge receipts, preserve corrupt authority in bounded quarantine, and require scoped re-evaluation",
|
|
451
|
+
agents: ["architect"]
|
|
452
|
+
},
|
|
453
|
+
record_directive_override: {
|
|
454
|
+
description: "record an audited architect override for identified critical-directive violations without bypassing unreadable authority",
|
|
439
455
|
agents: ["architect"]
|
|
440
456
|
},
|
|
441
457
|
save_plan: {
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
EvaluationRunV1Schema,
|
|
4
4
|
GateAuditResultV1Schema,
|
|
5
5
|
getProtectedEvaluationRunIds
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-nsr5b69r.js";
|
|
7
7
|
import {
|
|
8
8
|
loadDatabaseCtor
|
|
9
9
|
} from "./index-134d35c1.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
readTaskEvidence,
|
|
24
24
|
readTaskEvidenceRaw,
|
|
25
25
|
sanitizeTaskId
|
|
26
|
-
} from "./index-
|
|
26
|
+
} from "./index-92cxd0r1.js";
|
|
27
27
|
import {
|
|
28
28
|
LedgerStaleWriterError,
|
|
29
29
|
appendLedgerEvent,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
replayFromLedgerWithStatus,
|
|
44
44
|
takeSnapshotEvent,
|
|
45
45
|
takeSnapshotWithRetry
|
|
46
|
-
} from "./index-
|
|
46
|
+
} from "./index-fzqhn96z.js";
|
|
47
47
|
import {
|
|
48
48
|
init_executor,
|
|
49
49
|
isUntrustedEnvKey,
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
} from "./index-gprxjmm7.js";
|
|
57
57
|
import {
|
|
58
58
|
PlanSchema
|
|
59
|
-
} from "./index-
|
|
59
|
+
} from "./index-5qwmpamg.js";
|
|
60
60
|
import {
|
|
61
61
|
GIT_BINARY_ENV_VAR,
|
|
62
62
|
describeGitResolution,
|
|
@@ -76,10 +76,10 @@ import {
|
|
|
76
76
|
assertProjectRoot,
|
|
77
77
|
tryAcquireLock,
|
|
78
78
|
withEvidenceLock
|
|
79
|
-
} from "./index-
|
|
79
|
+
} from "./index-bghwrr59.js";
|
|
80
80
|
import {
|
|
81
81
|
emit
|
|
82
|
-
} from "./index-
|
|
82
|
+
} from "./index-qyvjp0bq.js";
|
|
83
83
|
import {
|
|
84
84
|
ZodError,
|
|
85
85
|
init_zod
|
|
@@ -2568,6 +2568,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2568
2568
|
const planHashForInit = computePlanHash(validated);
|
|
2569
2569
|
if (!await ledgerExists(directory)) {
|
|
2570
2570
|
try {
|
|
2571
|
+
options?.preCommitCheck?.();
|
|
2571
2572
|
await initLedger(directory, planId, planHashForInit, validated);
|
|
2572
2573
|
} catch (initErr) {
|
|
2573
2574
|
const msg = initErr instanceof Error ? initErr.message : String(initErr);
|
|
@@ -2584,6 +2585,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2584
2585
|
let backupExists = false;
|
|
2585
2586
|
if (existsSync4(oldLedgerPath)) {
|
|
2586
2587
|
try {
|
|
2588
|
+
options?.preCommitCheck?.();
|
|
2587
2589
|
renameSync2(oldLedgerPath, oldLedgerBackupPath);
|
|
2588
2590
|
backupExists = true;
|
|
2589
2591
|
} catch (renameErr) {
|
|
@@ -2593,6 +2595,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2593
2595
|
let initSucceeded = false;
|
|
2594
2596
|
if (backupExists) {
|
|
2595
2597
|
try {
|
|
2598
|
+
options?.preCommitCheck?.();
|
|
2596
2599
|
await initLedger(directory, planId, planHashForInit, validated);
|
|
2597
2600
|
initSucceeded = true;
|
|
2598
2601
|
} catch (initErr) {
|
|
@@ -2731,6 +2734,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2731
2734
|
}
|
|
2732
2735
|
try {
|
|
2733
2736
|
for (const missing of missingTasks) {
|
|
2737
|
+
options?.preCommitCheck?.();
|
|
2734
2738
|
const eventInput = {
|
|
2735
2739
|
plan_id: derivePlanId(validated),
|
|
2736
2740
|
event_type: "task_removed",
|
|
@@ -2768,6 +2772,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2768
2772
|
for (const task of phase.tasks) {
|
|
2769
2773
|
const oldTask = oldTaskMap.get(task.id);
|
|
2770
2774
|
if (oldTask && oldTask.status !== task.status) {
|
|
2775
|
+
options?.preCommitCheck?.();
|
|
2771
2776
|
const eventInput = {
|
|
2772
2777
|
plan_id: derivePlanId(validated),
|
|
2773
2778
|
event_type: "task_status_changed",
|
|
@@ -2809,6 +2814,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2809
2814
|
const replayedBeforeProjection = await replayFromLedger(directory);
|
|
2810
2815
|
const projectionCandidate = replayedBeforeProjection ? mergeStatusesTakingPrecedence(validated, replayedBeforeProjection, ledgerStatusTaskIds) : validated;
|
|
2811
2816
|
if (replayedBeforeProjection && computePlanHash(replayedBeforeProjection) !== computePlanHash(projectionCandidate)) {
|
|
2817
|
+
options?.preCommitCheck?.();
|
|
2812
2818
|
await takeSnapshotEvent(directory, projectionCandidate, {
|
|
2813
2819
|
planHashAfter: computePlanHash(projectionCandidate),
|
|
2814
2820
|
source: "savePlan_structural_projection"
|
|
@@ -2817,7 +2823,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2817
2823
|
const projectedPlan = projectionCandidate;
|
|
2818
2824
|
const SNAPSHOT_INTERVAL = 50;
|
|
2819
2825
|
const latestSeq = await getLatestLedgerSeq(directory);
|
|
2820
|
-
if (latestSeq > 0 && latestSeq % SNAPSHOT_INTERVAL === 0) {
|
|
2826
|
+
if (!options?.preCommitCheck && latestSeq > 0 && latestSeq % SNAPSHOT_INTERVAL === 0) {
|
|
2821
2827
|
await takeSnapshotWithRetry(directory, projectedPlan, {
|
|
2822
2828
|
planHashAfter: computePlanHash(projectedPlan),
|
|
2823
2829
|
source: "savePlan_manager"
|
|
@@ -2828,6 +2834,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2828
2834
|
const tempPath = path5.join(swarmDir, `plan.json.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
2829
2835
|
try {
|
|
2830
2836
|
await bunWrite(tempPath, JSON.stringify(projectedPlan, null, 2));
|
|
2837
|
+
options?.preCommitCheck?.();
|
|
2831
2838
|
renameSync2(tempPath, planPath);
|
|
2832
2839
|
} finally {
|
|
2833
2840
|
try {
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
resolveSwarmKnowledgePath,
|
|
7
7
|
transactKnowledge,
|
|
8
8
|
wordBigrams
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-kfmee1cr.js";
|
|
10
10
|
import {
|
|
11
11
|
queryHistoricalOutcomes,
|
|
12
12
|
readKnowledgeEvents,
|
|
13
13
|
recordKnowledgeEvent
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-zd1mfygt.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-
|
|
227
|
+
const { quarantineEntry } = await import("./knowledge-validator-707vsncy.js");
|
|
228
228
|
let policyConfig;
|
|
229
229
|
try {
|
|
230
|
-
const { KnowledgeConfigSchema } = await import("./schema-
|
|
231
|
-
const { loadPluginConfigWithMeta } = await import("./index-
|
|
230
|
+
const { KnowledgeConfigSchema } = await import("./schema-dnnm0p40.js");
|
|
231
|
+
const { loadPluginConfigWithMeta } = await import("./index-n6ke10ck.js");
|
|
232
232
|
const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
|
|
233
233
|
policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
|
|
234
234
|
} catch {
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ALL_AGENT_NAMES,
|
|
4
4
|
SUMMARIZER_EXEMPT_TOOL_NAMES,
|
|
5
5
|
init_constants
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-cpg98bh1.js";
|
|
7
7
|
import {
|
|
8
8
|
OUTCOME_BLOCK_THRESHOLD,
|
|
9
9
|
init_knowledge_types
|
|
@@ -21,7 +21,7 @@ var package_default;
|
|
|
21
21
|
var init_package = __esm(() => {
|
|
22
22
|
package_default = {
|
|
23
23
|
name: "opencode-swarm",
|
|
24
|
-
version: "7.
|
|
24
|
+
version: "7.146.0",
|
|
25
25
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
26
26
|
main: "dist/index.js",
|
|
27
27
|
types: "dist/index.d.ts",
|
|
@@ -129,9 +129,11 @@ var init_package = __esm(() => {
|
|
|
129
129
|
"repro:1144": "bun scripts/repro-1144.mjs",
|
|
130
130
|
"repro:1873": "bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs",
|
|
131
131
|
"check:events": "bun run scripts/check-event-contract.ts",
|
|
132
|
+
"check:retention": "bun run scripts/check-retention-registry.ts",
|
|
132
133
|
"check:test-file-cap": "bun run scripts/check-test-file-cap.ts",
|
|
133
134
|
"check:gate-portability": "bun run scripts/check-gate-portability.ts",
|
|
134
|
-
"check:bare-spawn": "bun run scripts/check-bare-executable-spawn.ts"
|
|
135
|
+
"check:bare-spawn": "bun run scripts/check-bare-executable-spawn.ts",
|
|
136
|
+
"check:memory-recall": "bun run scripts/memory-recall-regression.ts"
|
|
135
137
|
},
|
|
136
138
|
dependencies: {
|
|
137
139
|
"@opencode-ai/plugin": "^1.18.3",
|
|
@@ -151,6 +153,14 @@ var init_package = __esm(() => {
|
|
|
151
153
|
"bun-types": "1.3.8",
|
|
152
154
|
"js-yaml": "^4.1.1",
|
|
153
155
|
typescript: "^5.7.3"
|
|
156
|
+
},
|
|
157
|
+
peerDependencies: {
|
|
158
|
+
"@xenova/transformers": "^2.17.2"
|
|
159
|
+
},
|
|
160
|
+
peerDependenciesMeta: {
|
|
161
|
+
"@xenova/transformers": {
|
|
162
|
+
optional: true
|
|
163
|
+
}
|
|
154
164
|
}
|
|
155
165
|
};
|
|
156
166
|
});
|
|
@@ -1011,8 +1021,18 @@ var init_schema = __esm(() => {
|
|
|
1011
1021
|
mode: exports_external.literal("propose").default("propose")
|
|
1012
1022
|
}).default({ mode: "propose" }),
|
|
1013
1023
|
redaction: exports_external.object({
|
|
1014
|
-
rejectDurableSecrets: exports_external.boolean().default(true)
|
|
1015
|
-
|
|
1024
|
+
rejectDurableSecrets: exports_external.boolean().default(true),
|
|
1025
|
+
detectPii: exports_external.boolean().default(false),
|
|
1026
|
+
piiDetector: exports_external.enum(["regex", "ner"]).default("regex"),
|
|
1027
|
+
rejectDurablePii: exports_external.boolean().default(false),
|
|
1028
|
+
piiThreshold: exports_external.number().min(0).max(1).refine((v) => v < 1, "piiThreshold must be strictly less than 1 (rejection is score > threshold and scores never reach 1, so 1 would silently disable PII rejection)").default(0.7)
|
|
1029
|
+
}).default({
|
|
1030
|
+
rejectDurableSecrets: true,
|
|
1031
|
+
detectPii: false,
|
|
1032
|
+
piiDetector: "regex",
|
|
1033
|
+
rejectDurablePii: false,
|
|
1034
|
+
piiThreshold: 0.7
|
|
1035
|
+
}),
|
|
1016
1036
|
maintenance: exports_external.object({
|
|
1017
1037
|
lowUtilityMaxConfidence: exports_external.number().min(0).max(1).default(0.45),
|
|
1018
1038
|
lowUtilityMinAgeDays: exports_external.number().int().min(1).max(3650).default(30),
|