@linxin666/dsh-client-ui-task-board 0.4.5 → 0.4.6
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/README.i18n.yaml +2 -2
- package/README.md +20 -12
- package/README.zh.md +20 -12
- package/lib/client.js +1327 -229
- package/lib/client.js.map +1 -1
- package/lib/index.js +1909 -348
- package/lib/types/client/TaskBoardSettingsCard.d.ts +12 -0
- package/lib/types/client/index.d.ts +4 -5
- package/lib/types/client/locales.d.ts +65 -0
- package/lib/types/client/plugin-card-seat.d.ts +5 -0
- package/lib/types/client/schedule-zone.d.ts +50 -0
- package/lib/types/core/controller.d.ts +10 -11
- package/lib/types/core/poll-cadence.d.ts +31 -0
- package/lib/types/core/tasks.d.ts +144 -14
- package/lib/types/core/use-cases/task-schedule.d.ts +68 -10
- package/lib/types/core/verification-budget.d.ts +52 -0
- package/lib/types/core/verification.d.ts +376 -9
- package/lib/types/host/verification-gate.d.ts +24 -0
- package/lib/types/host/verification-runner.d.ts +38 -7
- package/lib/types/host-ledger.d.ts +82 -7
- package/lib/types/host-runner.d.ts +32 -9
- package/lib/types/host-service.d.ts +117 -9
- package/lib/types/index.d.ts +54 -0
- package/lib/types/protocol.d.ts +50 -12
- package/package.json +2 -6
- package/src/client/TaskBoardSettingsCard.tsx +74 -1
- package/src/client/board/NewTaskModal.tsx +151 -20
- package/src/client/board/TaskCard.tsx +3 -3
- package/src/client/board/TaskDetail.tsx +219 -18
- package/src/client/board/VerificationReport.tsx +132 -13
- package/src/client/board/status-key.ts +3 -0
- package/src/client/index.ts +43 -50
- package/src/client/locales.ts +137 -4
- package/src/client/plugin-card-seat.ts +7 -0
- package/src/client/schedule-zone.ts +100 -2
- package/src/core/controller.ts +12 -8
- package/src/core/poll-cadence.ts +41 -0
- package/src/core/store.ts +64 -15
- package/src/core/tasks.ts +193 -39
- package/src/core/use-cases/task-create.ts +30 -9
- package/src/core/use-cases/task-schedule.ts +190 -25
- package/src/core/use-cases/task-update.ts +3 -3
- package/src/core/verification-budget.ts +115 -0
- package/src/core/verification.ts +785 -17
- package/src/host/agent-tools.ts +106 -21
- package/src/host/verification-gate.ts +172 -16
- package/src/host/verification-runner.ts +207 -40
- package/src/host-ledger.ts +328 -42
- package/src/host-runner.ts +52 -19
- package/src/host-service.ts +299 -36
- package/src/index.ts +101 -5
- package/src/protocol.ts +132 -28
- package/lib/invariant.js +0 -6
- package/lib/types/client/board-card-seat.d.ts +0 -34
- package/lib/types/invariant.d.ts +0 -3
- package/src/client/board-card-seat.ts +0 -102
- package/src/invariant.ts +0 -4
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Judge calls one acceptance issues: every criterion, every round. */
|
|
2
|
+
export declare const ACCEPTANCE_JUDGE_CALLS: number;
|
|
3
|
+
/**
|
|
4
|
+
* Per-judge-call ceiling used when the row names none: two and a half minutes
|
|
5
|
+
* for a reasoning model reading an 80,000 character trace with a 16,384 token
|
|
6
|
+
* output cap. The former 120s constant was tight enough that a slow but healthy
|
|
7
|
+
* route produced a wall of per-call timeouts, and every one of them was charged
|
|
8
|
+
* as an acceptance anomaly against a budget that then failed the card.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_VERIFICATION_CALL_TIMEOUT_SECONDS = 150;
|
|
11
|
+
/** Shortest accepted per-call ceiling: below this no useful judge answers. */
|
|
12
|
+
export declare const VERIFICATION_CALL_TIMEOUT_MIN_SECONDS = 30;
|
|
13
|
+
/** Longest accepted per-call ceiling, ten minutes. */
|
|
14
|
+
export declare const VERIFICATION_CALL_TIMEOUT_MAX_SECONDS = 600;
|
|
15
|
+
/**
|
|
16
|
+
* Total ceiling of one acceptance attempt, covering evidence rendering and
|
|
17
|
+
* every judge call including retries. Derived from the per-call default rather
|
|
18
|
+
* than pinned, because a total budget smaller than
|
|
19
|
+
* {@link ACCEPTANCE_JUDGE_CALLS} times the per-call ceiling guarantees that no
|
|
20
|
+
* acceptance can ever finish.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DEFAULT_VERIFICATION_BUDGET_SECONDS: number;
|
|
23
|
+
/** Shortest accepted total budget: long enough for at least one judge call. */
|
|
24
|
+
export declare const VERIFICATION_BUDGET_MIN_SECONDS = 120;
|
|
25
|
+
/** Longest accepted total budget, thirty minutes. */
|
|
26
|
+
export declare const VERIFICATION_BUDGET_MAX_SECONDS = 1800;
|
|
27
|
+
/** The default total budget in milliseconds, the face the abort timer takes. */
|
|
28
|
+
export declare const DEFAULT_VERIFICATION_BUDGET_MS: number;
|
|
29
|
+
/**
|
|
30
|
+
* The effective per-judge-call ceiling.
|
|
31
|
+
* @param seconds - configured seconds, or undefined for the default.
|
|
32
|
+
* @returns the effective ceiling in seconds.
|
|
33
|
+
*/
|
|
34
|
+
export declare function normalizeVerificationCallTimeoutSeconds(seconds: number | undefined): number;
|
|
35
|
+
/**
|
|
36
|
+
* The effective per-judge-call ceiling the timer face takes.
|
|
37
|
+
* @param seconds - configured seconds, or undefined for the default.
|
|
38
|
+
* @returns the effective ceiling in milliseconds.
|
|
39
|
+
*/
|
|
40
|
+
export declare function verificationCallTimeoutMs(seconds: number | undefined): number;
|
|
41
|
+
/**
|
|
42
|
+
* The effective total budget of one acceptance attempt.
|
|
43
|
+
* @param seconds - configured seconds, or undefined for the default.
|
|
44
|
+
* @returns the effective budget in seconds.
|
|
45
|
+
*/
|
|
46
|
+
export declare function normalizeVerificationBudgetSeconds(seconds: number | undefined): number;
|
|
47
|
+
/**
|
|
48
|
+
* The effective total budget the abort face takes.
|
|
49
|
+
* @param seconds - configured seconds, or undefined for the default.
|
|
50
|
+
* @returns the effective budget in milliseconds.
|
|
51
|
+
*/
|
|
52
|
+
export declare function verificationBudgetMs(seconds: number | undefined): number;
|
|
@@ -37,10 +37,66 @@ export declare const MAX_QUALITY_ATTEMPTS = 2;
|
|
|
37
37
|
/**
|
|
38
38
|
* Anomaly budget of one cycle. A timeout, an authentication failure or an
|
|
39
39
|
* unparseable judge answer is not a quality verdict, so it never consumes a
|
|
40
|
-
* quality attempt
|
|
41
|
-
*
|
|
40
|
+
* quality attempt.
|
|
41
|
+
*
|
|
42
|
+
* Reaching it does NOT judge the card: an unusable judge route is a property of
|
|
43
|
+
* the environment, not of the work, so a card must never be failed for it. The
|
|
44
|
+
* gate instead HOLDS the cycle open and runs no further judge call until the
|
|
45
|
+
* recorded anomalies are cleared by an explicit user action (see
|
|
46
|
+
* {@link withoutAcceptanceAnomalies}), which is what keeps the bound: one cycle
|
|
47
|
+
* spends at most this many judge rounds, and clearing them is a human decision.
|
|
42
48
|
*/
|
|
43
49
|
export declare const MAX_EXCEPTION_ATTEMPTS = 2;
|
|
50
|
+
/**
|
|
51
|
+
* Retries of an INVALID acceptance: a quality veto whose required evidence is
|
|
52
|
+
* missing, unlocatable, or aimed at the empty-work baseline is not a judgement
|
|
53
|
+
* of the work, so it is recorded in its own stage and spent against this
|
|
54
|
+
* bound instead of the quality budget. Reaching it stops the judge calls and
|
|
55
|
+
* HOLDS the cycle for a human, exactly like a spent anomaly budget: an
|
|
56
|
+
* evidence-free veto must never fail a card, and it must never re-run forever.
|
|
57
|
+
*/
|
|
58
|
+
export declare const MAX_INVALID_ATTEMPTS = 2;
|
|
59
|
+
/**
|
|
60
|
+
* Capacity bound of the per-attempt acceptance detail — the repair/review
|
|
61
|
+
* material the acceptance mechanism itself creates. It is deliberately the
|
|
62
|
+
* ONLY large acceptance-only material this mechanism persists: findings are
|
|
63
|
+
* capped in count and rendered size, so nothing here needs an extra full
|
|
64
|
+
* evidence copy. It is removed by the automatic cleanup once the execution
|
|
65
|
+
* passed and settled (see {@link withAcceptanceDetailCleared}).
|
|
66
|
+
*/
|
|
67
|
+
export declare const VERIFICATION_DETAIL_MAX_FINDINGS = 12;
|
|
68
|
+
/** Longest verbatim citation kept from one judge finding. */
|
|
69
|
+
export declare const VERIFICATION_DETAIL_MAX_QUOTE_CHARS = 600;
|
|
70
|
+
/** Longest rendered detail kept for one attempt, across every finding. */
|
|
71
|
+
export declare const VERIFICATION_DETAIL_MAX_CHARS = 16000;
|
|
72
|
+
/**
|
|
73
|
+
* Shortest citation a veto may rest on. A one- or two-character quote matches
|
|
74
|
+
* almost any trace, so it cannot locate anything.
|
|
75
|
+
*/
|
|
76
|
+
export declare const VERIFICATION_MIN_QUOTE_CHARS = 12;
|
|
77
|
+
/** Shortest requirement/observation/gap text that states a real difference. */
|
|
78
|
+
export declare const VERIFICATION_MIN_PROBLEM_CHARS = 4;
|
|
79
|
+
/**
|
|
80
|
+
* Longest criterion identifier one persisted finding may name. An identifier,
|
|
81
|
+
* not prose: the reader rejects anything longer instead of clipping it, because
|
|
82
|
+
* a mangled id would silently detach the finding from the criterion it judges.
|
|
83
|
+
*/
|
|
84
|
+
export declare const VERIFICATION_DETAIL_MAX_CRITERION_ID_CHARS = 64;
|
|
85
|
+
/**
|
|
86
|
+
* Longest requirement / observation / gap / suggested-action text one finding
|
|
87
|
+
* keeps. Shared by the WRITER (which clips the judge's attributes to it) and the
|
|
88
|
+
* READER (which clips a hand-edited document back to it), so the acceptance
|
|
89
|
+
* detail has one capacity bound rather than two that can drift.
|
|
90
|
+
*/
|
|
91
|
+
export declare const VERIFICATION_DETAIL_MAX_PROBLEM_CHARS = 400;
|
|
92
|
+
/**
|
|
93
|
+
* Attempts one execution's acceptance cleanup may spend. Cleanup is started
|
|
94
|
+
* only after the pass record and the settlement are durable, is idempotent,
|
|
95
|
+
* and a failure never revokes the pass; the bound keeps a permanently failing
|
|
96
|
+
* filesystem from retrying forever, and the Host retries the remainder on its
|
|
97
|
+
* next start.
|
|
98
|
+
*/
|
|
99
|
+
export declare const MAX_CLEANUP_ATTEMPTS = 3;
|
|
44
100
|
/** The fixed baseline a session acceptance measures itself against. */
|
|
45
101
|
export declare const EMPTY_WORK_BASELINE = "(No useful work or verification was performed.)";
|
|
46
102
|
/** Ground-truth note prepended to every judge prompt. */
|
|
@@ -61,6 +117,18 @@ export interface VerificationCriterion {
|
|
|
61
117
|
export declare const CODING_CRITERIA: readonly VerificationCriterion[];
|
|
62
118
|
/** Rating scale text rendered into every judge prompt. */
|
|
63
119
|
export declare const SCALE_DESCRIPTION: string;
|
|
120
|
+
/**
|
|
121
|
+
* Which trajectory slot holds the WORK during one round.
|
|
122
|
+
*
|
|
123
|
+
* The even round (0) puts the work in slot A and the empty-work baseline in
|
|
124
|
+
* slot B; the odd round (1) swaps them, which is how the acceptance cancels
|
|
125
|
+
* position bias. The judge prompt ALWAYS introduces the work as
|
|
126
|
+
* `location="TRAJECTORY_B"`, because that is the slot the work occupies in the
|
|
127
|
+
* prompt's own framing; the parser maps the cited slot back through this table.
|
|
128
|
+
* @param round - the round index (0-based).
|
|
129
|
+
* @returns the slot letter the work occupies in that round.
|
|
130
|
+
*/
|
|
131
|
+
export declare function workSlotOfRound(round: number): 'A' | 'B';
|
|
64
132
|
/** A-T letters in scale order (A = best). */
|
|
65
133
|
export declare const LETTERS: readonly string[];
|
|
66
134
|
/**
|
|
@@ -119,7 +187,13 @@ export declare function evidenceNonce(...parts: readonly string[]): string;
|
|
|
119
187
|
* byte-identical for a deployment that serves no change service.
|
|
120
188
|
* @returns the rendered prompt.
|
|
121
189
|
*/
|
|
122
|
-
export declare function buildAcceptancePrompt(problem: string, traceA: string, traceB: string, criterion: VerificationCriterion, groundTruthNote?: string, context?: string
|
|
190
|
+
export declare function buildAcceptancePrompt(problem: string, traceA: string, traceB: string, criterion: VerificationCriterion, groundTruthNote?: string, context?: string,
|
|
191
|
+
/**
|
|
192
|
+
* The trajectory slot that holds the WORK this round. The judge is told the
|
|
193
|
+
* slot explicitly, so the citation it returns names the work whichever way
|
|
194
|
+
* the A/B slots were arranged. Defaults to A (round 0's arrangement).
|
|
195
|
+
*/
|
|
196
|
+
workSlot?: 'A' | 'B'): string;
|
|
123
197
|
/** Where the judge route of one execution came from. */
|
|
124
198
|
export type VerificationRouteSource = 'inherit' | 'explicit';
|
|
125
199
|
/** The resolved judge route of one execution's acceptance. */
|
|
@@ -222,13 +296,70 @@ export interface VerificationEvidenceSummary {
|
|
|
222
296
|
/** Files of host-observed workspace changes rendered into the prompt (0 = none). */
|
|
223
297
|
workspaceFiles?: number;
|
|
224
298
|
}
|
|
225
|
-
/**
|
|
299
|
+
/**
|
|
300
|
+
* One judge finding, structured against the requirement it vetoes.
|
|
301
|
+
*
|
|
302
|
+
* The acceptance only counts a criterion as vetoed when the judge names that
|
|
303
|
+
* criterion, states the requirement, the observation and the difference, and
|
|
304
|
+
* cites a passage that really occurs in THIS acceptance's evidence (the task
|
|
305
|
+
* text, the candidate's own trajectory, or the host's workspace record). A
|
|
306
|
+
* finding that names the empty-work baseline, another criterion, or a passage
|
|
307
|
+
* that is not in the reviewed evidence is dropped here, so it can never become
|
|
308
|
+
* the evidence for a veto.
|
|
309
|
+
*/
|
|
310
|
+
export interface VerificationCriterionFinding {
|
|
311
|
+
/** Criterion id this finding vetoes. */
|
|
312
|
+
criterionId: string;
|
|
313
|
+
/** The requirement the criterion demands of the work. */
|
|
314
|
+
requirement: string;
|
|
315
|
+
/** What was actually observed in the evidence. */
|
|
316
|
+
observation: string;
|
|
317
|
+
/** The difference: why that observation does not satisfy the requirement. */
|
|
318
|
+
gap: string;
|
|
319
|
+
/** Verbatim citation from the evidence; verified to occur in it. */
|
|
320
|
+
quote: string;
|
|
321
|
+
/**
|
|
322
|
+
* Which part of the reviewed evidence the citation was located in.
|
|
323
|
+
* `baseline` means the judge cited the empty-work baseline, which is never
|
|
324
|
+
* the work's own evidence and can never veto a criterion.
|
|
325
|
+
*/
|
|
326
|
+
location: 'task' | 'trajectory' | 'workspace' | 'baseline' | 'unknown';
|
|
327
|
+
/** Optional suggested action from the judge. */
|
|
328
|
+
action?: string;
|
|
329
|
+
}
|
|
330
|
+
/** Why an acceptance produced no valid quality verdict. */
|
|
331
|
+
export type VerificationInvalidReason =
|
|
332
|
+
/** The failing criteria have no structured finding of their own. */
|
|
333
|
+
'missing-finding'
|
|
334
|
+
/** A finding's citation does not occur in the evidence the judge saw. */
|
|
335
|
+
| 'unlocatable-quote'
|
|
336
|
+
/** A finding vetoes the empty-work baseline instead of the work. */
|
|
337
|
+
| 'baseline-finding'
|
|
338
|
+
/** A finding's text is empty or a generic evaluation. */
|
|
339
|
+
| 'vacuous-finding'
|
|
340
|
+
/** The judged evidence was truncated and cannot substantiate the veto. */
|
|
341
|
+
| 'insufficient-evidence';
|
|
342
|
+
/** One recorded acceptance attempt: a quality verdict, an anomaly, a budget stop, or an invalid veto. */
|
|
226
343
|
export interface VerificationAttempt {
|
|
227
344
|
/** 1-based ordinal within its own stage. */
|
|
228
345
|
index: number;
|
|
229
346
|
/** When the attempt ran (ms epoch). */
|
|
230
347
|
at: number;
|
|
231
|
-
|
|
348
|
+
/**
|
|
349
|
+
* `budget` records an acceptance the time budget ended before it could
|
|
350
|
+
* reach a verdict. It is neither a quality verdict nor an environment
|
|
351
|
+
* anomaly: the judge route may be perfectly healthy, the machine simply had
|
|
352
|
+
* no time left, so it is charged to no budget at all and cleared by the same
|
|
353
|
+
* explicit user action that clears anomalies.
|
|
354
|
+
*
|
|
355
|
+
* `invalid` records an acceptance that produced no usable quality verdict
|
|
356
|
+
* because the veto's required evidence was missing, unlocatable, or aimed at
|
|
357
|
+
* the empty-work baseline. It is neither a judgement of the work nor an
|
|
358
|
+
* environment anomaly: it consumes its own bounded retry budget, fails
|
|
359
|
+
* nothing, and is cleared by the same explicit user action that clears
|
|
360
|
+
* anomalies.
|
|
361
|
+
*/
|
|
362
|
+
stage: 'quality' | 'exception' | 'budget' | 'invalid';
|
|
232
363
|
/** Quality: whether the work passed. A recorded anomaly is never a pass. */
|
|
233
364
|
passed: boolean;
|
|
234
365
|
/** Total score of the task's own work (0 for an anomaly). */
|
|
@@ -246,6 +377,14 @@ export interface VerificationAttempt {
|
|
|
246
377
|
rounds: number;
|
|
247
378
|
/** Anomaly reason; absent on a quality verdict. */
|
|
248
379
|
error?: string;
|
|
380
|
+
/**
|
|
381
|
+
* Structured, locatable findings of a QUALITY attempt, keyed by criterion.
|
|
382
|
+
* A veto is only counted when the failing criterion appears here with a
|
|
383
|
+
* verified citation; otherwise the attempt is recorded as invalid instead.
|
|
384
|
+
*/
|
|
385
|
+
criterionFindings?: VerificationCriterionFinding[];
|
|
386
|
+
/** Why an invalid attempt carried no usable verdict; absent on other stages. */
|
|
387
|
+
invalidReason?: VerificationInvalidReason;
|
|
249
388
|
}
|
|
250
389
|
/** Persisted acceptance state of one execution. */
|
|
251
390
|
export interface ExecutionVerification {
|
|
@@ -259,19 +398,143 @@ export interface ExecutionVerification {
|
|
|
259
398
|
* out of the gate (`TaskRecord.skipVerification`), `goal-unavailable` when
|
|
260
399
|
* the run never became a goal run (so no completion gate could ever fire),
|
|
261
400
|
* and `team-member` for a teammate execution (the Lead's acceptance covers
|
|
262
|
-
* the team's aggregated evidence)
|
|
401
|
+
* the team's aggregated evidence), and `goal-disabled` when the GLOBAL
|
|
402
|
+
* native /goal switch was off at start, so this execution never became a
|
|
403
|
+
* goal run and its completion gate can never fire.
|
|
263
404
|
*/
|
|
264
|
-
applicability: 'enforced' | 'disabled' | 'skipped' | 'goal-unavailable' | 'team-member';
|
|
405
|
+
applicability: 'enforced' | 'disabled' | 'skipped' | 'goal-unavailable' | 'team-member' | 'goal-disabled';
|
|
265
406
|
/** Set when the cycle is spent and the execution must fail. */
|
|
266
407
|
failedReason?: string;
|
|
267
408
|
failedAt?: number;
|
|
409
|
+
/**
|
|
410
|
+
* Retention record of the acceptance-only detail this execution created.
|
|
411
|
+
*
|
|
412
|
+
* An execution that PASSED and settled has its bulky acceptance-only material
|
|
413
|
+
* (attempt findings, invalid diagnostics, judge metadata beyond the audit
|
|
414
|
+
* summary) removed automatically; this record is the lightweight audit trail
|
|
415
|
+
* that proves the cleanup happened and preserves the minimal credential
|
|
416
|
+
* (verdict, scores, time, model, evidence hash) the completion gate needs.
|
|
417
|
+
* Absent means nothing has been cleaned for this execution.
|
|
418
|
+
*/
|
|
419
|
+
cleanup?: AcceptanceCleanupRecord;
|
|
268
420
|
}
|
|
269
|
-
/**
|
|
270
|
-
export
|
|
421
|
+
/** Permanent, lightweight acceptance credential kept after a passed execution settles. */
|
|
422
|
+
export interface AcceptanceAuditRecord {
|
|
423
|
+
/** Stage of the attempt the credential describes. */
|
|
424
|
+
stage: VerificationAttempt['stage'];
|
|
425
|
+
/** Whether the attempt passed. */
|
|
426
|
+
passed: boolean;
|
|
427
|
+
/** When the attempt ran (ms epoch). */
|
|
428
|
+
at: number;
|
|
429
|
+
/** Total score of the task's own work. */
|
|
430
|
+
score: number;
|
|
431
|
+
/** Empty-work baseline score. */
|
|
432
|
+
baseline: number;
|
|
433
|
+
/** Per-criterion scores and thresholds. */
|
|
434
|
+
criteria: VerificationCriterionScore[];
|
|
435
|
+
/** Digest of the judged evidence; binds the pass record to what was reviewed. */
|
|
436
|
+
evidenceHash: string;
|
|
437
|
+
/** Judge route of the attempt. */
|
|
438
|
+
route: VerificationRoute;
|
|
439
|
+
/** Anomaly or invalid reason, when the attempt carried one. */
|
|
440
|
+
error?: string;
|
|
441
|
+
/** One-line problem summary kept for the audit trail. */
|
|
442
|
+
findingSummary?: string;
|
|
443
|
+
/** Token accounting of the attempt. */
|
|
444
|
+
usage: VerificationUsage;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* State of the automatic acceptance-detail cleanup of one execution.
|
|
448
|
+
*
|
|
449
|
+
* `state` is `pending` until the cleanup actually removed the detail (or found
|
|
450
|
+
* nothing left to remove); `failed` records the last failure so a Host restart
|
|
451
|
+
* can retry it. The pass record and the settlement are durable before a cleanup
|
|
452
|
+
* starts, so a failure here never revokes a valid pass.
|
|
453
|
+
*/
|
|
454
|
+
export interface AcceptanceCleanupRecord {
|
|
455
|
+
state: 'pending' | 'cleaned' | 'failed';
|
|
456
|
+
/** Attempts spent; bounded by {@link MAX_CLEANUP_ATTEMPTS}. */
|
|
457
|
+
attempts: number;
|
|
458
|
+
/** When the cleanup first ran (ms epoch). */
|
|
459
|
+
startedAt: number;
|
|
460
|
+
/** When the detail was actually removed (ms epoch); absent while pending. */
|
|
461
|
+
cleanedAt?: number;
|
|
462
|
+
/** Why the last attempt failed; absent when none did. */
|
|
463
|
+
lastError?: string;
|
|
464
|
+
/** Minimal credential kept for every attempt this execution recorded. */
|
|
465
|
+
audit: AcceptanceAuditRecord[];
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* UI/board phase of one execution's acceptance.
|
|
469
|
+
*
|
|
470
|
+
* `invalid` is its own phase, not a variant of `failed`: the cycle spent its
|
|
471
|
+
* invalid-acceptance budget without a usable veto, so the judge is no longer
|
|
472
|
+
* called and a human decision is required. A reader must never read it as a
|
|
473
|
+
* quality rejection.
|
|
474
|
+
*/
|
|
475
|
+
export type VerificationPhase = 'off' | 'executing' | 'verifying' | 'repairing' | 'passed' | 'failed' | 'invalid';
|
|
271
476
|
/** Quality attempts spent by this cycle. */
|
|
272
477
|
export declare function qualityAttempts(verification: ExecutionVerification | undefined): VerificationAttempt[];
|
|
273
478
|
/** Anomaly attempts spent by this cycle. */
|
|
274
479
|
export declare function exceptionAttempts(verification: ExecutionVerification | undefined): VerificationAttempt[];
|
|
480
|
+
/**
|
|
481
|
+
* Attempts the time budget ended before a verdict, charged to no budget. They
|
|
482
|
+
* are kept so the report can say WHY an acceptance produced nothing, and they
|
|
483
|
+
* are cleared by the same explicit user action that clears anomalies.
|
|
484
|
+
*/
|
|
485
|
+
export declare function budgetAttempts(verification: ExecutionVerification | undefined): VerificationAttempt[];
|
|
486
|
+
/**
|
|
487
|
+
* Invalid acceptances spent by this cycle: a veto whose required evidence was
|
|
488
|
+
* missing, unlocatable, or aimed at the empty-work baseline. They are NOT
|
|
489
|
+
* quality verdicts, so they never close the cycle and never fail the card; the
|
|
490
|
+
* bound is what keeps an evidence-free judge from re-running forever.
|
|
491
|
+
*/
|
|
492
|
+
export declare function invalidAttempts(verification: ExecutionVerification | undefined): VerificationAttempt[];
|
|
493
|
+
/** Whether this cycle still has invalid-acceptance budget left. */
|
|
494
|
+
export declare function hasInvalidBudget(verification: ExecutionVerification | undefined): boolean;
|
|
495
|
+
/**
|
|
496
|
+
* The acceptance block with every non-quality attempt dropped: the explicit
|
|
497
|
+
* reset a user performs after fixing the environment (issue #1828).
|
|
498
|
+
*
|
|
499
|
+
* Only attempts that are not a quality verdict are dropped. A quality verdict
|
|
500
|
+
* is the board's own judgement of the work and survives every reset, so this
|
|
501
|
+
* can never buy an extra acceptance or re-open a judged failure; it only lets
|
|
502
|
+
* the environment be judged again.
|
|
503
|
+
* @param verification - the persisted acceptance state.
|
|
504
|
+
* @returns the cleared block, or undefined when there is nothing to clear.
|
|
505
|
+
*/
|
|
506
|
+
export declare function withoutAcceptanceAnomalies(verification: ExecutionVerification): ExecutionVerification | undefined;
|
|
507
|
+
/**
|
|
508
|
+
* The one-line problem summary a cleaned execution keeps: the failing criteria
|
|
509
|
+
* with their scores, plus how many locatable findings were removed. This is the
|
|
510
|
+
* lightweight audit material that survives the detail cleanup.
|
|
511
|
+
* @param attempt - the attempt whose detail is being removed.
|
|
512
|
+
* @returns the bounded summary line.
|
|
513
|
+
*/
|
|
514
|
+
export declare function findingSummaryOf(attempt: VerificationAttempt): string | undefined;
|
|
515
|
+
/**
|
|
516
|
+
* The audit credential of one attempt: everything the completion gate, the
|
|
517
|
+
* report and a later review need, and nothing that makes the ledger heavy.
|
|
518
|
+
* @param attempt - the attempt being condensed.
|
|
519
|
+
* @returns the lightweight audit record.
|
|
520
|
+
*/
|
|
521
|
+
export declare function auditOf(attempt: VerificationAttempt): AcceptanceAuditRecord;
|
|
522
|
+
/**
|
|
523
|
+
* Remove this execution's OWN acceptance-only detail while keeping the light
|
|
524
|
+
* audit record — the acceptance mechanism's side of requirement 2.
|
|
525
|
+
*
|
|
526
|
+
* Only material the acceptance mechanism itself created is removed: the
|
|
527
|
+
* per-attempt findings, the invalid diagnostics and the token/evidence detail
|
|
528
|
+
* beyond the summary. Everything a human needs to see the verdict survives
|
|
529
|
+
* (stage, pass flag, time, scores, evidence hash, judge route, usage totals),
|
|
530
|
+
* so the completion gate's pass record and a later review are unaffected, and
|
|
531
|
+
* NO user file, task artifact, raw session history or other execution's record
|
|
532
|
+
* is ever touched by this function.
|
|
533
|
+
* @param verification - the execution's acceptance block.
|
|
534
|
+
* @param now - cleanup instant (ms epoch).
|
|
535
|
+
* @returns the cleaned block, or undefined when there is nothing to remove.
|
|
536
|
+
*/
|
|
537
|
+
export declare function withAcceptanceDetailCleared(verification: ExecutionVerification, now: number): ExecutionVerification | undefined;
|
|
275
538
|
/** The quality attempt that passed, when one did. */
|
|
276
539
|
export declare function passedAttempt(verification: ExecutionVerification | undefined): VerificationAttempt | undefined;
|
|
277
540
|
/**
|
|
@@ -284,12 +547,78 @@ export declare function passedAttempt(verification: ExecutionVerification | unde
|
|
|
284
547
|
* @returns true when a pass record is required.
|
|
285
548
|
*/
|
|
286
549
|
export declare function verificationRequired(verification: ExecutionVerification | undefined): boolean;
|
|
550
|
+
/**
|
|
551
|
+
* Whether this execution's acceptance gate was never opened: acceptance was
|
|
552
|
+
* enforced, the judge recorded nothing at all, and no cycle ever closed. Zero
|
|
553
|
+
* attempts is therefore a fact about the RUN, not a verdict about the work — a
|
|
554
|
+
* session that narrated completion instead of calling
|
|
555
|
+
* `update_goal(action: complete)` produces exactly this shape, and its failure
|
|
556
|
+
* reason must stay distinguishable from a quality verdict (issue #1837).
|
|
557
|
+
* @param verification - the execution's persisted acceptance state.
|
|
558
|
+
* @returns true when no acceptance attempt ever ran.
|
|
559
|
+
*/
|
|
560
|
+
export declare function verificationNeverInvoked(verification: ExecutionVerification | undefined): boolean;
|
|
561
|
+
/**
|
|
562
|
+
* Whether this execution's acceptance produced no usable veto at all: it was
|
|
563
|
+
* enforced, the judge recorded attempts, and every one of them is INVALID.
|
|
564
|
+
*
|
|
565
|
+
* Such a run must never be described as an evidence-backed quality veto (issue
|
|
566
|
+
* #1837's sibling): the judge could not locate its own rejection, so the run
|
|
567
|
+
* ended for lack of a matching pass rather than because the work was judged
|
|
568
|
+
* and rejected. The settlement reason names that difference.
|
|
569
|
+
* @param verification - the execution's persisted acceptance state.
|
|
570
|
+
* @returns true when nothing but invalid acceptances were recorded.
|
|
571
|
+
*/
|
|
572
|
+
export declare function verificationOnlyInvalid(verification: ExecutionVerification | undefined): boolean;
|
|
287
573
|
/** Whether this cycle still has quality budget left. */
|
|
288
574
|
export declare function hasQualityBudget(verification: ExecutionVerification | undefined): boolean;
|
|
289
575
|
/** Whether this cycle still has anomaly budget left. */
|
|
290
576
|
export declare function hasExceptionBudget(verification: ExecutionVerification | undefined): boolean;
|
|
291
577
|
/** Derived board phase of one execution's acceptance. */
|
|
292
578
|
export declare function verificationPhase(verification: ExecutionVerification | undefined): VerificationPhase;
|
|
579
|
+
/** The text of each evidence part one acceptance handed to the judge. */
|
|
580
|
+
export interface AcceptanceEvidenceText {
|
|
581
|
+
/** The task statement block. */
|
|
582
|
+
task: string;
|
|
583
|
+
/** The candidate's own trajectory block (the WORK). */
|
|
584
|
+
trajectory: string;
|
|
585
|
+
/** The host's rendered workspace-change block; empty when none was served. */
|
|
586
|
+
workspace: string;
|
|
587
|
+
}
|
|
588
|
+
/** The input the program-level validity check reads from one finished attempt. */
|
|
589
|
+
export interface AcceptanceValidityInput {
|
|
590
|
+
/** Per-criterion scores the attempt recorded. */
|
|
591
|
+
criteria: readonly VerificationCriterionScore[];
|
|
592
|
+
/** Structured findings the judge's answer produced. */
|
|
593
|
+
findings: readonly VerificationCriterionFinding[];
|
|
594
|
+
/** The exact evidence texts the judge was shown. */
|
|
595
|
+
evidence: AcceptanceEvidenceText;
|
|
596
|
+
/** Characters the evidence cap dropped from the trajectory. */
|
|
597
|
+
omittedCharacters: number;
|
|
598
|
+
}
|
|
599
|
+
/** The verdict of the program-level validity check. */
|
|
600
|
+
export type AcceptanceValidity = {
|
|
601
|
+
valid: true;
|
|
602
|
+
} | {
|
|
603
|
+
valid: false;
|
|
604
|
+
reason: VerificationInvalidReason;
|
|
605
|
+
detail: string;
|
|
606
|
+
};
|
|
607
|
+
/**
|
|
608
|
+
* Program-level validity of a REJECTING acceptance, decided before any quality
|
|
609
|
+
* verdict is booked (requirement 1: the rule cannot live in a prompt alone).
|
|
610
|
+
*
|
|
611
|
+
* A veto is only usable when every criterion that failed has its own structured
|
|
612
|
+
* finding carrying the requirement, the observation, the difference and a
|
|
613
|
+
* citation that really occurs in the evidence the judge saw. A citation aimed at
|
|
614
|
+
* the empty-work baseline, a citation that is not in the reviewed evidence, an
|
|
615
|
+
* empty or generic statement, and a truncated review that cannot substantiate
|
|
616
|
+
* the veto are all invalid acceptances: no quality verdict, no quality budget,
|
|
617
|
+
* and no card failure.
|
|
618
|
+
* @param input - the attempt's scores, findings and the evidence it judged.
|
|
619
|
+
* @returns valid, or the reason and detail of the invalidity.
|
|
620
|
+
*/
|
|
621
|
+
export declare function assessAcceptanceValidity(input: AcceptanceValidityInput): AcceptanceValidity;
|
|
293
622
|
/**
|
|
294
623
|
* The acceptance rule, mirrored from the verifier's `sessionAccepted`:
|
|
295
624
|
* the work must BEAT the empty-work baseline, reach the total threshold, and
|
|
@@ -320,6 +649,8 @@ export declare function normalizeVerification(value: unknown): ExecutionVerifica
|
|
|
320
649
|
export interface VerificationTotals {
|
|
321
650
|
quality: number;
|
|
322
651
|
exceptions: number;
|
|
652
|
+
/** Invalid acceptances: no usable veto, so no quality verdict and no card failure. */
|
|
653
|
+
invalid: number;
|
|
323
654
|
calls: number;
|
|
324
655
|
inputTokens: number;
|
|
325
656
|
outputTokens: number;
|
|
@@ -338,6 +669,32 @@ export declare function verificationTotals(verification: ExecutionVerification |
|
|
|
338
669
|
* @returns the model-facing feedback text.
|
|
339
670
|
*/
|
|
340
671
|
export declare function qualityFeedback(attempt: VerificationAttempt, remaining: number): string;
|
|
672
|
+
/**
|
|
673
|
+
* The feedback one INVALID acceptance returns.
|
|
674
|
+
*
|
|
675
|
+
* The claim is refused (the board still has no pass record, so completion may
|
|
676
|
+
* not take effect) but the agent is NOT handed a repair instruction: there is
|
|
677
|
+
* no located problem to repair, and telling it to "fix" an evidence-free veto
|
|
678
|
+
* would be exactly the blind repair the requirement forbids. The text says what
|
|
679
|
+
* was missing, what happens next, and what the agent should do instead (make
|
|
680
|
+
* the missing output itself observable, or let a human look).
|
|
681
|
+
* @param attempt - the invalid attempt.
|
|
682
|
+
* @param remaining - invalid-acceptance attempts left after this one.
|
|
683
|
+
* @returns the model-facing text.
|
|
684
|
+
*/
|
|
685
|
+
export declare function invalidAcceptanceFeedback(attempt: VerificationAttempt, remaining: number): string;
|
|
686
|
+
/**
|
|
687
|
+
* The reason one execution records when its invalid-acceptance budget is spent.
|
|
688
|
+
*
|
|
689
|
+
* Deliberately NOT a quality failure: no veto was ever substantiated, so the
|
|
690
|
+
* card stays open for a human and the reason says the acceptance is INVALID
|
|
691
|
+
* rather than rejected.
|
|
692
|
+
* @param used - invalid attempts spent.
|
|
693
|
+
* @returns the user- and model-facing text.
|
|
694
|
+
*/
|
|
695
|
+
export declare function invalidHoldReason(used: number): string;
|
|
696
|
+
/** Human-readable text of one invalid reason. */
|
|
697
|
+
export declare function invalidReasonText(reason: VerificationInvalidReason | undefined): string;
|
|
341
698
|
/**
|
|
342
699
|
* The reason one exhausted acceptance cycle records as the execution's final
|
|
343
700
|
* failure. Unlike {@link qualityFeedback} — which the fixing agent reads while
|
|
@@ -352,6 +709,16 @@ export declare function qualityFeedback(attempt: VerificationAttempt, remaining:
|
|
|
352
709
|
* @returns the model- and user-facing failure reason.
|
|
353
710
|
*/
|
|
354
711
|
export declare function finalFailureReason(attempt: VerificationAttempt, used: number, threshold: number): string;
|
|
712
|
+
/**
|
|
713
|
+
* The locatable problem lines of one attempt, structured findings first.
|
|
714
|
+
*
|
|
715
|
+
* A structured finding renders the requirement, the observed fact, the gap and
|
|
716
|
+
* the citation in a fixed order, so the fixing agent reads WHAT was required,
|
|
717
|
+
* WHAT was seen, WHY it falls short and WHERE to look — never a bare complaint.
|
|
718
|
+
* @param attempt - the attempt whose findings are rendered.
|
|
719
|
+
* @returns one line per finding, bounded.
|
|
720
|
+
*/
|
|
721
|
+
export declare function locatedFindingLines(attempt: VerificationAttempt): string[];
|
|
355
722
|
/** `0.42` style percentage. */
|
|
356
723
|
export declare function percent(value: number): string;
|
|
357
724
|
/** Split a qualified `provider/model` route; undefined when it is not one. */
|
|
@@ -18,7 +18,21 @@
|
|
|
18
18
|
* - an anomaly (timeout, authentication, unparseable answer, an unusable judge
|
|
19
19
|
* route) is recorded separately from a quality verdict and is never treated
|
|
20
20
|
* as one;
|
|
21
|
+
* - exhausting the anomaly budget does NOT judge the card: an environment that
|
|
22
|
+
* cannot answer is not the work failing, so the cycle is held open with no
|
|
23
|
+
* judge call until a user clears the recorded anomalies (issue #1828);
|
|
24
|
+
* - an attempt the time budget ends before any verdict is recorded as its own
|
|
25
|
+
* stage and charged to no budget at all (issue #1828);
|
|
26
|
+
* - an INVALID acceptance (a veto whose required evidence is missing,
|
|
27
|
+
* unlocatable, or aimed at the empty-work baseline) is recorded in its own
|
|
28
|
+
* stage, spends its OWN bounded budget, and never consumes a quality attempt
|
|
29
|
+
* or fails the card; when that budget is spent the cycle is held for a human
|
|
30
|
+
* exactly like a spent anomaly budget;
|
|
21
31
|
* - concurrent completion calls for one execution share one acceptance.
|
|
32
|
+
|
|
33
|
+
* The validity check itself is program-level (`assessAcceptanceValidity` in
|
|
34
|
+
* `core/verification.ts`), applied after the judge answers and BEFORE any
|
|
35
|
+
* quality verdict is written: a stronger prompt alone could not enforce it.
|
|
22
36
|
*/
|
|
23
37
|
import type { PreToolDecision } from '@deepseek-ai/dsh-tools';
|
|
24
38
|
import type { LlmRuntime } from '@deepseek-ai/dsh-llm';
|
|
@@ -51,6 +65,16 @@ export interface GoalVerificationGateDeps {
|
|
|
51
65
|
* that serves none) simply means the judge sees the trajectory alone.
|
|
52
66
|
*/
|
|
53
67
|
workspaceChanges?: () => WorkspaceChangeSource | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Ceiling of one judge request, read per acceptance (a row setting). Absent
|
|
70
|
+
* keeps the default, so a programmatic mount still judges.
|
|
71
|
+
*/
|
|
72
|
+
callTimeoutMs?: () => number;
|
|
73
|
+
/**
|
|
74
|
+
* Total ceiling of one acceptance attempt, read per acceptance (a row
|
|
75
|
+
* setting). Absent keeps the default.
|
|
76
|
+
*/
|
|
77
|
+
budgetMs?: () => number;
|
|
54
78
|
logger: {
|
|
55
79
|
warn(message: string, ...rest: unknown[]): void;
|
|
56
80
|
};
|
|
@@ -15,18 +15,45 @@ export declare const VERIFICATION_MAX_TRACE_CHARS = 80000;
|
|
|
15
15
|
export declare const VERIFICATION_MAX_ENTRY_CHARS = 4000;
|
|
16
16
|
/** Largest per-finding text kept from one judge answer. */
|
|
17
17
|
export declare const VERIFICATION_MAX_FINDING_CHARS = 400;
|
|
18
|
-
/**
|
|
18
|
+
/** Largest verbatim citation kept from one finding. */
|
|
19
|
+
export declare const VERIFICATION_MAX_QUOTE_CHARS = 600;
|
|
20
|
+
/** Largest requirement/observation/gap statement kept from one finding. */
|
|
21
|
+
export declare const VERIFICATION_MAX_PROBLEM_CHARS = 400;
|
|
22
|
+
/** Structured findings kept per judge answer and per acceptance. */
|
|
19
23
|
export declare const VERIFICATION_MAX_FINDINGS_PER_CALL = 3;
|
|
20
|
-
export declare const VERIFICATION_MAX_FINDINGS =
|
|
21
|
-
/**
|
|
22
|
-
|
|
24
|
+
export declare const VERIFICATION_MAX_FINDINGS = 12;
|
|
25
|
+
/**
|
|
26
|
+
* Default ceiling of ONE judge request. The effective ceiling is a row setting
|
|
27
|
+
* (`goalVerificationCallTimeoutSeconds`), read live by the gate, because 120s was
|
|
28
|
+
* tight for a reasoning model reading an 80,000 character trace with a 16,384
|
|
29
|
+
* token output cap: every timeout it produced was charged as an acceptance
|
|
30
|
+
* anomaly against a budget that then failed the card.
|
|
31
|
+
*/
|
|
32
|
+
export declare const VERIFICATION_CALL_TIMEOUT_MS = 150000;
|
|
23
33
|
export declare const VERIFICATION_MAX_TOKENS = 16384;
|
|
24
34
|
export declare const VERIFICATION_TEMPERATURE = 0.2;
|
|
25
35
|
export declare const VERIFICATION_REQUEST_ATTEMPTS = 3;
|
|
26
36
|
/** Redaction patterns, mirrored from the verifier's defaults. */
|
|
27
37
|
export declare const VERIFICATION_REDACT_PATTERNS: readonly string[];
|
|
28
38
|
/** Why one acceptance could not produce a verdict. */
|
|
29
|
-
export type VerificationErrorKind = 'route-unavailable' | 'timeout' | 'auth' | 'parse' | 'request' | 'aborted';
|
|
39
|
+
export type VerificationErrorKind = 'route-unavailable' | 'timeout' | 'auth' | 'parse' | 'request' | 'aborted' | 'budget';
|
|
40
|
+
/**
|
|
41
|
+
* The time one acceptance attempt may still spend.
|
|
42
|
+
*
|
|
43
|
+
* `deadline` is the instant the whole attempt runs out; `callTimeoutMs` is the
|
|
44
|
+
* ceiling of a single judge call. The pair is what ties the retry budget to the
|
|
45
|
+
* acceptance budget: a call is not started unless its own ceiling still fits
|
|
46
|
+
* inside what is left, because starting one the outer budget will abort anyway
|
|
47
|
+
* only burns wall time and turns a slow machine into an anomaly.
|
|
48
|
+
*/
|
|
49
|
+
export interface AcceptanceBudget {
|
|
50
|
+
/** Absolute instant (ms epoch) the acceptance attempt runs out at. */
|
|
51
|
+
deadline: number;
|
|
52
|
+
/** Ceiling of one judge call in milliseconds. */
|
|
53
|
+
callTimeoutMs: number;
|
|
54
|
+
/** Clock the caller runs on, injected so tests drive it deterministically. */
|
|
55
|
+
now: () => number;
|
|
56
|
+
}
|
|
30
57
|
/** An acceptance anomaly: never a quality verdict, always recorded as one. */
|
|
31
58
|
export declare class VerificationError extends Error {
|
|
32
59
|
readonly kind: VerificationErrorKind;
|
|
@@ -89,8 +116,8 @@ export interface AcceptanceResult {
|
|
|
89
116
|
* Run one acceptance: every criterion is judged twice, the odd round with the
|
|
90
117
|
* A/B slots swapped, and the per-round scores are mapped back and averaged per
|
|
91
118
|
* criterion.
|
|
92
|
-
* @param input - the judge route, evidence, threshold and cancellation.
|
|
93
|
-
* @returns the recorded attempt (quality verdict or
|
|
119
|
+
* @param input - the judge route, evidence, threshold, time budget and cancellation.
|
|
120
|
+
* @returns the recorded attempt (quality verdict, anomaly, or budget stop).
|
|
94
121
|
*/
|
|
95
122
|
export declare function runAcceptance(input: {
|
|
96
123
|
llm: LlmRuntime;
|
|
@@ -99,6 +126,10 @@ export declare function runAcceptance(input: {
|
|
|
99
126
|
threshold: number;
|
|
100
127
|
index: number;
|
|
101
128
|
signal: AbortSignal;
|
|
129
|
+
/** Instant (ms epoch) the attempt runs out at; defaults to now plus the default budget. */
|
|
130
|
+
deadline?: number;
|
|
131
|
+
/** Ceiling of one judge call; defaults to {@link VERIFICATION_CALL_TIMEOUT_MS}. */
|
|
132
|
+
callTimeoutMs?: number;
|
|
102
133
|
/** Host-observed workspace changes, rendered as the prompt's reference context. */
|
|
103
134
|
context?: string;
|
|
104
135
|
/** How many changed files that context shows. */
|