@sema-agent/core 7.24.4 → 7.25.1
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 +100 -0
- package/dist/agents/peer-session-drain.d.ts +16 -1
- package/dist/agents/peer-session-drain.js +16 -1
- package/dist/agents/send-message-tool.d.ts +10 -2
- package/dist/agents/send-message-tool.js +18 -7
- package/dist/agents/subagent.js +13 -10
- package/dist/core/arg-summary.d.ts +0 -7
- package/dist/core/arg-summary.js +2 -1
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/checkpoint-store.d.ts +1 -0
- package/dist/core/delegation-frames.d.ts +5 -0
- package/dist/core/gate-fold.js +85 -0
- package/dist/core/gate-lanes.js +23 -1
- package/dist/core/gate-outcome.d.ts +8 -2
- package/dist/core/gate-outcome.js +3 -1
- package/dist/core/hooks.d.ts +29 -0
- package/dist/core/hooks.js +2 -0
- package/dist/core/mailbox-store.d.ts +5 -0
- package/dist/core/mailbox-store.js +1 -1
- package/dist/core/parent-spec-seat.d.ts +7 -1
- package/dist/core/parent-spec-seat.js +2 -0
- package/dist/core/permission-rule-consent.js +29 -47
- package/dist/core/permission-rule-provider.js +4 -3
- package/dist/core/permission-rule-store.d.ts +143 -7
- package/dist/core/permission-rule-store.js +165 -15
- package/dist/core/runner/contracts.d.ts +36 -2
- package/dist/core/runner/gate-exit.d.ts +14 -0
- package/dist/core/runner/gate-exit.js +4 -0
- package/dist/core/runner/prepare-delegation-surface.d.ts +4 -4
- package/dist/core/runner/prepare-delegation-surface.js +2 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -0
- package/dist/core/runner/prepare-gate-stations.js +7 -4
- package/dist/core/runner/prepare-hands-readface.d.ts +8 -4
- package/dist/core/runner/prepare-hands-readface.js +25 -10
- package/dist/core/runner/prepare-inherited-gate.d.ts +23 -0
- package/dist/core/runner/prepare-inherited-gate.js +11 -6
- package/dist/core/runner/prepare-policy-chain.d.ts +15 -1
- package/dist/core/runner/prepare-policy-chain.js +14 -4
- package/dist/core/runner/prepare-suspend-saga.d.ts +5 -2
- package/dist/core/runner/prepare-suspend-saga.js +4 -3
- package/dist/core/runner/prepare-task.js +10 -9
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
- package/dist/core/runner/prepare-wiring-manifest.js +8 -4
- package/dist/core/runner/resume-apply.js +2 -0
- package/dist/core/runner/run-harness-handlers.js +1 -0
- package/dist/core/runner/run-identity-wiring.d.ts +2 -2
- package/dist/core/runner/run-leg.js +26 -0
- package/dist/core/runner/run-notification-lane.d.ts +2 -2
- package/dist/core/runner/run-notification-lane.js +2 -1
- package/dist/core/runner/run-settle-and-teardown.js +1 -0
- package/dist/core/runner/session-rule-policy.d.ts +3 -4
- package/dist/core/runner/session-rule-policy.js +11 -3
- package/dist/core/session-policy-store.d.ts +27 -3
- package/dist/core/session-policy-store.js +12 -4
- package/dist/core/store-contracts/background-agent-store-contract.js +10 -0
- package/dist/core/store-contracts/peer-directory-contract.d.ts +23 -0
- package/dist/core/store-contracts/peer-directory-contract.js +82 -0
- package/dist/core/task-event.d.ts +6 -0
- package/dist/core/task-notification.d.ts +79 -4
- package/dist/core/task-notification.js +90 -1
- package/dist/core/task-registry-agent.js +1 -2
- package/dist/core/task-registry-monitor.js +2 -1
- package/dist/core/task-registry-shared.d.ts +53 -5
- package/dist/core/task-registry-shared.js +13 -2
- package/dist/core/task-registry.js +8 -5
- package/dist/core/task-spec.d.ts +12 -5
- package/dist/core/tool-catalog-entries.js +1 -0
- package/dist/core/tool-policy.js +30 -23
- package/dist/core/tool-spec.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +2 -2
- package/dist/engine/loop/agent-loop.js +1 -1
- package/dist/engine/loop/types.d.ts +4 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -3
- package/dist/prompts/coordinator.d.ts +2 -1
- package/dist/stores/file/adoption/adopt.js +23 -1
- package/dist/stores/file/permission-rule-store.js +3 -1
- package/dist/stores/file/session-policy-store.d.ts +31 -0
- package/dist/stores/file/session-policy-store.js +87 -7
- package/dist/tools/fs/bash-lexer.d.ts +13 -0
- package/dist/tools/fs/bash-lexer.js +61 -0
- package/dist/tools/fs/bash-program-position.d.ts +36 -29
- package/dist/tools/fs/bash-program-position.js +33 -13
- package/dist/tools/fs/bash-readonly-classifier.d.ts +26 -313
- package/dist/tools/fs/bash-readonly-classifier.js +81 -782
- package/dist/tools/fs/fs-bash.d.ts +43 -207
- package/dist/tools/fs/fs-bash.js +20 -341
- package/dist/tools/fs/index.d.ts +12 -13
- package/dist/tools/fs/index.js +3 -4
- package/dist/tools/fs/read-deny.d.ts +25 -0
- package/dist/tools/fs/read-deny.js +19 -0
- package/dist/tools/fs/safety.js +2 -6
- package/dist/tools/fs/shell-read-check.d.ts +99 -0
- package/dist/tools/fs/shell-read-check.js +229 -0
- package/dist/tools/fs/shell-read-establish.d.ts +70 -115
- package/dist/tools/fs/shell-read-establish.js +216 -102
- package/dist/tools/fs/shell-read-judge.d.ts +231 -0
- package/dist/tools/fs/shell-read-judge.js +170 -0
- package/dist/tools/fs/shell-read-plan.d.ts +3 -0
- package/dist/tools/fs/shell-read-plan.js +88 -27
- package/dist/tools/monitor.d.ts +5 -5
- package/dist/tools/monitor.js +3 -5
- package/dist/tools/task-list.d.ts +4 -0
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +19 -3
- package/wire-changes/core@7.25.0.json +671 -0
- package/wire-changes/core@7.25.1.json +64 -0
|
@@ -41,7 +41,7 @@ export function maybeHumanRejectionHalt(input) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
export function prepareGateStations(input) {
|
|
44
|
-
const { askLane, parkAsk, tools, toolRosterDeltas, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, writeProtectionCheck, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash } = input;
|
|
44
|
+
const { askLane, parkAsk, tools, toolRosterDeltas, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, writeProtectionCheck, shellReadCheck, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash } = input;
|
|
45
45
|
if (askLane !== undefined && parkAsk !== undefined) {
|
|
46
46
|
const { adjudicate, resolveAskBound, notifyPermissionDenied, notifyHookError } = askLane;
|
|
47
47
|
const { resolveContentAsk, suspendAsk } = parkAsk;
|
|
@@ -58,7 +58,8 @@ export function prepareGateStations(input) {
|
|
|
58
58
|
irreversibleTools.size > 0 ||
|
|
59
59
|
spec.enablePlanMode === true ||
|
|
60
60
|
complianceDenies.has("web_fetch") ||
|
|
61
|
-
writeProtectionArmed
|
|
61
|
+
writeProtectionArmed ||
|
|
62
|
+
shellReadCheck !== undefined;
|
|
62
63
|
if (toolCallGateArmedRef.armed) {
|
|
63
64
|
harness.on("tool_call", async (e) => {
|
|
64
65
|
blockedToolCalls.delete(e.toolCallId);
|
|
@@ -112,6 +113,7 @@ export function prepareGateStations(input) {
|
|
|
112
113
|
egress: egressTools.has(e.toolName),
|
|
113
114
|
peerMessage: e.toolName === SEND_MESSAGE_TOOL_NAME,
|
|
114
115
|
...(writeProtectionCheck !== undefined ? { writeProtectionCheck } : {}),
|
|
116
|
+
...(shellReadCheck !== undefined ? { shellReadCheck } : {}),
|
|
115
117
|
irreversibility: irreversibilityTier.get(e.toolName),
|
|
116
118
|
reversibilityProbe: reversibilityProbes.get(e.toolName),
|
|
117
119
|
abortSignal: abortController.signal,
|
|
@@ -204,11 +206,12 @@ export function prepareGateStations(input) {
|
|
|
204
206
|
toolName: e.toolName,
|
|
205
207
|
toolCallId: e.toolCallId,
|
|
206
208
|
});
|
|
209
|
+
const details = result.details !== undefined ? { details: result.details } : {};
|
|
207
210
|
if (haltRemaining !== undefined) {
|
|
208
211
|
batchHaltRef.current = { rejectedToolCallId: e.toolCallId };
|
|
209
|
-
return { block: true, reason: result.reason, haltRemaining };
|
|
212
|
+
return { block: true, reason: result.reason, ...details, haltRemaining };
|
|
210
213
|
}
|
|
211
|
-
return { block: true, reason: result.reason };
|
|
214
|
+
return { block: true, reason: result.reason, ...details };
|
|
212
215
|
}
|
|
213
216
|
return result.updatedInput !== undefined ? { updatedInput: result.updatedInput } : undefined;
|
|
214
217
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type BeforeWriteHook, type CwdRef, type ReadDenyMatcher, type ContainmentFace } from "../../tools/fs/index.js";
|
|
2
2
|
import { type ReadFileState } from "../../tools/fs/safety.js";
|
|
3
|
+
import { type ShellReadAdmission, type ShellReadCheck } from "../../tools/fs/shell-read-check.js";
|
|
3
4
|
import type { RunnerDeps, ShellGateDoctrine, TaskSpec } from "../types.js";
|
|
4
5
|
import type { Model } from "../../internal/llm.js";
|
|
5
6
|
import type { AgentHarness, AgentTool, ExecutionEnv, WorkspaceState } from "../../internal/harness.js";
|
|
@@ -266,9 +267,12 @@ export interface PrepareHandsReadFaceResult {
|
|
|
266
267
|
/** owned — real shell + write hands + background-capable env: gates the driver's TaskOutput/
|
|
267
268
|
* TaskStop/Monitor/SendMessage mounts (P11) and the Monitor arm of the shellGate fold here. */
|
|
268
269
|
backgroundTaskToolsActive: boolean;
|
|
269
|
-
/** owned — this run's shell
|
|
270
|
-
*
|
|
271
|
-
|
|
270
|
+
/** owned — this run's shell READ STATION, the gate input (`ToolGateInput.shellReadCheck`): ONE judgment of
|
|
271
|
+
* where a shell command reads, for every shell face this leg mounts, under every doctrine. ⇔ a real shell. */
|
|
272
|
+
shellReadCheck: ShellReadCheck | undefined;
|
|
273
|
+
/** owned — the same station's pre-spawn ADMISSION, published for the P11 face that spawns a shell command
|
|
274
|
+
* and mounts LATER than the band (`Monitor`): the SAME function the band's shell faces got. ⇔ a real shell. */
|
|
275
|
+
shellReadAdmission: ShellReadAdmission | undefined;
|
|
272
276
|
/** write-back (D-3 hold) — the run's RESOLVED read face where hands mount; undefined ⇔ no hands
|
|
273
277
|
* (the hands-less value lives in `handsLessResolvedFace`). The driver assigns this onto its
|
|
274
278
|
* outer `let` for the call-time closures (ctx enrichment / checkpoint mint / envFacts). */
|
|
@@ -3,8 +3,10 @@ import { StubExecutionEnv } from "../stub-env.js";
|
|
|
3
3
|
import { hasBackgroundShell } from "../background-shell.js";
|
|
4
4
|
import { boundaryIsTheSandbox } from "../remote-env.js";
|
|
5
5
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
6
|
-
import {
|
|
6
|
+
import { bashReversibilityProbe, activeReadDenyBuiltinTiers, compileReadDeny, readDenySeat, createHandsToolkit, deploymentFaceClampNotice, pdfModelCapabilitiesOf, inheritSessionReadFileState, resolveContainmentFace, seedReadFileStateFromContext, seedReadFileStateFromTranscript, } from "../../tools/fs/index.js";
|
|
7
7
|
import { resolveKey, sha256 } from "../../tools/fs/safety.js";
|
|
8
|
+
import { createShellOverflowSpoolFence } from "../../tools/fs/fs-shared.js";
|
|
9
|
+
import { createShellReadStation } from "../../tools/fs/shell-read-check.js";
|
|
8
10
|
import { normalizeFileText } from "../../tools/fs/encoding.js";
|
|
9
11
|
import { wholeFileRecordsFromTranscript } from "./session-file-state-replay.js";
|
|
10
12
|
import { deliverEngineNotice } from "../types.js";
|
|
@@ -137,7 +139,8 @@ export function resolveHandsLessReadFace(input) {
|
|
|
137
139
|
wsSnapshot: undefined,
|
|
138
140
|
rebaseWsPath: (p) => p,
|
|
139
141
|
backgroundTaskToolsActive: false,
|
|
140
|
-
|
|
142
|
+
shellReadCheck: undefined,
|
|
143
|
+
shellReadAdmission: undefined,
|
|
141
144
|
resolvedReadFace: undefined,
|
|
142
145
|
resolvedWriteFace: undefined,
|
|
143
146
|
readDenyAdditionsNormalized,
|
|
@@ -168,7 +171,7 @@ export async function prepareHandsMount(input) {
|
|
|
168
171
|
let wsSnapshot;
|
|
169
172
|
let rebaseWsPath = (p) => p;
|
|
170
173
|
let backgroundTaskToolsActive = false;
|
|
171
|
-
let
|
|
174
|
+
let shellReadStation;
|
|
172
175
|
let resolvedReadFace;
|
|
173
176
|
let resolvedWriteFace;
|
|
174
177
|
let readDenyAdditionsNormalized = [];
|
|
@@ -337,7 +340,17 @@ export async function prepareHandsMount(input) {
|
|
|
337
340
|
...denySeat,
|
|
338
341
|
...(resolvedReadFace !== undefined ? { face: resolvedReadFace } : {}),
|
|
339
342
|
});
|
|
340
|
-
|
|
343
|
+
if (handsIncludeShell) {
|
|
344
|
+
const readonlyBoundary = handsReadOnly
|
|
345
|
+
? { roots: [rootCanonical, ...additionalRootsCanonical, ...additionalReadRootsCanonical], cwd: rootCanonical, ...denySeat, alsoInside: createShellOverflowSpoolFence(executionEnv) }
|
|
346
|
+
: undefined;
|
|
347
|
+
shellReadStation = createShellReadStation({
|
|
348
|
+
env: executionEnv,
|
|
349
|
+
tools: new Set(handsReadOnly ? ["Bash"] : backgroundTaskToolsActive ? ["Bash", "Monitor"] : ["Bash"]),
|
|
350
|
+
seatOf: () => (handsReadOnly ? "readonly" : effectiveShellGate === "classify" ? "bash_classify" : "bash_off"),
|
|
351
|
+
boundaryOf: () => readonlyBoundary ?? shellReadBoundary(),
|
|
352
|
+
});
|
|
353
|
+
}
|
|
341
354
|
const band = createHandsToolkit(executionEnv, readFileState, rootCanonical, {
|
|
342
355
|
...(additionalRootsCanonical.length > 0 ? { additionalRoots: additionalRootsCanonical } : {}),
|
|
343
356
|
...(additionalReadRootsCanonical.length > 0 ? { additionalReadRoots: additionalReadRootsCanonical } : {}),
|
|
@@ -352,7 +365,7 @@ export async function prepareHandsMount(input) {
|
|
|
352
365
|
...(input.onFileEdited !== undefined ? { onFileEdited: input.onFileEdited } : {}),
|
|
353
366
|
includeShell: handsIncludeShell,
|
|
354
367
|
readOnly: handsReadOnly,
|
|
355
|
-
|
|
368
|
+
...(shellReadStation !== undefined ? { shellReadAdmission: shellReadStation.admit } : {}),
|
|
356
369
|
...(handsCwdRef ? { cwdRef: handsCwdRef } : {}),
|
|
357
370
|
taskRegistry: defaultTaskRegistry,
|
|
358
371
|
taskOwner: hostTaskId,
|
|
@@ -395,7 +408,7 @@ export async function prepareHandsMount(input) {
|
|
|
395
408
|
if (!(executionEnv instanceof StubExecutionEnv) && spec.handsReadOnly !== true) {
|
|
396
409
|
if (shellGate === "off") {
|
|
397
410
|
deps.onError?.(new Error(`shell gate doctrine is "off" while a real writable shell (Bash) is mounted — the read boundary is ` +
|
|
398
|
-
`still judged on every command (a deny-listed
|
|
411
|
+
`still judged on every command (a deny-listed read is refused; an out-of-root read asks, and the ask is mandated${boundaryIsTheSandbox(executionEnv) ? "; under an isolated sandbox the paths are judged as written" : "; the paths are judged as the filesystem resolves them, symlinks and patterns included"}), but no ` +
|
|
399
412
|
`residual shell-risk classifier is installed: writes, egress and unknown commands are adjudicated by ` +
|
|
400
413
|
`the ordinary policy/hook chain only. Set spec.shellGate to "classify" or "always" if this deployment ` +
|
|
401
414
|
`expects doctrine-gated shell behavior.`), { phase: "config", sessionId, classification: "shell-gate-off" });
|
|
@@ -405,12 +418,13 @@ export async function prepareHandsMount(input) {
|
|
|
405
418
|
const seatOwned = !egressTools.has(name) && tierBefore !== "always" && tierBefore !== "maybe";
|
|
406
419
|
if (seatOwned)
|
|
407
420
|
shellGatedTools.add(name);
|
|
421
|
+
if (shellGate === "off" && tierBefore !== "always")
|
|
422
|
+
return;
|
|
408
423
|
const tier = shellGate === "always" || tierBefore === "always" ? "always" : "maybe";
|
|
409
424
|
irreversibilityTier.set(name, tier);
|
|
410
425
|
irreversibleTools.add(name);
|
|
411
|
-
if (seatOwned && tier === "maybe")
|
|
412
|
-
reversibilityProbes.set(name,
|
|
413
|
-
}
|
|
426
|
+
if (seatOwned && tier === "maybe")
|
|
427
|
+
reversibilityProbes.set(name, bashReversibilityProbe(undefined, shellReadBoundary));
|
|
414
428
|
};
|
|
415
429
|
installShellSeat("Bash");
|
|
416
430
|
if (backgroundTaskToolsActive)
|
|
@@ -425,7 +439,8 @@ export async function prepareHandsMount(input) {
|
|
|
425
439
|
wsSnapshot,
|
|
426
440
|
rebaseWsPath,
|
|
427
441
|
backgroundTaskToolsActive,
|
|
428
|
-
|
|
442
|
+
shellReadCheck: shellReadStation?.check,
|
|
443
|
+
shellReadAdmission: shellReadStation?.admit,
|
|
429
444
|
resolvedReadFace,
|
|
430
445
|
resolvedWriteFace,
|
|
431
446
|
handsLessResolvedWriteFace,
|
|
@@ -208,9 +208,32 @@ export interface PrepareInheritedGateResult {
|
|
|
208
208
|
sessionId: string;
|
|
209
209
|
principal?: string;
|
|
210
210
|
rev: number;
|
|
211
|
+
gen?: number;
|
|
211
212
|
rules: SessionPermissionRules;
|
|
212
213
|
};
|
|
213
214
|
};
|
|
215
|
+
/** borrowed-mutable — the ANCESTOR twin of {@link PrepareInheritedGateResult.ownSessionRulesRef}, keyed by
|
|
216
|
+
* the entry's POSITION in `inheritedAncestorRules`. Writers: the policy chain's ancestor layers, each time
|
|
217
|
+
* one comes to enforce a newer row than it prepared with. Read by {@link ancestorRulesNow}. Position, not
|
|
218
|
+
* `(sessionId, principal)`: the chain may legitimately carry two entries of the same identity with
|
|
219
|
+
* DIFFERENT floors (a leg whose own session is also an ancestor's, a seed and a live channel that both
|
|
220
|
+
* name it), each compiled into its own layer with its own floor — and a by-identity key lets the layer
|
|
221
|
+
* that advanced overwrite the entry of the layer that did not, publishing the weaker floor over the
|
|
222
|
+
* stronger one. A layer upgrades its OWN entry; position is what "its own" means. */
|
|
223
|
+
ancestorSessionRulesRef: {
|
|
224
|
+
current: Map<number, {
|
|
225
|
+
sessionId: string;
|
|
226
|
+
principal?: string;
|
|
227
|
+
rev: number;
|
|
228
|
+
gen?: number;
|
|
229
|
+
rules: SessionPermissionRules;
|
|
230
|
+
}>;
|
|
231
|
+
};
|
|
232
|
+
/** owned — the ancestor rules AS THIS LEG NOW ENFORCES THEM: the inherited entries with the seat above
|
|
233
|
+
* overlaid. The ONE projection, called by the child-chain assembly at spawn and by the checkpoint writer
|
|
234
|
+
* at suspend — two faces of one rule ("what a later reader inherits is what this leg enforces"), which
|
|
235
|
+
* were two implementations while the checkpoint cloned the prepare-time list. */
|
|
236
|
+
ancestorRulesNow: () => InheritedGate["ancestorRules"];
|
|
214
237
|
/** borrowed-mutable — THIS task's own frozen admitted org scopes for its children's chain. Writers: the memory phase's
|
|
215
238
|
* admission door, once per leg. Read by the chain assembly (always emitted, empty = no org plane). */
|
|
216
239
|
memoryAdmittedOrgScopesRef: {
|
|
@@ -13,13 +13,16 @@ export function prepareInheritedGate(input) {
|
|
|
13
13
|
const inheritedAncestorRules = (() => {
|
|
14
14
|
const seedRules = seedInheritedGate?.ancestorRules;
|
|
15
15
|
const liveRules = liveInheritedGate?.ancestorRules;
|
|
16
|
-
if (seedRules === undefined || seedRules.length === 0)
|
|
17
|
-
|
|
16
|
+
if (seedRules === undefined || seedRules.length === 0) {
|
|
17
|
+
const only = liveRules ?? seedRules;
|
|
18
|
+
return only === undefined ? undefined : [...only];
|
|
19
|
+
}
|
|
18
20
|
if (liveRules === undefined || liveRules.length === 0)
|
|
19
|
-
return seedRules;
|
|
21
|
+
return [...seedRules];
|
|
20
22
|
const merged = seedRules.map((s) => {
|
|
21
23
|
const live = liveRules.find((l) => l.sessionId === s.sessionId && l.principal === s.principal);
|
|
22
|
-
|
|
24
|
+
const sameLineage = live === undefined || live.gen === undefined || s.gen === undefined || live.gen === s.gen;
|
|
25
|
+
return live !== undefined && sameLineage && live.rev >= s.rev ? live : s;
|
|
23
26
|
});
|
|
24
27
|
const extras = liveRules.filter((l) => !seedRules.some((s) => s.sessionId === l.sessionId && s.principal === l.principal));
|
|
25
28
|
return [...merged, ...extras];
|
|
@@ -62,6 +65,8 @@ export function prepareInheritedGate(input) {
|
|
|
62
65
|
const specShellGate = spec.shellGate ?? "off";
|
|
63
66
|
const effectiveShellGate = inheritedShellGate !== undefined && shellGateRank[inheritedShellGate] > shellGateRank[specShellGate] ? inheritedShellGate : specShellGate;
|
|
64
67
|
const ownSessionRulesRef = {};
|
|
68
|
+
const ancestorSessionRulesRef = { current: new Map() };
|
|
69
|
+
const ancestorRulesNow = () => inheritedAncestorRules === undefined ? undefined : inheritedAncestorRules.map((a, i) => ancestorSessionRulesRef.current.get(i) ?? a);
|
|
65
70
|
const memoryAdmittedOrgScopesRef = { current: [] };
|
|
66
71
|
const ownOrgVerdictRef = { current: undefined };
|
|
67
72
|
const orgAdmissionCheckpointState = () => inheritedAdmittedOrgScopes !== undefined || ownOrgVerdictRef.current !== undefined || orgGovernedProvenance;
|
|
@@ -111,7 +116,7 @@ export function prepareInheritedGate(input) {
|
|
|
111
116
|
const autoModeDenialTracking = input.autoModeDenialTracking();
|
|
112
117
|
const autoModeArming = input.autoModeArming();
|
|
113
118
|
const ancestorRules = [
|
|
114
|
-
...(
|
|
119
|
+
...(ancestorRulesNow() ?? []),
|
|
115
120
|
...(ownSessionRulesRef.current !== undefined ? [ownSessionRulesRef.current] : []),
|
|
116
121
|
];
|
|
117
122
|
const ownCallerPolicy = lockedPreflight.toolPolicy;
|
|
@@ -271,5 +276,5 @@ export function prepareInheritedGate(input) {
|
|
|
271
276
|
...(spec.enablePlanMode === true ? { enterPlanMode } : {}),
|
|
272
277
|
};
|
|
273
278
|
};
|
|
274
|
-
return { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, autoModeIntent, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx };
|
|
279
|
+
return { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, autoModeIntent, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx };
|
|
275
280
|
}
|
|
@@ -89,8 +89,21 @@ export interface PreparePolicyChainInput {
|
|
|
89
89
|
/** borrowed-readonly — the resolved per-principal entitlements; only `forceDurableGate` (the mandate-park facility and
|
|
90
90
|
* the sandbox arming's prerequisite). */
|
|
91
91
|
runtimeCaps: Pick<RuntimeCaps, "forceDurableGate"> | undefined;
|
|
92
|
-
/** borrowed-readonly — the ancestors' session-rule snapshots (each re-read live-preferring, floor kept).
|
|
92
|
+
/** borrowed-readonly — the ancestors' session-rule snapshots (each re-read live-preferring, floor kept).
|
|
93
|
+
* Never written: an entry is some other leg's or some host's object — see `ancestorSessionRulesRef`. */
|
|
93
94
|
inheritedAncestorRules: InheritedGate["ancestorRules"];
|
|
95
|
+
/** borrowed-mutable — THIS leg's record of what each ancestor layer now ENFORCES, keyed by the entry's
|
|
96
|
+
* POSITION (see the seat's own declaration in `prepare-inherited-gate.ts` for why position and not
|
|
97
|
+
* identity). Writer: this phase, through each ancestor layer's `onEnforced`. */
|
|
98
|
+
ancestorSessionRulesRef: {
|
|
99
|
+
current: Map<number, {
|
|
100
|
+
sessionId: string;
|
|
101
|
+
principal?: string;
|
|
102
|
+
rev: number;
|
|
103
|
+
gen?: number;
|
|
104
|
+
rules: SessionPermissionRules;
|
|
105
|
+
}>;
|
|
106
|
+
};
|
|
94
107
|
/** borrowed-readonly — the ancestors' caller-policy constraints, ancestors first (one wrapper each). */
|
|
95
108
|
inheritedParentConstraints: NonNullable<InheritedGate["parentConstraints"]>[number][] | undefined;
|
|
96
109
|
/** borrowed-readonly — the resumed leg's SEED half; only `constraintChain` (the frozen deny projections). */
|
|
@@ -124,6 +137,7 @@ export interface PreparePolicyChainInput {
|
|
|
124
137
|
sessionId: string;
|
|
125
138
|
principal?: string;
|
|
126
139
|
rev: number;
|
|
140
|
+
gen?: number;
|
|
127
141
|
rules: SessionPermissionRules;
|
|
128
142
|
};
|
|
129
143
|
};
|
|
@@ -17,7 +17,7 @@ import { createPermissionRuleLanes, inheritedAskRuleEvidence, createRuleOffersOf
|
|
|
17
17
|
import { createLiveSessionRules, createSessionRulePolicy } from "./session-rule-policy.js";
|
|
18
18
|
import { thrownText } from "../thrown-value.js";
|
|
19
19
|
export async function preparePolicyChain(input) {
|
|
20
|
-
const { spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, envHandToolNames, handsCwdRef, readDenyMatcher, questionToolMounted, runtimeCaps, inheritedAncestorRules, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = input;
|
|
20
|
+
const { spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, envHandToolNames, handsCwdRef, readDenyMatcher, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = input;
|
|
21
21
|
const policy = lockedPreflight.toolPolicy;
|
|
22
22
|
const auditPolicyNames = (auditee) => {
|
|
23
23
|
const nameGroups = toolPolicyNameSets(auditee);
|
|
@@ -89,6 +89,7 @@ export async function preparePolicyChain(input) {
|
|
|
89
89
|
sessionId: sessionRuleKey.sessionId,
|
|
90
90
|
...(sessionRuleKey.principal !== undefined ? { principal: sessionRuleKey.principal } : {}),
|
|
91
91
|
rev: row.rev,
|
|
92
|
+
...(row.gen !== undefined ? { gen: row.gen } : {}),
|
|
92
93
|
rules: row,
|
|
93
94
|
};
|
|
94
95
|
};
|
|
@@ -97,12 +98,21 @@ export async function preparePolicyChain(input) {
|
|
|
97
98
|
publishOwnRules(rules);
|
|
98
99
|
}
|
|
99
100
|
const ancestorRulePolicies = [];
|
|
100
|
-
for (const snap of inheritedAncestorRules ?? []) {
|
|
101
|
-
const seed = { ...snap.rules, rev: snap.rev };
|
|
101
|
+
for (const [position, snap] of (inheritedAncestorRules ?? []).entries()) {
|
|
102
|
+
const seed = { ...snap.rules, rev: snap.rev, ...(snap.gen !== undefined ? { gen: snap.gen } : {}) };
|
|
103
|
+
const publishAncestorRules = (row) => {
|
|
104
|
+
ancestorSessionRulesRef.current.set(position, {
|
|
105
|
+
sessionId: snap.sessionId,
|
|
106
|
+
...(snap.principal !== undefined ? { principal: snap.principal } : {}),
|
|
107
|
+
rev: row.rev,
|
|
108
|
+
...(row.gen !== undefined ? { gen: row.gen } : {}),
|
|
109
|
+
rules: row,
|
|
110
|
+
});
|
|
111
|
+
};
|
|
102
112
|
ancestorRulePolicies.push(createSessionRulePolicy({
|
|
103
113
|
seed,
|
|
104
114
|
...(deps.sessionPolicyStore
|
|
105
|
-
? { read: createLiveSessionRules(deps.sessionPolicyStore, { sessionId: snap.sessionId, ...(snap.principal !== undefined ? { principal: snap.principal } : {}), seed }, { onUnreadable: announceSessionRulesUnreadable }) }
|
|
115
|
+
? { read: createLiveSessionRules(deps.sessionPolicyStore, { sessionId: snap.sessionId, ...(snap.principal !== undefined ? { principal: snap.principal } : {}), seed }, { onUnreadable: announceSessionRulesUnreadable, onEnforced: publishAncestorRules }) }
|
|
106
116
|
: {}),
|
|
107
117
|
}, { env: executionEnv, rootPath: taskRootFinal, toolEffects }));
|
|
108
118
|
}
|
|
@@ -125,8 +125,11 @@ export interface PrepareSuspendSagaInput {
|
|
|
125
125
|
inheritedParentConstraints: NonNullable<InheritedGate["parentConstraints"]>[number][] | undefined;
|
|
126
126
|
/** borrowed-readonly — the resume seed's inherited gate, or undefined (the carried-forward half of the same fields). */
|
|
127
127
|
seedInheritedGate: PrepareResume["seed"]["inheritedGate"];
|
|
128
|
-
/** borrowed-readonly — the
|
|
129
|
-
|
|
128
|
+
/** borrowed-readonly — the ancestor rules AS THIS LEG NOW ENFORCES THEM, read at MINT time (a getter, not
|
|
129
|
+
* a value: the prepare-time list is not what a resumed leg must inherit — an ancestor rule written
|
|
130
|
+
* mid-run and enforced here has to survive suspend exactly as it survives a spawn, and the same
|
|
131
|
+
* projection serves both). Cloned onto the row. */
|
|
132
|
+
ancestorRulesNow: () => InheritedGate["ancestorRules"];
|
|
130
133
|
/** borrowed-readonly — the inherited shell-gate doctrine, persisted verbatim. */
|
|
131
134
|
inheritedShellGate: InheritedGate["shellGate"];
|
|
132
135
|
/** borrowed-readonly — the auto-mode intent (seat ∨ live ∨ seed), carried while the latch is healthy. */
|
|
@@ -79,7 +79,7 @@ function stampPlacementRootSessionId(placementRootResolved) {
|
|
|
79
79
|
return placementValueOrAbsent(placementRootResolved);
|
|
80
80
|
}
|
|
81
81
|
export function prepareSuspendSaga(input) {
|
|
82
|
-
const { gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate,
|
|
82
|
+
const { gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, ancestorRulesNow, inheritedShellGate, autoModeIntent, inheritedAdmittedOrgScopes, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter } = input;
|
|
83
83
|
if (!gateMachineryActive)
|
|
84
84
|
return { saga: undefined };
|
|
85
85
|
const inFlightSpendMicroUsd = () => {
|
|
@@ -135,7 +135,8 @@ export function prepareSuspendSaga(input) {
|
|
|
135
135
|
? constraintChainDigest(constraintChain)
|
|
136
136
|
: seedInheritedGate?.constraintDigest;
|
|
137
137
|
const autoModeIntentCarried = autoModeIntent;
|
|
138
|
-
|
|
138
|
+
const ancestorRulesAtMint = ancestorRulesNow();
|
|
139
|
+
return ancestorRulesAtMint !== undefined ||
|
|
139
140
|
inheritedShellGate !== undefined ||
|
|
140
141
|
autoModeIntentCarried ||
|
|
141
142
|
inheritedAdmittedOrgScopes !== undefined ||
|
|
@@ -143,7 +144,7 @@ export function prepareSuspendSaga(input) {
|
|
|
143
144
|
orgGovernedProvenance ||
|
|
144
145
|
requiresParentConstraint
|
|
145
146
|
? {
|
|
146
|
-
...(
|
|
147
|
+
...(ancestorRulesAtMint !== undefined ? { ancestorRules: structuredClone(ancestorRulesAtMint) } : {}),
|
|
147
148
|
...(inheritedShellGate !== undefined ? { shellGate: inheritedShellGate } : {}),
|
|
148
149
|
...(autoModeIntentCarried ? { autoModeRequested: true } : {}),
|
|
149
150
|
...(inheritedAdmittedOrgScopes !== undefined ? { admittedOrgScopes: [...inheritedAdmittedOrgScopes] } : {}),
|
|
@@ -66,7 +66,7 @@ import { resolveTriggerWindow, } from "../context-edit.js";
|
|
|
66
66
|
import { isRemoteExecutionEnv } from "../remote-env.js";
|
|
67
67
|
import { settleTeardownLeg } from "./teardown-bounded.js";
|
|
68
68
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
69
|
-
import { announcePeerLaneMount } from "../../agents/peer-session-drain.js";
|
|
69
|
+
import { announcePeerLaneMount, judgeSessionBoxDrain } from "../../agents/peer-session-drain.js";
|
|
70
70
|
import { createSchedulerTools } from "../../tools/scheduler-tools.js";
|
|
71
71
|
import { selfOrchestrationFailClosedReason } from "../../orchestration/workflow-script-runner.js";
|
|
72
72
|
import { remainingBudgetMicroUsd, resolveCheckpointStore } from "../checkpoint-store.js";
|
|
@@ -288,6 +288,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
288
288
|
internals?.peerSelfRef?.addAxis("s", sessionId);
|
|
289
289
|
internals?.peerSelfRef?.addAxis("t", hostTaskId);
|
|
290
290
|
const peerLaneActive = announcePeerLaneMount(deps, { sessionId, runId });
|
|
291
|
+
const sessionBox = judgeSessionBoxDrain(deps, { sessionId, scope: taskScope, isDelegatedChild: delegation.isDelegatedChild });
|
|
291
292
|
const peerLaneRefs = {};
|
|
292
293
|
const peerSendMessageBuiltIn = runnerSelf !== undefined && !(toolFaceSnapshot.exclude ?? []).includes(SEND_MESSAGE_TOOL_NAME) && !(spec.tools ?? []).some((t) => t.name === SEND_MESSAGE_TOOL_NAME);
|
|
293
294
|
const { reminderMark, reminderDisclosureCounts } = await adoptReminderMark(session, sessionId, resume?.seed.reminderMark, internals?.reminderMark, deps.onError);
|
|
@@ -375,7 +376,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
375
376
|
let readDenyAdditionsNormalized = [];
|
|
376
377
|
let handsLessResolvedFace;
|
|
377
378
|
let handsLessResolvedWriteFace;
|
|
378
|
-
const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, autoModeIntent, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, checkpointSeat, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, autoModeSeat, handsEnabled, reportUsage, harnessRef, skillScope, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun: () => { abortController.abort(); void harness.abort(); }, runtimeCaps: () => runtimeCaps, hooks: () => hooks, preToolUseObservational: () => preToolUseObservational, hookTimeoutMs: () => hookTimeoutMs, hookEnvFace: () => hookEnvFace, autoModeDecider: () => autoModeDecider, autoModeDenialTracking: () => autoModeDenialTracking, autoModeArming: () => autoModeArming, agentForkDenial: () => agentForkDenial, observersActive: () => observersActive, resolvedReadFace: () => resolvedReadFace, resolvedWriteFace: () => resolvedWriteFace, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized, handsLessResolvedFace: () => handsLessResolvedFace, handsLessResolvedWriteFace: () => handsLessResolvedWriteFace, centerAdoption: () => centerAdoptionRef.current, memoryEngineSession: () => memoryEngineSession });
|
|
379
|
+
const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, autoModeIntent, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, checkpointSeat, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, autoModeSeat, handsEnabled, reportUsage, harnessRef, skillScope, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun: () => { abortController.abort(); void harness.abort(); }, runtimeCaps: () => runtimeCaps, hooks: () => hooks, preToolUseObservational: () => preToolUseObservational, hookTimeoutMs: () => hookTimeoutMs, hookEnvFace: () => hookEnvFace, autoModeDecider: () => autoModeDecider, autoModeDenialTracking: () => autoModeDenialTracking, autoModeArming: () => autoModeArming, agentForkDenial: () => agentForkDenial, observersActive: () => observersActive, resolvedReadFace: () => resolvedReadFace, resolvedWriteFace: () => resolvedWriteFace, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized, handsLessResolvedFace: () => handsLessResolvedFace, handsLessResolvedWriteFace: () => handsLessResolvedWriteFace, centerAdoption: () => centerAdoptionRef.current, memoryEngineSession: () => memoryEngineSession });
|
|
379
380
|
const { roster, blockedRef, runtimeCaps, runtimeCapsFaulted, complianceDenies, complianceDegraded, agentForkDenial, observersActive, autoModeArmReason, autoModeDecider, autoModeDenialTracking, autoModeArming, selfOrchestrationActive, workflowToolsActive, workflowSizeGuideline } = await prepareCapsAndWorkflow({ spec, deps, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, checkpointSeat, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, frozenOnAsk, parentSpecSeat, carrierReadFace, carrierWriteFace, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, autoModeIntent, peerLaneActive, peerSendMessageBuiltIn, runnerSelf, memoryEngineSession: () => memoryEngineSession, centerAdoption: () => centerAdoptionRef.current, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized });
|
|
380
381
|
const tools = roster.tools;
|
|
381
382
|
const pausedRef = {};
|
|
@@ -513,14 +514,14 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
513
514
|
}
|
|
514
515
|
const handsReadFaceInput = { handsEnabled, executionEnv, taskRootFinal, taskRootCanonical, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGate, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, harnessRef, toolProgressRef, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
|
|
515
516
|
const handsReadFace = handsEnabled ? await prepareHandsMount(handsReadFaceInput) : resolveHandsLessReadFace(handsReadFaceInput);
|
|
516
|
-
const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive,
|
|
517
|
+
const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive, shellReadCheck, shellReadAdmission, additionalRootsCanonical, additionalReadRootsCanonical, attachmentRootCanonical, readDenyMatcher, envHandToolNames, sealReadStateSeat } = handsReadFace;
|
|
517
518
|
resolvedReadFace = handsReadFace.resolvedReadFace;
|
|
518
519
|
resolvedWriteFace = handsReadFace.resolvedWriteFace;
|
|
519
520
|
readDenyAdditionsNormalized = handsReadFace.readDenyAdditionsNormalized;
|
|
520
521
|
handsLessResolvedFace = handsReadFace.handsLessResolvedFace;
|
|
521
522
|
handsLessResolvedWriteFace = handsReadFace.handsLessResolvedWriteFace;
|
|
522
523
|
shellGatedTools = handsReadFace.shellGatedTools;
|
|
523
|
-
const { worktreeSessionRef } = prepareDelegationSurface({ spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, executionEnv, runnerSelf, backgroundTaskToolsActive,
|
|
524
|
+
const { worktreeSessionRef } = prepareDelegationSurface({ spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, executionEnv, runnerSelf, backgroundTaskToolsActive, shellReadAdmission, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, roster, toolEffects, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle });
|
|
524
525
|
const { liveQuestionFace, contentAskBindings, contentAskRoutable, lateStrandedAnswers, discloseStrandedAnswers, settleContentAskBindings, durableQuestionFace, questionToolMounted, mountedQuestionTool } = prepareQuestionFace({ frozenOnQuestion, spec, deps, checkpointStore, runtimeCaps, resolvedInteractionPosture, resume, sessionId, roster, inheritedUnavailableAsks: () => inheritedUnavailableAsks });
|
|
525
526
|
if (spec.handsReadOnly !== true) {
|
|
526
527
|
const sessionScope = sessionId ?? spec.principal ?? spec.taskId ?? "default";
|
|
@@ -690,8 +691,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
690
691
|
releaseSignal = () => sig.removeEventListener("abort", onExternalAbort);
|
|
691
692
|
}
|
|
692
693
|
}
|
|
693
|
-
const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, envHandToolNames, handsCwdRef, readDenyMatcher, questionToolMounted, runtimeCaps, inheritedAncestorRules, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
|
|
694
|
-
const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtectionCheck, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace } = prepareWiringManifest({ spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs,
|
|
694
|
+
const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, envHandToolNames, handsCwdRef, readDenyMatcher, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
|
|
695
|
+
const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtectionCheck, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound } = prepareWiringManifest({ spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, shellReadStationArmed: shellReadCheck !== undefined, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive: handsReadFace.readDenyBuiltinTiersActive, lspManagerWired, lspDiagnosticsLive: lspDiagnostics !== undefined, sessionBox });
|
|
695
696
|
if (fileHistoryBoundary !== undefined) {
|
|
696
697
|
harness.on("tool_call", async () => {
|
|
697
698
|
await fileHistoryBoundary.settle();
|
|
@@ -699,15 +700,15 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
699
700
|
});
|
|
700
701
|
}
|
|
701
702
|
const { askLane } = prepareAskLane({ gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, advertisedWritableDirs, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash });
|
|
702
|
-
const { saga } = prepareSuspendSaga({ gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate,
|
|
703
|
+
const { saga } = prepareSuspendSaga({ gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, ancestorRulesNow, inheritedShellGate, autoModeIntent, inheritedAdmittedOrgScopes, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter });
|
|
703
704
|
const { suspendForResource, suspendForPlatformLimit, suspendForReview } = prepareBoundaryParks({ saga, spec, checkpointStore, abortController, harness, session, sessions, sessionId, deps, priorLedger, maxSlices, maxSuspends, resourceTotal, priorSuspendCount, suspendChainBase, humanReviewRef, liveSpendRef, now, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, pausedRef, remoteEnvFailures, resourceSuspendEligible, durableSuspendInfraReady, incompleteSuspendAdapter });
|
|
704
705
|
const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef });
|
|
705
|
-
prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, writeProtectionCheck, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash });
|
|
706
|
+
prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, writeProtectionCheck, shellReadCheck, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash });
|
|
706
707
|
const { microCompact, charsPerToken } = prepareContextLane({ model, deps, sessionId, runId, hostTaskId, offloadStore, microCompactKnob, harness, batchHaltRef, gitStatusRef, requestLossyRef, trimPressureRef, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}) });
|
|
707
708
|
const preparedHolder = {};
|
|
708
709
|
const { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved } = prepareTurnWiring({ deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, additionalRootsCanonical, additionalReadRootsCanonical, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder });
|
|
709
710
|
await onceLedger.settle(session, announcedListingsRef);
|
|
710
|
-
const buildPrepared = () => ({ harness, session, sessionId, runId, reminderMark, reminderDisclosureCounts, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(mcpRedial !== undefined ? { mcpRedial } : {}), ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, suspendForReview, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}), resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, gitStatusRef, listBackgroundTasks, hookIdentity, hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}) });
|
|
711
|
+
const buildPrepared = () => ({ harness, session, sessionId, runId, reminderMark, reminderDisclosureCounts, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(mcpRedial !== undefined ? { mcpRedial } : {}), ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, suspendForReview, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}), resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, gitStatusRef, listBackgroundTasks, hookIdentity, ...(sessionBoxBound !== undefined ? { sessionBox: sessionBoxBound } : {}), hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}) });
|
|
711
712
|
rollback.commit();
|
|
712
713
|
const prepared = buildPrepared();
|
|
713
714
|
preparedHolder.current = prepared;
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { AgentHarness, ExecutionEnv } from "../../internal/harness.js";
|
|
20
20
|
import { type PeerLaneRefs } from "../../agents/peer-session-drain.js";
|
|
21
|
+
import type { SessionBoxBinding } from "../task-notification.js";
|
|
21
22
|
import type { OnQuestion } from "../ask-question.js";
|
|
22
23
|
import type { CheckpointStore } from "../checkpoint-store.js";
|
|
23
24
|
import { type HookEnvCapabilities, type HookInvocationIdentity, type Hooks } from "../hooks.js";
|
|
@@ -47,8 +48,8 @@ export interface PrepareWiringManifestInput {
|
|
|
47
48
|
* `now`, `onUsageGovernance`…) the helper reads through the whole record. */
|
|
48
49
|
deps: RunnerDeps;
|
|
49
50
|
/** borrowed-readonly — the trusted spawn-side channel: `questionFaceStripped`, `isDelegatedChild`, `onTaskNotification`,
|
|
50
|
-
* `peerSelfRef`, `explicitAgentName` (the drain), `insideFork` / `agentName` / `parentToolCallId` (the identity). */
|
|
51
|
-
internals: Pick<RunInternals, "questionFaceStripped" | "isDelegatedChild" | "onTaskNotification" | "peerSelfRef" | "explicitAgentName" | "insideFork" | "agentName" | "parentToolCallId"> | undefined;
|
|
51
|
+
* `peerSelfRef`, `explicitAgentName` (the drain + the identity), `insideFork` / `agentName` / `spawnAgentType` / `parentToolCallId` (the identity). */
|
|
52
|
+
internals: Pick<RunInternals, "questionFaceStripped" | "isDelegatedChild" | "onTaskNotification" | "peerSelfRef" | "explicitAgentName" | "spawnAgentType" | "insideFork" | "agentName" | "parentToolCallId"> | undefined;
|
|
52
53
|
/** borrowed-readonly — the resume leg, or undefined (the manifest's leg derivation reads presence only). */
|
|
53
54
|
resume: Pick<PrepareResume, "seed"> | undefined;
|
|
54
55
|
/** borrowed-readonly — the acquired session id. */
|
|
@@ -77,6 +78,9 @@ export interface PrepareWiringManifestInput {
|
|
|
77
78
|
irreversibleTools: ReadonlySet<string>;
|
|
78
79
|
/** borrowed-readonly — see `irreversibleTools`. */
|
|
79
80
|
egressTools: ReadonlySet<string>;
|
|
81
|
+
/** borrowed-readonly — the hands phase mounted the shell READ STATION (a real shell was mounted): the gate
|
|
82
|
+
* machinery must run for it, under every doctrine — the read-only face's containment IS that station. */
|
|
83
|
+
shellReadStationArmed: boolean;
|
|
80
84
|
/** borrowed-readonly — the effect collection; read only here (the ungated scans). */
|
|
81
85
|
toolEffects: ReadonlyMap<string, ToolEffect>;
|
|
82
86
|
/** borrowed-readonly — the per-task owned env when a factory minted one (durable infra, the hook-env predicate). */
|
|
@@ -121,8 +125,8 @@ export interface PrepareWiringManifestInput {
|
|
|
121
125
|
/** borrowed-mutable — the peer lane's late-bound facts. Writer here: `askEffective` ← the manifest's ask derivation (the
|
|
122
126
|
* one fold of this session's permission-mode class). */
|
|
123
127
|
peerLaneRefs: PeerLaneRefs;
|
|
124
|
-
/** borrowed-readonly — the
|
|
125
|
-
|
|
128
|
+
/** borrowed-readonly — the session-box drain's mount verdict (prepare-task's one judgment): present ⇒ this leg drains its own box. */
|
|
129
|
+
sessionBox: SessionBoxBinding | undefined;
|
|
126
130
|
/** borrowed-readonly — the built harness the peer drain binds to. */
|
|
127
131
|
harness: AgentHarness;
|
|
128
132
|
/** borrowed-readonly — the durable-suspend holder; the drain's parked predicate reads `token` at run time. Not written here. */
|
|
@@ -179,6 +183,9 @@ export interface PrepareWiringManifestResult {
|
|
|
179
183
|
hookIdentity: HookInvocationIdentity;
|
|
180
184
|
/** owned — the read-only env capability face every hook context carries, or undefined (no hook consumer, or no env wired). */
|
|
181
185
|
hookEnvFace: HookEnvCapabilities | undefined;
|
|
186
|
+
/** owned — the session box this leg's drain was BOUND on (the mount judgment ∧ an injector to drain into); the notification
|
|
187
|
+
* lane binds the park seat on exactly this value, so "parked here" and "drained there" are one fact. */
|
|
188
|
+
sessionBoxBound: SessionBoxBinding | undefined;
|
|
182
189
|
}
|
|
183
190
|
/**
|
|
184
191
|
* The wiring manifest's per-server MCP read face for one leg ({@link WiringManifest.mcp}): every
|
|
@@ -115,7 +115,7 @@ function announceDurableGateUnavailable(args) {
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
export function prepareWiringManifest(input) {
|
|
118
|
-
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs,
|
|
118
|
+
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, sessionBox, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive } = input;
|
|
119
119
|
const onAsk = spec.onAsk ?? deps.onAsk;
|
|
120
120
|
const handWriteTools = toolRoster.entries.filter((e) => e.mountedBy === "hands" && (e.effect === "write" || e.effect === "idempotent")).map((e) => e.name);
|
|
121
121
|
const hasEffectAwareGate = Boolean(policyLayers.length > 0 || (hooks?.preToolUse !== undefined && !preToolUseObservational));
|
|
@@ -193,7 +193,7 @@ export function prepareWiringManifest(input) {
|
|
|
193
193
|
parkCapable: checkpointStore !== undefined,
|
|
194
194
|
parkDurableApprovalOptIn: spec.durableApproval !== undefined,
|
|
195
195
|
parkForceDurableGate: runtimeCaps?.forceDurableGate === true,
|
|
196
|
-
parkSafetyVocabularyArmed: irreversibleTools.size > 0 || egressTools.size > 0,
|
|
196
|
+
parkSafetyVocabularyArmed: irreversibleTools.size > 0 || egressTools.size > 0 || shellReadStationArmed,
|
|
197
197
|
...(checkpointStore !== undefined ? { checkpointDurability: resolveDeclaredDurability(checkpointStore, "checkpointStore") } : {}),
|
|
198
198
|
sessionDurability: resolveDeclaredDurability(sessions, "sessionStore"),
|
|
199
199
|
backgroundAgentStoreWired: deps.backgroundAgentStore !== undefined,
|
|
@@ -217,7 +217,8 @@ export function prepareWiringManifest(input) {
|
|
|
217
217
|
...(lspManagerWired ? { lsp: deriveLspSeam(toolRoster.entries.some((e) => e.contract.contractId === LSP_CONTRACT_ID), lspDiagnosticsLive) } : {}),
|
|
218
218
|
});
|
|
219
219
|
peerLaneRefs.askEffective = wiringManifest.ask.effective;
|
|
220
|
-
|
|
220
|
+
const sessionBoxBound = sessionBox !== undefined && internals?.onTaskNotification !== undefined ? sessionBox : undefined;
|
|
221
|
+
if (sessionBoxBound !== undefined && internals?.onTaskNotification !== undefined) {
|
|
221
222
|
bindPeerLaneDrain(harness, {
|
|
222
223
|
deps,
|
|
223
224
|
sessionId,
|
|
@@ -235,6 +236,7 @@ export function prepareWiringManifest(input) {
|
|
|
235
236
|
hooks?.preToolUse !== undefined ||
|
|
236
237
|
egressTools.size > 0 ||
|
|
237
238
|
irreversibleTools.size > 0 ||
|
|
239
|
+
shellReadStationArmed ||
|
|
238
240
|
resourceSuspendEligible ||
|
|
239
241
|
platformSuspendArmed ||
|
|
240
242
|
spec.enablePlanMode === true;
|
|
@@ -246,9 +248,11 @@ export function prepareWiringManifest(input) {
|
|
|
246
248
|
isDelegatedChild: delegation.isDelegatedChild,
|
|
247
249
|
...(internals?.insideFork === true ? { insideFork: true } : {}),
|
|
248
250
|
...(internals?.agentName !== undefined ? { agentName: internals.agentName } : {}),
|
|
251
|
+
...(internals?.explicitAgentName !== undefined ? { spawnName: internals.explicitAgentName } : {}),
|
|
252
|
+
...(internals?.spawnAgentType !== undefined ? { agentType: internals.spawnAgentType } : {}),
|
|
249
253
|
...(internals?.parentToolCallId !== undefined ? { parentToolCallId: internals.parentToolCallId } : {}),
|
|
250
254
|
});
|
|
251
255
|
const hookContextConsumerWired = hooks?.preToolUse !== undefined || hooks?.postToolUse !== undefined || hooks?.postToolUseFailure !== undefined;
|
|
252
256
|
const hookEnvFace = hookContextConsumerWired && (ownedEnv ?? deps.executionEnv) != null ? createHookEnvCapabilities(executionEnv) : undefined;
|
|
253
|
-
return { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, platformSuspendArmed, durableApproval, wiringManifest, writeProtectionCheck: writeProtection?.check, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace };
|
|
257
|
+
return { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, platformSuspendArmed, durableApproval, wiringManifest, writeProtectionCheck: writeProtection?.check, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound };
|
|
254
258
|
}
|
|
@@ -26,6 +26,8 @@ export async function resumeApply(input) {
|
|
|
26
26
|
isDelegatedChild: effectiveDelegationFacts(internals, cp.state.isDelegatedChild).isDelegatedChild,
|
|
27
27
|
...(internals?.insideFork === true ? { insideFork: true } : {}),
|
|
28
28
|
...(internals?.agentName !== undefined ? { agentName: internals.agentName } : {}),
|
|
29
|
+
...(internals?.explicitAgentName !== undefined ? { spawnName: internals.explicitAgentName } : {}),
|
|
30
|
+
...(internals?.spawnAgentType !== undefined ? { agentType: internals.spawnAgentType } : {}),
|
|
29
31
|
...(internals?.parentToolCallId !== undefined ? { parentToolCallId: internals.parentToolCallId } : {}),
|
|
30
32
|
});
|
|
31
33
|
const screenTimeoutMs = resolveHookTimeoutMs(resumeScreenHooks?.timeoutMs, (badErr) => {
|
|
@@ -309,6 +309,7 @@ export function createHarnessHandlers(input) {
|
|
|
309
309
|
...(internals?.cycleSeq !== undefined ? { seq: internals.cycleSeq } : {}),
|
|
310
310
|
...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
|
|
311
311
|
...(subagentName ? { name: subagentName } : {}),
|
|
312
|
+
...(internals?.explicitAgentName !== undefined ? { spawnName: internals.explicitAgentName } : {}),
|
|
312
313
|
model: prepared.model.id,
|
|
313
314
|
usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - rs.telemetry.taskStart },
|
|
314
315
|
status: "running",
|