blun-king-cli 9.1.448 → 9.1.450
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/bin/cognitive-action-checkpoint.cjs +139 -15
- package/bin/goal-completion-evidence-policy.cjs +11 -3
- package/blun.mjs +31 -4
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ const EPISTEMIC_STATES = new Set([
|
|
|
12
12
|
const TRIGGER_KINDS = new Set([
|
|
13
13
|
'immediate', 'external_event', 'time', 'dependency', 'user_decision',
|
|
14
14
|
]);
|
|
15
|
+
const VERIFICATION_SUBJECTS = new Set(['result', 'verifier']);
|
|
15
16
|
const MODEL_KEYS = new Set([
|
|
16
17
|
'revision', 'phase', 'evidenceBasis', 'epistemicState', 'lastVerified', 'nextAction', 'expectedEvidence', 'verificationProof', 'nextTrigger', 'problemFrame', 'updatedAt',
|
|
17
18
|
]);
|
|
@@ -22,6 +23,9 @@ const PROBLEM_FRAME_KEYS = new Set([
|
|
|
22
23
|
]);
|
|
23
24
|
const NEXT_TRIGGER_KEYS = new Set(['kind', 'condition', 'dueAt']);
|
|
24
25
|
const EVIDENCE_INPUT_KEYS = new Set([
|
|
26
|
+
'turnId', 'toolCallId', 'toolName', 'decision', 'outcome', 'durationMs', 'toolArgs',
|
|
27
|
+
]);
|
|
28
|
+
const REQUIRED_EVIDENCE_INPUT_KEYS = new Set([
|
|
25
29
|
'turnId', 'toolCallId', 'toolName', 'decision', 'outcome', 'durationMs',
|
|
26
30
|
]);
|
|
27
31
|
const EVIDENCE_DIGEST_RE = /^[a-f0-9]{16}$/u;
|
|
@@ -32,6 +36,14 @@ const ACTION_ONLY_TOOL_NAMES = new Set([
|
|
|
32
36
|
'ExitPlanMode', 'GenerateImage', 'GenerateSpeech', 'GenerateVideo', 'LipSyncMedia',
|
|
33
37
|
'MistakeRecord', 'SetGoalBudget', 'TaskStop', 'TaskUpdate', 'UpdateGoal', 'Write',
|
|
34
38
|
]);
|
|
39
|
+
const VERIFICATION_TOOL_NAMES = new Set([
|
|
40
|
+
'codebasesearch', 'cronlist', 'fetchurl', 'getgoal', 'getmedia', 'glob', 'grep',
|
|
41
|
+
'read', 'readmediafile', 'taskoutput', 'test', 'understandimage', 'understandvideo',
|
|
42
|
+
'websearch',
|
|
43
|
+
]);
|
|
44
|
+
const COMMAND_TOOL_NAMES = new Set(['bash', 'command', 'exec_command', 'shell']);
|
|
45
|
+
const MUTATING_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:cp|mv|rm|mkdir|touch|tee|install|scp|sftp|ssh)\b|(?:sed\s+-i\b)|(?:git\s+(?:add|commit|push|checkout|switch|reset|clean|merge|rebase)\b)|(?:Set-Content|Add-Content|Copy-Item|Move-Item|Remove-Item|New-Item|Start-Process)\b)/iu;
|
|
46
|
+
const VERIFICATION_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:node\s+--(?:test|check))|(?:node\s+[^\s;&|]*(?:check|test|verify|validate|lint|gate|probe)[^\s;&|]*\b)|(?:(?:npm|pnpm|yarn)\s+(?:test|(?:run\s+)?(?:test|lint|check|typecheck|build)))|(?:python(?:3)?\s+-m\s+pytest)|(?:pytest)|(?:go\s+test)|(?:cargo\s+test)|(?:dotnet\s+test)|(?:npx\s+)?(?:tsc|eslint|biome\s+check)|(?:git\s+(?:diff(?:\s+--check)?|fsck|status|rev-parse|show))|(?:sha(?:1|256|512)sum|shasum|cmp|diff|wc|rg|grep|cat|ls|stat)\b|(?:certutil\s+-hashfile)|(?:Get-FileHash|Get-Content|Get-Item|Test-Path|Compare-Object|Measure-Object)\b)/iu;
|
|
35
47
|
const MAX_SUCCESSFUL_TOOL_DIGESTS = 32;
|
|
36
48
|
|
|
37
49
|
function bounded(value, field, max = 512) {
|
|
@@ -159,10 +171,36 @@ function successfulToolDigest(toolName) {
|
|
|
159
171
|
return crypto.createHash('sha256').update(`tool:${name}`).digest('hex').slice(0, 16);
|
|
160
172
|
}
|
|
161
173
|
|
|
174
|
+
function successfulToolCallDigest(turnId, toolCallId, toolName) {
|
|
175
|
+
const turn = normalizedTurnId(turnId);
|
|
176
|
+
const callId = bounded(toolCallId, 'verificationProof toolCallId', 256);
|
|
177
|
+
const name = bounded(toolName, 'verificationProof toolName', 128);
|
|
178
|
+
return crypto.createHash('sha256')
|
|
179
|
+
.update(`turn:${turn}\0call:${callId}\0tool:${name}`)
|
|
180
|
+
.digest('hex')
|
|
181
|
+
.slice(0, 16);
|
|
182
|
+
}
|
|
183
|
+
|
|
162
184
|
function isActionOnlyTool(toolName) {
|
|
163
185
|
return ACTION_ONLY_TOOL_NAMES.has(String(toolName ?? '').trim());
|
|
164
186
|
}
|
|
165
187
|
|
|
188
|
+
function verificationCommand(toolArgs) {
|
|
189
|
+
if (!toolArgs || typeof toolArgs !== 'object' || Array.isArray(toolArgs)) return '';
|
|
190
|
+
const command = toolArgs.command ?? toolArgs.cmd;
|
|
191
|
+
return typeof command === 'string' ? command.trim().replace(/\s+/gu, ' ') : '';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function isVerificationToolCall(toolName, toolArgs) {
|
|
195
|
+
const normalizedName = String(toolName ?? '').trim().toLowerCase();
|
|
196
|
+
if (VERIFICATION_TOOL_NAMES.has(normalizedName)) return true;
|
|
197
|
+
if (!COMMAND_TOOL_NAMES.has(normalizedName)) return false;
|
|
198
|
+
const command = verificationCommand(toolArgs);
|
|
199
|
+
return command.length > 0
|
|
200
|
+
&& !MUTATING_COMMAND.test(command)
|
|
201
|
+
&& VERIFICATION_COMMAND.test(command);
|
|
202
|
+
}
|
|
203
|
+
|
|
166
204
|
function normalizeSuccessfulToolDigests(value) {
|
|
167
205
|
if (value === undefined) return Object.freeze([]);
|
|
168
206
|
if (!Array.isArray(value) || value.length > MAX_SUCCESSFUL_TOOL_DIGESTS
|
|
@@ -173,23 +211,85 @@ function normalizeSuccessfulToolDigests(value) {
|
|
|
173
211
|
return Object.freeze([...value]);
|
|
174
212
|
}
|
|
175
213
|
|
|
176
|
-
function
|
|
214
|
+
function normalizeExactVerificationCall(input, receipt, label) {
|
|
177
215
|
if (!input || typeof input !== 'object' || Array.isArray(input)
|
|
178
|
-
|| Object.keys(input).length !==
|
|
216
|
+
|| Object.keys(input).length !== 3
|
|
217
|
+
|| !Object.hasOwn(input, 'toolCallId')
|
|
179
218
|
|| !Object.hasOwn(input, 'toolName')
|
|
180
219
|
|| !Object.hasOwn(input, 'claim')) {
|
|
181
|
-
throw new TypeError(
|
|
220
|
+
throw new TypeError(`${label} fields are invalid`);
|
|
182
221
|
}
|
|
183
|
-
const
|
|
184
|
-
const
|
|
222
|
+
const toolCallId = bounded(input.toolCallId, `${label} toolCallId`, 256);
|
|
223
|
+
const toolName = bounded(input.toolName, `${label} toolName`, 128);
|
|
224
|
+
const claim = bounded(input.claim, `${label} claim`);
|
|
185
225
|
if (isActionOnlyTool(toolName)) {
|
|
186
|
-
|
|
226
|
+
const purpose = label === 'verificationProof' ? 'verification proof' : label;
|
|
227
|
+
throw new TypeError(`action-only tool cannot serve as ${purpose}`);
|
|
187
228
|
}
|
|
188
|
-
const
|
|
189
|
-
if (!receipt.
|
|
190
|
-
throw new TypeError(
|
|
229
|
+
const callDigest = successfulToolCallDigest(receipt.turnId, toolCallId, toolName);
|
|
230
|
+
if (!receipt.successfulToolCallDigests.includes(callDigest)) {
|
|
231
|
+
throw new TypeError(`${label} must match a successful current-turn verification call`);
|
|
191
232
|
}
|
|
192
|
-
return Object.freeze({ toolName, claim });
|
|
233
|
+
return Object.freeze({ toolCallId, toolName, claim });
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function normalizeVerificationProof(input, evidenceReceipt, options = {}) {
|
|
237
|
+
const keys = input && typeof input === 'object' && !Array.isArray(input)
|
|
238
|
+
? Object.keys(input)
|
|
239
|
+
: [];
|
|
240
|
+
const legacyName = options.allowLegacy === true
|
|
241
|
+
&& keys.length === 2
|
|
242
|
+
&& Object.hasOwn(input, 'toolName')
|
|
243
|
+
&& Object.hasOwn(input, 'claim');
|
|
244
|
+
const legacyExact = options.allowLegacy === true
|
|
245
|
+
&& keys.length === 3
|
|
246
|
+
&& Object.hasOwn(input, 'toolCallId')
|
|
247
|
+
&& Object.hasOwn(input, 'toolName')
|
|
248
|
+
&& Object.hasOwn(input, 'claim');
|
|
249
|
+
const subject = String(input?.subject ?? '').trim();
|
|
250
|
+
const currentResult = subject === 'result'
|
|
251
|
+
&& keys.length === 4
|
|
252
|
+
&& Object.hasOwn(input, 'toolCallId')
|
|
253
|
+
&& Object.hasOwn(input, 'toolName')
|
|
254
|
+
&& Object.hasOwn(input, 'claim');
|
|
255
|
+
const currentVerifier = subject === 'verifier'
|
|
256
|
+
&& (keys.length === 4 || keys.length === 5)
|
|
257
|
+
&& Object.hasOwn(input, 'toolCallId')
|
|
258
|
+
&& Object.hasOwn(input, 'toolName')
|
|
259
|
+
&& Object.hasOwn(input, 'claim')
|
|
260
|
+
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'claim', 'sharpnessProof'].includes(key));
|
|
261
|
+
if (!legacyName && !legacyExact && !currentResult && !currentVerifier) {
|
|
262
|
+
throw new TypeError('verificationProof fields are invalid');
|
|
263
|
+
}
|
|
264
|
+
const receipt = normalizeActionEvidenceReceipt(evidenceReceipt);
|
|
265
|
+
if (legacyName) {
|
|
266
|
+
const toolName = bounded(input.toolName, 'verificationProof toolName', 128);
|
|
267
|
+
const claim = bounded(input.claim, 'verificationProof claim');
|
|
268
|
+
if (isActionOnlyTool(toolName)) {
|
|
269
|
+
throw new TypeError('action-only tool cannot serve as verification proof');
|
|
270
|
+
}
|
|
271
|
+
if (!receipt.successfulToolDigests.includes(successfulToolDigest(toolName))) {
|
|
272
|
+
throw new TypeError('verificationProof must name a successful current-turn tool');
|
|
273
|
+
}
|
|
274
|
+
return Object.freeze({ toolName, claim });
|
|
275
|
+
}
|
|
276
|
+
const primary = normalizeExactVerificationCall(legacyExact ? input : {
|
|
277
|
+
toolCallId: input.toolCallId,
|
|
278
|
+
toolName: input.toolName,
|
|
279
|
+
claim: input.claim,
|
|
280
|
+
}, receipt, 'verificationProof');
|
|
281
|
+
if (legacyExact) return primary;
|
|
282
|
+
if (!VERIFICATION_SUBJECTS.has(subject)) throw new TypeError('verificationProof subject is invalid');
|
|
283
|
+
if (subject === 'result') return Object.freeze({ subject, ...primary });
|
|
284
|
+
if (input.sharpnessProof === undefined) {
|
|
285
|
+
throw new TypeError('verifier proof requires a sharpnessProof');
|
|
286
|
+
}
|
|
287
|
+
const sharpnessProof = normalizeExactVerificationCall(input.sharpnessProof, receipt, 'sharpnessProof');
|
|
288
|
+
if (sharpnessProof.toolCallId === primary.toolCallId
|
|
289
|
+
&& sharpnessProof.toolName === primary.toolName) {
|
|
290
|
+
throw new TypeError('sharpnessProof must name a distinct verification call');
|
|
291
|
+
}
|
|
292
|
+
return Object.freeze({ subject, ...primary, sharpnessProof });
|
|
193
293
|
}
|
|
194
294
|
|
|
195
295
|
function emptyActionEvidenceReceipt(turnId) {
|
|
@@ -200,6 +300,7 @@ function emptyActionEvidenceReceipt(turnId) {
|
|
|
200
300
|
successfulTools: 0,
|
|
201
301
|
failedTools: 0,
|
|
202
302
|
successfulToolDigests: Object.freeze([]),
|
|
303
|
+
successfulToolCallDigests: Object.freeze([]),
|
|
203
304
|
digest: crypto.createHash('sha256').update(`turn:${normalized}:empty`).digest('hex').slice(0, 16),
|
|
204
305
|
});
|
|
205
306
|
}
|
|
@@ -207,7 +308,7 @@ function emptyActionEvidenceReceipt(turnId) {
|
|
|
207
308
|
function normalizeActionEvidenceReceipt(input) {
|
|
208
309
|
if (!input || typeof input !== 'object' || Array.isArray(input)) throw new TypeError('evidence receipt must be an object');
|
|
209
310
|
const requiredKeys = new Set(['turnId', 'completedTools', 'successfulTools', 'failedTools', 'digest']);
|
|
210
|
-
const allowedKeys = new Set([...requiredKeys, 'successfulToolDigests']);
|
|
311
|
+
const allowedKeys = new Set([...requiredKeys, 'successfulToolDigests', 'successfulToolCallDigests']);
|
|
211
312
|
if (!Object.keys(input).every((key) => allowedKeys.has(key))
|
|
212
313
|
|| ![...requiredKeys].every((key) => Object.hasOwn(input, key))) {
|
|
213
314
|
throw new TypeError('evidence receipt fields are invalid');
|
|
@@ -218,6 +319,7 @@ function normalizeActionEvidenceReceipt(input) {
|
|
|
218
319
|
successfulTools: Number(input.successfulTools),
|
|
219
320
|
failedTools: Number(input.failedTools),
|
|
220
321
|
successfulToolDigests: normalizeSuccessfulToolDigests(input.successfulToolDigests),
|
|
322
|
+
successfulToolCallDigests: normalizeSuccessfulToolDigests(input.successfulToolCallDigests),
|
|
221
323
|
digest: String(input.digest ?? ''),
|
|
222
324
|
};
|
|
223
325
|
if (![receipt.completedTools, receipt.successfulTools, receipt.failedTools]
|
|
@@ -232,8 +334,8 @@ function normalizeActionEvidenceReceipt(input) {
|
|
|
232
334
|
function advanceActionEvidenceReceipt(current, input) {
|
|
233
335
|
const prior = normalizeActionEvidenceReceipt(current);
|
|
234
336
|
if (!input || typeof input !== 'object' || Array.isArray(input)
|
|
235
|
-
|| Object.keys(input).
|
|
236
|
-
|| !
|
|
337
|
+
|| !Object.keys(input).every((key) => EVIDENCE_INPUT_KEYS.has(key))
|
|
338
|
+
|| ![...REQUIRED_EVIDENCE_INPUT_KEYS].every((key) => Object.hasOwn(input, key))) {
|
|
237
339
|
throw new TypeError('evidence input fields are invalid');
|
|
238
340
|
}
|
|
239
341
|
const turnId = normalizedTurnId(input.turnId);
|
|
@@ -249,13 +351,21 @@ function advanceActionEvidenceReceipt(current, input) {
|
|
|
249
351
|
}
|
|
250
352
|
const successful = decision === 'passed' && outcome === 'success';
|
|
251
353
|
const successfulToolDigests = [...prior.successfulToolDigests];
|
|
354
|
+
const successfulToolCallDigests = [...prior.successfulToolCallDigests];
|
|
252
355
|
const toolDigest = successfulToolDigest(toolName);
|
|
253
356
|
if (successful && !successfulToolDigests.includes(toolDigest)) {
|
|
254
357
|
successfulToolDigests.push(toolDigest);
|
|
255
358
|
if (successfulToolDigests.length > MAX_SUCCESSFUL_TOOL_DIGESTS) successfulToolDigests.shift();
|
|
256
359
|
}
|
|
360
|
+
const verificationCall = successful && isVerificationToolCall(toolName, input.toolArgs);
|
|
361
|
+
if (verificationCall) {
|
|
362
|
+
const callDigest = successfulToolCallDigest(turnId, toolCallId, toolName);
|
|
363
|
+
if (!successfulToolCallDigests.includes(callDigest)) successfulToolCallDigests.push(callDigest);
|
|
364
|
+
if (successfulToolCallDigests.length > MAX_SUCCESSFUL_TOOL_DIGESTS) successfulToolCallDigests.shift();
|
|
365
|
+
}
|
|
257
366
|
const digest = crypto.createHash('sha256').update([
|
|
258
367
|
prior.digest, String(turnId), toolCallId, toolName, decision, outcome, String(durationMs),
|
|
368
|
+
String(verificationCall),
|
|
259
369
|
].join('\0')).digest('hex').slice(0, 16);
|
|
260
370
|
return Object.freeze({
|
|
261
371
|
turnId,
|
|
@@ -263,6 +373,7 @@ function advanceActionEvidenceReceipt(current, input) {
|
|
|
263
373
|
successfulTools: prior.successfulTools + (successful ? 1 : 0),
|
|
264
374
|
failedTools: prior.failedTools + (successful ? 0 : 1),
|
|
265
375
|
successfulToolDigests: Object.freeze(successfulToolDigests),
|
|
376
|
+
successfulToolCallDigests: Object.freeze(successfulToolCallDigests),
|
|
266
377
|
digest,
|
|
267
378
|
});
|
|
268
379
|
}
|
|
@@ -352,7 +463,9 @@ function normalizeActionCheckpoint(input, options = {}) {
|
|
|
352
463
|
if (phase !== 'verify' || evidenceBasis !== 'runtime_tool') {
|
|
353
464
|
throw new TypeError('verificationProof requires a runtime_tool verify checkpoint');
|
|
354
465
|
}
|
|
355
|
-
checkpoint.verificationProof = normalizeVerificationProof(input.verificationProof, evidenceReceipt
|
|
466
|
+
checkpoint.verificationProof = normalizeVerificationProof(input.verificationProof, evidenceReceipt, {
|
|
467
|
+
allowLegacy: replay,
|
|
468
|
+
});
|
|
356
469
|
}
|
|
357
470
|
return Object.freeze(checkpoint);
|
|
358
471
|
}
|
|
@@ -371,7 +484,17 @@ function projectActionCheckpoint(checkpoint) {
|
|
|
371
484
|
lines.push(`Next action: ${value.nextAction}`);
|
|
372
485
|
lines.push(`Expected evidence: ${value.expectedEvidence}`);
|
|
373
486
|
if (value.verificationProof !== undefined) {
|
|
374
|
-
|
|
487
|
+
const call = value.verificationProof.toolCallId === undefined
|
|
488
|
+
? value.verificationProof.toolName
|
|
489
|
+
: `${value.verificationProof.toolName} call ${value.verificationProof.toolCallId}`;
|
|
490
|
+
const subject = value.verificationProof.subject === undefined
|
|
491
|
+
? ''
|
|
492
|
+
: ` [${value.verificationProof.subject}]`;
|
|
493
|
+
lines.push(`Verification proof${subject}: ${call} - ${value.verificationProof.claim}`);
|
|
494
|
+
if (value.verificationProof.sharpnessProof !== undefined) {
|
|
495
|
+
const sharpness = value.verificationProof.sharpnessProof;
|
|
496
|
+
lines.push(`Sharpness proof: ${sharpness.toolName} call ${sharpness.toolCallId} - ${sharpness.claim}`);
|
|
497
|
+
}
|
|
375
498
|
}
|
|
376
499
|
if (value.nextTrigger !== undefined) {
|
|
377
500
|
lines.push(`Next trigger: ${value.nextTrigger.kind.replaceAll('_', ' ')} - ${value.nextTrigger.condition}`);
|
|
@@ -410,5 +533,6 @@ module.exports = {
|
|
|
410
533
|
normalizeActionCheckpoint,
|
|
411
534
|
normalizeVerificationProof,
|
|
412
535
|
projectActionCheckpoint,
|
|
536
|
+
successfulToolCallDigest,
|
|
413
537
|
successfulToolDigest,
|
|
414
538
|
};
|
|
@@ -19,14 +19,22 @@ function verificationProofGaps(checkpoint) {
|
|
|
19
19
|
return ['Bind the completion claim to a successful verification tool from the checkpoint turn.'];
|
|
20
20
|
}
|
|
21
21
|
try {
|
|
22
|
-
normalizeVerificationProof(checkpoint.verificationProof, checkpoint.evidenceReceipt);
|
|
22
|
+
normalizeVerificationProof(checkpoint.verificationProof, checkpoint.evidenceReceipt, { allowLegacy: true });
|
|
23
23
|
return [];
|
|
24
24
|
} catch (error) {
|
|
25
|
+
if (/verifier proof requires a sharpnessProof|sharpnessProof must name a distinct verification call/u
|
|
26
|
+
.test(String(error?.message ?? ''))) {
|
|
27
|
+
return ['A verifier completion needs a distinct current-turn counterexample or mutation call.'];
|
|
28
|
+
}
|
|
29
|
+
if (/sharpnessProof must match a successful current-turn verification call/u
|
|
30
|
+
.test(String(error?.message ?? ''))) {
|
|
31
|
+
return ['The verifier sharpness proof does not match a successful current-turn verification call.'];
|
|
32
|
+
}
|
|
25
33
|
if (/action-only tool/u.test(String(error?.message ?? ''))) {
|
|
26
34
|
return ['The completion proof names an action-only tool, not a verification tool.'];
|
|
27
35
|
}
|
|
28
|
-
if (/successful current-turn tool/u.test(String(error?.message ?? ''))) {
|
|
29
|
-
return ['The completion proof does not match a successful verification
|
|
36
|
+
if (/successful current-turn (?:tool|verification call)/u.test(String(error?.message ?? ''))) {
|
|
37
|
+
return ['The completion proof does not match a successful verification call from the checkpoint turn.'];
|
|
30
38
|
}
|
|
31
39
|
return ['The completion verification proof is malformed.'];
|
|
32
40
|
}
|
package/blun.mjs
CHANGED
|
@@ -260349,9 +260349,34 @@ function createActionCheckpointInputSchema(problemFrameSchema, requireProblemFra
|
|
|
260349
260349
|
nextAction: string().min(1).max(512),
|
|
260350
260350
|
expectedEvidence: string().min(1).max(512),
|
|
260351
260351
|
verificationProof: object({
|
|
260352
|
+
subject: _enum(["result", "verifier"]),
|
|
260353
|
+
toolCallId: string().min(1).max(256),
|
|
260352
260354
|
toolName: string().min(1).max(128),
|
|
260353
|
-
claim: string().min(1).max(512)
|
|
260354
|
-
|
|
260355
|
+
claim: string().min(1).max(512),
|
|
260356
|
+
sharpnessProof: object({
|
|
260357
|
+
toolCallId: string().min(1).max(256),
|
|
260358
|
+
toolName: string().min(1).max(128),
|
|
260359
|
+
claim: string().min(1).max(512)
|
|
260360
|
+
}).strict().optional()
|
|
260361
|
+
}).strict().superRefine((value, ctx) => {
|
|
260362
|
+
if (value.subject === "verifier" && value.sharpnessProof === void 0) ctx.addIssue({
|
|
260363
|
+
code: "custom",
|
|
260364
|
+
path: ["sharpnessProof"],
|
|
260365
|
+
message: "verifier subject requires sharpnessProof"
|
|
260366
|
+
});
|
|
260367
|
+
if (value.subject === "result" && value.sharpnessProof !== void 0) ctx.addIssue({
|
|
260368
|
+
code: "custom",
|
|
260369
|
+
path: ["sharpnessProof"],
|
|
260370
|
+
message: "result subject cannot carry sharpnessProof"
|
|
260371
|
+
});
|
|
260372
|
+
if (value.sharpnessProof !== void 0
|
|
260373
|
+
&& value.sharpnessProof.toolCallId === value.toolCallId
|
|
260374
|
+
&& value.sharpnessProof.toolName === value.toolName) ctx.addIssue({
|
|
260375
|
+
code: "custom",
|
|
260376
|
+
path: ["sharpnessProof"],
|
|
260377
|
+
message: "sharpnessProof must name a distinct verification call"
|
|
260378
|
+
});
|
|
260379
|
+
}).optional(),
|
|
260355
260380
|
nextTrigger: object({
|
|
260356
260381
|
kind: _enum(["immediate", "external_event", "time", "dependency", "user_decision"]),
|
|
260357
260382
|
condition: string().min(1).max(512),
|
|
@@ -262737,6 +262762,7 @@ var init_turn = __esmMin((() => {
|
|
|
262737
262762
|
this.toolCallDupType.set(event.toolCallId, dupType === "cross_step" ? "cross_step" : "normal");
|
|
262738
262763
|
this.toolCallStartedAt.set(event.toolCallId, {
|
|
262739
262764
|
name: event.name,
|
|
262765
|
+
args: event.args,
|
|
262740
262766
|
startedAt: Date.now()
|
|
262741
262767
|
});
|
|
262742
262768
|
this.agent.feedRootMissionContract("start", {
|
|
@@ -262767,7 +262793,8 @@ var init_turn = __esmMin((() => {
|
|
|
262767
262793
|
toolCallId: event.toolCallId,
|
|
262768
262794
|
toolName: started.name,
|
|
262769
262795
|
outcome,
|
|
262770
|
-
durationMs: Date.now() - started.startedAt
|
|
262796
|
+
durationMs: Date.now() - started.startedAt,
|
|
262797
|
+
toolArgs: started.args
|
|
262771
262798
|
});
|
|
262772
262799
|
this.agent.telemetry.track("tool_call", properties);
|
|
262773
262800
|
this.agent.feedRootMissionContract("result", {
|
|
@@ -262872,7 +262899,7 @@ var init_outcome_prompts = __esmMin((() => {}));
|
|
|
262872
262899
|
var update_goal_default;
|
|
262873
262900
|
var init_update_goal$1 = __esmMin((() => {
|
|
262874
262901
|
update_goal_default = "Update the current autonomous goal. Set `status` only for a lifecycle change. After a coherent work slice, save `actionCheckpoint` with a monotone revision, the last verified result, exact next action, expected evidence, exact `nextTrigger`, and an explicit evidence basis. Persist the exact `nextTrigger` that releases `nextAction`: use `immediate` outside the `wait` phase; while waiting, name the external event, time, dependency, or user decision instead of pretending work can continue. A `time` trigger must include the exact ISO timestamp in `dueAt`; no other trigger kind may include `dueAt`. Use `runtime_tool` only when a successful tool in this turn measured the result; use `user_statement` for a direct user assertion, `external_report` for a report not independently measured here, and `carried_forward` only when the last verified text is unchanged. Classify knowledge as `verified`, `credible_unverified`, `hypothesis`, `uncertain_memory`, `stale`, or `unknown`; never present a weaker state as verified, and preserve the state on carry-forward. Start at revision 1 and increment the currently projected revision by exactly one; stale writers fail closed. This is durable progress state, not permission, and should change only when the facts change. A checkpoint-only call keeps the goal active.\n\n- `active` — resume a paused or blocked goal when the user explicitly asks you to work on that goal.\n- `complete` — the objective is fully satisfied, all files are written, all tests pass, and any stated validation has passed. When the goal has a completion criterion, first save a `verify` checkpoint with `runtime_tool`, `verified`, and a successful runtime evidence receipt.\n- `blocked` — a genuine external condition or required user decision prevents progress.\n- `paused` — set the goal aside for now.\n\nDo not mark complete after a plan or partial result. If useful work remains, checkpoint it and continue. Do not ask for permission merely to execute an already authorized checkpoint; ask only at a real rights boundary or missing user decision.\n";
|
|
262875
|
-
update_goal_default += "\nBefore completing a goal with a criterion, bind the verified claim to the successful current-turn verification
|
|
262902
|
+
update_goal_default += "\nBefore completing a goal with a criterion, bind the verified claim to the exact successful current-turn verification call in `verificationProof`, including its `toolCallId`. A write, edit, copy, deploy, or other action is not proof that the changed behavior works, even when it shares a mixed-use tool such as `Bash` with tests. Use `subject: result` for a result, report, measurement, or download. Use `subject: verifier` only when the new or changed test, gate, harness, or detector itself is the completion subject; then bind `sharpnessProof` to a separate successful current-turn counterexample or mutation call. Do not require a red probe for a normal report or measurement.\n";
|
|
262876
262903
|
update_goal_default += "\nFor a non-trivial or unfamiliar problem, preserve `problemFrame` with the success criterion, missing knowledge, bounded candidate actions, selected action and reason, support choice, risk, and reversibility. The selected action must match one candidate. Bind each selected action to the projected durable facts or assumptions it relies on by copying their explicit refs into `decisionBasis`. A stale or unknown decision basis requires replanning before execution. Problem framing is descriptive state and never grants permission.\n";
|
|
262877
262904
|
}));
|
|
262878
262905
|
//#endregion
|