@sema-agent/core 7.24.4 → 7.25.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 +78 -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/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-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-program-position.d.ts +4 -26
- package/dist/tools/fs/bash-program-position.js +0 -11
- package/dist/tools/fs/bash-readonly-classifier.d.ts +20 -309
- package/dist/tools/fs/bash-readonly-classifier.js +28 -766
- 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 +82 -19
- 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
|
@@ -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",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PeerInboundChainRef } from "../../agents/peer-admission.js";
|
|
2
|
-
import { type PendingSessionNotifications, type SystemInjectionPriority, type TaskNotificationPayload } from "../task-notification.js";
|
|
2
|
+
import { type NotificationInjectionOutcome, type PendingSessionNotifications, type SystemInjectionPriority, type TaskNotificationPayload } from "../task-notification.js";
|
|
3
3
|
import type { PushQueue } from "../push-queue.js";
|
|
4
4
|
import type { TaskEvent, TaskSpec } from "../types.js";
|
|
5
5
|
import type { Stats } from "./assemble-result.js";
|
|
@@ -32,7 +32,7 @@ export interface RunIdentityWiringInput {
|
|
|
32
32
|
/** borrowed-readonly — the notification lane's ONE injection entry (the R0 lane's). */
|
|
33
33
|
injectTaskNotification: (notification: TaskNotificationPayload, opts?: {
|
|
34
34
|
priority?: SystemInjectionPriority;
|
|
35
|
-
}) => Promise<
|
|
35
|
+
}) => Promise<NotificationInjectionOutcome>;
|
|
36
36
|
/** borrowed-mutable — the turn-open dedup set (the cross-layer double-park dedup): a redelivered frame's key is registered here. */
|
|
37
37
|
deliveredAtTurnOpen: Set<string>;
|
|
38
38
|
/** borrowed-mutable — the peer inbound chain, overwritten by each consumed peer-class payload. */
|
|
@@ -19,6 +19,7 @@ import { DEFAULT_PRECALL_OUTPUT_TOKENS, platformLimitTerminal } from "./clock-an
|
|
|
19
19
|
import { deepJsonEqual, resumeContinuation } from "./decide-continuation.js";
|
|
20
20
|
import { settleExecutionRecord } from "./execution-record.js";
|
|
21
21
|
import { mintGateOutcome } from "./gate-exit.js";
|
|
22
|
+
import { withGateTimeout } from "../gate-bounded-await.js";
|
|
22
23
|
import { resolveGitLegDelivery, wrapGitFrame } from "./git-leg-delivery.js";
|
|
23
24
|
import { GIT_STATUS_ECHO_PREVIEW } from "./git-status-frame.js";
|
|
24
25
|
import { toImageContent } from "./image.js";
|
|
@@ -678,6 +679,31 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
678
679
|
return;
|
|
679
680
|
}
|
|
680
681
|
}
|
|
682
|
+
if (prepared.shellReadCheck !== undefined) {
|
|
683
|
+
const edited = outcome.updatedInput !== undefined && !deepJsonEqual(outcome.updatedInput, pendingAction.args);
|
|
684
|
+
const judged = prepared.shellReadCheck.judge(pendingAction.toolName, resolvedArgs, prepared.cwdRef?.current, prepared.abortController.signal, {
|
|
685
|
+
toolCallId: pendingAction.toolCallId,
|
|
686
|
+
...(edited ? { seat: "rejudge" } : {}),
|
|
687
|
+
});
|
|
688
|
+
if (judged !== null) {
|
|
689
|
+
let verdict;
|
|
690
|
+
let answered = true;
|
|
691
|
+
try {
|
|
692
|
+
verdict = await withGateTimeout(judged, ORG_ADJUDICATION_TIMEOUT_MS, prepared.abortController.signal, "shellReadStation");
|
|
693
|
+
}
|
|
694
|
+
catch {
|
|
695
|
+
answered = false;
|
|
696
|
+
verdict = prepared.shellReadCheck.unanswered(pendingAction.toolName, "the read station could not answer on the resumed leg");
|
|
697
|
+
}
|
|
698
|
+
if (!answered || verdict.disposition === "refuse" || (edited && verdict.disposition !== "vouch")) {
|
|
699
|
+
const readDenial = formatHookFeedback(`The approved tool call "${pendingAction.toolName}" was not executed: ${verdict.sentence ?? "the read boundary does not vouch for what it reads on this leg"} This approval is spent — the call has to be re-issued and approved again.`, prepared.reminderMark);
|
|
700
|
+
await settleEnd(true, { content: readDenial, ...(verdict.details !== undefined ? { details: verdict.details } : {}) }, vetoed("read_boundary"));
|
|
701
|
+
const eid = await prepared.session.appendMessage(toolResultMsg(pendingAction.toolCallId, pendingAction.toolName, readDenial, true));
|
|
702
|
+
emitCommitted(eid, "toolResult", pendingAction.toolCallId);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
681
707
|
const tool = prepared.tools.find((t) => t.name === pendingAction.toolName);
|
|
682
708
|
if (!tool) {
|
|
683
709
|
const e = new Error(`the approved tool "${pendingAction.toolName}" is no longer available on resume`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type PeerInboundChainRef } from "../../agents/peer-admission.js";
|
|
2
2
|
import type { PushQueue } from "../push-queue.js";
|
|
3
3
|
import type { SessionStore } from "../session.js";
|
|
4
|
-
import { type PendingSessionNotifications, type SystemInjectionPriority, type TaskNotificationPayload } from "../task-notification.js";
|
|
4
|
+
import { type NotificationInjectionOutcome, type PendingSessionNotifications, type SystemInjectionPriority, type TaskNotificationPayload } from "../task-notification.js";
|
|
5
5
|
import type { RunnerDeps, TaskEvent, TaskSpec } from "../types.js";
|
|
6
6
|
import type { SessionReadFileStates } from "./prepare-hands-readface.js";
|
|
7
7
|
import type { NotificationLaneBindings, Prepared, PrepareTaskFn, ResumeRun, RunInternals, RunnerDepsSeat, RunnerSelfSeat, TaskIdRef } from "./contracts.js";
|
|
@@ -41,7 +41,7 @@ export interface RunNotificationLaneResult {
|
|
|
41
41
|
/** The ONE injection entry every notification producer rides (the identity lane binds the notify() bridge to it). */
|
|
42
42
|
injectTaskNotification: (notification: TaskNotificationPayload, opts?: {
|
|
43
43
|
priority?: SystemInjectionPriority;
|
|
44
|
-
}) => Promise<
|
|
44
|
+
}) => Promise<NotificationInjectionOutcome>;
|
|
45
45
|
/** The turn-open dedup set (the cross-layer double-park dedup): the identity lane registers a redelivered frame's key here. */
|
|
46
46
|
deliveredAtTurnOpen: Set<string>;
|
|
47
47
|
/** The peer inbound chain ref this run carries (the spawn chain's, or a fresh one). */
|
|
@@ -118,9 +118,10 @@ export async function runNotificationLane(input) {
|
|
|
118
118
|
}
|
|
119
119
|
catch {
|
|
120
120
|
}
|
|
121
|
-
injectTaskNotification(notification, opts);
|
|
121
|
+
return injectTaskNotification(notification, opts);
|
|
122
122
|
},
|
|
123
123
|
}, self, taskIdRef);
|
|
124
|
+
pendingSessionNotifications.bindSessionBox(prepared.sessionId, prepared.sessionBox);
|
|
124
125
|
const notificationLane = {
|
|
125
126
|
get harness() { return notificationHarness; }, set harness(h) { notificationHarness = h; },
|
|
126
127
|
get sessionId() { return notificationSessionId; },
|
|
@@ -266,6 +266,7 @@ export async function runSettleAndTeardown(input) {
|
|
|
266
266
|
...(internals?.cycleSeq !== undefined ? { seq: internals.cycleSeq } : {}),
|
|
267
267
|
...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
|
|
268
268
|
...(subagentName ? { name: subagentName } : {}),
|
|
269
|
+
...(internals?.explicitAgentName !== undefined ? { spawnName: internals.explicitAgentName } : {}),
|
|
269
270
|
model: prepared.model.id,
|
|
270
271
|
usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - rs.telemetry.taskStart },
|
|
271
272
|
status: result.terminal.kind === "completed" ? "completed" : "failed",
|
|
@@ -87,10 +87,9 @@ export interface SessionRuleSource {
|
|
|
87
87
|
* DELETED and written again starts over at 1. At `>=`, a recreated row whose rev merely TIES the
|
|
88
88
|
* enforced one would replace it — an unauthorized loosening dressed as an update. At `>`, a tie enforces
|
|
89
89
|
* the floor, which is a no-op for the honest case (equal rev is the same row) and fail-closed for the
|
|
90
|
-
* recycled one.
|
|
91
|
-
*
|
|
92
|
-
* a
|
|
93
|
-
* generation identity), which is a cross-backend contract change, not a reader-side one.
|
|
90
|
+
* recycled one. Closed since 7.25.0 by the STORE's lineage identity (`StoredSessionRules.gen`): a
|
|
91
|
+
* recreated row is another generation and is never compared to the enforced one, whatever its rev, and
|
|
92
|
+
* a backend without lineages (gen 0 throughout) keeps the `>` protection above.
|
|
94
93
|
*
|
|
95
94
|
* The per-call handoff mirrors the permission-rule lanes': the first reader of a `toolCallId` takes the read
|
|
96
95
|
* and hands it on, a second reader of the SAME call claims that one snapshot, and an unclaimed entry is
|
|
@@ -60,9 +60,17 @@ export function createLiveSessionRules(store, floor, hooks) {
|
|
|
60
60
|
}
|
|
61
61
|
return enforced;
|
|
62
62
|
}
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if (enforced.rev > 0) {
|
|
64
|
+
if (live.gen !== undefined && enforced.gen !== undefined) {
|
|
65
|
+
if (live.gen !== enforced.gen) {
|
|
66
|
+
announce(`session ${JSON.stringify(floor.sessionId)} has a rules row of a new lineage (generation ${live.gen}, rev ${live.rev}), which does not continue the row this leg enforces (generation ${enforced.gen})`);
|
|
67
|
+
return enforced;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (vanished) {
|
|
71
|
+
announce(`session ${JSON.stringify(floor.sessionId)} has a new rules row at rev ${live.rev} after the row this leg enforced was deleted, and its backend carries no lineage to continue it by`);
|
|
72
|
+
return enforced;
|
|
73
|
+
}
|
|
66
74
|
}
|
|
67
75
|
if (live.rev <= enforced.rev) {
|
|
68
76
|
if (live.rev < enforced.rev) {
|