@sema-agent/core 7.5.2 → 7.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/agents/cascade.d.ts +2 -2
- package/dist/agents/cascade.js +12 -10
- package/dist/agents/repair-loop.d.ts +5 -3
- package/dist/agents/repair-loop.js +13 -15
- package/dist/agents/subagent.d.ts +24 -42
- package/dist/agents/subagent.js +119 -105
- package/dist/agents/suspend-guard.d.ts +31 -19
- package/dist/agents/suspend-guard.js +14 -8
- package/dist/agents/teacher.js +9 -9
- package/dist/agents/team.d.ts +4 -3
- package/dist/agents/team.js +10 -8
- package/dist/agents/verify.d.ts +3 -3
- package/dist/agents/verify.js +17 -17
- package/dist/core/a2a.js +2 -1
- package/dist/core/ask-origin.d.ts +60 -7
- package/dist/core/ask-origin.js +26 -1
- package/dist/core/checkpoint-store.d.ts +78 -76
- package/dist/core/checkpoint-store.js +17 -1
- package/dist/core/gate-outcome.d.ts +189 -0
- package/dist/core/gate-outcome.js +70 -0
- package/dist/core/hooks.d.ts +18 -92
- package/dist/core/hooks.js +88 -85
- package/dist/core/mcp-failure.d.ts +104 -0
- package/dist/core/mcp-failure.js +128 -0
- package/dist/core/mcp.d.ts +21 -77
- package/dist/core/mcp.js +76 -150
- package/dist/core/pause-registry.d.ts +131 -0
- package/dist/core/pause-registry.js +27 -0
- package/dist/core/runner/assemble-result.d.ts +32 -41
- package/dist/core/runner/assemble-result.js +55 -74
- package/dist/core/runner/contracts.d.ts +46 -64
- package/dist/core/runner/denial-limit-arms.d.ts +1 -1
- package/dist/core/runner/denial-limit-arms.js +3 -3
- package/dist/core/runner/gate-exit.d.ts +74 -0
- package/dist/core/runner/gate-exit.js +55 -0
- package/dist/core/runner/park-commit.d.ts +17 -23
- package/dist/core/runner/park-commit.js +14 -15
- package/dist/core/runner/prepare-ask-lane.d.ts +0 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -5
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -6
- package/dist/core/runner/prepare-boundary-parks.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -7
- package/dist/core/runner/prepare-gate-stations.js +29 -54
- package/dist/core/runner/prepare-inherited-gate.js +1 -1
- package/dist/core/runner/prepare-memory.d.ts +44 -26
- package/dist/core/runner/prepare-park-ask.d.ts +2 -4
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-task.js +8 -9
- package/dist/core/runner/prepare-wiring-manifest.d.ts +7 -15
- package/dist/core/runner/prepare-wiring-manifest.js +9 -10
- package/dist/core/runner/runtask.d.ts +16 -31
- package/dist/core/runner/runtask.js +109 -120
- package/dist/core/runner/terminal-projection.d.ts +22 -0
- package/dist/core/runner/terminal-projection.js +28 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +4 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +8 -2
- package/dist/core/terminal-cause.d.ts +137 -0
- package/dist/core/terminal-cause.js +9 -0
- package/dist/core/tool-policy.d.ts +43 -139
- package/dist/core/tool-policy.js +79 -112
- package/dist/core/types.d.ts +67 -164
- package/dist/core/wiring-manifest.d.ts +6 -3
- package/dist/core/workflow-journal-store.js +3 -4
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.js +8 -5
- package/dist/orchestration/builtin-workflows.d.ts +2 -2
- package/dist/orchestration/builtin-workflows.js +1 -1
- package/dist/orchestration/goal.js +8 -7
- package/dist/orchestration/run-spec.js +5 -3
- package/dist/orchestration/run-workflow-tool.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.js +4 -4
- package/dist/orchestration/workflow-governance.d.ts +4 -4
- package/dist/orchestration/workflow-governance.js +4 -2
- package/dist/orchestration/workflow-primitives.d.ts +1 -1
- package/dist/orchestration/workflow-primitives.js +1 -1
- package/dist/orchestration/workflow.d.ts +11 -0
- package/dist/orchestration/workflow.js +64 -39
- package/dist/prompts/supervisor.d.ts +1 -1
- package/dist/prompts/supervisor.js +3 -3
- package/dist/scenarios/scenario-registry.js +1 -1
- package/package.json +3 -1
- package/test/export-surface.snapshot.json +74 -22
|
@@ -7,26 +7,25 @@ export function sanitizedTtlMs(ttlMs) {
|
|
|
7
7
|
return Number.isFinite(ttlMs) && ttlMs > 0 ? ttlMs : DEFAULT_RESOURCE_TTL_MS;
|
|
8
8
|
}
|
|
9
9
|
export function gatedCallIdOf(p) {
|
|
10
|
-
|
|
11
|
-
return p.suspendRef.gatedCallId;
|
|
12
|
-
if (p.reviewRef.token !== undefined)
|
|
13
|
-
return p.reviewRef.gatedCallId;
|
|
14
|
-
return undefined;
|
|
10
|
+
return p.pausedRef.current?.gatedCallId;
|
|
15
11
|
}
|
|
16
12
|
export function parkContaminationMarker(refs) {
|
|
17
|
-
if (refs.
|
|
13
|
+
if (refs.pausedRef.current === undefined)
|
|
18
14
|
return undefined;
|
|
19
15
|
const gatedCallId = gatedCallIdOf(refs);
|
|
20
16
|
return { code: "gate.parked", ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
|
|
21
17
|
}
|
|
22
18
|
export function publishCommittedSuspend(refs, token, gate, scope, remoteHandle, checkpointId, pendingAction) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
const pause = {
|
|
20
|
+
cause: {
|
|
21
|
+
kind: "paused",
|
|
22
|
+
gate,
|
|
23
|
+
token,
|
|
24
|
+
...(checkpointId !== undefined ? { checkpointId } : {}),
|
|
25
|
+
...(remoteHandle !== undefined ? { restoreMode: remoteHandle.restoreMode === "park_only" ? "park_only" : "snapshot" } : {}),
|
|
26
|
+
},
|
|
27
|
+
scope,
|
|
28
|
+
...(pendingAction?.kind === "tool_approval" ? { gatedCallId: pendingAction.toolCallId } : {}),
|
|
29
|
+
};
|
|
30
|
+
refs.pausedRef.current = pause;
|
|
32
31
|
}
|
|
@@ -60,9 +60,6 @@ export interface PrepareAskLaneInput {
|
|
|
60
60
|
* synchronous resolve that a person actually judged (count / totalWaitMs / gates push); runtask adds the durable
|
|
61
61
|
* resume latency. */
|
|
62
62
|
humanReviewRef: Prepared["humanReviewRef"];
|
|
63
|
-
/** borrowed-mutable — the bare-human-rejection sideband. Writer here: a `settledBy:"human"` deny with no note
|
|
64
|
-
* (`add`); the gate station judges and sweeps it. */
|
|
65
|
-
humanBareRejections: Set<string>;
|
|
66
63
|
/** borrowed-readonly — the injectable wall clock every human-time observable reads (`Prepared.now`). */
|
|
67
64
|
now: () => number;
|
|
68
65
|
/** borrowed-readonly — the policy-chain phase's rule-offer factory (the suggestion members the ask mint threads). */
|
|
@@ -55,7 +55,7 @@ function resolveApprovalPreview(tools, toolName, args) {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
export function prepareAskLane(input) {
|
|
58
|
-
const { gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef,
|
|
58
|
+
const { gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash } = input;
|
|
59
59
|
if (!gateMachineryActive)
|
|
60
60
|
return { askLane: undefined };
|
|
61
61
|
const composedCallSignal = (callSignal) => composeCallSignal(abortController.signal, callSignal);
|
|
@@ -77,6 +77,7 @@ export function prepareAskLane(input) {
|
|
|
77
77
|
`(no live approver reachable, or a durable-park mandate applies), and no durable approval park is ` +
|
|
78
78
|
`available — denied fail-closed (the inherited constraint stands).`,
|
|
79
79
|
decisionReason: "mode",
|
|
80
|
+
settlement: { kind: "approver_unavailable", who: { party: "none" }, when: now() },
|
|
80
81
|
approverUnavailable: true,
|
|
81
82
|
};
|
|
82
83
|
}
|
|
@@ -104,7 +105,7 @@ export function prepareAskLane(input) {
|
|
|
104
105
|
...(decision.action === "ask" && decision.ruleEvidence !== undefined ? { ruleEvidence: decision.ruleEvidence } : {}),
|
|
105
106
|
}, onAsk, composedCallSignal(callSignal), lateAskSettlementObserver({ toolName: req.toolName, toolCallId: req.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice, onError: deps.onError }));
|
|
106
107
|
const waitMs = Math.max(0, now() - t0);
|
|
107
|
-
if (resolved.approverUnavailable !== true && resolved.
|
|
108
|
+
if (resolved.approverUnavailable !== true && resolved.settlement?.kind !== "task_aborted") {
|
|
108
109
|
humanReviewRef.count += 1;
|
|
109
110
|
humanReviewRef.totalWaitMs += waitMs;
|
|
110
111
|
const toolArg = primaryActivityArg(req.args);
|
|
@@ -116,9 +117,6 @@ export function prepareAskLane(input) {
|
|
|
116
117
|
...(toolArg !== undefined ? { toolArg } : {}),
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
|
-
if (resolved.action === "deny" && resolved.settledBy === "human" && resolved.humanRefusalNote !== true) {
|
|
120
|
-
humanBareRejections.add(req.toolCallId);
|
|
121
|
-
}
|
|
122
120
|
return resolved;
|
|
123
121
|
};
|
|
124
122
|
const notifyPermissionDenied = createDenyObserverNotifier(hooks, hookTimeoutMs, abortController.signal, notifyOwnHookCrash);
|
|
@@ -78,12 +78,9 @@ export interface PrepareBoundaryParksInput {
|
|
|
78
78
|
f012CheckpointState: () => boolean;
|
|
79
79
|
/** borrowed-readonly — see `faceCheckpointState`. */
|
|
80
80
|
orgAdmissionCheckpointState: () => boolean;
|
|
81
|
-
/** borrowed-mutable — the
|
|
82
|
-
* committed resource
|
|
83
|
-
|
|
84
|
-
/** borrowed-mutable — the review holder (`Prepared.reviewRef`). Writer here: the commit-side publication of a committed
|
|
85
|
-
* plan_review row. */
|
|
86
|
-
reviewRef: Prepared["reviewRef"];
|
|
81
|
+
/** borrowed-mutable — the run's committed-pause holder (`Prepared.pausedRef`). Writer here: the commit-side publication
|
|
82
|
+
* of a committed resource / platform / plan-review checkpoint. */
|
|
83
|
+
pausedRef: Prepared["pausedRef"];
|
|
87
84
|
/** borrowed-mutable — the run-scoped remote-lifecycle failure log. Writer here: a refused `suspendVM` (`push`). */
|
|
88
85
|
remoteEnvFailures: Prepared["remoteEnvFailures"];
|
|
89
86
|
/** borrowed-readonly — the wiring-manifest phase's task-axis predicate (opt-in ∧ durable infra): exposes `suspendForResource`. */
|
|
@@ -5,7 +5,7 @@ import { checkpointScopeOf } from "./checkpoint-scope.js";
|
|
|
5
5
|
import { DEFAULT_RESOURCE_TTL_MS, publishCommittedSuspend, sanitizedTtlMs, USAGE_WINDOW_REAP_MARGIN_MS } from "./park-commit.js";
|
|
6
6
|
import { remoteEnvFailureNote } from "./remote-env-retry.js";
|
|
7
7
|
export function prepareBoundaryParks(input) {
|
|
8
|
-
const { saga, spec, checkpointStore, abortController, harness, session, sessions, sessionId, deps, priorLedger, maxSlices, maxSuspends, resourceTotal, priorSuspendCount, suspendChainBase, humanReviewRef, liveSpendRef, now, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState,
|
|
8
|
+
const { 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 } = input;
|
|
9
9
|
if (saga === undefined)
|
|
10
10
|
return { suspendForResource: undefined, suspendForPlatformLimit: undefined, suspendForReview: undefined };
|
|
11
11
|
const { inFlightSpendMicroUsd, serializeCheckpointState, commitSuspendSaga, suspendLoopCapHit, suspendableEnv, parkOnlyRemoteEnv, parkOnlyHandle } = saga;
|
|
@@ -67,7 +67,7 @@ export function prepareBoundaryParks(input) {
|
|
|
67
67
|
};
|
|
68
68
|
if ((await commitSuspendSaga(token, cp, suspendableEnv, remoteHandle)).tag !== "committed")
|
|
69
69
|
return false;
|
|
70
|
-
publishCommittedSuspend({
|
|
70
|
+
publishCommittedSuspend({ pausedRef }, token, gate, scope, remoteHandle, cp.checkpointId, cp.pendingAction);
|
|
71
71
|
try {
|
|
72
72
|
await sessions.pin?.(sessionId);
|
|
73
73
|
}
|
|
@@ -153,7 +153,7 @@ export function prepareBoundaryParks(input) {
|
|
|
153
153
|
};
|
|
154
154
|
if ((await commitSuspendSaga(token, cp, suspendableEnv, remoteHandle)).tag !== "committed")
|
|
155
155
|
return false;
|
|
156
|
-
publishCommittedSuspend({
|
|
156
|
+
publishCommittedSuspend({ pausedRef }, token, gate, scope, remoteHandle, cp.checkpointId, cp.pendingAction);
|
|
157
157
|
try {
|
|
158
158
|
await sessions.pin?.(sessionId);
|
|
159
159
|
}
|
|
@@ -244,7 +244,7 @@ export async function prepareCapsAndWorkflow(input) {
|
|
|
244
244
|
},
|
|
245
245
|
...(spec.handsReadOnly === true ? { parentHandsReadOnly: true } : {}), ...(spec.interactiveTools === false ? { parentInteractiveTools: false } : {}),
|
|
246
246
|
onNotice: deps.onNotice,
|
|
247
|
-
parentCheckpointStoreDisabled: spec.checkpointStore ===
|
|
247
|
+
parentCheckpointStoreDisabled: spec.checkpointStore === "disabled",
|
|
248
248
|
parentCenterArtifactDigest: () => input.centerAdoption()?.artifact.artifactDigest,
|
|
249
249
|
parentCenterSourceRevision: () => input.centerAdoption()?.sourceRevision,
|
|
250
250
|
...(forwardEvent ? { forwardEvent } : {}),
|
|
@@ -27,7 +27,7 @@ import type { AskClass } from "../ask-class.js";
|
|
|
27
27
|
import type { AutoModeDecider, AutoModeDenialTracker } from "../auto-mode.js";
|
|
28
28
|
import { type ComplianceCapability } from "../compliance.js";
|
|
29
29
|
import { type HookEnvCapabilities, type HookInvocationIdentity, type Hooks } from "../hooks.js";
|
|
30
|
-
import {
|
|
30
|
+
import type { ToolPolicy } from "../tool-policy.js";
|
|
31
31
|
import type { RunnerDeps, TaskSpec, ToolEffect } from "../types.js";
|
|
32
32
|
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
33
33
|
import type { AskLane, IrreversibilityTier, ParkAsk, Prepared, ReversibilityProbes } from "./contracts.js";
|
|
@@ -74,9 +74,6 @@ export interface PrepareGateStationsInput {
|
|
|
74
74
|
blockedToolCalls: Set<string>;
|
|
75
75
|
/** borrowed-mutable — the duplicate-frame ask-grant record. Writer here: the head-of-evaluation and lifecycle-end `delete`. */
|
|
76
76
|
inheritedAskGrants: Map<string, unknown>;
|
|
77
|
-
/** borrowed-mutable — the bare-human-rejection sideband. Writer here: the head-of-evaluation `delete` and the lifecycle
|
|
78
|
-
* sweep whose `delete` IS the read the boundary judgment consumes. */
|
|
79
|
-
humanBareRejections: Set<string>;
|
|
80
77
|
/** borrowed-mutable — the inherited-unavailable marker set. Writer here: the lifecycle-end `delete`; `has` is handed to
|
|
81
78
|
* the gate as the read-only `isMarkedUnresolvable`. */
|
|
82
79
|
inheritedUnavailableAsks: Set<string>;
|
|
@@ -94,9 +91,9 @@ export interface PrepareGateStationsInput {
|
|
|
94
91
|
/** borrowed-mutable — PreToolUse `additionalContext` per call id. Writers here: the `tool_call` station's stash (`set`, only
|
|
95
92
|
* for calls that will execute) and the `tool_result` station's one-shot drain (`delete`). */
|
|
96
93
|
preToolContexts: Map<string, string[]>;
|
|
97
|
-
/** borrowed-mutable — the
|
|
98
|
-
* gate
|
|
99
|
-
|
|
94
|
+
/** borrowed-mutable — the gate-outcome sideband (`Prepared.gateOutcomes`). Writer here: the single screened write per
|
|
95
|
+
* gated call (the two short-circuits and the gate's terminal exits); the frame mint reads and deletes. */
|
|
96
|
+
gateOutcomes: Prepared["gateOutcomes"];
|
|
100
97
|
/** borrowed-mutable — the turn halt fact (`Prepared.batchHaltRef`). Writer here: the bare-rejection boundary (`current`). */
|
|
101
98
|
batchHaltRef: Prepared["batchHaltRef"];
|
|
102
99
|
/** borrowed-readonly — whether blocked/suspended ids are tracked at all (the post-tool callbacks exist). */
|
|
@@ -2,54 +2,29 @@ import { SEND_MESSAGE_TOOL_NAME } from "../../agents/send-message-tool.js";
|
|
|
2
2
|
import { complianceCallDenial } from "../compliance.js";
|
|
3
3
|
import { cloneObserverInput, formatHookFeedback, hookSeatExpiredError, runHookSeat, runToolGate } from "../hooks.js";
|
|
4
4
|
import { PRESENT_PLAN_TOOL_NAME } from "../present-plan-tool.js";
|
|
5
|
-
import {
|
|
5
|
+
import { screenGateOutcome } from "../gate-outcome.js";
|
|
6
|
+
import { directDeny } from "./gate-exit.js";
|
|
6
7
|
import { emitTrace } from "../trace.js";
|
|
7
8
|
import { createWriteProtectionCheck } from "../write-protect.js";
|
|
8
9
|
import { PATH_CONFINABLE_WRITE_TOOLS } from "./session-rule-policy.js";
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
settledBy = reportedBy;
|
|
20
|
-
}
|
|
21
|
-
const attribution = screenApproverAttribution(result.approver);
|
|
22
|
-
if (attribution.defect !== undefined) {
|
|
23
|
-
defects.push(`a tool-gate settlement reported an attribution this engine refuses: ${attribution.defect}; the frame carries no approver`);
|
|
24
|
-
}
|
|
25
|
-
const reportedResolution = result.resolution;
|
|
26
|
-
let resolution;
|
|
27
|
-
if (reportedResolution !== undefined) {
|
|
28
|
-
if (!isAskDenyResolution(reportedResolution) || !settling) {
|
|
29
|
-
defects.push(`a tool-gate settlement reported a deny resolution "${String(reportedResolution)}" on ${settling ? "a blocked" : "an executing"} call — ` +
|
|
30
|
-
`it is one of the closed ask-deny vocabulary and only a BLOCKED call can carry one; the frame carries no resolution`);
|
|
31
|
-
}
|
|
32
|
-
else
|
|
33
|
-
resolution = reportedResolution;
|
|
34
|
-
}
|
|
35
|
-
const reportedAutoDenied = result.autoDenied;
|
|
36
|
-
let autoDenied;
|
|
37
|
-
if (reportedAutoDenied === true) {
|
|
38
|
-
if (!settling)
|
|
39
|
-
defects.push("a tool-gate settlement reported autoDenied on an executing call — only a BLOCKED call can carry the marker; the frame carries none");
|
|
40
|
-
else
|
|
41
|
-
autoDenied = true;
|
|
10
|
+
function screenGateResult(result) {
|
|
11
|
+
if (result.suspend !== undefined)
|
|
12
|
+
return { defects: [] };
|
|
13
|
+
const gate = result.gate;
|
|
14
|
+
if (gate === undefined)
|
|
15
|
+
return { defects: ["a tool-gate result carried no outcome record on a terminal exit — every terminal exit mints one; the frame carries none"] };
|
|
16
|
+
const defects = screenGateOutcome(gate);
|
|
17
|
+
const blocked = result.block === true;
|
|
18
|
+
if ((gate.disposition.kind === "denied") !== blocked) {
|
|
19
|
+
defects.push(`a tool-gate result's outcome reads "${gate.disposition.kind}" on ${blocked ? "a blocked" : "an executing"} call — the two faces of one verdict disagree; the frame carries no outcome`);
|
|
42
20
|
}
|
|
43
|
-
|
|
44
|
-
...(settledBy !== undefined ? { settledBy } : {}),
|
|
45
|
-
...(attribution.approver !== undefined ? { approver: attribution.approver } : {}),
|
|
46
|
-
...(resolution !== undefined ? { resolution } : {}),
|
|
47
|
-
...(autoDenied !== undefined ? { autoDenied } : {}),
|
|
48
|
-
};
|
|
49
|
-
return { ...(settledBy !== undefined || attribution.approver !== undefined || resolution !== undefined || autoDenied !== undefined ? { record } : {}), defects };
|
|
21
|
+
return defects.length > 0 ? { defects } : { gate, defects };
|
|
50
22
|
}
|
|
51
23
|
function maybeHumanRejectionHalt(input) {
|
|
52
|
-
|
|
24
|
+
const d = input.gate?.disposition;
|
|
25
|
+
const s = input.gate?.settlement;
|
|
26
|
+
const bare = d?.kind === "denied" && d.deniedBy === "ask_resolution" && s?.kind === "human_refused" && s.note === undefined;
|
|
27
|
+
if (!bare || input.isDelegatedChild)
|
|
53
28
|
return undefined;
|
|
54
29
|
return {
|
|
55
30
|
reason: `This tool call was NOT executed: the user rejected the "${input.toolName}" tool call in the same ` +
|
|
@@ -64,7 +39,7 @@ function maybeHumanRejectionHalt(input) {
|
|
|
64
39
|
};
|
|
65
40
|
}
|
|
66
41
|
export function prepareGateStations(input) {
|
|
67
|
-
const { askLane, parkAsk, tools, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants,
|
|
42
|
+
const { askLane, parkAsk, tools, 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, irreversibilityTier, reversibilityProbes, abortController, shellGatedBash, shellGatedMonitor, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash } = input;
|
|
68
43
|
if (askLane !== undefined && parkAsk !== undefined) {
|
|
69
44
|
const { adjudicate, resolveAskBound, notifyPermissionDenied, notifyHookError } = askLane;
|
|
70
45
|
const { resolveContentAsk, suspendAsk } = parkAsk;
|
|
@@ -87,14 +62,15 @@ export function prepareGateStations(input) {
|
|
|
87
62
|
harness.on("tool_call", async (e) => {
|
|
88
63
|
blockedToolCalls.delete(e.toolCallId);
|
|
89
64
|
inheritedAskGrants.delete(e.toolCallId);
|
|
90
|
-
humanBareRejections.delete(e.toolCallId);
|
|
91
65
|
{
|
|
92
66
|
const complianceDeny = complianceCallDenial(complianceDenies, e.toolName);
|
|
93
67
|
if (complianceDeny !== undefined) {
|
|
94
68
|
if (blockedTracked)
|
|
95
69
|
blockedToolCalls.add(e.toolCallId);
|
|
70
|
+
const gate = directDeny("compliance");
|
|
71
|
+
gateOutcomes.set(e.toolCallId, gate);
|
|
96
72
|
if (notifyPermissionDenied) {
|
|
97
|
-
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny,
|
|
73
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny, gate, identity: hookIdentity });
|
|
98
74
|
}
|
|
99
75
|
return { block: true, reason: formatHookFeedback(complianceDeny, reminderMark), preToolContext: [] };
|
|
100
76
|
}
|
|
@@ -104,8 +80,10 @@ export function prepareGateStations(input) {
|
|
|
104
80
|
blockedToolCalls.add(e.toolCallId);
|
|
105
81
|
const planDenyReason = `Plan mode is active — "${e.toolName}" is a write/mutating tool and is read-only-blocked. ` +
|
|
106
82
|
`Research with read-only tools, then call ${PRESENT_PLAN_TOOL_NAME} with your plan to get it approved before acting.`;
|
|
83
|
+
const gate = directDeny("plan_mode");
|
|
84
|
+
gateOutcomes.set(e.toolCallId, gate);
|
|
107
85
|
if (notifyPermissionDenied) {
|
|
108
|
-
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: planDenyReason,
|
|
86
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: planDenyReason, gate, identity: hookIdentity });
|
|
109
87
|
}
|
|
110
88
|
return {
|
|
111
89
|
block: true,
|
|
@@ -114,7 +92,6 @@ export function prepareGateStations(input) {
|
|
|
114
92
|
};
|
|
115
93
|
}
|
|
116
94
|
let result;
|
|
117
|
-
let humanBareRejection = false;
|
|
118
95
|
try {
|
|
119
96
|
result = await runToolGate({
|
|
120
97
|
onNotifyError: (f) => emitTrace(deps.tracer, () => ({ kind: "observer.notify_failed", version: 1, taskId: hostTaskId, site: f.site, message: f.error.message, ts: Date.now() })),
|
|
@@ -190,7 +167,6 @@ export function prepareGateStations(input) {
|
|
|
190
167
|
inheritedUnavailableAsks.delete(e.toolCallId);
|
|
191
168
|
inheritedAskGrants.delete(e.toolCallId);
|
|
192
169
|
foldAskClasses.delete(e.toolCallId);
|
|
193
|
-
humanBareRejection = humanBareRejections.delete(e.toolCallId);
|
|
194
170
|
}
|
|
195
171
|
const ancestorAdmitted = ancestorSandboxAdmissions.get(e.toolCallId);
|
|
196
172
|
ancestorSandboxAdmissions.delete(e.toolCallId);
|
|
@@ -204,15 +180,14 @@ export function prepareGateStations(input) {
|
|
|
204
180
|
if (blockedTracked && (result.block || result.suspend)) {
|
|
205
181
|
blockedToolCalls.add(e.toolCallId);
|
|
206
182
|
}
|
|
207
|
-
const
|
|
208
|
-
for (const defect of
|
|
183
|
+
const screened = screenGateResult(result);
|
|
184
|
+
for (const defect of screened.defects)
|
|
209
185
|
deps.onError?.(new Error(defect), { phase: "config", sessionId });
|
|
210
|
-
if (
|
|
211
|
-
|
|
186
|
+
if (screened.gate !== undefined)
|
|
187
|
+
gateOutcomes.set(e.toolCallId, screened.gate);
|
|
212
188
|
if (result.block) {
|
|
213
189
|
const haltRemaining = maybeHumanRejectionHalt({
|
|
214
|
-
|
|
215
|
-
settledBy: result.settledBy,
|
|
190
|
+
gate: screened.gate,
|
|
216
191
|
isDelegatedChild: delegation.isDelegatedChild === true,
|
|
217
192
|
toolName: e.toolName,
|
|
218
193
|
toolCallId: e.toolCallId,
|
|
@@ -221,7 +221,7 @@ export function prepareInheritedGate(input) {
|
|
|
221
221
|
delegationSettlement: delegationSettlementForChildren,
|
|
222
222
|
...(autoModeDecider ? { autoModeReview: { decider: autoModeDecider } } : {}),
|
|
223
223
|
...(spec.durableApproval !== undefined ? { durableApprovalForChildren: { ...spec.durableApproval } } : {}),
|
|
224
|
-
...(spec.checkpointStore ===
|
|
224
|
+
...(spec.checkpointStore === "disabled" ? { checkpointStoreDisabledForChildren: true } : {}),
|
|
225
225
|
taskId: hostTaskId,
|
|
226
226
|
...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
|
|
227
227
|
...(internals?.parentSessionId !== undefined ? { parentSessionId: internals.parentSessionId } : {}),
|
|
@@ -2,15 +2,29 @@ import type { BeforeWriteHook, EffectiveMemoryScopes, RunnerDeps, TaskSpec, Tool
|
|
|
2
2
|
import { type CaptureEntitlementInput, type MemoryCapturePosture } from "./memory-capture-optout.js";
|
|
3
3
|
import type { Prepared } from "./contracts.js";
|
|
4
4
|
export interface PrepareMemoryInput {
|
|
5
|
+
/** borrowed-readonly — the REBOUND spec. Read: `memory` (the scope declaration this phase
|
|
6
|
+
* normalizes) and `principal` (the org-admission subject). Never mutated. */
|
|
5
7
|
spec: TaskSpec;
|
|
8
|
+
/** borrowed-readonly — the deployment seams this phase reads: the two operator lanes (`onError`,
|
|
9
|
+
* `onNotice`), the memory planes (`memoryBackend`, `memoryStore`, `memoryEngineDir`, `rootPath`,
|
|
10
|
+
* `deploymentMemoryScopes`, `memoryScopeAdmission`), `memoryCaptureRecordStore`,
|
|
11
|
+
* `memoryConsolidation`, `runtimeCapsResolver` and `onMemoryHarvestReport`. Receivers preserved
|
|
12
|
+
* (`deps.onError?.(…)`). */
|
|
6
13
|
deps: RunnerDeps;
|
|
14
|
+
/** borrowed-readonly — the acquired session's id: the engine session's key, the operator lines'
|
|
15
|
+
* context, and the capture record's subject. */
|
|
7
16
|
sessionId: string;
|
|
17
|
+
/** borrowed-readonly — the resolved task root: the containment boundary every derived memory dir
|
|
18
|
+
* is checked against, and the repo-root fallback when `deps.rootPath` is unset. */
|
|
8
19
|
taskRootPath: string;
|
|
20
|
+
/** borrowed-mutable — the caller's write-gate cell, and THIS phase is its writer: it installs the
|
|
21
|
+
* memory write gate into `.current` (the module header's one out-param effect). Identity is the
|
|
22
|
+
* contract — the caller's hands/read-face seat reads this exact cell. */
|
|
9
23
|
memoryWriteGateRef: {
|
|
10
24
|
current?: BeforeWriteHook;
|
|
11
25
|
};
|
|
12
26
|
/**
|
|
13
|
-
* #181-F5
|
|
27
|
+
* borrowed-readonly — #181-F5: whether a tool NAMED `Write` (the tool the CC `# Memory` instruction names) is on the
|
|
14
28
|
* ASSEMBLED roster this run, not excluded, AND can actually REACH the host-side memory root:
|
|
15
29
|
* prepare-task's `tools.some(t => t.name === "Write") && !exclude.includes("Write")` plus the
|
|
16
30
|
* remote-env conjunct (a hand-band Write on a remote ExecutionEnv writes the sandbox filesystem,
|
|
@@ -22,12 +36,12 @@ export interface PrepareMemoryInput {
|
|
|
22
36
|
* its roster (or cannot reach the store); the RB-276 index seed follows the same gate.
|
|
23
37
|
*/
|
|
24
38
|
writeToolsMounted: boolean;
|
|
25
|
-
/** design/319 (A ticket)
|
|
39
|
+
/** borrowed-readonly — design/319 (A ticket): the run's reminder provenance mark: the memory engine's announcement
|
|
26
40
|
* block is an engine-authored `<system-reminder>`, so its open tag must carry the same mark the
|
|
27
41
|
* system-prompt declaration names. Threaded into every `engine.inject` call this phase builds. */
|
|
28
42
|
reminderMark: string;
|
|
29
43
|
/**
|
|
30
|
-
*
|
|
44
|
+
* borrowed-readonly — the session-wide persistence verdict: `TaskSpec.memoryPersistenceCapable` (the deployment's own
|
|
31
45
|
* statement — the only honest channel for a custom memory writer persisting through its closure,
|
|
32
46
|
* which no inference can see) when set, else the KNOWN-store-path inference: a mounted,
|
|
33
47
|
* non-excluded file-write tool (Write/Edit/NotebookEdit) or a write-capable shell. A generic
|
|
@@ -37,7 +51,7 @@ export interface PrepareMemoryInput {
|
|
|
37
51
|
*/
|
|
38
52
|
rosterCanPersist: boolean;
|
|
39
53
|
/**
|
|
40
|
-
*
|
|
54
|
+
* borrowed-readonly — the raw `TaskSpec.memoryPersistenceCapable` DECLARATION, kept separate from the composed
|
|
41
55
|
* {@link rosterCanPersist} verdict because the two drive different arms:
|
|
42
56
|
* - `true` (declared) RETRACTS the engine's own read-only notice — the deployment vouches for a
|
|
43
57
|
* persistence channel the engine cannot see (a custom writer persisting through its closure),
|
|
@@ -52,14 +66,14 @@ export interface PrepareMemoryInput {
|
|
|
52
66
|
*/
|
|
53
67
|
memoryPersistenceDeclared?: boolean;
|
|
54
68
|
/**
|
|
55
|
-
* design/336 §13-3
|
|
69
|
+
* borrowed-readonly — design/336 §13-3: the memory-provenance master switch, screened at the config doors
|
|
56
70
|
* (`config.memory_provenance`, exact spellings, absent folded to `"carry"`). Every engine this
|
|
57
71
|
* phase constructs runs under it, and the pollution notices/tool wording state the mode-true
|
|
58
72
|
* behavior off it. See {@link RunnerDeps.memoryProvenance}.
|
|
59
73
|
*/
|
|
60
74
|
memoryProvenance: "off" | "carry";
|
|
61
75
|
/**
|
|
62
|
-
* design/178 ②-1
|
|
76
|
+
* borrowed-readonly — design/178 ②-1: whether the `memory_search`/`memory_get` pair PASSED its early mount conjuncts
|
|
63
77
|
* (exclusion + name occupancy, decided in prepare-task BEFORE this phase). True ⇒ this phase builds
|
|
64
78
|
* the pair's ToolSpecs ({@link PrepareMemoryResult.memoryTools}) and the injection's instruction
|
|
65
79
|
* teaches the retrieval discipline; false ⇒ neither happens, so the teaching and the roster agree
|
|
@@ -68,29 +82,22 @@ export interface PrepareMemoryInput {
|
|
|
68
82
|
*/
|
|
69
83
|
memorySearchToolsPlanned: boolean;
|
|
70
84
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* for this principal (the veto covers the request-origin plane);
|
|
74
|
-
* - `parentAdmittedOrgScopes`: the delegation chain's FROZEN admitted org set — `undefined` for a
|
|
75
|
-
* top-level task; for a delegated child the caller passes the fail-closed empty set when the
|
|
76
|
-
* chain carries no verdict (an older-shape chain must not read as "unconstrained").
|
|
77
|
-
*/
|
|
78
|
-
/**
|
|
79
|
-
* design/383 §3.1 — the SCREENED capture posture (prepare-config-doors; absent deps seat folded
|
|
80
|
-
* to `"open"`) plus whether the deployment DECLARED one at all (the once-per-process "switch in
|
|
81
|
-
* use, no policy configured" operator line fires only on the undeclared arm).
|
|
85
|
+
* borrowed-readonly — design/383 §3.1: the SCREENED capture posture (prepare-config-doors; an
|
|
86
|
+
* absent deps seat folded to `"open"`).
|
|
82
87
|
*/
|
|
83
88
|
memoryCapturePolicy?: MemoryCapturePosture;
|
|
89
|
+
/** borrowed-readonly — whether the deployment DECLARED a posture at all: the once-per-process
|
|
90
|
+
* "switch in use, no policy configured" operator line fires only on the undeclared arm. */
|
|
84
91
|
memoryCapturePolicyDeclared?: boolean;
|
|
85
92
|
/**
|
|
86
|
-
* design/383 §3.1
|
|
93
|
+
* borrowed-readonly — design/383 §3.1: the per-principal entitlement as resolved by prepare-task's ONE caps resolve
|
|
87
94
|
* (`value` = `runtimeCaps.allowMemoryOptOut` when boolean; `faulted` = the resolve threw or the
|
|
88
95
|
* member was non-boolean — per the member's F2 fault-transit contract a fault must never arrive
|
|
89
96
|
* as a coined explicit value). Consumed by the adjudicator on every ingress of this prepare.
|
|
90
97
|
*/
|
|
91
98
|
captureEntitlement?: CaptureEntitlementInput;
|
|
92
99
|
/**
|
|
93
|
-
* design/383 §2.1b
|
|
100
|
+
* borrowed-readonly — design/383 §2.1b: the carrier-absence verdict, judged by prepare-task from the DECLARED
|
|
94
101
|
* deployment shape: a remote-execution deployment whose control plane does not follow the run
|
|
95
102
|
* (the per-run sandbox / stateless-replica form) with no
|
|
96
103
|
* {@link RunnerDeps.memoryCaptureRecordStore} supplied. TRUE + a `capture:"off"` declaration ⇒
|
|
@@ -99,7 +106,7 @@ export interface PrepareMemoryInput {
|
|
|
99
106
|
*/
|
|
100
107
|
captureCarrierUnsupported?: boolean;
|
|
101
108
|
/**
|
|
102
|
-
* design/383 §2.5
|
|
109
|
+
* borrowed-readonly — design/383 §2.5: the IMMEDIATE spawner's session id (trusted internals seat, filled by the
|
|
103
110
|
* delegation lanes; absent on top-level runs). The record-query leg of the delegation floor: a
|
|
104
111
|
* child's harvest legs also read the PARENT's opt-out record off the shared write-plane control
|
|
105
112
|
* store, so a parent whose opt-out landed AFTER this child spawned (the mid-run flip) still gets
|
|
@@ -112,7 +119,7 @@ export interface PrepareMemoryInput {
|
|
|
112
119
|
*/
|
|
113
120
|
parentSessionId?: string;
|
|
114
121
|
/**
|
|
115
|
-
* design/383 §2.5
|
|
122
|
+
* borrowed-readonly — design/383 §2.5: the delegation FLOOR bit off the trusted internals chain
|
|
116
123
|
* (`internals.memoryCaptureFloor === true`): the spawning session was opted out at spawn time.
|
|
117
124
|
* A floored leg runs opted-out WITHOUT re-adjudication (the parent's granted opt-out tightens
|
|
118
125
|
* the tree; re-asking could only loosen) and mints its own one-way record (reason names the
|
|
@@ -120,7 +127,7 @@ export interface PrepareMemoryInput {
|
|
|
120
127
|
*/
|
|
121
128
|
captureFloor?: boolean;
|
|
122
129
|
/**
|
|
123
|
-
* design/383 §2.5 (rescan post-6.0.0-RC)
|
|
130
|
+
* borrowed-readonly — design/383 §2.5 (rescan post-6.0.0-RC): the floor seat's THIRD state off the same trusted
|
|
124
131
|
* chain: the spawning session's capture state was INDETERMINATE at spawn time (its record store
|
|
125
132
|
* faulted at the getter read). This leg resolves it against the live record query (see
|
|
126
133
|
* `armCaptureOptOut`): ancestor record found ⇒ floor; still faulting ⇒ this session runs
|
|
@@ -129,7 +136,7 @@ export interface PrepareMemoryInput {
|
|
|
129
136
|
*/
|
|
130
137
|
captureFloorIndeterminate?: boolean;
|
|
131
138
|
/**
|
|
132
|
-
* design/383 §2.5 (rescan post-6.0.0-RC)
|
|
139
|
+
* borrowed-readonly — design/383 §2.5 (rescan post-6.0.0-RC): the HOST-SIDE FORK lane: the session this one was
|
|
133
140
|
* forked FROM (`SessionMetadata.forkedFrom`, read by prepare-task off the acquired session). A
|
|
134
141
|
* fork byte-copies the source's committed transcript, so the source's standing opt-out governs
|
|
135
142
|
* the copy: record found at prepare ⇒ the floor arm (mint, reason naming the fork, no
|
|
@@ -138,22 +145,33 @@ export interface PrepareMemoryInput {
|
|
|
138
145
|
* record-query walk, so a source that flips WHILE the fork runs suppresses it live.
|
|
139
146
|
*/
|
|
140
147
|
captureForkOrigin?: string;
|
|
141
|
-
/** design/383 §2.5 (rescan, codex adversarial round)
|
|
148
|
+
/** borrowed-readonly — design/383 §2.5 (rescan, codex adversarial round): the fork-lineage read itself FAULTED
|
|
142
149
|
* (session metadata unreadable): whether this session forks an opted-out source is unknowable,
|
|
143
150
|
* so the capture arm runs INDETERMINATE (suppress fail-closed, disclose, mint nothing) — a
|
|
144
151
|
* metadata outage must not read as "no lineage" (读错不许伪装 clean). */
|
|
145
152
|
captureLineageFault?: boolean;
|
|
146
|
-
/** design/383 §2.5 (codex review adopted)
|
|
153
|
+
/** borrowed-readonly — design/383 §2.5 (codex review adopted): the SPAWNING session's write-plane control dir
|
|
147
154
|
* (trusted internals chain), so the record-query leg reaches a parent on a DIFFERENT memory
|
|
148
155
|
* plane (project-writing parent, personal-writing child). Absent ⇒ same-plane query only. */
|
|
149
156
|
parentCaptureQueryDir?: string;
|
|
150
|
-
/** design/383 §2.5 (codex round 3)
|
|
157
|
+
/** borrowed-readonly — design/383 §2.5 (codex round 3): the full ancestor chain's capture coordinates off the
|
|
151
158
|
* trusted internals seat; the harvest closure walks every row (deduped with the parent seat),
|
|
152
159
|
* so a mid-run flip anywhere up the tree suppresses this in-flight descendant. */
|
|
153
160
|
captureAncestors?: ReadonlyArray<{
|
|
154
161
|
sessionId: string;
|
|
155
162
|
controlDir?: string;
|
|
156
163
|
}>;
|
|
164
|
+
/**
|
|
165
|
+
* borrowed-readonly — the org-memory admission context (ruled 2026-08-05), assembled by
|
|
166
|
+
* prepare-task:
|
|
167
|
+
* - `orgMemoryDenied`/`complianceDegraded`: the compliance capability `org_memory_mount` verdict
|
|
168
|
+
* for this principal (the veto covers the request-origin plane);
|
|
169
|
+
* - `parentAdmittedOrgScopes`: the delegation chain's FROZEN admitted org set — `undefined` for a
|
|
170
|
+
* top-level task; for a delegated child the caller passes the fail-closed empty set when the
|
|
171
|
+
* chain carries no verdict (an older-shape chain must not read as "unconstrained");
|
|
172
|
+
* - `priorOwnVerdict`/`governedProvenance`: the session freeze and the monotonic governance bit.
|
|
173
|
+
* Read as a whole into the admission call; never mutated.
|
|
174
|
+
*/
|
|
157
175
|
admissionCtx: {
|
|
158
176
|
orgMemoryDenied: boolean;
|
|
159
177
|
complianceDegraded: boolean;
|
|
@@ -142,10 +142,8 @@ export interface PrepareParkAskInput {
|
|
|
142
142
|
};
|
|
143
143
|
/** borrowed-mutable — the built harness. Writer here: `abort()` (release the gate, then stop the loop). */
|
|
144
144
|
harness: Pick<AgentHarness, "abort">;
|
|
145
|
-
/** borrowed-mutable — the
|
|
146
|
-
|
|
147
|
-
/** borrowed-readonly — the review holder; handed to the commit-side discriminant, which never writes it for these kinds. */
|
|
148
|
-
reviewRef: Prepared["reviewRef"];
|
|
145
|
+
/** borrowed-mutable — the run's committed-pause holder (`Prepared.pausedRef`). Writer here: the commit-side publication. */
|
|
146
|
+
pausedRef: Prepared["pausedRef"];
|
|
149
147
|
}
|
|
150
148
|
export interface PrepareParkAskResult {
|
|
151
149
|
/** owned — the two closures as ONE value, or undefined exactly when the ask lane (and so the saga) is absent. */
|
|
@@ -4,6 +4,7 @@ import { ASK_USER_QUESTION_TOOL_NAME, classifyQuestionOutcome, validateAskQuesti
|
|
|
4
4
|
import { hasBackgroundShell, sweepBackgroundShells } from "../background-shell.js";
|
|
5
5
|
import { boundInputHashOf } from "../canonical-json.js";
|
|
6
6
|
import { BINDING_CHECKPOINT_VERSION, buildRiskDescriptor, debitLedger, encodeAtFidelity, F012_CHECKPOINT_VERSION, FACE_CHECKPOINT_VERSION, mintCheckpointId, mintCheckpointToken, ORG_ADMISSION_CHECKPOINT_VERSION, REAL_APPROVAL_CHECKPOINT_VERSION, resolveDeclaredFidelity, samePlainValue, TOKEN_CHECKPOINT_VERSION, } from "../checkpoint-store.js";
|
|
7
|
+
import { pauseOf } from "../pause-registry.js";
|
|
7
8
|
import { askCarryRowMembers } from "../hooks.js";
|
|
8
9
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
9
10
|
import { isLiveApproverSeat, carriesBidiControls, describeThrown, refuseOutOfContractDecision, tryCloneArgs } from "../tool-policy.js";
|
|
@@ -20,7 +21,7 @@ class ParkRefusal extends Error {
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
export function prepareParkAsk(input) {
|
|
23
|
-
const { askLane, saga, spec, deps, sessionId, checkpointStore, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedBash, shellGatedMonitor, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness,
|
|
24
|
+
const { askLane, saga, spec, deps, sessionId, checkpointStore, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedBash, shellGatedMonitor, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef } = input;
|
|
24
25
|
if (askLane === undefined || saga === undefined)
|
|
25
26
|
return { parkAsk: undefined };
|
|
26
27
|
const { composedCallSignal, approvalPreviewOf } = askLane;
|
|
@@ -272,8 +273,7 @@ export function prepareParkAsk(input) {
|
|
|
272
273
|
scope,
|
|
273
274
|
sessionId,
|
|
274
275
|
leafId,
|
|
275
|
-
gate,
|
|
276
|
-
pendingAction: {
|
|
276
|
+
...pauseOf(gate, {
|
|
277
277
|
kind: "tool_approval",
|
|
278
278
|
toolCallId: req.toolCallId,
|
|
279
279
|
toolName: req.toolName,
|
|
@@ -301,7 +301,7 @@ export function prepareParkAsk(input) {
|
|
|
301
301
|
boundInputHash: boundInputHashOf(parkedArgs),
|
|
302
302
|
batchToolCallIds,
|
|
303
303
|
completedCallIds,
|
|
304
|
-
},
|
|
304
|
+
}),
|
|
305
305
|
state: checkpointState,
|
|
306
306
|
deadline: ttlMs !== undefined
|
|
307
307
|
? mintedAt + ttlMs
|
|
@@ -348,7 +348,7 @@ export function prepareParkAsk(input) {
|
|
|
348
348
|
}
|
|
349
349
|
return { parkFailed: committed.reason };
|
|
350
350
|
}
|
|
351
|
-
publishCommittedSuspend({
|
|
351
|
+
publishCommittedSuspend({ pausedRef }, token, gate, cp.scope, remoteHandle, cp.checkpointId, cp.pendingAction);
|
|
352
352
|
try {
|
|
353
353
|
await sessions.pin?.(sessionId);
|
|
354
354
|
}
|