@sema-agent/core 7.5.1 → 7.6.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 +61 -0
- package/dist/agents/cascade.d.ts +2 -2
- package/dist/agents/cascade.js +12 -10
- package/dist/agents/repair-loop.d.ts +5 -3
- package/dist/agents/repair-loop.js +13 -15
- package/dist/agents/subagent.d.ts +24 -42
- package/dist/agents/subagent.js +119 -105
- package/dist/agents/suspend-guard.d.ts +31 -19
- package/dist/agents/suspend-guard.js +14 -8
- package/dist/agents/teacher.js +9 -9
- package/dist/agents/team.d.ts +4 -3
- package/dist/agents/team.js +10 -8
- package/dist/agents/verify.d.ts +3 -3
- package/dist/agents/verify.js +17 -17
- package/dist/core/a2a.js +2 -1
- package/dist/core/ask-origin.d.ts +60 -7
- package/dist/core/ask-origin.js +26 -1
- package/dist/core/checkpoint-store.d.ts +78 -76
- package/dist/core/checkpoint-store.js +17 -1
- package/dist/core/gate-outcome.d.ts +189 -0
- package/dist/core/gate-outcome.js +70 -0
- package/dist/core/hooks.d.ts +18 -92
- package/dist/core/hooks.js +88 -85
- package/dist/core/mcp-failure.d.ts +104 -0
- package/dist/core/mcp-failure.js +128 -0
- package/dist/core/mcp.d.ts +21 -77
- package/dist/core/mcp.js +76 -150
- package/dist/core/pause-registry.d.ts +131 -0
- package/dist/core/pause-registry.js +27 -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/assemble-result.d.ts +32 -41
- package/dist/core/runner/assemble-result.js +55 -74
- 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 +144 -50
- package/dist/core/runner/denial-limit-arms.d.ts +24 -1
- package/dist/core/runner/denial-limit-arms.js +24 -3
- package/dist/core/runner/gate-exit.d.ts +74 -0
- package/dist/core/runner/gate-exit.js +55 -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 +102 -0
- package/dist/core/runner/park-commit.js +31 -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 +107 -0
- package/dist/core/runner/prepare-ask-lane.js +131 -0
- package/dist/core/runner/prepare-boundary-parks.d.ts +102 -0
- package/dist/core/runner/prepare-boundary-parks.js +169 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- 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 +174 -0
- package/dist/core/runner/prepare-gate-stations.js +265 -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-inherited-gate.js +1 -1
- 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-memory.d.ts +44 -26
- package/dist/core/runner/prepare-park-ask.d.ts +162 -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 +47 -2745
- 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 +17 -17
- package/dist/core/runner/prepare-wiring-manifest.js +16 -10
- 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.d.ts +16 -31
- package/dist/core/runner/runtask.js +110 -121
- package/dist/core/runner/terminal-projection.d.ts +22 -0
- package/dist/core/runner/terminal-projection.js +28 -0
- package/dist/core/session.d.ts +12 -0
- package/dist/core/session.js +3 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +4 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +8 -2
- package/dist/core/terminal-cause.d.ts +137 -0
- package/dist/core/terminal-cause.js +9 -0
- package/dist/core/tool-policy.d.ts +43 -139
- package/dist/core/tool-policy.js +79 -112
- package/dist/core/types.d.ts +67 -164
- package/dist/core/wiring-manifest.d.ts +6 -3
- package/dist/core/workflow-journal-store.js +3 -4
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.js +8 -5
- package/dist/orchestration/builtin-workflows.d.ts +2 -2
- package/dist/orchestration/builtin-workflows.js +1 -1
- package/dist/orchestration/goal.js +8 -7
- package/dist/orchestration/run-spec.js +5 -3
- package/dist/orchestration/run-workflow-tool.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.js +4 -4
- package/dist/orchestration/workflow-governance.d.ts +4 -4
- package/dist/orchestration/workflow-governance.js +4 -2
- package/dist/orchestration/workflow-primitives.d.ts +1 -1
- package/dist/orchestration/workflow-primitives.js +1 -1
- package/dist/orchestration/workflow.d.ts +11 -0
- package/dist/orchestration/workflow.js +64 -39
- package/dist/prompts/supervisor.d.ts +1 -1
- package/dist/prompts/supervisor.js +3 -3
- package/dist/scenarios/scenario-registry.js +1 -1
- package/package.json +3 -1
- package/test/export-surface.snapshot.json +74 -22
- /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
|
+
}
|
|
@@ -2,15 +2,29 @@ import type { BeforeWriteHook, EffectiveMemoryScopes, RunnerDeps, TaskSpec, Tool
|
|
|
2
2
|
import { type CaptureEntitlementInput, type MemoryCapturePosture } from "./memory-capture-optout.js";
|
|
3
3
|
import type { Prepared } from "./contracts.js";
|
|
4
4
|
export interface PrepareMemoryInput {
|
|
5
|
+
/** borrowed-readonly — the REBOUND spec. Read: `memory` (the scope declaration this phase
|
|
6
|
+
* normalizes) and `principal` (the org-admission subject). Never mutated. */
|
|
5
7
|
spec: TaskSpec;
|
|
8
|
+
/** borrowed-readonly — the deployment seams this phase reads: the two operator lanes (`onError`,
|
|
9
|
+
* `onNotice`), the memory planes (`memoryBackend`, `memoryStore`, `memoryEngineDir`, `rootPath`,
|
|
10
|
+
* `deploymentMemoryScopes`, `memoryScopeAdmission`), `memoryCaptureRecordStore`,
|
|
11
|
+
* `memoryConsolidation`, `runtimeCapsResolver` and `onMemoryHarvestReport`. Receivers preserved
|
|
12
|
+
* (`deps.onError?.(…)`). */
|
|
6
13
|
deps: RunnerDeps;
|
|
14
|
+
/** borrowed-readonly — the acquired session's id: the engine session's key, the operator lines'
|
|
15
|
+
* context, and the capture record's subject. */
|
|
7
16
|
sessionId: string;
|
|
17
|
+
/** borrowed-readonly — the resolved task root: the containment boundary every derived memory dir
|
|
18
|
+
* is checked against, and the repo-root fallback when `deps.rootPath` is unset. */
|
|
8
19
|
taskRootPath: string;
|
|
20
|
+
/** borrowed-mutable — the caller's write-gate cell, and THIS phase is its writer: it installs the
|
|
21
|
+
* memory write gate into `.current` (the module header's one out-param effect). Identity is the
|
|
22
|
+
* contract — the caller's hands/read-face seat reads this exact cell. */
|
|
9
23
|
memoryWriteGateRef: {
|
|
10
24
|
current?: BeforeWriteHook;
|
|
11
25
|
};
|
|
12
26
|
/**
|
|
13
|
-
* #181-F5
|
|
27
|
+
* borrowed-readonly — #181-F5: whether a tool NAMED `Write` (the tool the CC `# Memory` instruction names) is on the
|
|
14
28
|
* ASSEMBLED roster this run, not excluded, AND can actually REACH the host-side memory root:
|
|
15
29
|
* prepare-task's `tools.some(t => t.name === "Write") && !exclude.includes("Write")` plus the
|
|
16
30
|
* remote-env conjunct (a hand-band Write on a remote ExecutionEnv writes the sandbox filesystem,
|
|
@@ -22,12 +36,12 @@ export interface PrepareMemoryInput {
|
|
|
22
36
|
* its roster (or cannot reach the store); the RB-276 index seed follows the same gate.
|
|
23
37
|
*/
|
|
24
38
|
writeToolsMounted: boolean;
|
|
25
|
-
/** design/319 (A ticket)
|
|
39
|
+
/** borrowed-readonly — design/319 (A ticket): the run's reminder provenance mark: the memory engine's announcement
|
|
26
40
|
* block is an engine-authored `<system-reminder>`, so its open tag must carry the same mark the
|
|
27
41
|
* system-prompt declaration names. Threaded into every `engine.inject` call this phase builds. */
|
|
28
42
|
reminderMark: string;
|
|
29
43
|
/**
|
|
30
|
-
*
|
|
44
|
+
* borrowed-readonly — the session-wide persistence verdict: `TaskSpec.memoryPersistenceCapable` (the deployment's own
|
|
31
45
|
* statement — the only honest channel for a custom memory writer persisting through its closure,
|
|
32
46
|
* which no inference can see) when set, else the KNOWN-store-path inference: a mounted,
|
|
33
47
|
* non-excluded file-write tool (Write/Edit/NotebookEdit) or a write-capable shell. A generic
|
|
@@ -37,7 +51,7 @@ export interface PrepareMemoryInput {
|
|
|
37
51
|
*/
|
|
38
52
|
rosterCanPersist: boolean;
|
|
39
53
|
/**
|
|
40
|
-
*
|
|
54
|
+
* borrowed-readonly — the raw `TaskSpec.memoryPersistenceCapable` DECLARATION, kept separate from the composed
|
|
41
55
|
* {@link rosterCanPersist} verdict because the two drive different arms:
|
|
42
56
|
* - `true` (declared) RETRACTS the engine's own read-only notice — the deployment vouches for a
|
|
43
57
|
* persistence channel the engine cannot see (a custom writer persisting through its closure),
|
|
@@ -52,14 +66,14 @@ export interface PrepareMemoryInput {
|
|
|
52
66
|
*/
|
|
53
67
|
memoryPersistenceDeclared?: boolean;
|
|
54
68
|
/**
|
|
55
|
-
* design/336 §13-3
|
|
69
|
+
* borrowed-readonly — design/336 §13-3: the memory-provenance master switch, screened at the config doors
|
|
56
70
|
* (`config.memory_provenance`, exact spellings, absent folded to `"carry"`). Every engine this
|
|
57
71
|
* phase constructs runs under it, and the pollution notices/tool wording state the mode-true
|
|
58
72
|
* behavior off it. See {@link RunnerDeps.memoryProvenance}.
|
|
59
73
|
*/
|
|
60
74
|
memoryProvenance: "off" | "carry";
|
|
61
75
|
/**
|
|
62
|
-
* design/178 ②-1
|
|
76
|
+
* borrowed-readonly — design/178 ②-1: whether the `memory_search`/`memory_get` pair PASSED its early mount conjuncts
|
|
63
77
|
* (exclusion + name occupancy, decided in prepare-task BEFORE this phase). True ⇒ this phase builds
|
|
64
78
|
* the pair's ToolSpecs ({@link PrepareMemoryResult.memoryTools}) and the injection's instruction
|
|
65
79
|
* teaches the retrieval discipline; false ⇒ neither happens, so the teaching and the roster agree
|
|
@@ -68,29 +82,22 @@ export interface PrepareMemoryInput {
|
|
|
68
82
|
*/
|
|
69
83
|
memorySearchToolsPlanned: boolean;
|
|
70
84
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* for this principal (the veto covers the request-origin plane);
|
|
74
|
-
* - `parentAdmittedOrgScopes`: the delegation chain's FROZEN admitted org set — `undefined` for a
|
|
75
|
-
* top-level task; for a delegated child the caller passes the fail-closed empty set when the
|
|
76
|
-
* chain carries no verdict (an older-shape chain must not read as "unconstrained").
|
|
77
|
-
*/
|
|
78
|
-
/**
|
|
79
|
-
* design/383 §3.1 — the SCREENED capture posture (prepare-config-doors; absent deps seat folded
|
|
80
|
-
* to `"open"`) plus whether the deployment DECLARED one at all (the once-per-process "switch in
|
|
81
|
-
* use, no policy configured" operator line fires only on the undeclared arm).
|
|
85
|
+
* borrowed-readonly — design/383 §3.1: the SCREENED capture posture (prepare-config-doors; an
|
|
86
|
+
* absent deps seat folded to `"open"`).
|
|
82
87
|
*/
|
|
83
88
|
memoryCapturePolicy?: MemoryCapturePosture;
|
|
89
|
+
/** borrowed-readonly — whether the deployment DECLARED a posture at all: the once-per-process
|
|
90
|
+
* "switch in use, no policy configured" operator line fires only on the undeclared arm. */
|
|
84
91
|
memoryCapturePolicyDeclared?: boolean;
|
|
85
92
|
/**
|
|
86
|
-
* design/383 §3.1
|
|
93
|
+
* borrowed-readonly — design/383 §3.1: the per-principal entitlement as resolved by prepare-task's ONE caps resolve
|
|
87
94
|
* (`value` = `runtimeCaps.allowMemoryOptOut` when boolean; `faulted` = the resolve threw or the
|
|
88
95
|
* member was non-boolean — per the member's F2 fault-transit contract a fault must never arrive
|
|
89
96
|
* as a coined explicit value). Consumed by the adjudicator on every ingress of this prepare.
|
|
90
97
|
*/
|
|
91
98
|
captureEntitlement?: CaptureEntitlementInput;
|
|
92
99
|
/**
|
|
93
|
-
* design/383 §2.1b
|
|
100
|
+
* borrowed-readonly — design/383 §2.1b: the carrier-absence verdict, judged by prepare-task from the DECLARED
|
|
94
101
|
* deployment shape: a remote-execution deployment whose control plane does not follow the run
|
|
95
102
|
* (the per-run sandbox / stateless-replica form) with no
|
|
96
103
|
* {@link RunnerDeps.memoryCaptureRecordStore} supplied. TRUE + a `capture:"off"` declaration ⇒
|
|
@@ -99,7 +106,7 @@ export interface PrepareMemoryInput {
|
|
|
99
106
|
*/
|
|
100
107
|
captureCarrierUnsupported?: boolean;
|
|
101
108
|
/**
|
|
102
|
-
* design/383 §2.5
|
|
109
|
+
* borrowed-readonly — design/383 §2.5: the IMMEDIATE spawner's session id (trusted internals seat, filled by the
|
|
103
110
|
* delegation lanes; absent on top-level runs). The record-query leg of the delegation floor: a
|
|
104
111
|
* child's harvest legs also read the PARENT's opt-out record off the shared write-plane control
|
|
105
112
|
* store, so a parent whose opt-out landed AFTER this child spawned (the mid-run flip) still gets
|
|
@@ -112,7 +119,7 @@ export interface PrepareMemoryInput {
|
|
|
112
119
|
*/
|
|
113
120
|
parentSessionId?: string;
|
|
114
121
|
/**
|
|
115
|
-
* design/383 §2.5
|
|
122
|
+
* borrowed-readonly — design/383 §2.5: the delegation FLOOR bit off the trusted internals chain
|
|
116
123
|
* (`internals.memoryCaptureFloor === true`): the spawning session was opted out at spawn time.
|
|
117
124
|
* A floored leg runs opted-out WITHOUT re-adjudication (the parent's granted opt-out tightens
|
|
118
125
|
* the tree; re-asking could only loosen) and mints its own one-way record (reason names the
|
|
@@ -120,7 +127,7 @@ export interface PrepareMemoryInput {
|
|
|
120
127
|
*/
|
|
121
128
|
captureFloor?: boolean;
|
|
122
129
|
/**
|
|
123
|
-
* design/383 §2.5 (rescan post-6.0.0-RC)
|
|
130
|
+
* borrowed-readonly — design/383 §2.5 (rescan post-6.0.0-RC): the floor seat's THIRD state off the same trusted
|
|
124
131
|
* chain: the spawning session's capture state was INDETERMINATE at spawn time (its record store
|
|
125
132
|
* faulted at the getter read). This leg resolves it against the live record query (see
|
|
126
133
|
* `armCaptureOptOut`): ancestor record found ⇒ floor; still faulting ⇒ this session runs
|
|
@@ -129,7 +136,7 @@ export interface PrepareMemoryInput {
|
|
|
129
136
|
*/
|
|
130
137
|
captureFloorIndeterminate?: boolean;
|
|
131
138
|
/**
|
|
132
|
-
* design/383 §2.5 (rescan post-6.0.0-RC)
|
|
139
|
+
* borrowed-readonly — design/383 §2.5 (rescan post-6.0.0-RC): the HOST-SIDE FORK lane: the session this one was
|
|
133
140
|
* forked FROM (`SessionMetadata.forkedFrom`, read by prepare-task off the acquired session). A
|
|
134
141
|
* fork byte-copies the source's committed transcript, so the source's standing opt-out governs
|
|
135
142
|
* the copy: record found at prepare ⇒ the floor arm (mint, reason naming the fork, no
|
|
@@ -138,22 +145,33 @@ export interface PrepareMemoryInput {
|
|
|
138
145
|
* record-query walk, so a source that flips WHILE the fork runs suppresses it live.
|
|
139
146
|
*/
|
|
140
147
|
captureForkOrigin?: string;
|
|
141
|
-
/** design/383 §2.5 (rescan, codex adversarial round)
|
|
148
|
+
/** borrowed-readonly — design/383 §2.5 (rescan, codex adversarial round): the fork-lineage read itself FAULTED
|
|
142
149
|
* (session metadata unreadable): whether this session forks an opted-out source is unknowable,
|
|
143
150
|
* so the capture arm runs INDETERMINATE (suppress fail-closed, disclose, mint nothing) — a
|
|
144
151
|
* metadata outage must not read as "no lineage" (读错不许伪装 clean). */
|
|
145
152
|
captureLineageFault?: boolean;
|
|
146
|
-
/** design/383 §2.5 (codex review adopted)
|
|
153
|
+
/** borrowed-readonly — design/383 §2.5 (codex review adopted): the SPAWNING session's write-plane control dir
|
|
147
154
|
* (trusted internals chain), so the record-query leg reaches a parent on a DIFFERENT memory
|
|
148
155
|
* plane (project-writing parent, personal-writing child). Absent ⇒ same-plane query only. */
|
|
149
156
|
parentCaptureQueryDir?: string;
|
|
150
|
-
/** design/383 §2.5 (codex round 3)
|
|
157
|
+
/** borrowed-readonly — design/383 §2.5 (codex round 3): the full ancestor chain's capture coordinates off the
|
|
151
158
|
* trusted internals seat; the harvest closure walks every row (deduped with the parent seat),
|
|
152
159
|
* so a mid-run flip anywhere up the tree suppresses this in-flight descendant. */
|
|
153
160
|
captureAncestors?: ReadonlyArray<{
|
|
154
161
|
sessionId: string;
|
|
155
162
|
controlDir?: string;
|
|
156
163
|
}>;
|
|
164
|
+
/**
|
|
165
|
+
* borrowed-readonly — the org-memory admission context (ruled 2026-08-05), assembled by
|
|
166
|
+
* prepare-task:
|
|
167
|
+
* - `orgMemoryDenied`/`complianceDegraded`: the compliance capability `org_memory_mount` verdict
|
|
168
|
+
* for this principal (the veto covers the request-origin plane);
|
|
169
|
+
* - `parentAdmittedOrgScopes`: the delegation chain's FROZEN admitted org set — `undefined` for a
|
|
170
|
+
* top-level task; for a delegated child the caller passes the fail-closed empty set when the
|
|
171
|
+
* chain carries no verdict (an older-shape chain must not read as "unconstrained");
|
|
172
|
+
* - `priorOwnVerdict`/`governedProvenance`: the session freeze and the monotonic governance bit.
|
|
173
|
+
* Read as a whole into the admission call; never mutated.
|
|
174
|
+
*/
|
|
157
175
|
admissionCtx: {
|
|
158
176
|
orgMemoryDenied: boolean;
|
|
159
177
|
complianceDegraded: boolean;
|
|
@@ -0,0 +1,162 @@
|
|
|
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 run's committed-pause holder (`Prepared.pausedRef`). Writer here: the commit-side publication. */
|
|
146
|
+
pausedRef: Prepared["pausedRef"];
|
|
147
|
+
}
|
|
148
|
+
export interface PrepareParkAskResult {
|
|
149
|
+
/** owned — the two closures as ONE value, or undefined exactly when the ask lane (and so the saga) is absent. */
|
|
150
|
+
parkAsk: ParkAsk | undefined;
|
|
151
|
+
}
|
|
152
|
+
/** The M19 park-ask phase body — prepareTask's park closure and content-ask routing stretch, verbatim (see the module header). */
|
|
153
|
+
export declare function prepareParkAsk(input: PrepareParkAskInput): PrepareParkAskResult;
|
|
154
|
+
/**
|
|
155
|
+
* From the resumed/active transcript, the batch position of `currentId` (design/45 §4.ter): the tool-call
|
|
156
|
+
* ids of the assistant message that issued it (the batch), and the subset already resolved (executed
|
|
157
|
+
* before the suspend — #1..k-1). ID-based, not positional (council Question #1): immune to reordering.
|
|
158
|
+
*/
|
|
159
|
+
export declare function batchContextAt(messages: AgentMessage[], currentId: string): {
|
|
160
|
+
batchToolCallIds: string[];
|
|
161
|
+
completedCallIds: string[];
|
|
162
|
+
};
|