@sema-agent/core 7.5.1 → 7.5.2
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 +20 -0
- package/dist/core/protocol-table.d.ts +5 -0
- package/dist/core/protocol-table.js +1 -0
- package/dist/core/runner/abort-race.d.ts +41 -0
- package/dist/core/runner/abort-race.js +38 -0
- package/dist/core/runner/checkpoint-scope.d.ts +15 -3
- package/dist/core/runner/checkpoint-scope.js +3 -0
- package/dist/core/runner/compaction-call-options.d.ts +1 -1
- package/dist/core/runner/content-ask-bindings.d.ts +27 -0
- package/dist/core/runner/content-ask-bindings.js +1 -0
- package/dist/core/runner/contracts.d.ts +118 -6
- package/dist/core/runner/denial-limit-arms.d.ts +23 -0
- package/dist/core/runner/denial-limit-arms.js +21 -0
- package/dist/core/runner/inherited-ask-grants.d.ts +46 -0
- package/dist/core/runner/inherited-ask-grants.js +29 -0
- package/dist/core/runner/park-commit.d.ts +108 -0
- package/dist/core/runner/park-commit.js +32 -0
- package/dist/core/runner/{prepare-permission-rules.d.ts → permission-rule-lanes.d.ts} +109 -3
- package/dist/core/runner/{prepare-permission-rules.js → permission-rule-lanes.js} +47 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +110 -0
- package/dist/core/runner/prepare-ask-lane.js +133 -0
- package/dist/core/runner/prepare-boundary-parks.d.ts +105 -0
- package/dist/core/runner/prepare-boundary-parks.js +169 -0
- package/dist/core/runner/prepare-context-lane.d.ts +119 -0
- package/dist/core/runner/prepare-context-lane.js +230 -0
- package/dist/core/runner/prepare-gate-stations.d.ts +177 -0
- package/dist/core/runner/prepare-gate-stations.js +290 -0
- package/dist/core/runner/prepare-hands-readface.d.ts +4 -4
- package/dist/core/runner/prepare-inherited-gate.d.ts +4 -4
- package/dist/core/runner/prepare-memory-engine-session.d.ts +84 -0
- package/dist/core/runner/prepare-memory-engine-session.js +233 -0
- package/dist/core/runner/prepare-park-ask.d.ts +164 -0
- package/dist/core/runner/prepare-park-ask.js +377 -0
- package/dist/core/runner/prepare-policy-chain.d.ts +208 -0
- package/dist/core/runner/prepare-policy-chain.js +584 -0
- package/dist/core/runner/prepare-project-context.d.ts +1 -13
- package/dist/core/runner/prepare-project-context.js +1 -3
- package/dist/core/runner/prepare-prompt-assembly.d.ts +95 -0
- package/dist/core/runner/prepare-prompt-assembly.js +162 -0
- package/dist/core/runner/prepare-prompt-inputs.d.ts +1 -20
- package/dist/core/runner/prepare-protocol-tools.d.ts +3 -3
- package/dist/core/runner/prepare-protocol-tools.js +0 -3
- package/dist/core/runner/prepare-question-face.d.ts +3 -21
- package/dist/core/runner/prepare-question-face.js +2 -1
- package/dist/core/runner/prepare-safety-scan.d.ts +0 -5
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +170 -0
- package/dist/core/runner/prepare-suspend-saga.js +308 -0
- package/dist/core/runner/prepare-task.d.ts +9 -136
- package/dist/core/runner/prepare-task.js +44 -2741
- package/dist/core/runner/prepare-turn-wiring.d.ts +154 -0
- package/dist/core/runner/prepare-turn-wiring.js +201 -0
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -3
- package/dist/core/runner/prepare-wiring-manifest.js +9 -2
- package/dist/core/runner/prepare-workspace-restore.d.ts +2 -29
- package/dist/core/runner/prepare-workspace-restore.js +3 -16
- package/dist/core/runner/prompt-hash-salt.d.ts +1 -0
- package/dist/core/runner/prompt-hash-salt.js +2 -0
- package/dist/core/runner/remote-env-retry.d.ts +29 -0
- package/dist/core/runner/remote-env-retry.js +16 -0
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/session.d.ts +12 -0
- package/dist/core/session.js +3 -0
- package/package.json +1 -1
- /package/dist/core/runner/{prepare-announce-once.d.ts → announce-once-ledger.d.ts} +0 -0
- /package/dist/core/runner/{prepare-announce-once.js → announce-once-ledger.js} +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { classifyToolContentOrigin, contentOriginPollutes, delegationCallIsExternal } from "../memory-engine/content-origin.js";
|
|
2
|
+
import { narrowContentSafety, readCardAttestation } from "../memory-engine/delegation-provenance.js";
|
|
3
|
+
import { recordSyncUnattestable, sessionSettlements } from "../memory-engine/delegation-settlement.js";
|
|
4
|
+
import { protocolOf } from "../protocol-table.js";
|
|
5
|
+
import { deliverEngineNotice } from "../types.js";
|
|
6
|
+
import { inlineUntrusted } from "../untrusted-text.js";
|
|
7
|
+
import { fileArgPath } from "../../tools/fs/safety.js";
|
|
8
|
+
export function prepareMemoryEngineSession(input) {
|
|
9
|
+
const { memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, tools, contentOriginWrapRef } = input;
|
|
10
|
+
const delegationProvenanceChannel = internals?.delegationProvenance;
|
|
11
|
+
if (memoryEngineSession !== undefined || delegationProvenanceChannel !== undefined) {
|
|
12
|
+
const pollution = memoryEngineSession?.pollution;
|
|
13
|
+
const delegationEvidenceAttestedOnly = memoryDelegationEvidence === "attested-only";
|
|
14
|
+
let staticMarkWaiverAnnounced = false;
|
|
15
|
+
const effectiveSafety = narrowContentSafety(delegationProvenanceChannel?.contentSafety, memoryEngineSession?.contentSafety);
|
|
16
|
+
const trustedTools = effectiveSafety.trustedTools;
|
|
17
|
+
const execIsExternalContent = effectiveSafety.execIsExternalContent || externalContentTargetActive;
|
|
18
|
+
provenanceForChildrenRef.current = { trustedTools: [...trustedTools], execIsExternalContent };
|
|
19
|
+
announceDeclaredMcpContentClasses({
|
|
20
|
+
entries: lockedPreflight.mcp,
|
|
21
|
+
statuses: mcp.statuses,
|
|
22
|
+
execIsExternalContent,
|
|
23
|
+
sessionId,
|
|
24
|
+
runId,
|
|
25
|
+
onNotice: deps.onNotice,
|
|
26
|
+
});
|
|
27
|
+
if (memoryEngineSession?.settlement !== undefined) {
|
|
28
|
+
delegationSettlementRef.current = { controlDir: memoryEngineSession.settlement.controlDir, sessionId: memoryEngineSession.settlement.sessionId };
|
|
29
|
+
}
|
|
30
|
+
const recordExternal = () => {
|
|
31
|
+
if (delegationProvenanceChannel !== undefined)
|
|
32
|
+
delegationProvenanceChannel.ref.current.sawExternal = true;
|
|
33
|
+
};
|
|
34
|
+
const recordIncomplete = () => {
|
|
35
|
+
if (delegationProvenanceChannel !== undefined)
|
|
36
|
+
delegationProvenanceChannel.ref.current.incomplete = true;
|
|
37
|
+
};
|
|
38
|
+
const callerToolNames = new Set((spec.tools ?? []).map((t) => t.name));
|
|
39
|
+
const contentOriginWrapped = new WeakSet();
|
|
40
|
+
const classOf = (t) => externalContentTargetActive && envHandToolNames.has(t.name)
|
|
41
|
+
? "external"
|
|
42
|
+
: classifyToolContentOrigin({
|
|
43
|
+
declared: t.contentOrigin,
|
|
44
|
+
isProtocolTool: protocolOf(t.name) !== undefined,
|
|
45
|
+
isCallerTool: callerToolNames.has(t.name),
|
|
46
|
+
trusted: trustedTools.has(t.name),
|
|
47
|
+
});
|
|
48
|
+
const delegationByName = new Map();
|
|
49
|
+
for (const t of spec.tools ?? []) {
|
|
50
|
+
const withFaces = t;
|
|
51
|
+
if (withFaces.agentToolFaces === undefined && t.agentListing === undefined)
|
|
52
|
+
continue;
|
|
53
|
+
delegationByName.set(t.name, { faces: withFaces.agentToolFaces, pool: withFaces.agentToolPool });
|
|
54
|
+
}
|
|
55
|
+
const poolToolPollutes = (t) => contentOriginPollutes(classifyToolContentOrigin({
|
|
56
|
+
declared: t.contentOrigin,
|
|
57
|
+
isProtocolTool: protocolOf(t.name) !== undefined,
|
|
58
|
+
isCallerTool: true,
|
|
59
|
+
trusted: trustedTools.has(t.name),
|
|
60
|
+
}), execIsExternalContent);
|
|
61
|
+
const recallTaintJudge = memoryEngineSession?.recallTaint?.judgeDeliveredPath;
|
|
62
|
+
contentOriginWrapRef.current = () => {
|
|
63
|
+
for (let i = 0; i < tools.length; i++) {
|
|
64
|
+
const t = tools[i];
|
|
65
|
+
if (contentOriginWrapped.has(t))
|
|
66
|
+
continue;
|
|
67
|
+
const origin = classOf(t);
|
|
68
|
+
const delegation = delegationByName.get(t.name);
|
|
69
|
+
const isDelegation = delegation !== undefined;
|
|
70
|
+
const pollutes = contentOriginPollutes(origin, execIsExternalContent);
|
|
71
|
+
const readsMemoryPlane = recallTaintJudge !== undefined && t.name === "Read";
|
|
72
|
+
if (!pollutes && !isDelegation && !readsMemoryPlane) {
|
|
73
|
+
contentOriginWrapped.add(t);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const inner = t.execute.bind(t);
|
|
77
|
+
const mark = (reason, cause) => {
|
|
78
|
+
try {
|
|
79
|
+
pollution?.markPolluted(reason, cause);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const wrapped = {
|
|
85
|
+
...t,
|
|
86
|
+
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
87
|
+
if (pollutes) {
|
|
88
|
+
mark(`tool "${t.name}" (${origin} content class) was invoked in this session`, "observed");
|
|
89
|
+
recordExternal();
|
|
90
|
+
}
|
|
91
|
+
if (!isDelegation) {
|
|
92
|
+
if (!readsMemoryPlane)
|
|
93
|
+
return inner(toolCallId, params, signal, onUpdate);
|
|
94
|
+
const result = await inner(toolCallId, params, signal, onUpdate);
|
|
95
|
+
const raw = result;
|
|
96
|
+
const contentField = typeof raw === "object" && raw !== null ? raw.content : undefined;
|
|
97
|
+
const headText = typeof raw === "string"
|
|
98
|
+
? raw
|
|
99
|
+
: typeof contentField === "string"
|
|
100
|
+
? contentField
|
|
101
|
+
: Array.isArray(contentField) && typeof contentField[0]?.text === "string"
|
|
102
|
+
? contentField[0].text
|
|
103
|
+
: "";
|
|
104
|
+
const delivered = result?.isError !== true &&
|
|
105
|
+
result?.details?.type !== "file_unchanged" &&
|
|
106
|
+
!headText.startsWith("<system-reminder");
|
|
107
|
+
const fp = fileArgPath(params);
|
|
108
|
+
if (delivered && fp !== undefined && recallTaintJudge(fp)) {
|
|
109
|
+
mark(`the "${t.name}" tool delivered the content of an external-origin memory entry file`, "derived");
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
let preCallLaunchRows;
|
|
114
|
+
if (delegationEvidenceAttestedOnly && memoryEngineSession?.settlement !== undefined) {
|
|
115
|
+
try {
|
|
116
|
+
preCallLaunchRows = new Set(sessionSettlements(memoryEngineSession.settlement.controlDir, memoryEngineSession.settlement.sessionId)
|
|
117
|
+
.filter((r) => r.row.lane === "background" && r.row.toolUseId === toolCallId)
|
|
118
|
+
.map((r) => r.row.settleId));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
preCallLaunchRows = undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const requested = params?.subagent_type;
|
|
125
|
+
const external = delegationCallIsExternal({
|
|
126
|
+
requestedType: typeof requested === "string" ? requested : undefined,
|
|
127
|
+
faces: delegation.faces,
|
|
128
|
+
pool: delegation.pool,
|
|
129
|
+
isPolluting: poolToolPollutes,
|
|
130
|
+
});
|
|
131
|
+
const result = await inner(toolCallId, params, signal, onUpdate);
|
|
132
|
+
const att = readCardAttestation(result?.details);
|
|
133
|
+
if (att === "external") {
|
|
134
|
+
mark(`tool "${t.name}" returned the output of a delegated agent that invoked an external-content-class tool at runtime` +
|
|
135
|
+
(typeof requested === "string" ? ` (subagent_type "${requested}")` : ""), "observed");
|
|
136
|
+
recordExternal();
|
|
137
|
+
}
|
|
138
|
+
else if (att !== "clean") {
|
|
139
|
+
if (external) {
|
|
140
|
+
const staticFaceReason = `tool "${t.name}" returned the output of a delegated agent whose tool face can reach external content` +
|
|
141
|
+
(typeof requested === "string" ? ` (subagent_type "${requested}")` : " (no subagent_type named — classified fail-closed)");
|
|
142
|
+
if (!delegationEvidenceAttestedOnly) {
|
|
143
|
+
mark(staticFaceReason, "static");
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const receiptDetails = result?.details;
|
|
147
|
+
const claimsLaunchReceipt = receiptDetails !== undefined && receiptDetails !== null && receiptDetails.status === "async_launched";
|
|
148
|
+
const claimedSettleId = claimsLaunchReceipt && typeof receiptDetails.settle_id === "string" ? receiptDetails.settle_id : undefined;
|
|
149
|
+
const settlementSeat = memoryEngineSession?.settlement;
|
|
150
|
+
let isLaunchReceipt = false;
|
|
151
|
+
if (claimsLaunchReceipt && settlementSeat !== undefined) {
|
|
152
|
+
try {
|
|
153
|
+
isLaunchReceipt =
|
|
154
|
+
preCallLaunchRows !== undefined &&
|
|
155
|
+
claimedSettleId !== undefined &&
|
|
156
|
+
!preCallLaunchRows.has(claimedSettleId) &&
|
|
157
|
+
sessionSettlements(settlementSeat.controlDir, settlementSeat.sessionId).some((r) => r.row.lane === "background" && r.row.settleId === claimedSettleId && r.row.toolUseId === toolCallId);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
isLaunchReceipt = false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!isLaunchReceipt && settlementSeat !== undefined) {
|
|
164
|
+
try {
|
|
165
|
+
recordSyncUnattestable(settlementSeat.controlDir, { sessionId: settlementSeat.sessionId, toolCallId, now: Date.now });
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
const e = new Error(`delegated output withheld (fail-closed): the delegation delivered without a provable attestation and the settlement account could not record the fact (${err instanceof Error ? err.message : String(err)}) — repair the memory control plane or retry`);
|
|
169
|
+
e.code = "memory.settlement_record_failed";
|
|
170
|
+
throw e;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (delegationEvidenceAttestedOnly && pollution !== undefined && !staticMarkWaiverAnnounced) {
|
|
175
|
+
staticMarkWaiverAnnounced = true;
|
|
176
|
+
const waivedReason = inlineUntrusted(staticFaceReason, 200);
|
|
177
|
+
deliverEngineNotice(deps.onNotice, {
|
|
178
|
+
code: "memory.delegation_static_mark_waived",
|
|
179
|
+
message: `Delegation static-face pollution mark waived: ${waivedReason}. The deployment configured ` +
|
|
180
|
+
`memoryDelegationEvidence="attested-only", so a static tool-face verdict alone does not mark this ` +
|
|
181
|
+
`session's memory polluted; a delivered "external" attestation and a direct polluting-class ` +
|
|
182
|
+
`invocation still mark, and on a provenance-armed chain this delegation still records as ` +
|
|
183
|
+
`incomplete. At most one notice per prepared task leg.`,
|
|
184
|
+
detail: {
|
|
185
|
+
reason: waivedReason,
|
|
186
|
+
...(typeof requested === "string" ? { subagentType: inlineUntrusted(requested, 120) } : {}),
|
|
187
|
+
sessionId,
|
|
188
|
+
runId,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
recordIncomplete();
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
contentOriginWrapped.add(wrapped);
|
|
199
|
+
tools[i] = wrapped;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
contentOriginWrapRef.current();
|
|
203
|
+
}
|
|
204
|
+
return { armed: memoryEngineSession !== undefined || delegationProvenanceChannel !== undefined };
|
|
205
|
+
}
|
|
206
|
+
function announceDeclaredMcpContentClasses(args) {
|
|
207
|
+
for (const entry of args.entries ?? []) {
|
|
208
|
+
const declaredClass = entry.contentOrigin;
|
|
209
|
+
if (declaredClass === undefined)
|
|
210
|
+
continue;
|
|
211
|
+
const server = inlineUntrusted(String(entry.name), 160);
|
|
212
|
+
const toolCount = args.statuses?.find((s) => s.name === entry.name)?.toolNames?.length ?? 0;
|
|
213
|
+
const resourceFaceCaveat = " (Not covered: the cross-server resource faces — ListMcpResourcesTool/ReadMcpResourceTool/ReadMcpResourceDirTool — stay externally classified and still mark.)";
|
|
214
|
+
const posture = declaredClass === "local"
|
|
215
|
+
? `this server's mounted tools' invocations will not mark this session's memory as externally exposed.${resourceFaceCaveat}`
|
|
216
|
+
: declaredClass === "execution"
|
|
217
|
+
? `this server's mounted tools' invocations will not mark this session's memory unless the execIsExternalContent strict upgrade is armed (currently: ${args.execIsExternalContent ? "armed" : "off"}).${resourceFaceCaveat}`
|
|
218
|
+
: "its tools stay externally classified and this declaration PINS that — the trustedTools allowlist no longer exempts them, and invocations mark this session's memory.";
|
|
219
|
+
deliverEngineNotice(args.onNotice, {
|
|
220
|
+
code: "memory.content_class_declared",
|
|
221
|
+
message: `MCP server "${server}" (${toolCount} tool(s) mounted) is declared ` +
|
|
222
|
+
`contentOrigin "${declaredClass}" by this deployment's configuration — ${posture}`,
|
|
223
|
+
detail: {
|
|
224
|
+
server,
|
|
225
|
+
contentOrigin: declaredClass,
|
|
226
|
+
toolCount,
|
|
227
|
+
...(declaredClass === "execution" ? { execIsExternalContent: args.execIsExternalContent } : {}),
|
|
228
|
+
sessionId: args.sessionId,
|
|
229
|
+
runId: args.runId,
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/390 §1.2 M19 (park ask) — prepareTask's PARK CLOSURE and CONTENT-ASK ROUTING closure, verbatim from the driver's
|
|
3
|
+
* gate-machinery block: `resolveContentAsk` (the question face's delivery race, the binding table's cap and redemption
|
|
4
|
+
* identity, the stranded-answer disclosure) and `suspendAsk` (the sync-first decline and the park-priority mandates, the
|
|
5
|
+
* args capture / fidelity projection / re-adjudication steps, the pause-then-cut fence, the gate-kind choice, the row
|
|
6
|
+
* mint, the commit through the saga and the post-commit publication). The one module-scope helper only this segment
|
|
7
|
+
* threw (`ParkRefusal`) moved with it. The interface is the dependency list the segment had implicitly (design/238
|
|
8
|
+
* R-1) — the two closures used to capture every seat here off the driver's scope, which is the capture surface this
|
|
9
|
+
* decomposition exists to make explicit.
|
|
10
|
+
*
|
|
11
|
+
* The thirteen-argument park closure is unchanged: twelve positional seats then the structural {@link AskCarry}, the
|
|
12
|
+
* shape the gate's one invocation site (`parkWith`) holds. The ask's origin word and the denial-limit fallback ride the
|
|
13
|
+
* carry onto the row exactly as before — this phase mints no origin, changes no word, adds no arm to the closed set.
|
|
14
|
+
*
|
|
15
|
+
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await of its own (both closures run per tool call), so the
|
|
16
|
+
* phase adds no yield between the boundary parks before it and the gate station after it (design/390 §1.5).
|
|
17
|
+
* Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
18
|
+
*
|
|
19
|
+
* Both closures exist exactly when the ask lane and the saga do (the same predicate) — an absent lane answers two absent
|
|
20
|
+
* closures, so the orchestrator grows no branch.
|
|
21
|
+
*/
|
|
22
|
+
import type { AgentHarness, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
23
|
+
import { type OnQuestion } from "../ask-question.js";
|
|
24
|
+
import { type CheckpointStore } from "../checkpoint-store.js";
|
|
25
|
+
import type { SessionStore } from "../session.js";
|
|
26
|
+
import { type OnAsk, type ToolCallRequest, type ToolPolicy } from "../tool-policy.js";
|
|
27
|
+
import { type ToolResultStore } from "../tool-result-store.js";
|
|
28
|
+
import type { RunnerDeps, RuntimeCaps, TaskSpec } from "../types.js";
|
|
29
|
+
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
30
|
+
import { type ContentAskBinding } from "./content-ask-bindings.js";
|
|
31
|
+
import type { AskLane, ParkAsk, Prepared, SuspendSaga } from "./contracts.js";
|
|
32
|
+
import type { createRuleOffersOf } from "./permission-rule-lanes.js";
|
|
33
|
+
export interface PrepareParkAskInput {
|
|
34
|
+
/** borrowed-readonly — the in-stream ask lane, or undefined when the gate machinery is inactive (then both closures are
|
|
35
|
+
* absent). Read: `composedCallSignal` (the fence and the delivery race), `approvalPreviewOf` (the row's preview). */
|
|
36
|
+
askLane: AskLane | undefined;
|
|
37
|
+
/** borrowed-readonly — the durable settlement saga, or undefined (same law). Read: `suspendableEnv` / `parkOnlyRemoteEnv` /
|
|
38
|
+
* `parkOnlyHandle` (the pause target), `suspendLoopCapHit`, `serializeCheckpointState`, `inFlightSpendMicroUsd`,
|
|
39
|
+
* `compensatePausedVM` (the pause-then-cut arm), `commitSuspendSaga` (the point of no return). */
|
|
40
|
+
saga: SuspendSaga | undefined;
|
|
41
|
+
/** borrowed-readonly — the REBOUND spec. Read: `principal` (the question's source identity, the unattended re-scope, the
|
|
42
|
+
* row's identity record), `retainBackgroundProcesses` (the park-only sweep gate). Never mutated. */
|
|
43
|
+
spec: Pick<TaskSpec, "principal" | "retainBackgroundProcesses">;
|
|
44
|
+
/** borrowed-readonly — the deployment's error face, as a Pick over the SAME `deps` object (receiver preserved for
|
|
45
|
+
* `deps.onError?.()`): the park refusals' disclosure, the pin failure. */
|
|
46
|
+
deps: Pick<RunnerDeps, "onError">;
|
|
47
|
+
/** borrowed-readonly — the acquired session id (the question's `sourceTaskId`, the row's session and source, every tag). */
|
|
48
|
+
sessionId: string;
|
|
49
|
+
/** borrowed-readonly — the leg's checkpoint store, or undefined (then `suspendAsk` is absent — the park predicate's store
|
|
50
|
+
* term). Read: the declared fidelity; the saga writes to it. */
|
|
51
|
+
checkpointStore: CheckpointStore | undefined;
|
|
52
|
+
/** borrowed-readonly — the wiring-manifest phase's park predicate (`parkLane.effective`): arms `suspendAsk`. */
|
|
53
|
+
parkLaneArmed: boolean;
|
|
54
|
+
/** borrowed-readonly — the question-face phase's routability predicate (the mounted question tool is the engine's own,
|
|
55
|
+
* resolved against the LIVE roster per call). */
|
|
56
|
+
contentAskRoutable: (toolCallId: string) => boolean;
|
|
57
|
+
/** borrowed-readonly — the live question face, or undefined (then a content ask answers `unavailable`). */
|
|
58
|
+
liveQuestionFace: OnQuestion | undefined;
|
|
59
|
+
/** borrowed-readonly — the mounted AskUserQuestion tool, or undefined; only its `parameters` schema is read (the pre-delivery
|
|
60
|
+
* validation). */
|
|
61
|
+
mountedQuestionTool: AgentTool | undefined;
|
|
62
|
+
/** borrowed-mutable — the content-ask binding table (the question-face phase mints it). Writer here: `bindOutcome`
|
|
63
|
+
* (`set`, cap-checked before every insertion); the mounted tool and the leg-end settle consume. */
|
|
64
|
+
contentAskBindings: Map<string, ContentAskBinding>;
|
|
65
|
+
/** borrowed-mutable — the stranded late answers (the question-face phase mints it). Writer here: the delivery race's
|
|
66
|
+
* aborted arm (`push`) when an answer lands after the race. */
|
|
67
|
+
lateStrandedAnswers: Array<{
|
|
68
|
+
deliveryId: string;
|
|
69
|
+
toolCallId: string;
|
|
70
|
+
}>;
|
|
71
|
+
/** borrowed-readonly — the question-face phase's stranded-answer disclosure (called on the same late arm). */
|
|
72
|
+
discloseStrandedAnswers: (records: ReadonlyArray<{
|
|
73
|
+
deliveryId: string;
|
|
74
|
+
toolCallId: string;
|
|
75
|
+
}>, why: string) => void;
|
|
76
|
+
/** borrowed-readonly — the run's own approver seat, or undefined (the sync-first decline's live-approver test). */
|
|
77
|
+
onAsk: OnAsk | undefined;
|
|
78
|
+
/** borrowed-readonly — the resolved per-principal entitlements, or undefined (`forceDurableGate` keeps park priority). */
|
|
79
|
+
runtimeCaps: RuntimeCaps | undefined;
|
|
80
|
+
/** borrowed-readonly — the inherited-unavailable marker set; read only here (`has`: park priority and the row's
|
|
81
|
+
* `inheritedUnresolved`). The ask lane consumes, the gate station sweeps. */
|
|
82
|
+
inheritedUnavailableAsks: ReadonlySet<string>;
|
|
83
|
+
/** borrowed-readonly — the policy the projection re-adjudication consults when the codec moved the value, or undefined
|
|
84
|
+
* (then a moved projection refuses the park). Called at park time. */
|
|
85
|
+
basePolicyForResumeEdit: ToolPolicy | undefined;
|
|
86
|
+
/** borrowed-readonly — the per-leg-immutable budget snapshot the re-adjudication carries (same object as the main gate). */
|
|
87
|
+
budgetSnapshot: NonNullable<ToolCallRequest["budget"]>;
|
|
88
|
+
/** borrowed-readonly — the hand's live tracked cwd, or undefined; `current` is read at park time for the re-adjudication.
|
|
89
|
+
* Not written here. */
|
|
90
|
+
handsCwdRef: CwdRef | undefined;
|
|
91
|
+
/** borrowed-readonly — the run's offload store, or undefined (a volatile store holding results refuses the park). */
|
|
92
|
+
offloadStore: ToolResultStore | undefined;
|
|
93
|
+
/** borrowed-readonly — the per-task owned env, or undefined (a non-remote per-task env refuses the park). Never destroyed. */
|
|
94
|
+
ownedEnv: ExecutionEnv | undefined;
|
|
95
|
+
/** borrowed-readonly — the restore-incomplete adapter's missing members, or undefined (names the actual gap in the refusal). */
|
|
96
|
+
incompleteSuspendAdapter: readonly ("resumeVM" | "postResumeInit")[] | undefined;
|
|
97
|
+
/** borrowed-readonly — the acquired session; `getLeafId` (the resume point) and `buildContext` (the batch position) are read. */
|
|
98
|
+
session: Pick<Prepared["session"], "getLeafId" | "buildContext">;
|
|
99
|
+
/** borrowed-readonly — the session store; only the optional `pin` is called (best-effort, after commit). */
|
|
100
|
+
sessions: Pick<SessionStore, "pin">;
|
|
101
|
+
/** borrowed-readonly — the restart-loop chain base (the row's `suspendCount`, the cap's count). */
|
|
102
|
+
suspendChainBase: () => number;
|
|
103
|
+
/** borrowed-readonly — the restart-loop cap. */
|
|
104
|
+
maxSuspends: number;
|
|
105
|
+
/** borrowed-mutable — the run-scoped remote-lifecycle failure log. Writer here: a refused `suspendVM` (`push`). */
|
|
106
|
+
remoteEnvFailures: Prepared["remoteEnvFailures"];
|
|
107
|
+
/** borrowed-readonly — whether Bash is coarsely shell-gated (the risk descriptor's `shellGated`). */
|
|
108
|
+
shellGatedBash: boolean;
|
|
109
|
+
/** borrowed-readonly — whether Monitor is coarsely shell-gated (same). */
|
|
110
|
+
shellGatedMonitor: boolean;
|
|
111
|
+
/** borrowed-readonly — the effective shell-gate doctrine persisted on the descriptor. */
|
|
112
|
+
effectiveShellGate: "off" | "classify" | "always";
|
|
113
|
+
/** borrowed-readonly — the EFFECTIVE durable-approval opt-in (the caller's, or the synthesized mandate scope): picks the
|
|
114
|
+
* gate kind, the scope and the ttl. */
|
|
115
|
+
durableApproval: TaskSpec["durableApproval"];
|
|
116
|
+
/** borrowed-readonly — the cross-slice ledger carried on the resumed checkpoint, or undefined. */
|
|
117
|
+
priorLedger: Prepared["resourceLedger"];
|
|
118
|
+
/** borrowed-readonly — the loop's live spend seat; `.get` is read at mint time. */
|
|
119
|
+
liveSpendRef: Prepared["liveSpendRef"];
|
|
120
|
+
/** borrowed-readonly — the human total the first slice seeds the ledger from, or undefined. */
|
|
121
|
+
resourceTotal: {
|
|
122
|
+
totalBudgetMicroUsd?: number;
|
|
123
|
+
totalTokens?: number;
|
|
124
|
+
} | undefined;
|
|
125
|
+
/** borrowed-readonly — the inherited-gate phase's three version-stamp predicates (face / F-012 / org admission). */
|
|
126
|
+
faceCheckpointState: () => boolean;
|
|
127
|
+
/** borrowed-readonly — see `faceCheckpointState`. */
|
|
128
|
+
f012CheckpointState: () => boolean;
|
|
129
|
+
/** borrowed-readonly — see `faceCheckpointState`. */
|
|
130
|
+
orgAdmissionCheckpointState: () => boolean;
|
|
131
|
+
/** borrowed-readonly — the policy-chain phase's rule-offer factory (the row's suggestion members). */
|
|
132
|
+
ruleOffersOf: ReturnType<typeof createRuleOffersOf>;
|
|
133
|
+
/** borrowed-readonly — the injectable wall clock (the row's `suspendedAt`). */
|
|
134
|
+
now: () => number;
|
|
135
|
+
/** borrowed-readonly — the per-task human-review accumulator; snapshotted onto the row (never written here). */
|
|
136
|
+
humanReviewRef: Prepared["humanReviewRef"];
|
|
137
|
+
/** borrowed-mutable — prepare's abort seat. Writers here: `abort()` after a committed park and on a failed pause
|
|
138
|
+
* compensation; `.signal` is composed into the fence. */
|
|
139
|
+
abortController: {
|
|
140
|
+
readonly signal: AbortSignal;
|
|
141
|
+
abort(): void;
|
|
142
|
+
};
|
|
143
|
+
/** borrowed-mutable — the built harness. Writer here: `abort()` (release the gate, then stop the loop). */
|
|
144
|
+
harness: Pick<AgentHarness, "abort">;
|
|
145
|
+
/** borrowed-mutable — the durable-suspend holder (`Prepared.suspendRef`). Writer here: the commit-side publication. */
|
|
146
|
+
suspendRef: Prepared["suspendRef"];
|
|
147
|
+
/** borrowed-readonly — the review holder; handed to the commit-side discriminant, which never writes it for these kinds. */
|
|
148
|
+
reviewRef: Prepared["reviewRef"];
|
|
149
|
+
}
|
|
150
|
+
export interface PrepareParkAskResult {
|
|
151
|
+
/** owned — the two closures as ONE value, or undefined exactly when the ask lane (and so the saga) is absent. */
|
|
152
|
+
parkAsk: ParkAsk | undefined;
|
|
153
|
+
}
|
|
154
|
+
/** The M19 park-ask phase body — prepareTask's park closure and content-ask routing stretch, verbatim (see the module header). */
|
|
155
|
+
export declare function prepareParkAsk(input: PrepareParkAskInput): PrepareParkAskResult;
|
|
156
|
+
/**
|
|
157
|
+
* From the resumed/active transcript, the batch position of `currentId` (design/45 §4.ter): the tool-call
|
|
158
|
+
* ids of the assistant message that issued it (the batch), and the subset already resolved (executed
|
|
159
|
+
* before the suspend — #1..k-1). ID-based, not positional (council Question #1): immune to reordering.
|
|
160
|
+
*/
|
|
161
|
+
export declare function batchContextAt(messages: AgentMessage[], currentId: string): {
|
|
162
|
+
batchToolCallIds: string[];
|
|
163
|
+
completedCallIds: string[];
|
|
164
|
+
};
|