@sema-agent/core 7.53.0 → 7.54.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 +277 -1
- package/LICENSE +3 -1
- package/dist/agents/peer-session-drain.d.ts +0 -1
- package/dist/agents/peer-session-drain.js +0 -2
- package/dist/agents/send-message-tool.js +3 -4
- package/dist/agents/subagent.d.ts +3 -5
- package/dist/agents/subagent.js +18 -11
- package/dist/agents/tool-filter.d.ts +7 -4
- package/dist/agents/tool-filter.js +7 -3
- package/dist/core/a2a.js +4 -2
- package/dist/core/allow-entry.d.ts +1 -0
- package/dist/core/allow-entry.js +1 -0
- package/dist/core/approval-object.d.ts +87 -0
- package/dist/core/approval-object.js +85 -0
- package/dist/core/arg-summary.d.ts +3 -2
- package/dist/core/arg-summary.js +17 -11
- package/dist/core/ask-origin.d.ts +43 -27
- package/dist/core/ask-origin.js +20 -11
- package/dist/core/ask-question.d.ts +0 -1
- package/dist/core/ask-question.js +4 -67
- package/dist/core/ask-unresolvable-notice.d.ts +3 -2
- package/dist/core/auto-compaction.d.ts +49 -50
- package/dist/core/auto-compaction.js +41 -51
- package/dist/core/auto-mode-prompt.d.ts +4 -2
- package/dist/core/auto-mode-prompt.js +4 -3
- package/dist/core/canonical-json.d.ts +69 -0
- package/dist/core/canonical-json.js +130 -8
- package/dist/core/checkpoint-requirements.d.ts +13 -7
- package/dist/core/checkpoint-requirements.js +4 -1
- package/dist/core/checkpoint-store.d.ts +33 -18
- package/dist/core/checkpoint-store.js +5 -4
- package/dist/core/child-clamp-seats.d.ts +45 -6
- package/dist/core/child-clamp-seats.js +56 -4
- package/dist/core/consolidate-scope.d.ts +1 -1
- package/dist/core/cross-boundary-taint.d.ts +213 -0
- package/dist/core/cross-boundary-taint.js +196 -0
- package/dist/core/decision-receipt.d.ts +44 -1
- package/dist/core/decision-receipt.js +16 -0
- package/dist/core/effective-path-target.d.ts +3 -0
- package/dist/core/effective-path-target.js +4 -0
- package/dist/core/engine-notice.d.ts +34 -2
- package/dist/core/engine-notice.js +17 -1
- package/dist/core/engine-storage-backend.d.ts +73 -0
- package/dist/core/engine-storage-backend.js +1 -0
- package/dist/core/file-history-store.d.ts +6 -2
- package/dist/core/file-history-store.js +1 -0
- package/dist/core/gate-fold.js +10 -2
- package/dist/core/gate-lanes.js +30 -21
- package/dist/core/gate-outcome.d.ts +7 -3
- package/dist/core/governance-codes.d.ts +7 -2
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +14 -14
- package/dist/core/hooks.js +1 -2
- package/dist/core/locked-config.d.ts +28 -1
- package/dist/core/locked-config.js +30 -3
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp-server-spec.d.ts +66 -9
- package/dist/core/mcp-server-spec.js +52 -19
- package/dist/core/mcp.js +5 -4
- package/dist/core/memory-engine/engine.js +2 -1
- package/dist/core/memory-engine/export-bundle.d.ts +1 -1
- package/dist/core/memory-engine/export-bundle.js +1 -1
- package/dist/core/memory-engine/file-backend.d.ts +2 -6
- package/dist/core/memory-engine/file-backend.js +1 -12
- package/dist/core/memory.d.ts +3 -3
- package/dist/core/mode-policy.d.ts +13 -8
- package/dist/core/mode-policy.js +3 -2
- package/dist/core/mods/kernel/receive.d.ts +2 -1
- package/dist/core/mods/kernel/receive.js +7 -2
- package/dist/core/parent-spec-seat.d.ts +10 -13
- package/dist/core/parent-spec-seat.js +14 -6
- package/dist/core/pause-registry.d.ts +35 -1
- package/dist/core/pause-registry.js +10 -0
- package/dist/core/permission-rule-consent.d.ts +18 -5
- package/dist/core/permission-rule-consent.js +13 -8
- package/dist/core/permission-rule-model.d.ts +29 -6
- package/dist/core/permission-rule-model.js +6 -1
- package/dist/core/permission-rule-org.d.ts +37 -0
- package/dist/core/permission-rule-org.js +34 -42
- package/dist/core/permission-rule-session.js +2 -2
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +1 -0
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/read-only-shell.js +30 -9
- package/dist/core/remote-env.d.ts +41 -1
- package/dist/core/remote-env.js +18 -0
- package/dist/core/resume-startup-cause.d.ts +18 -0
- package/dist/core/resume-startup-cause.js +12 -0
- package/dist/core/runner/approval-feedback.d.ts +46 -0
- package/dist/core/runner/approval-feedback.js +41 -0
- package/dist/core/runner/compaction-call-options.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.js +2 -2
- package/dist/core/runner/contracts.d.ts +33 -41
- package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
- package/dist/core/runner/cross-boundary-lane.js +190 -0
- package/dist/core/runner/decide-continuation.d.ts +4 -4
- package/dist/core/runner/decide-continuation.js +3 -1
- package/dist/core/runner/gate-exit.d.ts +32 -12
- package/dist/core/runner/gate-exit.js +75 -33
- package/dist/core/runner/inherited-ask-grants.js +2 -2
- package/dist/core/runner/person-path-rows.d.ts +2 -2
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -4
- package/dist/core/runner/prepare-acquire-reconcile.js +3 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
- package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
- package/dist/core/runner/prepare-config-doors.d.ts +12 -15
- package/dist/core/runner/prepare-config-doors.js +8 -3
- package/dist/core/runner/prepare-context-lane.js +6 -3
- package/dist/core/runner/prepare-delegation-surface.d.ts +3 -2
- package/dist/core/runner/prepare-delegation-surface.js +2 -3
- package/dist/core/runner/prepare-execution-env.d.ts +1 -2
- package/dist/core/runner/prepare-execution-env.js +2 -1
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
- package/dist/core/runner/prepare-gate-stations.js +4 -3
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -2
- package/dist/core/runner/prepare-hands-readface.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
- package/dist/core/runner/prepare-inherited-gate.js +1 -0
- package/dist/core/runner/prepare-park-ask.d.ts +1 -1
- package/dist/core/runner/prepare-park-ask.js +9 -3
- package/dist/core/runner/prepare-policy-chain.js +2 -7
- package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
- package/dist/core/runner/prepare-safety-scan.js +34 -27
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.js +6 -2
- package/dist/core/runner/prepare-task.js +13 -10
- package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
- package/dist/core/runner/prepare-turn-wiring.js +14 -49
- package/dist/core/runner/prepare-wiring-manifest.d.ts +2 -2
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/prepare-workspace-restore.js +2 -2
- package/dist/core/runner/resume-admission.js +9 -9
- package/dist/core/runner/resume-apply.js +4 -4
- package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
- package/dist/core/runner/resume-policy-outcome.js +18 -15
- package/dist/core/runner/resume-preflight.js +2 -2
- package/dist/core/runner/resume-review-outcome.js +3 -3
- package/dist/core/runner/run-leg.js +57 -33
- package/dist/core/runner/run-settle-and-teardown.js +2 -0
- package/dist/core/runner/run-terminal-adoption.js +15 -4
- package/dist/core/runner/session-file-state-replay.d.ts +5 -2
- package/dist/core/runner/session-file-state-replay.js +3 -2
- package/dist/core/runner/stream-steer-verb.js +2 -2
- package/dist/core/runner/tool-face-overlay.d.ts +24 -6
- package/dist/core/runner/tool-face-overlay.js +24 -15
- package/dist/core/runner-deps.d.ts +9 -9
- package/dist/core/session-store.d.ts +35 -16
- package/dist/core/session-store.js +20 -12
- package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
- package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
- package/dist/core/shell-wrapper-table.d.ts +5 -3
- package/dist/core/shell-wrapper-table.js +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
- package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
- package/dist/core/store-contracts/session-store-contract.js +639 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
- package/dist/core/task-event.d.ts +6 -4
- package/dist/core/task-registry-agent.js +1 -0
- package/dist/core/task-registry-shared.d.ts +5 -0
- package/dist/core/task-registry.d.ts +7 -0
- package/dist/core/task-registry.js +17 -0
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +6 -6
- package/dist/core/tighten-task-spec.d.ts +6 -4
- package/dist/core/tighten-task-spec.js +2 -2
- package/dist/core/tool-catalog-entries.d.ts +1 -1
- package/dist/core/tool-catalog-entries.js +52 -52
- package/dist/core/tool-face-reader.d.ts +49 -0
- package/dist/core/tool-face-reader.js +94 -0
- package/dist/core/tool-face.d.ts +17 -8
- package/dist/core/tool-face.js +1 -0
- package/dist/core/tool-policy.d.ts +64 -23
- package/dist/core/tool-policy.js +62 -56
- package/dist/core/tool-roster.d.ts +46 -28
- package/dist/core/tool-roster.js +91 -14
- package/dist/core/tool-spec-members.js +2 -2
- package/dist/core/tool-spec.d.ts +20 -4
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +24 -2
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +7 -0
- package/dist/core/untrusted-text.js +3 -8
- package/dist/core/user-attachment.d.ts +43 -0
- package/dist/core/user-attachment.js +92 -15
- package/dist/engine/compaction/compaction.d.ts +2 -2
- package/dist/engine/compaction/utils.d.ts +2 -2
- package/dist/engine/harness/types.d.ts +7 -4
- package/dist/engine/llm/types.d.ts +7 -2
- package/dist/engine/llm/types.js +2 -1
- package/dist/engine/session/repo-utils.d.ts +5 -0
- package/dist/engine/session/repo-utils.js +9 -0
- package/dist/engine/session/storage-base.js +2 -2
- package/dist/index.d.ts +23 -9
- package/dist/index.js +19 -8
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +3 -0
- package/dist/orchestration/run-workflow-tool.js +1 -0
- package/dist/orchestration/workflow-governance.d.ts +1 -1
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +2 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +3 -0
- package/dist/prompt-assembly/catalog/schema.js +3 -0
- package/dist/prompt-assembly/overlay.js +2 -2
- package/dist/prompt-assembly/select.js +2 -2
- package/dist/prompts/default.d.ts +1 -1
- package/dist/shell/lex.d.ts +87 -8
- package/dist/shell/lex.js +283 -49
- package/dist/stores/file/index.d.ts +8 -6
- package/dist/tools/artifact/artifact-tool.js +10 -0
- package/dist/tools/fs/bash-program-position.d.ts +3 -15
- package/dist/tools/fs/bash-program-position.js +3 -10
- package/dist/tools/fs/bash-readonly-classifier.js +2 -0
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-bash.js +72 -101
- package/dist/tools/fs/fs-read.d.ts +12 -0
- package/dist/tools/fs/fs-read.js +10 -9
- package/dist/tools/fs/fs-shared.d.ts +27 -31
- package/dist/tools/fs/fs-shared.js +12 -15
- package/dist/tools/fs/fs-write.js +1 -1
- package/dist/tools/fs/index.js +2 -2
- package/dist/tools/fs/read-deny-home.d.ts +1 -1
- package/dist/tools/fs/read-deny-home.js +5 -4
- package/dist/tools/fs/read-deny.d.ts +16 -3
- package/dist/tools/fs/read-deny.js +12 -9
- package/dist/tools/fs/safety.d.ts +7 -6
- package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
- package/dist/tools/fs/shell-read-bindings.js +15 -16
- package/dist/tools/fs/shell-read-device.js +1 -1
- package/dist/tools/fs/shell-read-plan.js +36 -47
- package/dist/tools/fs/shell-read-word.d.ts +1 -6
- package/dist/tools/fs/shell-read-word.js +2 -20
- package/dist/tools/fs/shell-reentry-text.js +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/package.json +4 -1
- package/test/export-surface.snapshot.json +5654 -5520
- package/wire-changes/core@7.53.0.json +30 -8
- package/wire-changes/core@7.54.0.json +2870 -0
- package/dist/core/shell-scan.d.ts +0 -60
- package/dist/core/shell-scan.js +0 -183
|
@@ -8,7 +8,7 @@ import { detectConflicts, settleBranchWriteBack } from "./branch-writeback.js";
|
|
|
8
8
|
import { settleTeardownLeg } from "./teardown-bounded.js";
|
|
9
9
|
const RECONCILE_MAX_RETRIES = 3;
|
|
10
10
|
export async function prepareAcquireReconcile(input) {
|
|
11
|
-
const { sessions, spec, resume,
|
|
11
|
+
const { sessions, spec, resume, wakeEffects } = input;
|
|
12
12
|
let acquired;
|
|
13
13
|
let session;
|
|
14
14
|
let conflictRef;
|
|
@@ -64,7 +64,7 @@ export async function prepareAcquireReconcile(input) {
|
|
|
64
64
|
throw e;
|
|
65
65
|
}
|
|
66
66
|
if (userAttachmentOf(msg) !== undefined) {
|
|
67
|
-
const e = new Error(`resumeAt entry "${spec.resumeAt}" is an attachment frame
|
|
67
|
+
const e = new Error(`resumeAt entry "${spec.resumeAt}" is an attachment frame — a file the engine delivered, not a turn boundary; resume at the user message it belongs to, or at another user message or finished assistant turn`);
|
|
68
68
|
e.code = "resume_at.not_a_message";
|
|
69
69
|
throw e;
|
|
70
70
|
}
|
|
@@ -100,7 +100,7 @@ export async function prepareAcquireReconcile(input) {
|
|
|
100
100
|
own.ids = new Set();
|
|
101
101
|
branch = { storage, leafBefore, leafSet, own };
|
|
102
102
|
}
|
|
103
|
-
wakeRecovered = (await reconcileInterruptedSession(session,
|
|
103
|
+
wakeRecovered = (await reconcileInterruptedSession(session, wakeEffects, resume?.suspendedBatch)).recovered;
|
|
104
104
|
break;
|
|
105
105
|
}
|
|
106
106
|
catch (err) {
|
|
@@ -2,7 +2,7 @@ import { cardDisclosureOf } from "../allow-entry.js";
|
|
|
2
2
|
import { primaryActivityArg } from "../arg-summary.js";
|
|
3
3
|
import { classicEventBase, observeClassic } from "../mods/stations.js";
|
|
4
4
|
import { advertisedWritableRootsSeat, exemptRootsSeat, attest, attestationOf, isLiveApproverSeat, resolveAsk } from "../tool-policy.js";
|
|
5
|
-
import {
|
|
5
|
+
import { exactBoundInputHashOf } from "../canonical-json.js";
|
|
6
6
|
import { composeCallSignal, raceSettlementAgainstSignal } from "./abort-race.js";
|
|
7
7
|
import { failedJudgmentDeny, policyCheckAbortedDeny } from "./policy-throw.js";
|
|
8
8
|
import { askMandateMember } from "../ask-origin.js";
|
|
@@ -85,8 +85,8 @@ export function prepareAskLane(input) {
|
|
|
85
85
|
};
|
|
86
86
|
const settlement = { kind: "approver_unavailable", who: { party: "none" }, when: now() };
|
|
87
87
|
return decision.action === "ask"
|
|
88
|
-
? attest(intercepted, req, { settlement, ...(decision.origin !== undefined ? { origin: decision.origin } : {}), ...(decision.classes !== undefined ? { classes: decision.classes } : {}), inputDigest:
|
|
89
|
-
: attest(intercepted, req, { settlement, inputDigest:
|
|
88
|
+
? attest(intercepted, req, { settlement, ...(decision.origin !== undefined ? { origin: decision.origin } : {}), ...(decision.classes !== undefined ? { classes: decision.classes } : {}), inputDigest: exactBoundInputHashOf(req.args) })
|
|
89
|
+
: attest(intercepted, req, { settlement, inputDigest: exactBoundInputHashOf(req.args) });
|
|
90
90
|
}
|
|
91
91
|
const grantReuse = consumeInheritedAskGrant(inheritedAskGrants, onAsk, humanReviewRef, decision, req);
|
|
92
92
|
if (grantReuse !== undefined)
|
|
@@ -36,7 +36,7 @@ import type { AssertAllKeysHandled } from "../ask-origin.js";
|
|
|
36
36
|
import { type ChildClampSource } from "../child-clamp-seats.js";
|
|
37
37
|
import type { InheritedGate, Prepared, RunInternals, RunnerSelfSeat, ToolFaceSnapshot } from "./contracts.js";
|
|
38
38
|
import { type BlockedRef } from "./synthetic-tools.js";
|
|
39
|
-
import { RosterBuilder } from "../tool-roster.js";
|
|
39
|
+
import { RosterBuilder, type RosterAxisTables } from "../tool-roster.js";
|
|
40
40
|
import type { ParentSpecSeat } from "../parent-spec-seat.js";
|
|
41
41
|
import { type RosterSpec } from "./caller-roster.js";
|
|
42
42
|
export interface PrepareCapsAndWorkflowInput {
|
|
@@ -48,8 +48,7 @@ export interface PrepareCapsAndWorkflowInput {
|
|
|
48
48
|
/** borrowed-readonly — the deployment seats, whole: `runtimeCapsResolver`, `compliancePostureResolver`, `onError`, `onNotice`,
|
|
49
49
|
* `autoMode`, `brain`, `models`, and the Workflow mount's dozen deps (`workflowScriptRunner`,
|
|
50
50
|
* `workflowGovernanceBaseline`, `workflowRunStore`, `workflowJournalStore`, `workflowScriptStore`,
|
|
51
|
-
* `onWorkflowAgentSpawn`, `workflowCompletionNotifier`, `workflowLimits`, `agents`, `builtinAgents`, `onBackgroundChildEvent`).
|
|
52
|
-
* The self-orchestration predicate takes the whole record. */
|
|
51
|
+
* `onWorkflowAgentSpawn`, `workflowCompletionNotifier`, `workflowLimits`, `agents`, `builtinAgents`, `onBackgroundChildEvent`). The self-orchestration predicate takes the whole record. */
|
|
53
52
|
deps: RunnerDeps;
|
|
54
53
|
/** borrowed-readonly — the seat this run hands its children (`checkpointSeatOf`, minted once by the driver right after the
|
|
55
54
|
* config doors): the plan-pair face reads the store it names, the Workflow mount hands the seat itself to its children. */
|
|
@@ -58,6 +57,7 @@ export interface PrepareCapsAndWorkflowInput {
|
|
|
58
57
|
* `onTaskNotification`, `workflowDepth`, the capture-floor getter reads `memoryCaptureAncestors`, and the arming reads
|
|
59
58
|
* the chain's auto-mode face (`inheritedGate.autoModeFace`). */
|
|
60
59
|
internals: Pick<RunInternals, "rootSessionId" | "placementRoot" | "onTaskNotification" | "workflowDepth" | "memoryCaptureAncestors" | "workflowParkedResume" | "questionFaceStripped" | "inheritedGate"> | undefined;
|
|
60
|
+
/** borrowed-readonly — the tree's cross-boundary token (inherited or minted), which the Workflow mount hands to its children. */ crossBoundaryTree: import("../cross-boundary-taint.js").CrossBoundaryTreeToken;
|
|
61
61
|
/** borrowed-readonly — the acquired session; the classifier leg rebuilds its transcript window from `buildContext`. */
|
|
62
62
|
session: Pick<StoredSession, "buildContext">;
|
|
63
63
|
/** borrowed-readonly — the acquired session id (operator-line context, the refusal codes' phase record). */
|
|
@@ -76,9 +76,10 @@ export interface PrepareCapsAndWorkflowInput {
|
|
|
76
76
|
thinking: ThinkingLevel | undefined;
|
|
77
77
|
/** borrowed-readonly — the frozen preflight; only `mcp` (the compliance veto's mcp_servers conflict check). */
|
|
78
78
|
lockedPreflight: Pick<LockedPreflight, "mcp">;
|
|
79
|
-
/** borrowed-mutable — the effect collection (`Prepared.toolEffects`)
|
|
80
|
-
* Every other writer is the safety scan (the seed) and the later mounts (see the roster table on `Prepared.tools`). */
|
|
79
|
+
/** borrowed-mutable — the effect collection (`Prepared.toolEffects`): the safety scan's caller entries, then the mounts' writes. */
|
|
81
80
|
toolEffects: Prepared["toolEffects"];
|
|
81
|
+
/** borrowed-mutable — the scan's axis tables, so the builder moves an alias's axes with its member (a phase test may omit them). */
|
|
82
|
+
safetyAxes?: RosterAxisTables;
|
|
82
83
|
/** borrowed-readonly — the frozen tool-face snapshot the Workflow mount forwards (exclude / defer / alwaysLoad / restoreGated). */
|
|
83
84
|
toolFaceSnapshot: ToolFaceSnapshot;
|
|
84
85
|
/** borrowed-readonly — the resolved prompt profile (the Workflow mount's parentPromptProfile). */
|
|
@@ -117,8 +117,8 @@ function autoModeArmReasonOf(intent, facePresent, caps, capsFaulted) {
|
|
|
117
117
|
return { armed: true, reason: "armed" };
|
|
118
118
|
}
|
|
119
119
|
export async function prepareCapsAndWorkflow(input) {
|
|
120
|
-
const { spec, deps, parentSpecSeat, checkpointSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, askSeat, runClampSource, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, permissionMode, readDenyEntries, peerLaneActive, peerSendMessageBuiltIn, runnerSelf, delegated, sideCallBookRef } = input;
|
|
121
|
-
const roster = new RosterBuilder(toolEffects);
|
|
120
|
+
const { spec, deps, parentSpecSeat, checkpointSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, toolEffects, safetyAxes, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, askSeat, runClampSource, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, permissionMode, readDenyEntries, peerLaneActive, peerSendMessageBuiltIn, runnerSelf, delegated, sideCallBookRef } = input;
|
|
121
|
+
const roster = new RosterBuilder(toolEffects, safetyAxes);
|
|
122
122
|
for (const t of spec.tools ?? []) {
|
|
123
123
|
const mounted = mountCallerTool(t);
|
|
124
124
|
roster.mount(mounted, { source: callerMountSource(mounted), mountedBy: "scenario" });
|
|
@@ -329,7 +329,7 @@ export async function prepareCapsAndWorkflow(input) {
|
|
|
329
329
|
scope: taskScope,
|
|
330
330
|
notifier: deps.workflowCompletionNotifier,
|
|
331
331
|
originatingSessionId: sessionId,
|
|
332
|
-
rootSessionId: internals?.rootSessionId ?? sessionId, ...(internals?.placementRoot !== undefined ? { placementRoot: internals.placementRoot } : {}),
|
|
332
|
+
rootSessionId: internals?.rootSessionId ?? sessionId, ...(internals?.placementRoot !== undefined ? { placementRoot: internals.placementRoot } : {}), crossBoundaryTree: input.crossBoundaryTree,
|
|
333
333
|
taskRegistry: defaultTaskRegistry,
|
|
334
334
|
taskNotification: internals?.onTaskNotification,
|
|
335
335
|
taskOwner: hostTaskId,
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
* the safety scan after it run BEFORE prepareTask's first await (`sessions.acquire`), so a caller
|
|
11
11
|
* has no microtask window in which to mutate `spec.tools`/the face arrays between the snapshots,
|
|
12
12
|
* the doors and the scan. An `async` wrapper — even with a zero-await body — would hand the caller
|
|
13
|
-
* exactly that window (the driver's `await` yields one microtask). Pinned by the
|
|
14
|
-
* `prepare-task-phase-pins` microtask-latch tests.
|
|
13
|
+
* exactly that window (the driver's `await` yields one microtask). Pinned by the `prepare-task-phase-pins` microtask-latch tests.
|
|
15
14
|
*
|
|
16
15
|
* Throws pass through unchanged: every `config.*` / `resume_at.*` refusal here is a DELIBERATE
|
|
17
16
|
* at-the-door rejection (a throw before acquisition needs no cleanup), and the
|
|
@@ -23,6 +22,7 @@ import { type BrainCallGuardrailRef } from "../../brain/timeout.js";
|
|
|
23
22
|
import type { Model } from "../../internal/llm.js";
|
|
24
23
|
import type { ThinkingLevel } from "../../internal/harness.js";
|
|
25
24
|
import { type MicroCompactMachine } from "../context-edit.js";
|
|
25
|
+
import { type CrossBoundaryPosture } from "../cross-boundary-taint.js";
|
|
26
26
|
import { recordedModeSeed } from "../checkpoint-store.js";
|
|
27
27
|
import { type ConfigDoorEntry, type LockedPreflight } from "../locked-config.js";
|
|
28
28
|
import { type ResolvedRole } from "../roles.js";
|
|
@@ -137,8 +137,7 @@ export interface PrepareConfigDoorsInput {
|
|
|
137
137
|
export interface PrepareConfigDoorsResult {
|
|
138
138
|
/** owned (by the caller, from here on) — the REBOUND spec: identical to the input object unless
|
|
139
139
|
* `spec.agents` was set, in which case it is a shallow copy whose `tools` is the
|
|
140
|
-
* withAgents-rebuilt roster. Every later phase (the safety scan above all — T21) must read THIS,
|
|
141
|
-
* never the original input. */
|
|
140
|
+
* withAgents-rebuilt roster. Every later phase (the safety scan above all — T21) must read THIS, never the original input. */
|
|
142
141
|
spec: RosterSpec;
|
|
143
142
|
/** owned — the frozen task-start copies of the caller's tool-face control arrays; the driver compiles the leg's selector
|
|
144
143
|
* from them, and the selector (with the disclosure lists) is the ONLY thing later face reads consult. Frozen-immutable. */
|
|
@@ -156,17 +155,15 @@ export interface PrepareConfigDoorsResult {
|
|
|
156
155
|
resolvedInteractionPosture: "interactive" | "headless" | undefined;
|
|
157
156
|
/** owned, frozen — the run's approval seat ({@link resolveAskSeat}), the one read of the seats; later phases read only this. */
|
|
158
157
|
askSeat: AskSeat;
|
|
159
|
-
/** owned — the validated/resolved microCompact knob ({@link resolveMicroCompactKnob}
|
|
160
|
-
*
|
|
161
|
-
* the deps bag is never re-read after this door. */
|
|
158
|
+
/** owned — the validated/resolved microCompact knob ({@link resolveMicroCompactKnob} for the door + placement reasoning). The per-run
|
|
159
|
+
* state builder consumes exactly these values — the deps bag is never re-read after this door. */
|
|
162
160
|
microCompactKnob: {
|
|
163
161
|
machine: MicroCompactMachine;
|
|
164
162
|
clearOnRejection: boolean;
|
|
165
163
|
};
|
|
166
164
|
/** owned — the resolved role; its `systemPrompt` seat is still read at prompt-input time. */
|
|
167
165
|
resolvedRole: ResolvedRole;
|
|
168
|
-
/** owned — the resolved main model (`resolvedRole.model`, re-exposed as the name every later
|
|
169
|
-
* phase reads). */
|
|
166
|
+
/** owned — the resolved main model (`resolvedRole.model`, re-exposed as the name every later phase reads). */
|
|
170
167
|
model: Model;
|
|
171
168
|
/** owned — caller-explicit > role default > model default; undefined = off. */
|
|
172
169
|
thinking: ThinkingLevel | undefined;
|
|
@@ -191,8 +188,7 @@ export interface PrepareConfigDoorsResult {
|
|
|
191
188
|
/** owned — the NORMALIZED per-leg delegation-evidence standard: the deps seat read
|
|
192
189
|
* ONCE, in this synchronous pre-await stretch, screened, and absent folded to the "static-face"
|
|
193
190
|
* default. The delegation wrap consumes THIS value, never the live deps object — a deps seat
|
|
194
|
-
* mutated (or getter-backed) after the door must not present an unscreened value to the mark
|
|
195
|
-
* branch (the read-once posture). */
|
|
191
|
+
* mutated (or getter-backed) after the door must not present an unscreened value to the mark branch (the read-once posture). */
|
|
196
192
|
memoryDelegationEvidence: "static-face" | "attested-only";
|
|
197
193
|
/** owned — the lowered skills-listing budget seats (`TaskSpec.skillListingBudgetFraction` /
|
|
198
194
|
* `skillListingMaxDescChars`): the renderer's two numbers, resolved once against the resolved main
|
|
@@ -213,9 +209,10 @@ export interface PrepareConfigDoorsResult {
|
|
|
213
209
|
/** owned, out-param cell — created EMPTY here; the brain-call wiring later installs into
|
|
214
210
|
* `.current`. Returned so driver and harness share one cell identity. */
|
|
215
211
|
brainCallGuardrailRef: BrainCallGuardrailRef;
|
|
216
|
-
/** owned — the resolved outer brain-call guardrail (task > deployment > default; undefined per
|
|
217
|
-
* the resolver's off states). */
|
|
212
|
+
/** owned — the resolved outer brain-call guardrail (task > deployment > default; undefined per the resolver's off states). */
|
|
218
213
|
brainCallGuardrailMs: number | undefined;
|
|
214
|
+
/** owned — the screened cross-boundary posture: the deps seat read ONCE, a bad value refused; absent stays `undefined` (undeclared is its own fact). */
|
|
215
|
+
crossBoundaryPosture: CrossBoundaryPosture | undefined;
|
|
219
216
|
}
|
|
220
217
|
/** The microCompact knob door (坏值响亮度默认律, the sibling knob doors' form:
|
|
221
218
|
* interactionPosture / toolModelGate / staleToolResultOffload). Placement is load-bearing:
|
|
@@ -240,7 +237,7 @@ export declare const checkpointStoreSeat: (spec: {
|
|
|
240
237
|
export declare function assertResumeConfigRecord(config: unknown): void;
|
|
241
238
|
/** The spec the value doors read: a prepare's (its roster is faces) or a resume's re-supplied config (no objective, no session id). */
|
|
242
239
|
type ValueDoorSpec = Omit<TaskSpec, "tools" | "objective" | "sessionId" | "userAttachments"> & Partial<Pick<TaskSpec, "objective" | "sessionId">>;
|
|
243
|
-
type ConfigValueDoorsResult = Pick<PrepareConfigDoorsResult, "toolFaceLists" | "promptHost" | "promptBinding" | "lockedPreflight" | "microCompactKnob" | "memoryDelegationEvidence" | "memoryProvenance" | "memoryCapturePolicy" | "usageWindows" | "brainCallGuardrailMs"> & {
|
|
240
|
+
type ConfigValueDoorsResult = Pick<PrepareConfigDoorsResult, "toolFaceLists" | "promptHost" | "promptBinding" | "lockedPreflight" | "microCompactKnob" | "memoryDelegationEvidence" | "memoryProvenance" | "memoryCapturePolicy" | "usageWindows" | "brainCallGuardrailMs" | "crossBoundaryPosture"> & {
|
|
244
241
|
skillListingSeats: {
|
|
245
242
|
fraction: unknown;
|
|
246
243
|
maxDescChars: unknown;
|
|
@@ -265,7 +262,7 @@ export declare function configValueDoors(input: {
|
|
|
265
262
|
* The doors a RESUMED leg's prepare refuses at, run as one screen BEFORE the claim — prepare's own functions, so a refusal carries
|
|
266
263
|
* the very sentence and code prepare throws: the mode doors (`refusePermissionModeDoors`), the output-style seat, the approval
|
|
267
264
|
* reach, the skills invoked by name (the part no roster changes), the attachments (a resume sends no new human message, so any
|
|
268
|
-
* entry is refused), this phase's value doors over the config, the deployment's deps and the session store the Runner holds
|
|
265
|
+
* entry is refused), the leg declarations of the tools it re-supplies (this phase's first door), this phase's value doors over the config, the deployment's deps and the session store the Runner holds
|
|
269
266
|
* ({@link configValueDoors}, the retention capability door included) and the mode words the row recorded (`recordedModeSeed`).
|
|
270
267
|
* It leaves by the resume's ONE refusal channel (`asResumeConfigRefusal`:
|
|
271
268
|
* `checkpoint.config_refused`, `detail.code` = prepare's code, `detail.field` = `"taskConfig"`, `"deps"` or `"inheritedGate"`)
|
|
@@ -2,6 +2,7 @@ import { resolveBrainCallGuardrailMs } from "../../brain/timeout.js";
|
|
|
2
2
|
import { assertContainmentFaceValue } from "../../tools/fs/index.js";
|
|
3
3
|
import { MICRO_COMPACT_MACHINES } from "../context-edit.js";
|
|
4
4
|
import { assertAddOnlySeats } from "../child-clamp-seats.js";
|
|
5
|
+
import { CROSS_BOUNDARY_POSTURES } from "../cross-boundary-taint.js";
|
|
5
6
|
import { assertNoRetiredRunnerDeps } from "./retired-runner-deps.js";
|
|
6
7
|
import { recordedModeSeed, resolveCheckpointStore } from "../checkpoint-store.js";
|
|
7
8
|
import { asResumeConfigRefusal, refusePermissionModeDoors } from "../mode-policy.js";
|
|
@@ -26,6 +27,7 @@ import { assertPeerPresenceValue } from "../../agents/peer-directory.js";
|
|
|
26
27
|
import { snapshotDefinitionLists } from "../../agents/tool-filter.js";
|
|
27
28
|
import { TOTAL_TOKENS_REMINDER_MODES } from "./turn-attachments.js";
|
|
28
29
|
import { rosterFaceOf } from "./caller-roster.js";
|
|
30
|
+
import { assertToolBoundaryLegs } from "../tool-roster.js";
|
|
29
31
|
import { refuseRenamedDelegationMounts } from "./sub-agent-deny-lists.js";
|
|
30
32
|
const TASK_LIMIT_KEY_DICT = {
|
|
31
33
|
maxTokens: true,
|
|
@@ -232,6 +234,7 @@ export function configValueDoors(input, enter = ENTER_AS_IS) {
|
|
|
232
234
|
const memoryDelegationEvidence = enter("deps", () => deploymentWord(deps.memoryDelegationEvidence, "memoryDelegationEvidence", ["static-face", "attested-only"], "static-face", "config.memory_delegation_evidence", "an unevaluable evidence standard is refused loudly, never folded to either standard."));
|
|
233
235
|
const memoryProvenance = enter("deps", () => deploymentWord(deps.memoryProvenance, "memoryProvenance", ["off", "carry"], "carry", "config.memory_provenance", "an unevaluable provenance mode is refused loudly, never folded to either mode."));
|
|
234
236
|
const memoryCapturePolicy = enter("deps", () => deploymentWord(deps.memoryCapturePolicy, "memoryCapturePolicy", ["open", "governed", "capture-required"], "open", "config.memory_capture_policy", "an unevaluable capture posture is refused loudly, never folded to any posture (the fault arms differ per posture, so a guess would pick a polarity nobody configured)."));
|
|
237
|
+
const crossBoundaryPosture = enter("deps", () => deploymentWord(deps.crossBoundaryPosture, "crossBoundaryPosture", CROSS_BOUNDARY_POSTURES, undefined, "config.cross_boundary_posture", "an unevaluable posture is refused loudly, never folded to either word (an absent seat is undeclared, which is its own fact)."));
|
|
235
238
|
enter("deps", () => assertAutoConsolidationWirable(deps));
|
|
236
239
|
if (spec.resumeAtMode !== undefined)
|
|
237
240
|
enter("taskConfig", () => {
|
|
@@ -314,7 +317,7 @@ export function configValueDoors(input, enter = ENTER_AS_IS) {
|
|
|
314
317
|
}));
|
|
315
318
|
if (taskStore !== undefined)
|
|
316
319
|
enter("taskConfig", () => assertRetentionCapability({ ...retention, stores: [{ name: "checkpointStore", store: taskStore }] }));
|
|
317
|
-
return { toolFaceLists, promptHost, promptBinding, lockedPreflight, skillListingSeats, skills, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs };
|
|
320
|
+
return { toolFaceLists, promptHost, promptBinding, lockedPreflight, skillListingSeats, skills, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs, crossBoundaryPosture };
|
|
318
321
|
}
|
|
319
322
|
export function refuseResumeDoors(config, recordedGate, deps, sessions) {
|
|
320
323
|
asResumeConfigRefusal("taskConfig", () => {
|
|
@@ -323,6 +326,7 @@ export function refuseResumeDoors(config, recordedGate, deps, sessions) {
|
|
|
323
326
|
screenApprovalReach(config.approvalReach);
|
|
324
327
|
screenUserInvokedSkills(config);
|
|
325
328
|
screenUserAttachments(config.userAttachments, { resumeLeg: true });
|
|
329
|
+
assertToolBoundaryLegs(config.tools);
|
|
326
330
|
});
|
|
327
331
|
const { lockedPreflight, skills } = configValueDoors({ spec: config, deps, resumeLeg: true, sessions }, asResumeConfigRefusal);
|
|
328
332
|
asResumeConfigRefusal("inheritedGate", () => void recordedModeSeed(recordedGate));
|
|
@@ -330,8 +334,9 @@ export function refuseResumeDoors(config, recordedGate, deps, sessions) {
|
|
|
330
334
|
}
|
|
331
335
|
export function prepareConfigDoors(input) {
|
|
332
336
|
const { deps, sessions, resume, internals } = input;
|
|
337
|
+
assertToolBoundaryLegs(input.spec.tools);
|
|
333
338
|
let spec = input.spec;
|
|
334
|
-
const { toolFaceLists, promptHost, promptBinding, lockedPreflight, skillListingSeats, skills, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs } = configValueDoors({ spec, deps, resumeLeg: resume !== undefined, sessions });
|
|
339
|
+
const { toolFaceLists, promptHost, promptBinding, lockedPreflight, skillListingSeats, skills, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs, crossBoundaryPosture } = configValueDoors({ spec, deps, resumeLeg: resume !== undefined, sessions });
|
|
335
340
|
spec = Object.create(Object.getPrototypeOf(spec), { ...Object.getOwnPropertyDescriptors(spec), skills: { value: skills, enumerable: skills !== undefined, writable: false, configurable: false } });
|
|
336
341
|
const promptProfile = resolveModelPromptTraits({ id: "" }, spec, internals).promptProfile;
|
|
337
342
|
const resolvedInteractionPosture = spec.interactionPosture ?? internals?.parentInteractionPosture ?? deps.interactionPosture;
|
|
@@ -476,7 +481,7 @@ export function prepareConfigDoors(input) {
|
|
|
476
481
|
memoryDelegationEvidence,
|
|
477
482
|
skillListingBudget,
|
|
478
483
|
memoryProvenance,
|
|
479
|
-
memoryCapturePolicy,
|
|
484
|
+
memoryCapturePolicy, crossBoundaryPosture,
|
|
480
485
|
usageWindows,
|
|
481
486
|
brainCallGuardrailRef,
|
|
482
487
|
brainCallGuardrailMs,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_CHARS_PER_TOKEN, estimateContextTokens } from "../../internal/harness.js";
|
|
2
2
|
import { TOOL_TURN_REPAIR_DROPS } from "../../internal/llm.js";
|
|
3
|
+
import { droppedTransmissions } from "../user-attachment.js";
|
|
3
4
|
import { clearStaleToolResults, createClearedProjectionLedger, dropEmptyFailureAssistants, editBudget, replayClearedProjection, resolveTriggerWindow } from "../context-edit.js";
|
|
4
5
|
import { guardBudget, insertTrimNotice, protectGitFrame, trimToBudget } from "../context-guard.js";
|
|
5
6
|
import { capAggregateMediaBytes, mediaBudgetBytes } from "../media-byte-cap.js";
|
|
@@ -155,14 +156,14 @@ function buildMicroCompactState(deps, model, sessionId, runId, offloadStore, kno
|
|
|
155
156
|
};
|
|
156
157
|
}
|
|
157
158
|
export function landStaleResultClears(args) {
|
|
158
|
-
const
|
|
159
|
+
const transmissions = [];
|
|
159
160
|
for (const c of args.cleared) {
|
|
160
161
|
args.ledger.entries.set(c.key, { marker: c.marker, groupCount: c.groupCount, fp: c.fp });
|
|
161
162
|
if (c.toolCallId !== undefined)
|
|
162
|
-
|
|
163
|
+
transmissions.push(c.toolCallId);
|
|
163
164
|
}
|
|
164
165
|
if (args.readFileState !== undefined) {
|
|
165
|
-
applyContextShrinkToReadFileState(args.readFileState, { kind: "
|
|
166
|
+
applyContextShrinkToReadFileState(args.readFileState, { kind: "transmissions-gone", transmissions });
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
function recordFrontierClears(args) {
|
|
@@ -209,6 +210,8 @@ export async function runGuardChain(args) {
|
|
|
209
210
|
if (dropped) {
|
|
210
211
|
args.trimPressureRef.droppedMessages = true;
|
|
211
212
|
const droppedCount = view.length - trimmed.length;
|
|
213
|
+
if (args.readFileState !== undefined)
|
|
214
|
+
applyContextShrinkToReadFileState(args.readFileState, { kind: "transmissions-gone", transmissions: droppedTransmissions(view, trimmed) });
|
|
212
215
|
trimmed = insertTrimNotice(trimmed);
|
|
213
216
|
emitTrace(deps.tracer, () => ({
|
|
214
217
|
kind: "context.trim",
|
|
@@ -75,8 +75,9 @@ export interface PrepareDelegationSurfaceInput {
|
|
|
75
75
|
* Writers here: the eight mounts (TaskOutput, TaskStop, SendMessage, AgentTranscript, ListAgents, Monitor, the worktree
|
|
76
76
|
* pair, the offload reader), every one a `mount`. */
|
|
77
77
|
roster: RosterBuilder;
|
|
78
|
-
/** borrowed-
|
|
79
|
-
* (
|
|
78
|
+
/** borrowed-readonly — not read by this phase: the effect collection (`Prepared.toolEffects`), the same map `roster` writes at each mount
|
|
79
|
+
* (TaskOutput → read, TaskStop / SendMessage / Monitor / EnterWorktree / ExitWorktree → write, ReadInbox / ListAgents and its
|
|
80
|
+
* alias → read), each from the mounted tool's own declaration; this phase writes nothing into it by name. */
|
|
80
81
|
toolEffects: Map<string, ToolEffect>;
|
|
81
82
|
/** borrowed-mutable — the explicit-negative axis declarations. Writer here: the built-in SendMessage mount's `egress: false`
|
|
82
83
|
* (report-face only). */
|
|
@@ -13,7 +13,7 @@ import { deliverEngineNotice } from "../types.js";
|
|
|
13
13
|
import { RosterBuilder } from "../tool-roster.js";
|
|
14
14
|
import { sendMessageContinuationSeats } from "./send-message-continuation.js";
|
|
15
15
|
export function prepareDelegationSurface(input) {
|
|
16
|
-
const { spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, taskRootCanonical, executionEnv, runnerSelf, backgroundTaskToolsActive, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, sessionBox, roster,
|
|
16
|
+
const { spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, taskRootCanonical, executionEnv, runnerSelf, backgroundTaskToolsActive, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, sessionBox, roster, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, checkpointSeat, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle } = input;
|
|
17
17
|
let worktreeSessionRef;
|
|
18
18
|
const delegationSurfaceActive = backgroundTaskToolsActive || workflowToolsActive;
|
|
19
19
|
const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
|
|
@@ -83,10 +83,9 @@ export function prepareDelegationSurface(input) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
if (sessionBox !== undefined && internals?.onTaskNotification !== undefined && leaves({ name: READ_INBOX_TOOL_NAME }) && !(spec.tools ?? []).some((t) => t.name === READ_INBOX_TOOL_NAME)) {
|
|
86
|
-
toolEffects.set(READ_INBOX_TOOL_NAME, "read");
|
|
87
86
|
roster.mount(firstPartyOffload(createReadInboxTool({ pull: () => peerLaneRefs.pull, ...(terminalsDrainPrincipalInbox(deps) ? { coversPrincipalInbox: true } : {}) })), { source: "builtin", mountedBy: "peerLane" });
|
|
88
87
|
}
|
|
89
|
-
const listAgents = (peerLaneActive || delegationSurfaceActive) && peerSendMessageBuiltIn && listAgentsMountable({ leaves, specTools: spec.tools ?? [] }) ? mountListAgents({ ...(peerLaneActive ? { peerDirectory: deps.peerDirectory } : {}), freshWindowMs: resolvePeerLaneConfig(deps.peerLane, deps.onNotice).listingFreshWindowMs, sessionId, scope: taskScope, hostTaskId, ...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}), ...(internals?.parentSessionId !== undefined ? { parentSessionId: internals.parentSessionId } : {}), registry: defaultTaskRegistry, ...(deps.rosterStore !== undefined ? { roster: deps.rosterStore } : {}), ...(sendMessageTier !== undefined ? { continuationTier: sendMessageTier } : {}), ...(checkpointSeat !== undefined ? { readSeats: { checkpointSeat } } : {}), specTools: spec.tools ?? []
|
|
88
|
+
const listAgents = (peerLaneActive || delegationSurfaceActive) && peerSendMessageBuiltIn && listAgentsMountable({ leaves, specTools: spec.tools ?? [] }) ? mountListAgents({ ...(peerLaneActive ? { peerDirectory: deps.peerDirectory } : {}), freshWindowMs: resolvePeerLaneConfig(deps.peerLane, deps.onNotice).listingFreshWindowMs, sessionId, scope: taskScope, hostTaskId, ...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}), ...(internals?.parentSessionId !== undefined ? { parentSessionId: internals.parentSessionId } : {}), registry: defaultTaskRegistry, ...(deps.rosterStore !== undefined ? { roster: deps.rosterStore } : {}), ...(sendMessageTier !== undefined ? { continuationTier: sendMessageTier } : {}), ...(checkpointSeat !== undefined ? { readSeats: { checkpointSeat } } : {}), specTools: spec.tools ?? [] }) : undefined;
|
|
90
89
|
if (listAgents !== undefined)
|
|
91
90
|
roster.mount(firstPartyOffload(listAgents), { source: "builtin", mountedBy: "peerLane" });
|
|
92
91
|
if (backgroundTaskToolsActive) {
|
|
@@ -20,8 +20,7 @@ export interface PrepareExecutionEnvInput {
|
|
|
20
20
|
/** borrowed-readonly — the trusted spawn-side requests: the explicit cwd (a contract), the isolation
|
|
21
21
|
* request and the parent's cwd (both threaded to the factory ctx). */
|
|
22
22
|
internals: Pick<RunInternals, "requestedCwd" | "isolation" | "parentCwd" | "callerRoot" | "worktreeOffered"> | undefined;
|
|
23
|
-
/** borrowed-readonly — the resume leg
|
|
24
|
-
* restore would overrule. */
|
|
23
|
+
/** borrowed-readonly — the resume leg: read to refuse an explicit cwd a checkpoint restore would overrule, and to tell the factory which workspace it rebuilds. */
|
|
25
24
|
resume: Pick<PrepareResume, "workspaceHandle"> | undefined;
|
|
26
25
|
/** borrowed-readonly — the run tree's placement fixed point, resolved ONCE by the driver; the factory
|
|
27
26
|
* door refuses an empty value loudly before the factory is asked. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StubExecutionEnv } from "../stub-env.js";
|
|
2
|
-
import { hasDestroy } from "../remote-env.js";
|
|
2
|
+
import { frozenHandleCopy, hasDestroy } from "../remote-env.js";
|
|
3
3
|
import { announceMalformedCapabilities } from "./env-capability-census.js";
|
|
4
4
|
import { childPlacementOnLeg, deploymentCanRerootChild, worktreeNotHonored } from "./child-tree.js";
|
|
5
5
|
import { settleTeardownLeg } from "./teardown-bounded.js";
|
|
@@ -24,6 +24,7 @@ export async function prepareExecutionEnv(input) {
|
|
|
24
24
|
taskId: spec.taskId,
|
|
25
25
|
...(internals?.isolation ? { isolation: internals.isolation } : {}),
|
|
26
26
|
...(internals?.parentCwd ? { parentCwd: internals.parentCwd } : {}),
|
|
27
|
+
...(resume?.workspaceHandle !== undefined ? { resumeWorkspace: frozenHandleCopy(resume.workspaceHandle) } : {}),
|
|
27
28
|
})
|
|
28
29
|
: undefined;
|
|
29
30
|
if (ownedEnv !== undefined)
|
|
@@ -170,6 +170,8 @@ export interface PrepareGateStationsInput {
|
|
|
170
170
|
/** borrowed-readonly — the leg's shell READ STATION (`ToolGateInput.shellReadCheck`), mounted by the hands phase, or
|
|
171
171
|
* undefined with no real shell: no station, nothing judged. */
|
|
172
172
|
shellReadCheck: ShellReadCheck | undefined;
|
|
173
|
+
/** borrowed-readonly — the leg's cross-boundary seat (`ToolGateInput.crossBoundaryCheck`), or undefined on a leg whose station is not engaged. */
|
|
174
|
+
crossBoundaryCheck: import("../cross-boundary-taint.js").CrossBoundaryCheck | undefined;
|
|
173
175
|
/** borrowed-readonly — the leg's resolved read face (`undefined` with no hands), read per call into the class derivation. */
|
|
174
176
|
readFace: () => ContainmentFace | undefined;
|
|
175
177
|
/** borrowed-readonly — the per-tool irreversibility tier handed to the gate per call. */
|
|
@@ -46,7 +46,7 @@ export function maybeHumanRejectionHalt(input) {
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
export function prepareGateStations(input) {
|
|
49
|
-
const { askLane, parkAsk, tools, toolRosterDeltas, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, toolOccurrences, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, handsCwdRef, stampCallTarget, hookEnvFace, writeProtectionCheck, shellReadCheck, readFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, askRoute, permissionMode, toolMarkSources, a2aIsolatePeers, ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, frameSettlement, seatInputsFor, modBus, inheritedToolChecks } = input;
|
|
49
|
+
const { askLane, parkAsk, tools, toolRosterDeltas, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, toolOccurrences, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, handsCwdRef, stampCallTarget, hookEnvFace, writeProtectionCheck, shellReadCheck, crossBoundaryCheck, readFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, askRoute, permissionMode, toolMarkSources, a2aIsolatePeers, ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, frameSettlement, seatInputsFor, modBus, inheritedToolChecks } = input;
|
|
50
50
|
const releasesAnnounced = new Map();
|
|
51
51
|
const onModeReleased = (info) => {
|
|
52
52
|
const table = info.readUnestablished === true ? input.readDenyInForce(info.toolCallId) : undefined;
|
|
@@ -86,7 +86,8 @@ export function prepareGateStations(input) {
|
|
|
86
86
|
spec.enablePlanMode === true ||
|
|
87
87
|
complianceDenies.has("web_fetch") ||
|
|
88
88
|
writeProtectionArmed ||
|
|
89
|
-
shellReadCheck !== undefined
|
|
89
|
+
shellReadCheck !== undefined ||
|
|
90
|
+
crossBoundaryCheck !== undefined;
|
|
90
91
|
if (toolCallGateArmedRef.armed) {
|
|
91
92
|
harness.on("tool_call", async (called) => {
|
|
92
93
|
const e = { ...called, toolName: rosterToolName(toolRosterDeltas.current, called.toolName) };
|
|
@@ -132,7 +133,7 @@ export function prepareGateStations(input) {
|
|
|
132
133
|
egress: heldBy("gate.egress", egressTools, call),
|
|
133
134
|
peerMessage: heldBy("gate.peerMessage", PEER_MESSAGE_NAMES, call),
|
|
134
135
|
...(writeProtectionCheck !== undefined ? { writeProtectionCheck } : {}),
|
|
135
|
-
...(shellReadCheck !== undefined ? { shellReadCheck } : {}),
|
|
136
|
+
...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(crossBoundaryCheck !== undefined ? { crossBoundaryCheck } : {}),
|
|
136
137
|
readFace,
|
|
137
138
|
irreversibility: tierSeat?.value,
|
|
138
139
|
reversibilityProbe: tierSeat?.read(reversibilityProbes),
|
|
@@ -260,8 +260,8 @@ export interface PrepareHandsReadFaceResult {
|
|
|
260
260
|
grantReadRoot: GrantReadRoot | undefined;
|
|
261
261
|
/** owned — the store cell {@link grantReadRoot} judges against; the driver threads it to its one writer, the Artifact phase. */
|
|
262
262
|
artifactStoreRef: ArtifactStoreRef | undefined;
|
|
263
|
-
/** owned — the canonical containment root, published so the
|
|
264
|
-
*
|
|
263
|
+
/** owned — the canonical containment root, published so the compaction's kept-tail path
|
|
264
|
+
* normalizer resolves the way the hands tools do. Undefined ⇔ hands-less. */
|
|
265
265
|
attachmentRootCanonical: string | undefined;
|
|
266
266
|
/** owned — the run's read deny table ({@link pathTables}' facade: the run's latest, `forCall` a call's own). Undefined ⇔
|
|
267
267
|
* hands-less (its consumers only exist with hands). */
|
|
@@ -254,7 +254,7 @@ export async function prepareHandsMount(input) {
|
|
|
254
254
|
if (rk === undefined)
|
|
255
255
|
continue;
|
|
256
256
|
if ("content" in rec)
|
|
257
|
-
seedReadFileStateFromTranscript(readFileState, rk, rec.content, rec.at);
|
|
257
|
+
seedReadFileStateFromTranscript(readFileState, rk, rec.content, rec.at, rec.transmittedByToolCallId);
|
|
258
258
|
else
|
|
259
259
|
readFileState.set(rk, { ...rec.observation, lastReadAt: rec.at });
|
|
260
260
|
}
|
|
@@ -70,6 +70,8 @@ export interface PrepareInheritedGateInput {
|
|
|
70
70
|
deps: Pick<RunnerDeps, "autoMode" | "memoryScopeAdmission" | "deploymentMemoryScopes" | "compliancePostureResolver" | "onError" | "onNotice" | "executionEnv" | "delegationEntryCaps" | "rosterStore" | "onBackgroundChildEvent" | "onQuestion">;
|
|
71
71
|
/** borrowed-readonly — the run's approval seat as the config doors froze it: the frozen approver, and this leg's chain view. */
|
|
72
72
|
askSeat: import("../wiring-manifest.js").AskSeat;
|
|
73
|
+
/** borrowed-readonly — the tree's cross-boundary token (the leg's lane: inherited, or minted by a root leg), handed to children. */
|
|
74
|
+
crossBoundaryTree: import("../cross-boundary-taint.js").CrossBoundaryTreeToken;
|
|
73
75
|
/** borrowed-readonly — the trusted spawn-side channel: `inheritedGate` (the LIVE half of the chain fold), `ownOrgAdmissionRef`
|
|
74
76
|
* (the same-session continuation's freeze), `delegationProvenance` (the F-012 stamp), and the identity / peer / notification
|
|
75
77
|
* seats the ctx enrichment forwards. Never mutated. */
|
|
@@ -246,6 +246,7 @@ export function prepareInheritedGate(input) {
|
|
|
246
246
|
activeSkillGrants: () => skillGrants.records(),
|
|
247
247
|
activeRequestAllowedTools: () => input.requestAllowedTools.entries(),
|
|
248
248
|
inheritedGateForChildren,
|
|
249
|
+
crossBoundaryTreeForChildren: input.crossBoundaryTree,
|
|
249
250
|
delegationProvenanceForChildren,
|
|
250
251
|
delegationSettlement: delegationSettlementForChildren,
|
|
251
252
|
...(autoModeDecider ? { autoModeReview: { decider: autoModeDecider } } : {}),
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* closures, so the orchestrator grows no branch.
|
|
21
21
|
*/
|
|
22
22
|
import type { AgentHarness, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
23
|
-
import type
|
|
23
|
+
import { type CallTargetStamp } from "../effective-path-target.js";
|
|
24
24
|
import { type OnQuestion } from "../ask-question.js";
|
|
25
25
|
import { type CheckpointStore } from "../checkpoint-store.js";
|
|
26
26
|
import type { GrantBindingOf } from "../skill-grant-binding.js";
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { callTargetReadingOf } from "../effective-path-target.js";
|
|
2
|
+
import { approvalTargetsOf } from "../approval-object.js";
|
|
1
3
|
import { uuidv7 } from "../../engine/session/uuid.js";
|
|
2
4
|
import { Value } from "typebox/value";
|
|
3
5
|
import { classifyQuestionOutcome, validateAskQuestions } from "../ask-question.js";
|
|
4
6
|
import { hasBackgroundShell, sweepBackgroundShells, sweepRunBoundaryBackgroundShells } from "../background-shell.js";
|
|
5
|
-
import { boundInputHashOf } from "../canonical-json.js";
|
|
7
|
+
import { boundInputHashOf, exactBoundInputHashOf } from "../canonical-json.js";
|
|
6
8
|
import { unencodableIn } from "../checkpoint-requirements.js";
|
|
7
9
|
import { buildRiskDescriptor, debitLedger, encodeAtFidelity, mintCheckpointId, mintCheckpointToken, resolveDeclaredFidelity, samePlainValue, } from "../checkpoint-store.js";
|
|
8
10
|
import { pauseOf } from "../pause-registry.js";
|
|
9
11
|
import { askCarryRowMembers } from "../hooks.js";
|
|
10
12
|
import { askMandateMember, ownedClearanceFacts } from "../ask-origin.js";
|
|
11
13
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
12
|
-
import { advertisedWritableRootsSeat, exemptRootsSeat, isLiveApproverSeat, carriesBidiControls, describeThrown, ownArgs, refuseOutOfContractDecision, tryCloneArgs } from "../tool-policy.js";
|
|
14
|
+
import { advertisedWritableRootsSeat, exemptRootsSeat, isLiveApproverSeat, licenseCovers, carriesBidiControls, describeThrown, ownArgs, refuseOutOfContractDecision, tryCloneArgs } from "../tool-policy.js";
|
|
13
15
|
import { InMemoryToolResultStore, ScopedToolResultStore, isVolatileOffloadStore } from "../tool-result-store.js";
|
|
14
16
|
import { raceAbort, raceSettlementAgainstSignal } from "./abort-race.js";
|
|
15
17
|
import { CONTENT_ASK_BINDING_CAP } from "./content-ask-bindings.js";
|
|
@@ -147,6 +149,9 @@ export function prepareParkAsk(input) {
|
|
|
147
149
|
const unencodable = unencodableIn(parkedArgs, "pendingAction.args");
|
|
148
150
|
if (unencodable !== undefined)
|
|
149
151
|
throw new ParkRefusal(`the arguments of "${req.toolName}" cannot be bound into the approval row's digest (${unencodable.kind} at ${unencodable.path}) — a durable approval row must hold an inert snapshot of exactly what a human approves and a resume executes`);
|
|
152
|
+
const parkedHash = exactBoundInputHashOf(parkedArgs);
|
|
153
|
+
if (parkedHash === undefined)
|
|
154
|
+
throw new ParkRefusal(`the arguments of "${req.toolName}" hold a value no exact digest binds — no approval row can be bound to them`);
|
|
150
155
|
const projectionMovedArgs = backendFidelity !== "structured-clone" && !samePlainValue(parked.value, parkedArgs);
|
|
151
156
|
if (projectionMovedArgs && basePolicyForResumeEdit === undefined) {
|
|
152
157
|
throw new ParkRefusal(`the arguments of "${req.toolName}" change shape when stored by this checkpoint backend, and no policy is wired to re-adjudicate the stored shape ` +
|
|
@@ -306,6 +311,7 @@ export function prepareParkAsk(input) {
|
|
|
306
311
|
toolCallId: req.toolCallId,
|
|
307
312
|
toolName: req.toolName,
|
|
308
313
|
...parkedToolIdentity(toolRosterDeltas.current, req.toolName), ...parkedToolFace(toolRosterDeltas.current, req),
|
|
314
|
+
...approvalTargetsOf(licenseCovers(parkedHash, req.args) ? callTargetReadingOf(req) : undefined),
|
|
309
315
|
args: parkedArgs,
|
|
310
316
|
...(() => {
|
|
311
317
|
const p = approvalPreviewOf(req.toolName, parkedArgs);
|
|
@@ -320,7 +326,7 @@ export function prepareParkAsk(input) {
|
|
|
320
326
|
...askMandateMember(clearanceFacts),
|
|
321
327
|
...askCarryRowMembers(carry),
|
|
322
328
|
...ruleOffersOf(req, parkedArgs, clearanceFacts),
|
|
323
|
-
boundInputHash:
|
|
329
|
+
boundInputHash: parkedHash,
|
|
324
330
|
...grantBindingOf(req, parkedArgs),
|
|
325
331
|
batchToolCallIds,
|
|
326
332
|
completedCallIds,
|
|
@@ -639,7 +639,6 @@ export async function preparePolicyChain(input) {
|
|
|
639
639
|
const finalReq = await withArgsReading(req, decision.updatedInput, signal);
|
|
640
640
|
let asked;
|
|
641
641
|
let revalidated;
|
|
642
|
-
let restated;
|
|
643
642
|
try {
|
|
644
643
|
for (const layer of recheckLayers) {
|
|
645
644
|
const d = refuseOutOfContractDecision(await layer.check(finalReq, signal));
|
|
@@ -655,8 +654,6 @@ export async function preparePolicyChain(input) {
|
|
|
655
654
|
}
|
|
656
655
|
if (d.action === "ask" && asked === undefined)
|
|
657
656
|
asked = d;
|
|
658
|
-
if (d.action === "allow" && restated === undefined && d.decisionReason !== undefined)
|
|
659
|
-
restated = d.decisionReason;
|
|
660
657
|
revalidated = mergeAttestation(req, revalidated, d.attestation);
|
|
661
658
|
}
|
|
662
659
|
}
|
|
@@ -666,10 +663,8 @@ export async function preparePolicyChain(input) {
|
|
|
666
663
|
if (asked !== undefined && decision.action === "allow") {
|
|
667
664
|
return { ...asked, updatedInput: decision.updatedInput };
|
|
668
665
|
}
|
|
669
|
-
if (decision.action === "allow")
|
|
670
|
-
|
|
671
|
-
return withAttestation(owned, mergeAttestation(req, attestationOf(decision, req), revalidated));
|
|
672
|
-
}
|
|
666
|
+
if (decision.action === "allow")
|
|
667
|
+
return withAttestation(decision, mergeAttestation(req, attestationOf(decision, req), revalidated));
|
|
673
668
|
return decision;
|
|
674
669
|
})
|
|
675
670
|
: foldedPolicy;
|
|
@@ -7,7 +7,7 @@ export interface PrepareSafetyScanInput {
|
|
|
7
7
|
* `tools`, `handsReadOnly` and `enablePlanMode`; it never mutates. Typed as a spec whose roster is snapshot faces. */
|
|
8
8
|
spec: RosterSpec;
|
|
9
9
|
/** borrowed-readonly — read only for the hands-enablement fact (`executionEnvFactory`/
|
|
10
|
-
* `executionEnv` presence
|
|
10
|
+
* `executionEnv` presence puts the hand band among the wake candidates). */
|
|
11
11
|
deps: RunnerDeps;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -26,8 +26,13 @@ export interface PrepareSafetyScanInput {
|
|
|
26
26
|
* overrides a scanned value).
|
|
27
27
|
*/
|
|
28
28
|
export interface PrepareSafetyScanResult {
|
|
29
|
-
/** borrowed-mutable — per-tool effect registry (alias-complete), the
|
|
29
|
+
/** borrowed-mutable — per-tool effect registry (alias-complete), the path-policy / gate read. This scan writes the caller tools'
|
|
30
|
+
* own declarations (the roster's kept instance); every engine effect arrives with its tool's mount, never by name beforehand. Open
|
|
31
|
+
* defect #2107 (7.55.0, design ticket): a selector that keeps a caller instance under a name and unmounts only the engine's leaves the engine's entry. */
|
|
30
32
|
toolEffects: Map<string, ToolEffect>;
|
|
33
|
+
/** owned, read once — the wake reconcile's reading (`wakeEffectsOf`): `toolEffects` as this scan leaves it, with every catalog
|
|
34
|
+
* definition this leg may still mount (`engineCandidatesOf`) folded in as a candidate. Built before any mount; no later phase writes it. */
|
|
35
|
+
wakeEffects: Map<string, ToolEffect>;
|
|
31
36
|
/** borrowed-mutable — egress-marked tools (external writes; the gate never auto-allows them). */
|
|
32
37
|
egressTools: Set<string>;
|
|
33
38
|
/** borrowed-mutable — tools whose effect is irreversible (`always`, or `maybe` incl. by probe). */
|