@sema-agent/core 7.16.0 → 7.17.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/CHANGELOG.md +173 -0
- package/dist/agents/builtin-agents.d.ts +3 -3
- package/dist/agents/cross-session-envelope.d.ts +0 -1
- package/dist/agents/cross-session-envelope.js +0 -1
- package/dist/agents/peer-notices.d.ts +0 -9
- package/dist/agents/peer-notices.js +0 -63
- package/dist/agents/subagent.js +7 -15
- package/dist/brain/request-params.d.ts +2 -2
- package/dist/config/defaults.d.ts +0 -7
- package/dist/config/defaults.js +0 -2
- package/dist/core/artifact-host.d.ts +218 -0
- package/dist/core/artifact-host.js +92 -0
- package/dist/core/ask-origin.d.ts +29 -3
- package/dist/core/ask-origin.js +17 -9
- package/dist/core/ask-question.d.ts +25 -0
- package/dist/core/ask-question.js +4 -0
- package/dist/core/ask-unresolvable-notice.d.ts +30 -21
- package/dist/core/ask-unresolvable-notice.js +16 -8
- package/dist/core/auto-compaction.d.ts +10 -10
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/background-agent-store.d.ts +5 -5
- package/dist/core/background-shell.d.ts +1 -1
- package/dist/core/checkpoint-execution-record.d.ts +0 -3
- package/dist/core/checkpoint-execution-record.js +0 -4
- package/dist/core/checkpoint-store.d.ts +71 -99
- package/dist/core/checkpoint-store.js +9 -16
- package/dist/core/context-edit.d.ts +36 -104
- package/dist/core/context-edit.js +37 -60
- package/dist/core/effective-path-target.d.ts +68 -8
- package/dist/core/effective-path-target.js +42 -30
- package/dist/core/engine-notice.d.ts +46 -32
- package/dist/core/env-budget.d.ts +31 -0
- package/dist/core/env-budget.js +39 -0
- package/dist/core/exec-output-tail.d.ts +5 -5
- package/dist/core/file-history-store.js +3 -6
- package/dist/core/fs-write-gate-policy.d.ts +1 -1
- package/dist/core/fs-write-gate-policy.js +3 -3
- package/dist/core/gate-lanes.js +9 -15
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +18 -17
- package/dist/core/lsp-session.d.ts +1 -1
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/lsp.js +5 -4
- package/dist/core/mcp.d.ts +5 -5
- package/dist/core/mcp.js +4 -48
- package/dist/core/memory-recall.d.ts +0 -8
- package/dist/core/memory.d.ts +1 -1
- package/dist/core/oracle-isolation.js +2 -2
- package/dist/core/parent-spec-seat.d.ts +66 -0
- package/dist/core/parent-spec-seat.js +47 -0
- package/dist/core/permission-rule-model.d.ts +11 -6
- package/dist/core/permission-rule-model.js +53 -37
- package/dist/core/permission-rules.js +8 -3
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/remote-env.d.ts +1 -1
- package/dist/core/retired-keys.d.ts +19 -0
- package/dist/core/retired-keys.js +15 -0
- package/dist/core/runner/active-skill-scope.js +3 -3
- package/dist/core/runner/assemble-result.d.ts +15 -13
- package/dist/core/runner/assemble-result.js +5 -4
- package/dist/core/runner/compaction-call-options.d.ts +25 -89
- package/dist/core/runner/contracts.d.ts +10 -9
- package/dist/core/runner/gate-exit.js +15 -1
- package/dist/core/runner/halt-attribution.d.ts +35 -0
- package/dist/core/runner/halt-attribution.js +16 -0
- package/dist/core/runner/memory-consolidation.d.ts +0 -2
- package/dist/core/runner/memory-consolidation.js +0 -1
- package/dist/core/runner/prepare-artifact.d.ts +53 -0
- package/dist/core/runner/prepare-artifact.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
- package/dist/core/runner/prepare-caps-and-workflow.js +2 -3
- package/dist/core/runner/prepare-config-doors.d.ts +3 -3
- package/dist/core/runner/prepare-config-doors.js +5 -2
- package/dist/core/runner/prepare-context-lane.d.ts +2 -2
- package/dist/core/runner/prepare-context-lane.js +2 -13
- package/dist/core/runner/prepare-file-history.d.ts +1 -1
- package/dist/core/runner/prepare-file-history.js +3 -52
- package/dist/core/runner/prepare-hands-readface.d.ts +4 -7
- package/dist/core/runner/prepare-hands-readface.js +3 -2
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -2
- package/dist/core/runner/prepare-inherited-gate.js +7 -8
- package/dist/core/runner/prepare-memory.d.ts +4 -6
- package/dist/core/runner/prepare-memory.js +4 -2
- package/dist/core/runner/prepare-policy-chain.d.ts +3 -3
- package/dist/core/runner/prepare-policy-chain.js +15 -30
- package/dist/core/runner/prepare-prompt-assembly.js +1 -1
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-suspend-saga.js +0 -2
- package/dist/core/runner/prepare-task.js +10 -9
- package/dist/core/runner/prepare-wiring-manifest.js +9 -7
- package/dist/core/runner/resume-admission.js +2 -1
- package/dist/core/runner/resume-internals-and-config.js +4 -0
- package/dist/core/runner/retired-runner-deps.d.ts +3 -0
- package/dist/core/runner/retired-runner-deps.js +7 -0
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-settle-and-teardown.d.ts +1 -1
- package/dist/core/runner/run-settle-and-teardown.js +3 -1
- package/dist/core/runner/session-file-state-replay.js +3 -3
- package/dist/core/runner/session-rule-policy.js +3 -4
- package/dist/core/runner/stream-halt-verbs.js +1 -1
- package/dist/core/runner/stream-steer-verb.js +1 -4
- package/dist/core/runner/workspace-path.js +3 -0
- package/dist/core/runner-deps.d.ts +30 -49
- package/dist/core/safe-notify.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +4 -4
- package/dist/core/session.d.ts +2 -2
- package/dist/core/skill-tool-specifier.d.ts +1 -1
- package/dist/core/skills-directory.d.ts +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
- package/dist/core/strategy-store.d.ts +8 -11
- package/dist/core/task-event.d.ts +20 -17
- package/dist/core/task-limits.d.ts +1 -1
- package/dist/core/task-notification.d.ts +5 -5
- package/dist/core/task-registry-agent.d.ts +5 -5
- package/dist/core/task-registry-monitor.d.ts +2 -2
- package/dist/core/task-registry-shared.d.ts +27 -27
- package/dist/core/task-registry-shared.js +3 -13
- package/dist/core/task-registry.d.ts +8 -8
- package/dist/core/task-result.d.ts +37 -37
- package/dist/core/task-spec.d.ts +5 -5
- package/dist/core/task-stream.d.ts +16 -11
- package/dist/core/tool-catalog-entries.d.ts +1 -0
- package/dist/core/tool-catalog-entries.js +5 -0
- package/dist/core/tool-conformance.d.ts +0 -2
- package/dist/core/tool-conformance.js +1 -3
- package/dist/core/tool-errors.d.ts +5 -0
- package/dist/core/tool-errors.js +1 -0
- package/dist/core/tool-policy.d.ts +51 -22
- package/dist/core/tool-policy.js +28 -5
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +11 -11
- package/dist/core/tool-spec.d.ts +34 -38
- package/dist/core/tools.d.ts +2 -2
- package/dist/core/trace.d.ts +12 -15
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +4 -3
- package/dist/core/workflow-journal-store.d.ts +11 -11
- package/dist/engine/execution-env/node-execution-env.d.ts +3 -2
- package/dist/engine/execution-env/node-execution-env.js +4 -2
- package/dist/engine/harness/agent-harness.d.ts +47 -4
- package/dist/engine/harness/agent-harness.js +52 -9
- package/dist/engine/loop/agent-loop.js +15 -8
- package/dist/engine/loop/types.d.ts +5 -0
- package/dist/index.d.ts +19 -14
- package/dist/index.js +15 -10
- package/dist/internal/harness.d.ts +1 -0
- package/dist/orchestration/run-spec.d.ts +3 -0
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +12 -6
- package/dist/orchestration/run-workflow-tool.js +23 -5
- package/dist/orchestration/workflow-primitives.d.ts +4 -2
- package/dist/orchestration/workflow-primitives.js +1 -4
- package/dist/orchestration/workflow-types.d.ts +34 -4
- package/dist/orchestration/workflow-types.js +2 -0
- package/dist/orchestration/workflow.d.ts +39 -7
- package/dist/orchestration/workflow.js +234 -113
- package/dist/prompt-assembly/assemble.d.ts +2 -2
- package/dist/prompt-assembly/assemble.js +9 -9
- package/dist/prompt-assembly/composer.d.ts +6 -7
- package/dist/prompt-assembly/composer.js +10 -10
- package/dist/prompt-assembly/epoch.js +1 -1
- package/dist/prompt-assembly/event-registry.d.ts +0 -21
- package/dist/prompt-assembly/packs/sema-default.js +30 -30
- package/dist/prompt-assembly/types.d.ts +14 -14
- package/dist/prompts/coordinator.d.ts +0 -13
- package/dist/prompts/coordinator.js +0 -3
- package/dist/stores/file/checkpoint-store.js +1 -5
- package/dist/stores/file/file-history-store.js +2 -2
- package/dist/stores/file/permission-rule-store.d.ts +4 -35
- package/dist/stores/file/permission-rule-store.js +4 -148
- package/dist/tools/artifact/artifact-text.d.ts +62 -0
- package/dist/tools/artifact/artifact-text.js +68 -0
- package/dist/tools/artifact/artifact-tool.d.ts +52 -0
- package/dist/tools/artifact/artifact-tool.js +351 -0
- package/dist/tools/artifact/local-stub.d.ts +26 -0
- package/dist/tools/artifact/local-stub.js +296 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +74 -8
- package/dist/tools/fs/bash-readonly-classifier.js +171 -60
- package/dist/tools/fs/fs-bash.d.ts +14 -10
- package/dist/tools/fs/fs-bash.js +19 -27
- package/dist/tools/fs/fs-search-tools.js +5 -2
- package/dist/tools/fs/fs-shared.d.ts +2 -0
- package/dist/tools/fs/fs-shared.js +3 -11
- package/dist/tools/fs/index.d.ts +4 -0
- package/dist/tools/fs/index.js +4 -1
- package/dist/tools/fs/safety.d.ts +117 -1
- package/dist/tools/fs/safety.js +131 -31
- package/dist/tools/fs/search.js +8 -6
- package/package.json +2 -1
- package/test/export-surface.snapshot.json +115 -39
|
@@ -99,7 +99,7 @@ export interface CompactionForkContext {
|
|
|
99
99
|
modelId?: string;
|
|
100
100
|
}
|
|
101
101
|
export interface MaybeCompactOptions {
|
|
102
|
-
/**
|
|
102
|
+
/** Disclosure channel for CONTAINED host-callback failures in this scope (the RB-463
|
|
103
103
|
* isolation primitive's bounded first-failure per site). Absent ⇒ failures are counted only. */
|
|
104
104
|
onNotifyError?: (failure: import("./safe-notify.js").SafeNotifyFailure) => void;
|
|
105
105
|
/** The session to compact. Typed on the INTERFACE face (typecheck 车 2026-07-24): every member this
|
|
@@ -109,7 +109,7 @@ export interface MaybeCompactOptions {
|
|
|
109
109
|
* the compaction-boundary epoch restatement/advance must hash the SAME artifact identity as the
|
|
110
110
|
* prepare-time pin, or every compaction under a declaration-carrying run would flap the pin. */
|
|
111
111
|
epochDeclaredSections?: import("../prompt-assembly/epoch.js").EpochDeclaredSections;
|
|
112
|
-
/**
|
|
112
|
+
/** A compaction-boundary CENTER CANDIDATE ADOPTION, pre-assembled by the
|
|
113
113
|
* caller (prepare's seam): the descriptor advances with the candidate's declarations + provenance
|
|
114
114
|
* in the SAME CAS append as the new baseline, and `apply()` (the live prefix/fingerprint swap)
|
|
115
115
|
* runs ONLY after that append succeeded — a failed/blocked compaction must swap nothing. */
|
|
@@ -160,7 +160,7 @@ export interface MaybeCompactOptions {
|
|
|
160
160
|
* including the preCompact hook's additions, gets the same treatment). */
|
|
161
161
|
customInstructions?: string;
|
|
162
162
|
/**
|
|
163
|
-
*
|
|
163
|
+
* The user's / project's own INSTRUCTION-FILE content (the CLAUDE.md family this
|
|
164
164
|
* deployment loads into an ordinary session), for the INDEPENDENT summary form.
|
|
165
165
|
*
|
|
166
166
|
* Why it needs a seat at all: the summarization prompt carries CC's closing invitation to follow
|
|
@@ -300,7 +300,7 @@ export interface MaybeCompactOptions {
|
|
|
300
300
|
*/
|
|
301
301
|
instructionSourcePaths?: ReadonlyArray<string>;
|
|
302
302
|
/**
|
|
303
|
-
*
|
|
303
|
+
* `recentlyReadFiles` yields CANONICAL keys (resolveKey
|
|
304
304
|
* output — the same coordinate `ReadFileState` is keyed in), but `instructionSourcePaths` and the
|
|
305
305
|
* kept-tail scan inside `maybeCompact` (which reads raw tool-call arguments via
|
|
306
306
|
* `extractFileOpsFromMessage`) do NOT share that coordinate — a model-typed relative path and its
|
|
@@ -315,7 +315,7 @@ export interface MaybeCompactOptions {
|
|
|
315
315
|
*/
|
|
316
316
|
normalizePath?: (raw: string) => Promise<string>;
|
|
317
317
|
/**
|
|
318
|
-
*
|
|
318
|
+
* A kept-tail Read tool-CALL's mere presence does not prove the
|
|
319
319
|
* file's real content is visible there: its toolRESULT may be a dedup stub ("unchanged since you
|
|
320
320
|
* last read it…") whose ORIGINAL full transmission sits in the summarized prefix THIS compaction is
|
|
321
321
|
* about to cut away — preserving read-state for such a path would leave both the kept tail and the
|
|
@@ -328,14 +328,14 @@ export interface MaybeCompactOptions {
|
|
|
328
328
|
isDedupStubResult?: (resultText: string) => boolean;
|
|
329
329
|
};
|
|
330
330
|
/**
|
|
331
|
-
*
|
|
331
|
+
* Fires ONCE per LANDED compaction (after `appendCompaction` committed the new baseline), with the
|
|
332
332
|
* files that were attached WHOLE (untruncated) into the summary. The Runner wires this to the read-state
|
|
333
333
|
* invalidation (`applyCompactionToReadFileState`): the summary just replaced the history the read-dedup
|
|
334
334
|
* stubs point at, so stale entries must drop and the re-attached content re-registers. Kept OUTSIDE
|
|
335
335
|
* `workingFileAttachments` deliberately — the invalidation is owed even when attachments are disabled
|
|
336
336
|
* (an empty array then). Best-effort: a throwing callback must not fail the landed compaction.
|
|
337
337
|
*
|
|
338
|
-
*
|
|
338
|
+
* `preserveReadState`:
|
|
339
339
|
* canonical-coordinate paths (same shape as `normalizePath`'s output) whose read-state entry must
|
|
340
340
|
* survive the compaction's clear even though they are NOT in `attachedComplete` — every file
|
|
341
341
|
* `maybeCompact` deliberately skipped re-attaching, for EITHER exclusion reason (kept-tail-visible,
|
|
@@ -474,7 +474,7 @@ export interface MaybeCompactOptions {
|
|
|
474
474
|
keptChars: number;
|
|
475
475
|
}) => void;
|
|
476
476
|
/**
|
|
477
|
-
*
|
|
477
|
+
* The design/36 ToolSearch activation set LIVE at this pass (the
|
|
478
478
|
* runner threads `[...prepared.activeTools]` on all three lanes: boundary, PTL recovery, finish).
|
|
479
479
|
* Persisted into the landed compaction entry's details (`CompactionDetails.activeTools`) so the
|
|
480
480
|
* NEXT task boundary's re-derivation — whose transcript source (ToolSearch toolCall parts) this
|
|
@@ -510,7 +510,7 @@ export declare function maybeCompact(opts: MaybeCompactOptions): Promise<{
|
|
|
510
510
|
* (`enabled:false`) — the request can never be honored this run. Lets the caller resolve a manual
|
|
511
511
|
* /compact with the honest `"disabled"` outcome (and trace frame) instead of a structural noop. */
|
|
512
512
|
disabled?: boolean;
|
|
513
|
-
/**
|
|
513
|
+
/** Set (with `compacted:false`) when the pass PASSED the trigger gate
|
|
514
514
|
* (natural or forced) but found nothing to summarize — no valid cut point / empty history. Was
|
|
515
515
|
* previously indistinguishable from the quiet under-threshold return, so a forced pass with
|
|
516
516
|
* nothing to do looked identical to one that never wanted to run; the caller's outcome event
|
|
@@ -597,7 +597,7 @@ export declare function maybeCompact(opts: MaybeCompactOptions): Promise<{
|
|
|
597
597
|
modelId?: string;
|
|
598
598
|
};
|
|
599
599
|
/**
|
|
600
|
-
*
|
|
600
|
+
* The trigger inputs THIS pass used, reported on
|
|
601
601
|
* EVERY return path — including the ordinary "nothing to do" one. A consumer rendering "how full is the
|
|
602
602
|
* context" was otherwise forced to re-derive the numerator itself, and a re-derivation that drifts from
|
|
603
603
|
* the engine's own is the projection-antipattern this repo keeps paying for: the displayed percentage
|
|
@@ -29,7 +29,7 @@ export interface AutoModeArmingRecipe {
|
|
|
29
29
|
/** Classify round-trip cap, ms. */
|
|
30
30
|
timeoutMs?: number;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* The classifier DENIAL-LIMIT bounds (`RunnerDeps.autoMode.denialLimit`, CC 2.1.250 `FO`/`AKe`):
|
|
33
33
|
* how many blocks the ancestor's classifier was allowed before a person had to look, and the window the
|
|
34
34
|
* fallback ask ran under. A KNOB triple, not prompt body — every member is orderable, so the fold takes
|
|
35
35
|
* the strictest of the two sides rather than refusing on a difference.
|
|
@@ -87,7 +87,7 @@ export interface AutoModeArmingFace {
|
|
|
87
87
|
crossSessionMessagesRule?: boolean;
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
*
|
|
90
|
+
* The ONE tighten rule for the denial-limit bounds, shared by {@link foldAutoModeArming} and by
|
|
91
91
|
* the runner's rebuilt-tracker mint (a second computation of "the strictest of these two" is how the
|
|
92
92
|
* recipe's account and the tracker's actual bounds would come to disagree). Both sides' EFFECTIVE values
|
|
93
93
|
* are materialized first (an omitted bound is the default the tracker applies, never "unbounded" — the
|
|
@@ -104,18 +104,18 @@ export interface BackgroundAgentRecord {
|
|
|
104
104
|
parkClaimId?: string;
|
|
105
105
|
summary?: string;
|
|
106
106
|
finalOutput?: string;
|
|
107
|
-
/**
|
|
107
|
+
/** The FULL result (workflow.ts NH-1 shape via {@link BackgroundAgentTaskHandle.resultFull}),
|
|
108
108
|
* set only when it differs from `finalOutput` — the restart/durable-fallback poll path needs the same
|
|
109
109
|
* pairing the live handle carries, or a process restart loses the very recoverability this field exists
|
|
110
110
|
* to preserve. */
|
|
111
111
|
finalOutputFull?: string;
|
|
112
112
|
/** The child's failure text (registry `handle.error` mirror; the reap-stop sentinel never lands here).
|
|
113
|
-
*
|
|
113
|
+
* The stale-running reap flip ALSO writes its attribution here (`??`-guarded) —
|
|
114
114
|
* `error` is the field the durable serving face renders (`serveDurableAgentRow`), while `summary`
|
|
115
115
|
* has no reader on that face, so an attribution written only to `summary` was invisible: a host
|
|
116
116
|
* crash read as a bare `failed` + "(no result text)". */
|
|
117
117
|
error?: string;
|
|
118
|
-
/**
|
|
118
|
+
/** The classification triplet the in-memory handle carries under
|
|
119
119
|
* the SAME names (`errorCode`/`errorRetryable`/`errorKind`; see RB-386②/RB-405 G3 on
|
|
120
120
|
* {@link import("./task-registry-shared.js").BackgroundAgentTaskHandle}), written to this row at the
|
|
121
121
|
* same terminal write that lands `error` — so a cross-restart fallback read
|
|
@@ -146,7 +146,7 @@ export interface BackgroundAgentRecord {
|
|
|
146
146
|
rev: number;
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
|
-
*
|
|
149
|
+
* The terminal payload a REVIVAL must erase from the row it is re-launching, as ONE list.
|
|
150
150
|
*
|
|
151
151
|
* A revived handle starts a fresh cycle on an existing row: status flips back to `running`, but every
|
|
152
152
|
* field describing how the PREVIOUS cycle ended is still sitting there. Left standing, each one
|
|
@@ -249,7 +249,7 @@ export declare function canAccessAgentRecord(record: Pick<BackgroundAgentRecord,
|
|
|
249
249
|
* terminal-looking row whose rev the flush has not yet bumped. In-process sweeps are gated on the
|
|
250
250
|
* live handle; cross-process revival (S3) must claim-CAS FIRST (see {@link BackgroundAgentRecord.writerId}).
|
|
251
251
|
*/
|
|
252
|
-
/**
|
|
252
|
+
/** The stale-running reap flip's attribution, written to BOTH `summary` (legacy
|
|
253
253
|
* slot, kept for any out-of-repo reader) and `error` (the field {@link canAccessAgentRecord}-gated
|
|
254
254
|
* durable serving actually renders). One exported constant so the two store implementations (in-memory
|
|
255
255
|
* here, file twin) can never drift apart (RB-74/RB-111 family). Wording carries CC 2.1.220's three
|
|
@@ -133,7 +133,7 @@ export interface BackgroundShellCapability {
|
|
|
133
133
|
*/
|
|
134
134
|
export declare function hasBackgroundShell(env: ExecutionEnv): env is ExecutionEnv & BackgroundShellCapability;
|
|
135
135
|
/**
|
|
136
|
-
*
|
|
136
|
+
* The ONE way core runs an env-level background sweep.
|
|
137
137
|
*
|
|
138
138
|
* ## Why a single entry point
|
|
139
139
|
* `disposeBackgroundShells` lives in the execution-env layer and cannot reach the task registry, so the
|
|
@@ -24,9 +24,6 @@ import type { GateOutcome } from "./gate-outcome.js";
|
|
|
24
24
|
*/
|
|
25
25
|
export declare const EXECUTION_OUTCOME_RECORD_WORDS: readonly ["recorded", "already_recorded", "not_resolved", "absent"];
|
|
26
26
|
export type ExecutionOutcomeRecordWord = (typeof EXECUTION_OUTCOME_RECORD_WORDS)[number];
|
|
27
|
-
/** Membership test for {@link ExecutionOutcomeRecordWord} — a deployment store answers across a process
|
|
28
|
-
* boundary, so the consumer validating its word must not hand-roll the set. */
|
|
29
|
-
export declare function isExecutionOutcomeRecordWord(v: unknown): v is ExecutionOutcomeRecordWord;
|
|
30
27
|
/**
|
|
31
28
|
* The one disposition table over {@link ExecutionOutcomeRecordWord}: does this answer mean the row now
|
|
32
29
|
* carries NO execution record — i.e. the leg's disposition of the decided action is not on file? The
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import {} from "./ask-origin.js";
|
|
2
2
|
export const EXECUTION_OUTCOME_RECORD_WORDS = ["recorded", "already_recorded", "not_resolved", "absent"];
|
|
3
|
-
const EXECUTION_OUTCOME_RECORD_WORD_SET = new Set(EXECUTION_OUTCOME_RECORD_WORDS);
|
|
4
|
-
export function isExecutionOutcomeRecordWord(v) {
|
|
5
|
-
return EXECUTION_OUTCOME_RECORD_WORD_SET.has(v);
|
|
6
|
-
}
|
|
7
3
|
export const EXECUTION_RECORD_LEAVES_ROW_UNRECORDED = {
|
|
8
4
|
recorded: false,
|
|
9
5
|
already_recorded: false,
|
|
@@ -6,7 +6,6 @@ import { type QuestionAnswer } from "./ask-question.js";
|
|
|
6
6
|
import type { ReadEntry } from "../tools/fs/safety.js";
|
|
7
7
|
import type { RepairBundle } from "../agents/repair-loop.js";
|
|
8
8
|
import type { WorkspaceHandle } from "./remote-env.js";
|
|
9
|
-
import type { ConsolidationNote } from "./runner/memory-consolidation.js";
|
|
10
9
|
import type { SessionPermissionRules } from "./session-policy-store.js";
|
|
11
10
|
import type { NestedUsageAccum, ShellGateDoctrine, TaskResult } from "./types.js";
|
|
12
11
|
import type { ActiveWorktreeSession } from "../internal/harness-types.js";
|
|
@@ -95,17 +94,18 @@ export type ResourceLimitReason = "budget_tokens" | "budget_cost" | "walltime" |
|
|
|
95
94
|
*/
|
|
96
95
|
export type PlatformLimitReason = Extract<ResourceLimitReason, "env_lifetime" | "usage_window">;
|
|
97
96
|
/**
|
|
98
|
-
* design/80 D-2: which SAFETY
|
|
99
|
-
* `irreversible_ask`. Derived from the tool's
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* THE DURABLE RECORD (never re-derives risk from a model-controlled value — the model self-reports nothing
|
|
103
|
-
* here). Both can be true (a tool marked BOTH egress AND irreversible).
|
|
97
|
+
* design/80 D-2: which SAFETY axis of THIS call caused an `ask` to mint an {@link CheckpointGate}
|
|
98
|
+
* `irreversible_ask`. Derived by the gate (`safetyAxisOf`) from the tool's static marks plus the engine's own
|
|
99
|
+
* per-call facts — never from a decision member a policy composes (forgeable). Persisted on the gate so a
|
|
100
|
+
* network budget/escalation resolver reads WHY this is a safety ask FROM THE DURABLE RECORD. Both can be true.
|
|
104
101
|
*/
|
|
105
102
|
export interface SafetyAxis {
|
|
106
103
|
/** design/70: the tool is egress-marked (`ToolSpec.egress` — an external write: push, open PR, send). */
|
|
107
104
|
egress?: boolean;
|
|
108
|
-
/** design/77 §4: the tool's
|
|
105
|
+
/** design/77 §4: this call carries an irreversibility MANDATE — the tool's own `always`/`maybe` tier, the
|
|
106
|
+
* operator's `shellGate:"always"`, the probe's structural verdict (mandated / unanswered), or the shell
|
|
107
|
+
* gate's own tighten under its `"maybe"` tier; a policy ask the doctrine's probe neither tightened nor
|
|
108
|
+
* mandated carries no bit (its park is the budgetable kind). */
|
|
109
109
|
irreversible?: boolean;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
@@ -157,7 +157,7 @@ export interface RiskDescriptor {
|
|
|
157
157
|
* {@link summary} (a path name can carry the same reordering hazard as a command) + capped.
|
|
158
158
|
* Omitted when none derivable. */
|
|
159
159
|
touchedPaths?: string[];
|
|
160
|
-
/**
|
|
160
|
+
/** A persisted allow rule MATCHED this call but could not clear the mandated ask —
|
|
161
161
|
* the matched rule text (rendered through the same display baseline as {@link summary}, capped),
|
|
162
162
|
* threaded to the mint so the durable-park route carries the same disclosure the synchronous ask
|
|
163
163
|
* does. The inbox renders "their rule is alive, just outranked" instead of the person concluding
|
|
@@ -173,7 +173,7 @@ export interface RiskDescriptor {
|
|
|
173
173
|
* same-value contract (unlike `probeReason`/`probeCause` below), which is why the one-face move
|
|
174
174
|
* is legal — a byte-pinning consumer must read per face.) */
|
|
175
175
|
shadowedRule?: string;
|
|
176
|
-
/**
|
|
176
|
+
/** WHY the reversibility probe did not clear this call, in the probe's own
|
|
177
177
|
* words — the cause the tighten acted on, which until now existed only inside the probe and left the
|
|
178
178
|
* card showing WHAT is gated with no account of WHY. Present only for a `"maybe"`-tier tighten whose
|
|
179
179
|
* probe supplied a cause (an `"always"`-tier tighten runs no probe; a timeout/throw yields no verdict).
|
|
@@ -190,7 +190,7 @@ export interface RiskDescriptor {
|
|
|
190
190
|
* one-face re-render would break it. A consumer rendering this seat owes its own screen (or the
|
|
191
191
|
* descriptor family's display baseline). */
|
|
192
192
|
probeReason?: string;
|
|
193
|
-
/**
|
|
193
|
+
/** The STRUCTURED cause, for a probe whose verdict this engine understands —
|
|
194
194
|
* the built-in shell probe is the first. Carries a machine-readable {@link ProbeCause.code} and the
|
|
195
195
|
* operand families as ARRAYS with honest totals, so a consumer renders its own sentence in its own
|
|
196
196
|
* language instead of receiving one this engine had to write in advance.
|
|
@@ -202,7 +202,7 @@ export interface RiskDescriptor {
|
|
|
202
202
|
* whichever part sorts last. A code cannot be false and an array cannot be truncated into a lie. */
|
|
203
203
|
probeCause?: ProbeCause;
|
|
204
204
|
}
|
|
205
|
-
/**
|
|
205
|
+
/** One operand family inside a {@link ProbeCause} — the entries a card may NAME, plus how
|
|
206
206
|
* many the family really has. `shown.length` ≤ {@link total}, and a consumer that renders only `shown`
|
|
207
207
|
* is still obliged to tell the person when `total` exceeds it: the count is the part that cannot be
|
|
208
208
|
* cut, and "there is a second unreviewed operand" is exactly what a reader cannot recover from the
|
|
@@ -221,7 +221,7 @@ export interface ProbeCauseOperands {
|
|
|
221
221
|
readonly total: number;
|
|
222
222
|
}
|
|
223
223
|
/**
|
|
224
|
-
*
|
|
224
|
+
* An ENGINE-MINTED, structured account of why a reversibility probe did not clear a call.
|
|
225
225
|
*
|
|
226
226
|
* DISPLAY/TRIAGE metadata, exactly like the rest of {@link RiskDescriptor} — nothing reads it to gate,
|
|
227
227
|
* budget or suppress anything, and it deliberately never reaches the ask's `message` (that string is
|
|
@@ -248,14 +248,14 @@ export interface ProbeCause {
|
|
|
248
248
|
* account of an approval's reach is worse than none. */
|
|
249
249
|
readonly further?: ProbeCauseOperands;
|
|
250
250
|
}
|
|
251
|
-
/**
|
|
251
|
+
/** The bloat ceiling on {@link RiskDescriptor.probeReason} — one sentence of cause, sized
|
|
252
252
|
* like its {@link RiskDescriptor.shadowedRule} sibling. The neutralizer is the injection ceiling; this
|
|
253
253
|
* is only the length one. Exported (module-level, not part of the package's public surface) so the gate
|
|
254
254
|
* that sanitizes at the entry boundary and the descriptor builder that re-sanitizes at the persist
|
|
255
255
|
* boundary cannot cap the same value at two different lengths. */
|
|
256
256
|
export declare const PROBE_REASON_MAX = 200;
|
|
257
257
|
/**
|
|
258
|
-
*
|
|
258
|
+
* The ONE validator for a {@link ProbeCause} arriving from a probe.
|
|
259
259
|
*
|
|
260
260
|
* The value crosses a trust boundary twice — once at the gate (where a deployment-supplied probe hands
|
|
261
261
|
* it over) and once at the persist boundary (where {@link buildRiskDescriptor} is an exported function a
|
|
@@ -410,19 +410,19 @@ export declare function buildRiskDescriptor(input: {
|
|
|
410
410
|
shellGated?: boolean;
|
|
411
411
|
/** The resolved doctrine to persist when `shellGated` (see {@link RiskDescriptor.shellGateDoctrine}). */
|
|
412
412
|
shellGateDoctrine?: ShellGateDoctrine;
|
|
413
|
-
/**
|
|
413
|
+
/** The matched-but-outranked persisted rule to persist (see {@link RiskDescriptor.shadowedRule}). */
|
|
414
414
|
shadowedRule?: string;
|
|
415
|
-
/**
|
|
415
|
+
/** The reversibility probe's cause for not clearing this call (see
|
|
416
416
|
* {@link RiskDescriptor.probeReason}). Re-neutralized here like its shadowed-rule sibling: this
|
|
417
417
|
* function is exported, so a caller reaching it directly must get the same redaction the gate applies. */
|
|
418
418
|
probeReason?: string;
|
|
419
|
-
/**
|
|
419
|
+
/** The STRUCTURED cause (see {@link RiskDescriptor.probeCause}). Re-validated here for
|
|
420
420
|
* the same reason the prose sibling is re-neutralized — this function is exported, so a caller
|
|
421
421
|
* reaching it directly must not be able to persist a shape the gate would have rejected. */
|
|
422
422
|
probeCause?: unknown;
|
|
423
423
|
}): RiskDescriptor;
|
|
424
424
|
/**
|
|
425
|
-
*
|
|
425
|
+
* The durable record of an ask's `requiresRealApproval` bit, which used
|
|
426
426
|
* to DIE at the park: the mint keyed the gate kind on the static tool marks only, so an org-governed
|
|
427
427
|
* ask on an unmarked tool minted a plain `{kind:"human"}` — the one kind a network budget resolver may
|
|
428
428
|
* auto-approve — and the org's "only judgment clears this" demand was silently budgetable after the
|
|
@@ -567,7 +567,7 @@ export type ResumeOutcome = {
|
|
|
567
567
|
* that the human actually saw/approved (`PendingAction.tool_approval.boundInputHash`, computed by the
|
|
568
568
|
* engine at suspend-mint via {@link import("./canonical-json.js").boundInputHashOf} over the post-hook
|
|
569
569
|
* `args`). The caller echoes it VERBATIM — it is opaque; the SDK/service NEVER re-canonicalize args
|
|
570
|
-
* (
|
|
570
|
+
* (a second runtime's serialization could diverge → false mismatch → fail-closed a
|
|
571
571
|
* legitimate approval). The resume verifies it by **string equality** against the checkpoint's
|
|
572
572
|
* persisted value (`checkpoint.invalid_outcome`, fail-closed, pre-CAS) — closing the TOCTOU "same call
|
|
573
573
|
* id, different input" variant that `boundCallId` alone misses (a re-mint that swapped the input under
|
|
@@ -687,11 +687,11 @@ export type ResumeOutcome = {
|
|
|
687
687
|
*
|
|
688
688
|
* `message` (optional): operator content delivered to the resumed run — the ATOMIC equivalent of
|
|
689
689
|
* `setPendingSteer` + resume in one verb (same `validatePendingSteer` persist-time guards, same
|
|
690
|
-
* trusted/untrusted delivery framing as {@link CheckpointState.
|
|
691
|
-
* continuation's steer tail as its OWN segment, appended AFTER any already-parked
|
|
690
|
+
* trusted/untrusted delivery framing as {@link CheckpointState.pendingSteerQueue}). It rides the resume
|
|
691
|
+
* continuation's steer tail as its OWN segment, appended AFTER any already-parked queue entry
|
|
692
692
|
* (X5: both are delivered — the wake message never displaces a parked, undelivered supervisor steer;
|
|
693
693
|
* each segment is framed under its own `trusted` semantics, never one merged trust domain). WITHOUT a
|
|
694
|
-
* `message`, the checkpoint must already carry a parked
|
|
694
|
+
* `message`, the checkpoint must already carry a parked steer — a wake with nothing to
|
|
695
695
|
* deliver is rejected (`wake.nothing_to_deliver`, anti spin-wake). Idempotency rides the existing
|
|
696
696
|
* resolve CAS: a second wake of the same token loses the CAS (`checkpoint.already_resolved`). */
|
|
697
697
|
| {
|
|
@@ -798,7 +798,7 @@ export type PendingAction = {
|
|
|
798
798
|
* this"). Absent otherwise (never `false`). Display metadata: the resume belts keep reading the
|
|
799
799
|
* gate's own bit. */
|
|
800
800
|
requiresRealApproval?: true;
|
|
801
|
-
/**
|
|
801
|
+
/** The PARK twin of `AskRequest.denialLimitFallback`: present
|
|
802
802
|
* ⇔ this parked ask is the classifier DENIAL-LIMIT fallback, carrying the counts that tripped
|
|
803
803
|
* the bound. Its `autoDenyAfterMs` is ALWAYS `0` on a row: the window is a fact of the ask's
|
|
804
804
|
* route, armed only at a hand-out to a live approver, and nothing counts down on the parked lane
|
|
@@ -935,8 +935,6 @@ export interface CheckpointState {
|
|
|
935
935
|
};
|
|
936
936
|
/** design/38: nested sub-agent cumulative cost — else pre-suspend child cost evaporates (§4.bis/Q7). */
|
|
937
937
|
nestedStats: NestedUsageAccum;
|
|
938
|
-
/** design/41: consolidation notes collected pre-suspend — else the task-end pass loses them. */
|
|
939
|
-
consolidationNotes?: ConsolidationNote[];
|
|
940
938
|
/** design/44: the hand's read-file state (content hashes), serialized from the hands-toolkit closure
|
|
941
939
|
* (NOT part of Prepared — §15.2 net-add #8). Without it a resumed `edit_file` is rejected "not read". */
|
|
942
940
|
readFileState?: Array<[string, ReadEntry]>;
|
|
@@ -1002,56 +1000,31 @@ export interface CheckpointState {
|
|
|
1002
1000
|
*/
|
|
1003
1001
|
workspaceHandle?: WorkspaceHandle;
|
|
1004
1002
|
/**
|
|
1005
|
-
* design/
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1008
|
-
*
|
|
1009
|
-
* never
|
|
1003
|
+
* design/171 §5.3 — the BOUNDED, ORDERED queue of parked operator steers for a DURABLY-SUSPENDED task,
|
|
1004
|
+
* drained in `seq` order on resume with every entry framed under its own trust semantics. Live
|
|
1005
|
+
* `TaskStream.steer` (runtask.ts) is unreachable while the harness is idle, so a supervisor's guidance is
|
|
1006
|
+
* parked HERE via {@link CheckpointStore.setPendingSteer} and injected on resume (after the
|
|
1007
|
+
* resume-continuation prompt). It is GUIDANCE ONLY — never an approval channel (§3 inv #4) and never
|
|
1008
|
+
* parsed into control state (§3 inv #5); a budget/autonomy/gate-threshold is CONFIG, not steer text.
|
|
1010
1009
|
*
|
|
1011
1010
|
* `trusted` is FROZEN at `setPendingSteer` from the SERVICE's verified-principal check (an operator-role
|
|
1012
|
-
* check, NOT a client header
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1015
|
-
*
|
|
1016
|
-
* is REJECTED at `setPendingSteer` (typed `steering.invalid_content`) so a dirty steer never enters this
|
|
1017
|
-
* state (§3 inv #2); the untrusted-injection path ALSO sanitizes the text as untrusted data, belt-and-braces.
|
|
1018
|
-
* Absent when no steer is pending. All-string fields → JSON/`structuredClone` round-trips safely.
|
|
1011
|
+
* check, NOT a client header) and NEVER recomputed on resume (§3 inv #1). A `trusted:false` entry reaches
|
|
1012
|
+
* the model as a PLAIN user message with NO `<system-reminder>` wrapper (§3 inv #3); a `trusted:true`
|
|
1013
|
+
* entry MAY ride the reminder. `text` containing `</system-reminder>` is REJECTED at `setPendingSteer`
|
|
1014
|
+
* (`steering.invalid_content`) so a dirty steer never enters this state (§3 inv #2).
|
|
1019
1015
|
*
|
|
1020
|
-
*
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
1023
|
-
*
|
|
1024
|
-
* leg; the model re-does the work, re-seeing the steer). It is NOT carried onto a NEW re-suspend checkpoint
|
|
1025
|
-
* (serializeCheckpointState stamps `undefined`) — a supervisor steers the new checkpoint afresh.
|
|
1026
|
-
* - It is DROPPED (never delivered) on a resume that runs no turn (an exhausted-budget resume) or that is
|
|
1027
|
-
* set in the get→resolve race window of an in-flight resume — both rare; the run is ending or the steer
|
|
1028
|
-
* just missed its train. A supervisor re-issues `setPendingSteer` if a steer didn't land.
|
|
1029
|
-
* A precise exactly-once delivery would need clearing the steer from the persisted row on consume (a reopen
|
|
1030
|
-
* clear + a get→resolve interlock); deferred as not worth the cross-backend complexity for guidance text.
|
|
1031
|
-
*
|
|
1032
|
-
* **Superseded by {@link CheckpointState.pendingSteerQueue} (design/171 §5.3).** New writes go to the
|
|
1033
|
-
* queue; this seat remains ONLY so rows written before the queue existed keep delivering their parked
|
|
1034
|
-
* steer. Never read it directly — {@link readPendingSteerQueue} is the single read point that folds
|
|
1035
|
-
* this legacy seat in as queue member 0.
|
|
1036
|
-
*/
|
|
1037
|
-
pendingSteer?: {
|
|
1038
|
-
text: string;
|
|
1039
|
-
trusted: boolean;
|
|
1040
|
-
};
|
|
1041
|
-
/**
|
|
1042
|
-
* design/171 §5.3 — the BOUNDED, ORDERED queue of parked operator steers, drained in `seq` order on
|
|
1043
|
-
* resume with every entry framed under its own trust semantics.
|
|
1044
|
-
*
|
|
1045
|
-
* It replaces the single {@link CheckpointState.pendingSteer} seat, whose last-writer-wins overwrite
|
|
1046
|
-
* meant two people steering one suspended run silently destroyed the first instruction — and destroyed
|
|
1047
|
-
* it with no attribution, so nobody could tell afterwards that anything was lost.
|
|
1016
|
+
* Delivery is BEST-EFFORT, at-most-meaningfully-once: an entry rides EVERY resume of THIS checkpoint
|
|
1017
|
+
* that runs a turn (a faithful reopen→re-resume re-shows it), is NOT carried onto a re-suspend
|
|
1018
|
+
* checkpoint (serializeCheckpointState stamps `undefined`), and is DROPPED on a resume that runs no
|
|
1019
|
+
* turn. A supervisor re-issues `setPendingSteer` if a steer did not land.
|
|
1048
1020
|
*
|
|
1049
1021
|
* Bounds are fail-loud, never lossy: {@link MAX_PENDING_STEER_ENTRIES} entries and
|
|
1050
1022
|
* {@link PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES} serialized bytes, whichever binds first, reject the
|
|
1051
1023
|
* APPEND with `steering.queue_full` rather than evicting an already-accepted instruction.
|
|
1052
1024
|
*
|
|
1053
|
-
* Absent when nothing is parked.
|
|
1054
|
-
*
|
|
1025
|
+
* Absent when nothing is parked. {@link readPendingSteerQueue} is the single read point; a row that
|
|
1026
|
+
* still carries the retired pre-queue single seat (`pendingSteer`) is refused there
|
|
1027
|
+
* (`checkpoint.unsupported_version`, `seat_retired`), never folded in.
|
|
1055
1028
|
*/
|
|
1056
1029
|
pendingSteerQueue?: PendingSteerEntry[];
|
|
1057
1030
|
/**
|
|
@@ -1258,7 +1231,7 @@ export interface CheckpointState {
|
|
|
1258
1231
|
* EXPLICIT live `internals.placementRoot` wins when re-supplied; otherwise THIS key restores into
|
|
1259
1232
|
* `internals.placementRoot` at prepare so descendants and the NEXT re-suspend mint inherit it too
|
|
1260
1233
|
* — outranking a supplied `rootSessionId`, which is DELEGATION IDENTITY (the peer/registry axis a
|
|
1261
|
-
* revive leg re-supplies from its row), never a placement claim (
|
|
1234
|
+
* revive leg re-supplies from its row), never a placement claim (reading it as one
|
|
1262
1235
|
* permanently stuck every parked agent spawned under an explicit placement root). The resume entry
|
|
1263
1236
|
* ALSO reads this key as an identity record: a resume whose supplied `internals.placementRoot`
|
|
1264
1237
|
* CONTRADICTS it is refused pre-CAS (`resume.placement_mismatch`); either side absent skips the
|
|
@@ -1474,7 +1447,7 @@ export declare function remainingTokens(ledger: ResourceLedger | undefined): num
|
|
|
1474
1447
|
* later D-1 slice (1a.2) and is deliberately NOT part of this winner.
|
|
1475
1448
|
*/
|
|
1476
1449
|
export interface ResolvedOutcome {
|
|
1477
|
-
/** The pending tool call this decision was bound to (design/80 D-1 slice 1a).
|
|
1450
|
+
/** The pending tool call this decision was bound to (design/80 D-1 slice 1a). A REVIEW gate binds
|
|
1478
1451
|
* no tool call, so it records the synthetic `gate:<kind>` marker instead — the replay guard compares the
|
|
1479
1452
|
* DECISION for those, never a call id. */
|
|
1480
1453
|
boundCallId: string;
|
|
@@ -1878,7 +1851,7 @@ export interface CheckpointSummary {
|
|
|
1878
1851
|
*/
|
|
1879
1852
|
toolInput?: string;
|
|
1880
1853
|
/**
|
|
1881
|
-
*
|
|
1854
|
+
* HOW this pause's remote workspace comes back, projected from
|
|
1882
1855
|
* `state.workspaceHandle.restoreMode` so a supervisor inbox can tell the two apart in ONE `listByScope`
|
|
1883
1856
|
* call. `"snapshot"` = the VM was paused into a snapshot (billing typically stops, memory state
|
|
1884
1857
|
* captured); `"park_only"` = a non-suspendable target (SSH host / ADB device) was never paused — the
|
|
@@ -1906,12 +1879,12 @@ export interface CheckpointSummary {
|
|
|
1906
1879
|
* projection's own materials (a pre-#457 row therefore reads absent, which is honest: unreported).
|
|
1907
1880
|
* ECHO-ONLY display metadata; nothing gates on it. */
|
|
1908
1881
|
previewWithheld?: "oversize" | "unavailable";
|
|
1909
|
-
/**
|
|
1882
|
+
/** The row's `PendingAction.tool_approval.requiresRealApproval`, projected so the ONE-CALL
|
|
1910
1883
|
* inbox can label "only a person can clear this" without an N+1 `get`. `true` or OMITTED (the
|
|
1911
1884
|
* {@link toolCallId} absence-shape contract); pure echo of the persisted bit — a pre-#557 row reads
|
|
1912
1885
|
* absent, which is honest (unreported), never a claim that budget may clear it. */
|
|
1913
1886
|
requiresRealApproval?: true;
|
|
1914
|
-
/**
|
|
1887
|
+
/** The row's `PendingAction.tool_approval.denialLimitFallback`, projected BESIDE the preview
|
|
1915
1888
|
* for the same one-call reason: a card that shows the fallback's counts and limit must not re-open
|
|
1916
1889
|
* the row to learn them (`autoDenyAfterMs` is `0` on every row — see the row member). Pure echo;
|
|
1917
1890
|
* OMITTED when the row carries none. */
|
|
@@ -1925,7 +1898,7 @@ export interface CheckpointSummary {
|
|
|
1925
1898
|
* member of the closed set ({@link import("./ask-origin.js").isRuleStoreUnreadable}); OMITTED otherwise. */
|
|
1926
1899
|
ruleStoreUnreadable?: import("./ask-origin.js").RuleStoreUnreadable;
|
|
1927
1900
|
/**
|
|
1928
|
-
*
|
|
1901
|
+
* PRESENCE ONLY — this pending `tool_approval` row's payload carries at least one DIRECTIONAL
|
|
1929
1902
|
* format control (the {@link import("./tool-policy.js").AskRequest.hasBidiControls} character class;
|
|
1930
1903
|
* that doc owns the hazard). Only ever for a `tool_approval` pendingAction; OMITTED for every other
|
|
1931
1904
|
* kind (the {@link toolCallId} ABSENCE-SHAPE contract applies: never `null`, never present-but-
|
|
@@ -1984,12 +1957,14 @@ export declare function summarizeCheckpoint(cp: Checkpoint): CheckpointSummary;
|
|
|
1984
1957
|
* decides the orphaned card itself, no worker version redeems it), `"ledger_event_unknown"` (a durable
|
|
1985
1958
|
* LEDGER carries an event kind this binary does not know, so the replay is refused rather than served
|
|
1986
1959
|
* incomplete — the one arm that is not row-scoped: NO row in that data directory is readable here, so
|
|
1987
|
-
* the host rolls the binary forward instead of routing one token elsewhere)
|
|
1960
|
+
* the host rolls the binary forward instead of routing one token elsewhere), `"seat_retired"` (the row
|
|
1961
|
+
* parks a steer in the retired pre-queue single seat — terminal for the row's bytes; no worker version
|
|
1962
|
+
* reads that seat, the host decides the parked instruction itself).
|
|
1988
1963
|
* · `invalid_outcome` pre-CAS row-integrity arms: `"real_approval_damaged"`, `"real_approval_forged"`,
|
|
1989
1964
|
* `"read_face_damaged"`, `"read_face_forged"`, `"constraint_chain_missing"` (all terminal for the row's
|
|
1990
1965
|
* current bytes — no worker version redeems a damaged row).
|
|
1991
1966
|
*/
|
|
1992
|
-
export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "governed_unwired" | "origin_missing" | "ledger_event_unknown" | "real_approval_damaged" | "real_approval_forged" | "read_face_damaged" | "read_face_forged" | "constraint_chain_missing";
|
|
1967
|
+
export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "governed_unwired" | "origin_missing" | "ledger_event_unknown" | "seat_retired" | "real_approval_damaged" | "real_approval_forged" | "read_face_damaged" | "read_face_forged" | "constraint_chain_missing";
|
|
1993
1968
|
/** A typed checkpoint-store error so callers branch on `code` (mirrors `SessionError`). */
|
|
1994
1969
|
export declare class CheckpointError extends Error {
|
|
1995
1970
|
readonly code: "checkpoint.already_exists" | "checkpoint.already_resolved" | "checkpoint.not_found"
|
|
@@ -1997,7 +1972,7 @@ export declare class CheckpointError extends Error {
|
|
|
1997
1972
|
* persisted {@link CheckpointGate} `kind` (council #3 — type confusion guard), or a gate v1
|
|
1998
1973
|
* resume does not serve (`task_done`). */
|
|
1999
1974
|
| "checkpoint.gate_mismatch"
|
|
2000
|
-
/**
|
|
1975
|
+
/** `runner.resume` was handed an ALREADY-ABORTED `TaskSpec.signal`. Refused BEFORE the CAS, so
|
|
2001
1976
|
* the checkpoint stays `pending` — this worker demonstrably cannot execute the approved action, and
|
|
2002
1977
|
* consuming the human's decision on a leg that will abort immediately loses BOTH the decision and the
|
|
2003
1978
|
* suspended work with nothing to reopen. Re-resume with a live signal. */
|
|
@@ -2011,7 +1986,7 @@ export declare class CheckpointError extends Error {
|
|
|
2011
1986
|
* Rejected pre-CAS so the checkpoint stays `pending` and a capable worker can still resume it
|
|
2012
1987
|
* (design/49 §2/§3, code-ready council round-2). */
|
|
2013
1988
|
| "checkpoint.unsupported_version"
|
|
2014
|
-
/**
|
|
1989
|
+
/** `resume`/`resumeStream` was handed `internals.requestedCwd` for a checkpoint that
|
|
2015
1990
|
* carries a remote `workspaceHandle`. The restored workspace's mountPath is authoritative for the
|
|
2016
1991
|
* task root, so the cwd would be ignored at best — and verifying it would touch the env BEFORE the
|
|
2017
1992
|
* VM restore (a lazy-connect adapter then connects a fresh empty sandbox, the design/49 disease).
|
|
@@ -2074,7 +2049,7 @@ export declare class CheckpointError extends Error {
|
|
|
2074
2049
|
* the checkpoint through its own decide entry instead (the error message names it). */
|
|
2075
2050
|
| "wake.gate_pending"
|
|
2076
2051
|
/** design/144 §3 (anti spin-wake): a `wake` outcome carried no `message` and the checkpoint has no
|
|
2077
|
-
* parked
|
|
2052
|
+
* parked steer either — there is nothing to deliver, so the wake is rejected pre-CAS
|
|
2078
2053
|
* (the checkpoint stays pending) instead of burning the token on an empty continuation. */
|
|
2079
2054
|
| "wake.nothing_to_deliver"
|
|
2080
2055
|
/** Parent effective-policy inheritance: the checkpoint records `state.inheritedGate.requiresParentConstraint`
|
|
@@ -2114,7 +2089,7 @@ export declare class CheckpointError extends Error {
|
|
|
2114
2089
|
* the suspend mint. A target-bound env factory keys its placement lookup on that fixed point,
|
|
2115
2090
|
* so silently resuming under a different one would re-place the leg — and every descendant
|
|
2116
2091
|
* the child-internals chain hands it to — on another target than the parked workspace lives
|
|
2117
|
-
* on. A supplied `rootSessionId` deliberately does NOT take this refusal
|
|
2092
|
+
* on. A supplied `rootSessionId` deliberately does NOT take this refusal: it is
|
|
2118
2093
|
* delegation identity, re-supplied by every revive leg, and legitimately differs from the
|
|
2119
2094
|
* recorded root whenever the spawner carried an explicit placement — the recorded root simply
|
|
2120
2095
|
* outranks it in prepare's restore fold. Rejected PRE-CAS (the checkpoint stays `pending`);
|
|
@@ -2176,7 +2151,7 @@ export declare class CheckpointError extends Error {
|
|
|
2176
2151
|
* persisted {@link CheckpointGate} `kind` (council #3 — type confusion guard), or a gate v1
|
|
2177
2152
|
* resume does not serve (`task_done`). */
|
|
2178
2153
|
| "checkpoint.gate_mismatch"
|
|
2179
|
-
/**
|
|
2154
|
+
/** `runner.resume` was handed an ALREADY-ABORTED `TaskSpec.signal`. Refused BEFORE the CAS, so
|
|
2180
2155
|
* the checkpoint stays `pending` — this worker demonstrably cannot execute the approved action, and
|
|
2181
2156
|
* consuming the human's decision on a leg that will abort immediately loses BOTH the decision and the
|
|
2182
2157
|
* suspended work with nothing to reopen. Re-resume with a live signal. */
|
|
@@ -2190,7 +2165,7 @@ export declare class CheckpointError extends Error {
|
|
|
2190
2165
|
* Rejected pre-CAS so the checkpoint stays `pending` and a capable worker can still resume it
|
|
2191
2166
|
* (design/49 §2/§3, code-ready council round-2). */
|
|
2192
2167
|
| "checkpoint.unsupported_version"
|
|
2193
|
-
/**
|
|
2168
|
+
/** `resume`/`resumeStream` was handed `internals.requestedCwd` for a checkpoint that
|
|
2194
2169
|
* carries a remote `workspaceHandle`. The restored workspace's mountPath is authoritative for the
|
|
2195
2170
|
* task root, so the cwd would be ignored at best — and verifying it would touch the env BEFORE the
|
|
2196
2171
|
* VM restore (a lazy-connect adapter then connects a fresh empty sandbox, the design/49 disease).
|
|
@@ -2253,7 +2228,7 @@ export declare class CheckpointError extends Error {
|
|
|
2253
2228
|
* the checkpoint through its own decide entry instead (the error message names it). */
|
|
2254
2229
|
| "wake.gate_pending"
|
|
2255
2230
|
/** design/144 §3 (anti spin-wake): a `wake` outcome carried no `message` and the checkpoint has no
|
|
2256
|
-
* parked
|
|
2231
|
+
* parked steer either — there is nothing to deliver, so the wake is rejected pre-CAS
|
|
2257
2232
|
* (the checkpoint stays pending) instead of burning the token on an empty continuation. */
|
|
2258
2233
|
| "wake.nothing_to_deliver"
|
|
2259
2234
|
/** Parent effective-policy inheritance: the checkpoint records `state.inheritedGate.requiresParentConstraint`
|
|
@@ -2293,7 +2268,7 @@ export declare class CheckpointError extends Error {
|
|
|
2293
2268
|
* the suspend mint. A target-bound env factory keys its placement lookup on that fixed point,
|
|
2294
2269
|
* so silently resuming under a different one would re-place the leg — and every descendant
|
|
2295
2270
|
* the child-internals chain hands it to — on another target than the parked workspace lives
|
|
2296
|
-
* on. A supplied `rootSessionId` deliberately does NOT take this refusal
|
|
2271
|
+
* on. A supplied `rootSessionId` deliberately does NOT take this refusal: it is
|
|
2297
2272
|
* delegation identity, re-supplied by every revive leg, and legitimately differs from the
|
|
2298
2273
|
* recorded root whenever the spawner carried an explicit placement — the recorded root simply
|
|
2299
2274
|
* outranks it in prepare's restore fold. Rejected PRE-CAS (the checkpoint stays `pending`);
|
|
@@ -2627,11 +2602,9 @@ export interface CheckpointStore {
|
|
|
2627
2602
|
* {@link PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES} throws `steering.queue_full` — bounded fail-loud, never
|
|
2628
2603
|
* by evicting an accepted instruction.
|
|
2629
2604
|
*
|
|
2630
|
-
*
|
|
2631
|
-
* {@link
|
|
2632
|
-
*
|
|
2633
|
-
* fields, and must build its new queue with {@link appendPendingSteer} so the bounds and the `seq` mint
|
|
2634
|
-
* are one implementation rather than one per store.
|
|
2605
|
+
* A backend must round-trip the queue field verbatim and must build its new queue with
|
|
2606
|
+
* {@link appendPendingSteer} so the bounds and the `seq` mint are one implementation rather than one
|
|
2607
|
+
* per store.
|
|
2635
2608
|
*
|
|
2636
2609
|
* **Trust is FROZEN here** — `steer.trusted` is whatever the SERVICE computed from the verified principal
|
|
2637
2610
|
* at this call (an operator-role check, NOT a client header — the service's job); the core stores it
|
|
@@ -2841,17 +2814,16 @@ export declare const MAX_STEER_INPUT_ID_CHARS = 128;
|
|
|
2841
2814
|
export declare const ACTOR_ASSERTION_FROZEN_FIELDS: readonly ["id", "hostAsserted", "issuer"];
|
|
2842
2815
|
/**
|
|
2843
2816
|
* design/171 §5.3 — THE single read point for a checkpoint's parked steers, in delivery (`seq`) order.
|
|
2817
|
+
* Every consumer — the resume drain, the wake's nothing-to-deliver guard, a serving layer — goes through
|
|
2818
|
+
* here, so no site can grow its own idea of what "the parked steer" is.
|
|
2844
2819
|
*
|
|
2845
|
-
*
|
|
2846
|
-
*
|
|
2847
|
-
*
|
|
2848
|
-
*
|
|
2849
|
-
*
|
|
2820
|
+
* A row that still carries the RETIRED pre-queue single seat (`state.pendingSteer`, written before the
|
|
2821
|
+
* queue existed) is refused here rather than read: the seat has no `inputId`, `seq` or actor, so folding
|
|
2822
|
+
* it in would mint a synthetic identity nothing else can name. The refusal is `checkpoint.unsupported_version`
|
|
2823
|
+
* with `reason: "seat_retired"` — terminal for the row's bytes; the host decides the parked instruction
|
|
2824
|
+
* on its own surface and parks it again through `setPendingSteer` if it still applies.
|
|
2850
2825
|
*/
|
|
2851
|
-
export declare function readPendingSteerQueue(state: Pick<CheckpointState, "
|
|
2852
|
-
/** design/171 §5.3 — the synthetic `inputId` a pre-queue single-seat steer reads back as. Stable (never
|
|
2853
|
-
* minted per read) so dedupe and re-reads behave, and reserved so a caller cannot collide with it. */
|
|
2854
|
-
export declare const LEGACY_PENDING_STEER_INPUT_ID = "legacy-single-seat";
|
|
2826
|
+
export declare function readPendingSteerQueue(state: Pick<CheckpointState, "pendingSteerQueue">): PendingSteerEntry[];
|
|
2855
2827
|
/**
|
|
2856
2828
|
* design/171 §5.3/§6.3 — THE append, shared by every backend so the bounds and the ordering are one
|
|
2857
2829
|
* implementation rather than one per store.
|
|
@@ -2860,7 +2832,7 @@ export declare const LEGACY_PENDING_STEER_INPUT_ID = "legacy-single-seat";
|
|
|
2860
2832
|
* be crossed. Re-appending an entry whose `inputId` is already queued is a NO-OP returning the queue
|
|
2861
2833
|
* unchanged — that is what keeps `setPendingSteer` retry-safe now that it appends instead of overwriting.
|
|
2862
2834
|
*/
|
|
2863
|
-
export declare function appendPendingSteer(state: Pick<CheckpointState, "
|
|
2835
|
+
export declare function appendPendingSteer(state: Pick<CheckpointState, "pendingSteerQueue">, entry: Omit<PendingSteerEntry, "seq">): PendingSteerEntry[];
|
|
2864
2836
|
/**
|
|
2865
2837
|
* REF-A4 — THE row half of every guarded checkpoint transition's CAS predicate, shared by every backend:
|
|
2866
2838
|
* the row must EXIST, its `scope` must match (multi-tenant isolation, §2.1 — a wrong-scope caller never
|