@sema-agent/core 7.52.0 → 7.53.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 +194 -0
- package/README.md +3 -1
- package/dist/agents/cross-session-envelope.d.ts +8 -0
- package/dist/agents/cross-session-envelope.js +6 -0
- package/dist/agents/cross-session-judge.d.ts +21 -1
- package/dist/agents/cross-session-judge.js +8 -0
- package/dist/agents/cross-session-ref.d.ts +5 -0
- package/dist/agents/cross-session-ref.js +1 -0
- package/dist/agents/org-delivery-gate.d.ts +122 -0
- package/dist/agents/org-delivery-gate.js +69 -0
- package/dist/agents/peer-held-queue.d.ts +9 -4
- package/dist/agents/peer-held-queue.js +6 -5
- package/dist/agents/peer-session-drain.d.ts +35 -5
- package/dist/agents/peer-session-drain.js +271 -180
- package/dist/agents/read-inbox-tool.d.ts +7 -0
- package/dist/agents/read-inbox-tool.js +5 -1
- package/dist/agents/subagent.d.ts +3 -0
- package/dist/agents/subagent.js +99 -72
- package/dist/agents/tool-filter.d.ts +18 -0
- package/dist/agents/tool-filter.js +6 -0
- package/dist/brain/anthropic.d.ts +6 -1
- package/dist/brain/anthropic.js +4 -4
- package/dist/brain/model-presets.js +2 -1
- package/dist/brain/route-adjudicator.d.ts +6 -0
- package/dist/brain/routing.d.ts +24 -1
- package/dist/brain/routing.js +54 -19
- package/dist/brain/timeout.js +5 -4
- package/dist/core/a2a.d.ts +5 -2
- package/dist/core/a2a.js +30 -13
- package/dist/core/allow-entry.d.ts +2 -1
- package/dist/core/allow-entry.js +2 -2
- package/dist/core/auto-compaction.d.ts +57 -0
- package/dist/core/auto-compaction.js +28 -2
- package/dist/core/checkpoint-store.d.ts +29 -20
- package/dist/core/checkpoint-store.js +3 -3
- package/dist/core/compliance.js +3 -1
- package/dist/core/effective-path-target.d.ts +25 -6
- package/dist/core/effective-path-target.js +24 -2
- package/dist/core/engine-notice.d.ts +13 -2
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +11 -13
- package/dist/core/gate-outcome.d.ts +11 -6
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hands-band-screen.d.ts +7 -0
- package/dist/core/hands-band-screen.js +32 -0
- package/dist/core/hooks.d.ts +7 -5
- package/dist/core/hooks.js +5 -3
- package/dist/core/locked-config.d.ts +84 -32
- package/dist/core/locked-config.js +128 -42
- package/dist/core/mcp-probe.js +1 -1
- package/dist/core/mcp-server-spec.d.ts +88 -10
- package/dist/core/mcp-server-spec.js +183 -33
- package/dist/core/mcp.d.ts +21 -14
- package/dist/core/mcp.js +55 -51
- package/dist/core/memory-engine/engine.d.ts +14 -19
- package/dist/core/memory-engine/engine.js +7 -5
- package/dist/core/mode-policy.d.ts +3 -18
- package/dist/core/mode-policy.js +2 -16
- package/dist/core/mods/kernel/dispatch.js +13 -15
- package/dist/core/mods/kernel/events.d.ts +9 -6
- package/dist/core/mods/kernel/events.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -10
- package/dist/core/mods/kernel/receive.js +119 -54
- package/dist/core/mods/kernel/site-rules.d.ts +80 -15
- package/dist/core/mods/kernel/site-rules.js +232 -40
- package/dist/core/mods/stations.d.ts +0 -6
- package/dist/core/mods/stations.js +0 -7
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +71 -2
- package/dist/core/own-property-receipt.d.ts +13 -0
- package/dist/core/own-property-receipt.js +3 -1
- package/dist/core/parent-spec-seat.d.ts +2 -2
- package/dist/core/permission-rule-model.d.ts +58 -9
- package/dist/core/permission-rule-model.js +81 -7
- package/dist/core/permission-rule-org.d.ts +163 -33
- package/dist/core/permission-rule-org.js +205 -71
- package/dist/core/permission-rules.d.ts +7 -1
- package/dist/core/permission-rules.js +37 -8
- package/dist/core/retention.js +7 -2
- package/dist/core/retired-keys.d.ts +8 -2
- package/dist/core/retired-keys.js +12 -1
- package/dist/core/roles.js +60 -10
- package/dist/core/rule-lane-reads.js +1 -1
- package/dist/core/runner/contracts.d.ts +1 -0
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/mcp-redial.d.ts +52 -10
- package/dist/core/runner/mcp-redial.js +38 -9
- package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
- package/dist/core/runner/permission-rule-lanes.js +22 -10
- package/dist/core/runner/person-path-rows.d.ts +3 -1
- package/dist/core/runner/person-path-rows.js +2 -2
- package/dist/core/runner/prepare-config-doors.d.ts +48 -2
- package/dist/core/runner/prepare-config-doors.js +161 -145
- package/dist/core/runner/prepare-defer-classify.js +4 -7
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +7 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +1 -1
- package/dist/core/runner/prepare-hands-readface.js +2 -1
- package/dist/core/runner/prepare-inherited-gate.js +2 -2
- package/dist/core/runner/prepare-listings.d.ts +1 -1
- package/dist/core/runner/prepare-listings.js +4 -2
- package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
- package/dist/core/runner/prepare-memory-engine-session.js +19 -6
- package/dist/core/runner/prepare-memory.d.ts +3 -2
- package/dist/core/runner/prepare-memory.js +6 -2
- package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
- package/dist/core/runner/prepare-offload-wrappers.js +2 -1
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +12 -12
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +6 -4
- package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
- package/dist/core/runner/prepare-prompt-assembly.js +20 -16
- package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
- package/dist/core/runner/prepare-prompt-inputs.js +6 -3
- package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
- package/dist/core/runner/prepare-protocol-tools.js +19 -12
- package/dist/core/runner/prepare-question-face.d.ts +4 -2
- package/dist/core/runner/prepare-question-face.js +4 -3
- package/dist/core/runner/prepare-task.js +10 -10
- package/dist/core/runner/prepare-wiring-manifest.d.ts +8 -3
- package/dist/core/runner/prepare-wiring-manifest.js +8 -5
- package/dist/core/runner/resume-admission.d.ts +4 -1
- package/dist/core/runner/resume-admission.js +7 -5
- package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
- package/dist/core/runner/resume-internals-and-config.js +3 -8
- package/dist/core/runner/retired-runner-deps.d.ts +5 -6
- package/dist/core/runner/retired-runner-deps.js +1 -4
- package/dist/core/runner/run-leg.js +42 -12
- package/dist/core/runner/run-recovery-lanes.js +5 -3
- package/dist/core/runner/run-terminal-adoption.js +6 -5
- package/dist/core/runner/run-turn-boundary.js +9 -3
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/runner/skills-seat.d.ts +15 -0
- package/dist/core/runner/skills-seat.js +57 -0
- package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
- package/dist/core/runner/sub-agent-deny-lists.js +7 -5
- package/dist/core/runner/synthetic-tools.d.ts +5 -2
- package/dist/core/runner/synthetic-tools.js +2 -12
- package/dist/core/runner-deps.d.ts +29 -14
- package/dist/core/session-policy-store.d.ts +19 -0
- package/dist/core/session-policy-store.js +22 -2
- package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
- package/dist/core/task-event.d.ts +38 -2
- package/dist/core/task-notification.js +2 -2
- package/dist/core/task-spec.d.ts +1 -1
- package/dist/core/tool-policy.d.ts +3 -0
- package/dist/core/tool-policy.js +10 -4
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +16 -0
- package/dist/core/untrusted-text.js +7 -2
- package/dist/core/user-attachment.d.ts +13 -2
- package/dist/core/user-attachment.js +47 -41
- package/dist/core/wiring-manifest.d.ts +4 -2
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/harness/types.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +12 -1
- package/dist/engine/loop/agent-loop.js +17 -5
- package/dist/engine/loop/types.d.ts +7 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.js +12 -6
- package/dist/internal/harness.d.ts +1 -0
- package/dist/internal/harness.js +1 -0
- package/dist/orchestration/goal.d.ts +24 -1
- package/dist/orchestration/goal.js +3 -2
- package/dist/prompt-assembly/artifact-store.d.ts +44 -9
- package/dist/prompt-assembly/artifact-store.js +38 -12
- package/dist/prompt-assembly/artifact.d.ts +12 -11
- package/dist/prompt-assembly/artifact.js +52 -21
- package/dist/prompt-assembly/assemble.d.ts +2 -0
- package/dist/prompt-assembly/assemble.js +2 -1
- package/dist/prompt-assembly/catalog/index.js +2 -1
- package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
- package/dist/prompt-assembly/catalog/memory.js +6 -0
- package/dist/prompt-assembly/catalog/schema.d.ts +16 -2
- package/dist/prompt-assembly/composer.d.ts +2 -0
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/overlay.d.ts +21 -11
- package/dist/prompt-assembly/overlay.js +55 -17
- package/dist/prompt-assembly/select.d.ts +21 -6
- package/dist/prompt-assembly/select.js +39 -2
- package/dist/prompts/default.d.ts +0 -11
- package/dist/prompts/default.js +0 -3
- package/dist/stores/file/permission-rule-store.d.ts +1 -1
- package/dist/stores/file/permission-rule-store.js +2 -1
- package/dist/tools/artifact/artifact-tool.js +4 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +65 -5
- package/wire-changes/core@7.53.0.json +1946 -0
|
@@ -20,7 +20,7 @@ import type { AgentTool } from "../../internal/harness.js";
|
|
|
20
20
|
import { type OnQuestion } from "../ask-question.js";
|
|
21
21
|
import type { CheckpointStore } from "../checkpoint-store.js";
|
|
22
22
|
import type { RunnerDeps, RuntimeCaps, TaskSpec } from "../types.js";
|
|
23
|
-
import type { PrepareResume } from "./contracts.js";
|
|
23
|
+
import type { PrepareResume, ToolFaceSnapshot } from "./contracts.js";
|
|
24
24
|
import { type ContentAskBinding } from "./content-ask-bindings.js";
|
|
25
25
|
import { RosterBuilder } from "../tool-roster.js";
|
|
26
26
|
export { CONTENT_ASK_BINDING_CAP, type ContentAskBinding } from "./content-ask-bindings.js";
|
|
@@ -31,7 +31,9 @@ export interface PrepareQuestionFaceInput {
|
|
|
31
31
|
/** borrowed-readonly — the REBOUND spec. Read: `durableApproval` (the durable face's opt-in), `interactiveTools`
|
|
32
32
|
* (the override), `principal` (the tool's source identity), `interactiveQuestionFallback` (restores the
|
|
33
33
|
* continuation under a resolved posture). Never mutated. */
|
|
34
|
-
spec: Pick<TaskSpec, "durableApproval" | "interactiveTools" | "principal" | "interactiveQuestionFallback">;
|
|
34
|
+
spec: Pick<TaskSpec, "durableApproval" | "interactiveTools" | "principal" | "interactiveQuestionFallback" | "excludeAllTools">;
|
|
35
|
+
/** borrowed-readonly — the frozen tool face; its selector with the spec's `excludeAllTools` is the valve's reading: the tool mounts only if the valve leaves it. */
|
|
36
|
+
toolFaceSnapshot: Pick<ToolFaceSnapshot, "selector">;
|
|
35
37
|
/** borrowed-readonly — the deployment seat `onError` (the stranded-answer and synthetic-continuation operator
|
|
36
38
|
* lines; swallow-guarded). */
|
|
37
39
|
deps: Pick<RunnerDeps, "onError">;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { valveLeaves } from "../../agents/tool-filter.js";
|
|
2
|
+
import { ASK_USER_QUESTION_TOOL_NAME, createAskUserQuestionTool, isLiveQuestionFace } from "../ask-question.js";
|
|
2
3
|
import { boundInputHashOf } from "../canonical-json.js";
|
|
3
4
|
import { durableParkOptInDeclared } from "../tool-policy.js";
|
|
4
5
|
import { CONTENT_ASK_BINDING_CAP } from "./content-ask-bindings.js";
|
|
5
6
|
import { RosterBuilder } from "../tool-roster.js";
|
|
6
7
|
export { CONTENT_ASK_BINDING_CAP } from "./content-ask-bindings.js";
|
|
7
8
|
export function prepareQuestionFace(input) {
|
|
8
|
-
const { frozenOnQuestion, spec, deps, checkpointStore, runtimeCaps, resolvedInteractionPosture, resume, sessionId, roster, inheritedUnavailableAsks } = input;
|
|
9
|
+
const { frozenOnQuestion, spec, deps, checkpointStore, runtimeCaps, resolvedInteractionPosture, resume, sessionId, roster, toolFaceSnapshot, inheritedUnavailableAsks } = input;
|
|
9
10
|
const tools = roster.tools;
|
|
10
11
|
const onQuestion = frozenOnQuestion;
|
|
11
12
|
const liveQuestionFace = isLiveQuestionFace(onQuestion) ? onQuestion : undefined;
|
|
@@ -58,7 +59,7 @@ export function prepareQuestionFace(input) {
|
|
|
58
59
|
return liveQuestionFace(req, signal);
|
|
59
60
|
}
|
|
60
61
|
: onQuestion;
|
|
61
|
-
const questionToolMounted = spec.interactiveTools === true || (spec.interactiveTools !== false && (onQuestion !== undefined || durableQuestionFace));
|
|
62
|
+
const questionToolMounted = (spec.interactiveTools === true || (spec.interactiveTools !== false && (onQuestion !== undefined || durableQuestionFace))) && valveLeaves(spec, toolFaceSnapshot.selector)({ name: ASK_USER_QUESTION_TOOL_NAME });
|
|
62
63
|
let mountedQuestionTool;
|
|
63
64
|
if (questionToolMounted)
|
|
64
65
|
roster.mount((mountedQuestionTool =
|
|
@@ -86,7 +86,7 @@ import { announcePeerLaneMount, judgeSessionBoxDrain } from "../../agents/peer-s
|
|
|
86
86
|
import { createFrameSettlement } from "../frame-settlement.js";
|
|
87
87
|
import { createSchedulerTools } from "../../tools/scheduler-tools.js";
|
|
88
88
|
import { selfOrchestrationFailClosedReason } from "../../orchestration/workflow-script-runner.js";
|
|
89
|
-
import { compileToolSelector } from "../../agents/tool-filter.js";
|
|
89
|
+
import { compileToolSelector, valveLeaves } from "../../agents/tool-filter.js";
|
|
90
90
|
import { boundOwnToolLists, boundToolListsJudgment, judgeRunToolLists } from "./sub-agent-deny-lists.js";
|
|
91
91
|
import { remainingBudgetMicroUsd, resolveCheckpointStore } from "../checkpoint-store.js";
|
|
92
92
|
import { checkpointSeatOf } from "../checkpoint-seat.js";
|
|
@@ -355,7 +355,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
355
355
|
const sessionBox = judgeSessionBoxDrain(deps, { sessionId, scope: taskScope, isDelegatedChild: delegation.isDelegatedChild });
|
|
356
356
|
const peerLaneRefs = {};
|
|
357
357
|
const frameSettlement = createFrameSettlement();
|
|
358
|
-
const peerSendMessageBuiltIn = runnerSelf !== undefined && toolFaceSnapshot.selector
|
|
358
|
+
const peerSendMessageBuiltIn = runnerSelf !== undefined && valveLeaves(spec, toolFaceSnapshot.selector)({ name: SEND_MESSAGE_TOOL_NAME }) && !(spec.tools ?? []).some((t) => t.name === SEND_MESSAGE_TOOL_NAME);
|
|
359
359
|
const { reminderMark, reminderDisclosureCounts } = await adoptReminderMark(session, sessionId, resume?.seed.reminderMark, internals?.reminderMark, deps.onError);
|
|
360
360
|
const offloadScope = spec.principal ?? "default";
|
|
361
361
|
if (internals?.registryScope !== undefined && internals.registryScope !== offloadScope) {
|
|
@@ -549,7 +549,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
549
549
|
for (const alias of t.aliases ?? [])
|
|
550
550
|
memoryPairNameDomain.add(alias);
|
|
551
551
|
}
|
|
552
|
-
const memoryPairExcludedName = MEMORY_ENGINE_TOOL_NAMES.find((n) => !toolFaceSnapshot.selector
|
|
552
|
+
const memoryPairExcludedName = MEMORY_ENGINE_TOOL_NAMES.find((n) => !valveLeaves(spec, toolFaceSnapshot.selector)({ name: n }));
|
|
553
553
|
const memoryPairOccupiedName = MEMORY_ENGINE_TOOL_NAMES.find((n) => memoryPairNameDomain.has(n));
|
|
554
554
|
const memorySearchToolsPlanned = memoryPairExcludedName === undefined && memoryPairOccupiedName === undefined;
|
|
555
555
|
const captureLineage = await (async () => {
|
|
@@ -569,7 +569,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
569
569
|
taskRootPath: taskRootFinal,
|
|
570
570
|
reminderMark,
|
|
571
571
|
writeToolsMounted: (handsWriteHalfPlanned || tools.some((t) => t.name === "Write")) &&
|
|
572
|
-
toolFaceSnapshot.selector
|
|
572
|
+
valveLeaves(spec, toolFaceSnapshot.selector)({ name: "Write" }) &&
|
|
573
573
|
!(handsEnabled && isRemoteExecutionEnv(executionEnv) && spec.memoryPersistenceCapable !== true),
|
|
574
574
|
memoryProvenance,
|
|
575
575
|
memoryCapturePolicy,
|
|
@@ -626,7 +626,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
626
626
|
shellGatedTools = handsReadFace.shellGatedTools;
|
|
627
627
|
await armAutoMode();
|
|
628
628
|
const { worktreeSessionRef } = prepareDelegationSurface({ spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, taskRootCanonical, executionEnv, runnerSelf, backgroundTaskToolsActive, shellReadAdmission, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, sessionBox, roster, toolEffects, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, checkpointSeat, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle });
|
|
629
|
-
const { liveQuestionFace, contentAskBindings, contentAskRoutable, lateStrandedAnswers, discloseStrandedAnswers, settleContentAskBindings, durableQuestionFace, questionToolMounted, mountedQuestionTool } = prepareQuestionFace({ frozenOnQuestion, spec, deps, checkpointStore, runtimeCaps, resolvedInteractionPosture, resume, sessionId, roster, inheritedUnavailableAsks: () => inheritedUnavailableAsks });
|
|
629
|
+
const { liveQuestionFace, contentAskBindings, contentAskRoutable, lateStrandedAnswers, discloseStrandedAnswers, settleContentAskBindings, durableQuestionFace, questionToolMounted, mountedQuestionTool } = prepareQuestionFace({ frozenOnQuestion, spec, deps, checkpointStore, runtimeCaps, resolvedInteractionPosture, resume, sessionId, roster, toolFaceSnapshot, inheritedUnavailableAsks: () => inheritedUnavailableAsks });
|
|
630
630
|
if (spec.handsReadOnly !== true) {
|
|
631
631
|
const sessionScope = sessionId ?? spec.principal ?? spec.taskId ?? "default";
|
|
632
632
|
roster.mountAll(createSchedulerTools(executionEnv, {
|
|
@@ -659,8 +659,8 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
659
659
|
live.incomplete = true;
|
|
660
660
|
}
|
|
661
661
|
}
|
|
662
|
-
const rosterCanPersist = rosterCanPersistMemory(tools.filter((
|
|
663
|
-
const { memoryBlock: memoryBlockFromEngine, recallDisciplineSegment: memoryRecallSegment, seedFiles: memorySeedFiles } = composeMemoryInjection({ rosterCanPersist });
|
|
662
|
+
const rosterCanPersist = rosterCanPersistMemory(tools.filter(valveLeaves(spec, toolFaceSnapshot.selector)), { effects: toolEffects, remoteHands: handsEnabled && isRemoteExecutionEnv(executionEnv) }, spec.memoryPersistenceCapable);
|
|
663
|
+
const { memoryBlock: memoryBlockFromEngine, recallDisciplineSegment: memoryRecallSegment, seedFiles: memorySeedFiles } = composeMemoryInjection({ rosterCanPersist, isSubagent: delegation.isNonForkChild });
|
|
664
664
|
if (memorySeedFiles?.length && seedContextFiles) {
|
|
665
665
|
try {
|
|
666
666
|
await seedContextFiles(memorySeedFiles);
|
|
@@ -671,10 +671,10 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
671
671
|
}
|
|
672
672
|
const projectContext = await prepareProjectContext({ deps, spec, internals, session, sessionId, runId, hostTaskId, taskRootFinal, handsEnabled, delegation, seedContextFiles, memoryBlockFromEngine, skillGrants, allowedTools, allowedToolTables, roster, toolFaceSnapshot, onceLedger, memoryTools, memoryEngineSession, memorySearchToolsPlanned, memoryPairExcludedName, memoryPairOccupiedName, resume, skillListingBudget: doors.skillListingBudget });
|
|
673
673
|
const { memoryBlock: memoryBlockWithProject, instructionSources, projectInstructionContent, skillSpecs, skillSeatOf, skillsListing, sharedMemoryPairMounted, memoryEnginePairMounted } = projectContext;
|
|
674
|
-
const { featureFlags, sugar, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef } = await preparePromptInputs({ modBus: legMods.bus, spec, deps, contextOverlay: legContextOverlay(), failClosedReason: selfOrchestrationFailClosedReason(spec, deps), lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace: resolvedWriteFace?.inForce(), toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical: (await readRoots.ready().then(readRoots)).filter((r) => !additionalRootsCanonical.includes(r)), sessionId, session, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}) });
|
|
674
|
+
const { featureFlags, sugar, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef } = await preparePromptInputs({ modBus: legMods.bus, spec, deps, contextOverlay: legContextOverlay(), failClosedReason: selfOrchestrationFailClosedReason(spec, deps), lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace: resolvedWriteFace?.inForce(), toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, roster, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical: (await readRoots.ready().then(readRoots)).filter((r) => !additionalRootsCanonical.includes(r)), sessionId, session, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}) });
|
|
675
675
|
judgeRunToolLists({ spec, tools: roster.tools, declaredPeers: { mcp: lockedPreflight.mcp, a2a: a2a.statuses }, own: { allow: toolFaceLists.allow, exclude: toolFaceLists.exclude }, layers: toolFaceSnapshot.selector.layers, legs: toolLegs, judgedUpstream: toolListsJudged !== undefined, toldUpstream: internals?.ownToolLists !== undefined && ownToolLists !== undefined && toolCeiling !== undefined, ownBy: ownToolLists, onceLedger, sessionId });
|
|
676
676
|
const { deferred, memoryBlock, toolSearch: toolSearchPolicy } = prepareDeferClassify({ spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryBlock: memoryBlockWithProject, memoryRecallSegment, onceLedger, sessionId });
|
|
677
|
-
prepareMemoryEngineSession({ memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight,
|
|
677
|
+
prepareMemoryEngineSession({ memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, ...(mountedMcpNow !== undefined ? { mountedMcp: mountedMcpNow } : {}), sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef });
|
|
678
678
|
const { systemPromptSeat, renderWithDate, systemBlocks, promptManifest, promptIdentity, buildAssembleInputs, identityFor, adoptsCandidates, centerAdoptionRef } = await preparePromptAssembly({ session, deps, internals, resume, sugar, host: promptHost, binding: promptBinding, modBus: legMods.bus, signal: abortController.signal, featureFlags, mcpInstructionsBlock, memoryBlock, envFacts, promptProfile, fableMitigations, tools, model, sessionId, onceLedger });
|
|
679
679
|
const { activeTools, fpRef, turnSnapshotRef, harnessTools, toolsDeltaRef, toolMaterializeStatic, deferDirectCall, staticFaceForRef, listingRideRef, toolSearch, toolDisclosureSeat } = await prepareToolDisclosureMount({ spec, deps, session, resume, deferred, tools, onceLedger, mcp, promptManifest, toolSearchPolicy, offloadReachableToolsRef, contentOriginWrapRef, rebuildHarnessToolsRef, harnessRef });
|
|
680
680
|
if (toolSearch !== undefined)
|
|
@@ -786,7 +786,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
|
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
788
|
const { basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, grantBindingOf, permissionRuleLane, ruleLaneFacts, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations, inheritedToolChecks } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight: installedPreflight, pathRuleAnchors: { leg: legAnchors, chainTop }, headLeads, tools, harnessTools, selector: toolFaceSnapshot.selector, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, personRows, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, modBus: legMods.bus, ownModChain, autoModeDecider: () => autoModeDeciderRef.current, readFace: () => resolvedReadFace, permissionMode, scratchpadDir: spec.envFacts?.scratchpadDir, toolRosterDeltas: rosterSeat, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
|
|
789
|
-
const { onAsk, preToolContexts, blockedToolCalls, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtection, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound } = prepareWiringManifest({ spec, deps, askSeat: doors.askSeat, internals, resume, sessionId, runId, hostTaskId, taskScope, modBus: legMods.bus, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, legWriteGuard, mcp, irreversibleTools, egressTools, shellReadStationArmed: handsReadFace.shellReadStationArmed, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, permissionMode, lockedPreflight, peerLaneRefs, frameSettlement, harness, pausedRef, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive: handsReadFace.readDenyBuiltinTiersActive, lspManagerWired, lspDiagnosticsLive: lspDiagnostics !== undefined, fileHistoryFact, sessionBox, checkpointScope });
|
|
789
|
+
const { onAsk, preToolContexts, blockedToolCalls, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtection, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound } = prepareWiringManifest({ spec, deps, askSeat: doors.askSeat, internals, resume, sessionId, runId, hostTaskId, taskScope, modBus: legMods.bus, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, legWriteGuard, mcp, irreversibleTools, egressTools, shellReadStationArmed: handsReadFace.shellReadStationArmed, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, permissionMode, lockedPreflight, peerLaneRefs, frameSettlement, harness, pausedRef, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive: handsReadFace.readDenyBuiltinTiersActive, lspManagerWired, lspDiagnosticsLive: lspDiagnostics !== undefined, fileHistoryFact, sessionBox, checkpointScope, memoryPollution: () => memoryEngineSession?.pollution });
|
|
790
790
|
const writeProtectionCheck = writeProtection.mount?.check;
|
|
791
791
|
writeTargetJudgeRef.current = writeProtection.judgeWriteTarget;
|
|
792
792
|
if (fileHistoryBoundary !== undefined) {
|
|
@@ -114,7 +114,8 @@ export interface PrepareWiringManifestInput {
|
|
|
114
114
|
/** borrowed-readonly — the model gate's per-leg read face, or undefined. */
|
|
115
115
|
modelGateManifest: WiringManifest["modelGate"];
|
|
116
116
|
/** borrowed-readonly — the leg's minted tool roster: rides the manifest's `tools` section and is the
|
|
117
|
-
* source of the hand band's write-capable names for the ungated-write warning (what actually MOUNTED)
|
|
117
|
+
* source of the hand band's write-capable names for the ungated-write warning (what actually MOUNTED) and of each MCP server's
|
|
118
|
+
* `toolCount` (its tools among the roster's names). */
|
|
118
119
|
toolRoster: ToolRoster;
|
|
119
120
|
/** borrowed-readonly — from the read-face phase: the built-in read-deny TIERS that leg's own
|
|
120
121
|
* resolution materially activated; relayed onto the manifest (present iff non-empty), never
|
|
@@ -140,6 +141,9 @@ export interface PrepareWiringManifestInput {
|
|
|
140
141
|
frameSettlement: import("../frame-settlement.js").FrameSettlement;
|
|
141
142
|
/** borrowed-readonly — the session-box drain's mount verdict (prepare-task's one judgment): present ⇒ this leg drains its own box. */
|
|
142
143
|
sessionBox: SessionBoxBinding | undefined;
|
|
144
|
+
/** borrowed-readonly, read late — the memory session's one-way pollution face (absent with no memory session). The drain marks
|
|
145
|
+
* it when it INJECTS a letter from another principal (the injection path; the tool path is accounted by `ReadInbox`'s class). */
|
|
146
|
+
memoryPollution?: () => Pick<NonNullable<Prepared["memoryEngineSession"]>["pollution"], "markPolluted"> | undefined;
|
|
143
147
|
/** borrowed-readonly — the built harness the peer drain binds to. */
|
|
144
148
|
harness: AgentHarness;
|
|
145
149
|
/** borrowed-readonly — the durable-suspend holder; the drain's parked predicate reads `token` at run time. Not written here. */
|
|
@@ -202,7 +206,8 @@ export interface PrepareWiringManifestResult {
|
|
|
202
206
|
* The wiring manifest's per-server MCP read face for one leg ({@link WiringManifest.mcp}): every
|
|
203
207
|
* server the leg's FROZEN entry snapshot declared, in declaration order, joined by name to this leg's
|
|
204
208
|
* materialization statuses. Pure projection — no connection logic, no second look at any transport:
|
|
205
|
-
* · a status `connected` ⇒ `connected` with the
|
|
209
|
+
* · a status `connected` ⇒ `connected` with the server's tools among `rosterNames` — the names of the roster the row is read
|
|
210
|
+
* against: a run's (the valve and the deployment's overlay applied), or the no-run probe's own dials (no run, so no lists apply);
|
|
206
211
|
* · a status `failed` ⇒ `failed` with the failure record the materialization stamped (`errorCode`/`delivered`/
|
|
207
212
|
* `httpStatus` = the MCP vocabulary's `McpFailure` spread flat) and the remote text SECRET-REDACTED (an HTTP endpoint's error body rides the SDK's message
|
|
208
213
|
* verbatim, and a body that echoes the bearer it rejected must not reach a stream consumer),
|
|
@@ -213,6 +218,6 @@ export interface PrepareWiringManifestResult {
|
|
|
213
218
|
* `liveness` is the status record's own observation deep-copied (see {@link WiringManifestMcpEntry.liveness}).
|
|
214
219
|
* The entries are fresh objects so the manifest never aliases the status records the refresh face mutates.
|
|
215
220
|
*/
|
|
216
|
-
export declare function mcpManifestEntries(entries: ReadonlyArray<import("../types.js").McpServerSpec> | undefined, statuses: ReadonlyArray<import("../mcp.js").McpServerStatus>): WiringManifestMcpEntry[];
|
|
221
|
+
export declare function mcpManifestEntries(entries: ReadonlyArray<import("../types.js").McpServerSpec> | undefined, statuses: ReadonlyArray<import("../mcp.js").McpServerStatus>, rosterNames: ReadonlyArray<string>): WiringManifestMcpEntry[];
|
|
217
222
|
/** The M18 phase body — prepareTask's wiring-manifest stretch, verbatim (see the module header). */
|
|
218
223
|
export declare function prepareWiringManifest(input: PrepareWiringManifestInput): PrepareWiringManifestResult;
|
|
@@ -3,6 +3,7 @@ import { teamRoleOf } from "../../agents/team-role.js";
|
|
|
3
3
|
import { resolveCheckpointStore } from "../checkpoint-store.js";
|
|
4
4
|
import { createHookEnvCapabilities, mintHookInvocationIdentity } from "../hooks.js";
|
|
5
5
|
import { chainJudges } from "../mods/stations.js";
|
|
6
|
+
import { toolNamesOfServer } from "../mounted-mcp.js";
|
|
6
7
|
import { isRemoteExecutionEnv, missingRestoreSurface } from "../remote-env.js";
|
|
7
8
|
import { isVolatileOffloadStore } from "../tool-result-store.js";
|
|
8
9
|
import { durableMandateSourceOf, isLiveApproverSeat } from "../tool-policy.js";
|
|
@@ -13,7 +14,7 @@ import { autoRunOnRecommendationEffective } from "./memory-consolidation-driver.
|
|
|
13
14
|
import { GLOBAL_USAGE_KEY, usageRetryAfterMs, windowsGovernCost } from "../usage-window-store.js";
|
|
14
15
|
import { LSP_CONTRACT_ID, askSeatEffective, countElicitOptIns, deriveHandsSeam, deriveLspSeam, deriveWiringManifest, resolveDeclaredDurability, resolveElicitSeam, resolveQuestionSeam, resolveSubagentTranscriptTier } from "../wiring-manifest.js";
|
|
15
16
|
import { modePolicyOf } from "../mode-policy.js";
|
|
16
|
-
export function mcpManifestEntries(entries, statuses) {
|
|
17
|
+
export function mcpManifestEntries(entries, statuses, rosterNames) {
|
|
17
18
|
return (entries ?? []).map((entry) => {
|
|
18
19
|
const status = statuses.find((s) => s.name === entry.name);
|
|
19
20
|
const source = typeof entry.source === "string" && entry.source.length > 0 ? { source: inlineUntrusted(entry.source, 80) } : {};
|
|
@@ -21,7 +22,7 @@ export function mcpManifestEntries(entries, statuses) {
|
|
|
21
22
|
if (status === undefined)
|
|
22
23
|
return { name: entry.name, ...source, status: "skipped", toolCount: 0 };
|
|
23
24
|
if (status.status === "connected")
|
|
24
|
-
return { name: entry.name, ...source, status: "connected", toolCount:
|
|
25
|
+
return { name: entry.name, ...source, status: "connected", toolCount: toolNamesOfServer(rosterNames, entry.name).length, ...liveness };
|
|
25
26
|
return {
|
|
26
27
|
name: entry.name,
|
|
27
28
|
...source,
|
|
@@ -116,13 +117,14 @@ function announceDurableGateUnavailable(args) {
|
|
|
116
117
|
});
|
|
117
118
|
}
|
|
118
119
|
export function prepareWiringManifest(input) {
|
|
119
|
-
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, modBus, checkpointScope, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, legWriteGuard, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, permissionMode, lockedPreflight, peerLaneRefs, frameSettlement, sessionBox, harness, pausedRef, askSeat, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive, fileHistoryFact } = input;
|
|
120
|
+
const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, modBus, checkpointScope, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, legWriteGuard, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, permissionMode, lockedPreflight, peerLaneRefs, frameSettlement, sessionBox, harness, pausedRef, askSeat, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive, fileHistoryFact, memoryPollution } = input;
|
|
120
121
|
const onAsk = askSeat.value;
|
|
121
122
|
const handWriteTools = toolRoster.entries.filter((e) => e.mountedBy === "hands" && (e.effect === "write" || e.effect === "idempotent")).map((e) => e.name);
|
|
122
123
|
const hasEffectAwareGate = policyLayers.length > 0 || chainJudges(modBus);
|
|
124
|
+
const rosterHolds = new Set(toolRoster.entries.map((e) => e.name));
|
|
123
125
|
const peerWriteUngated = modePolicyOf(permissionMode.current).unstated === "ask"
|
|
124
126
|
? []
|
|
125
|
-
: mcp.tools.filter((t) => t.permissionSeat === "passthrough" && !irreversibleTools.has(t.name) && !egressTools.has(t.name) && (toolEffects.get(t.name) ?? "write") !== "read").map((t) => t.name);
|
|
127
|
+
: mcp.tools.filter((t) => rosterHolds.has(t.name) && t.permissionSeat === "passthrough" && !irreversibleTools.has(t.name) && !egressTools.has(t.name) && (toolEffects.get(t.name) ?? "write") !== "read").map((t) => t.name);
|
|
126
128
|
const firstPartyWriteUngated = (spec.tools ?? [])
|
|
127
129
|
.map((t) => t.name)
|
|
128
130
|
.filter((name) => !irreversibleTools.has(name) && !egressTools.has(name) && toolEffects.get(name) === "write");
|
|
@@ -213,7 +215,7 @@ export function prepareWiringManifest(input) {
|
|
|
213
215
|
...(modelGateManifest !== undefined ? { modelGate: modelGateManifest } : {}),
|
|
214
216
|
autoMode: { ...autoModeArmReason() },
|
|
215
217
|
permissionMode: permissionMode.receipt(),
|
|
216
|
-
mcp: mcpManifestEntries(lockedPreflight.mcp, mcp.statuses),
|
|
218
|
+
mcp: mcpManifestEntries(lockedPreflight.mcp, mcp.statuses, toolRoster.entries.map((e) => e.name)),
|
|
217
219
|
...(writeProtection.mount !== undefined ? { writeProtectionTargetView: writeProtection.mount.targetView } : {}),
|
|
218
220
|
readDenyBuiltinTiersActive,
|
|
219
221
|
autoConsolidationOnRecommendation: autoRunOnRecommendationEffective(deps),
|
|
@@ -238,6 +240,7 @@ export function prepareWiringManifest(input) {
|
|
|
238
240
|
settlement: frameSettlement,
|
|
239
241
|
selfName: () => internals?.explicitAgentName,
|
|
240
242
|
parked: () => pausedRef.current !== undefined,
|
|
243
|
+
markExternalContent: (reason) => memoryPollution?.()?.markPolluted(reason, "observed"),
|
|
241
244
|
});
|
|
242
245
|
frameSettlement.boxBacked = (payload) => peerLaneRefs.isBoxBacked?.(payload) ?? false;
|
|
243
246
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { type Checkpoint, type CheckpointStore, type CheckpointToken, type PendingSteerEntry, type ResumeOutcome } from "../checkpoint-store.js";
|
|
14
14
|
import type { InheritedGate, ResumeTaskConfig, RunInternals, RunnerDepsSeat } from "./contracts.js";
|
|
15
|
+
import type { SessionStore } from "../session.js";
|
|
15
16
|
/** What the admission rung was called with. */
|
|
16
17
|
export interface ResumeAdmissionInput<R> {
|
|
17
18
|
/** borrowed-readonly — the checkpoint token the caller is redeeming. */
|
|
@@ -28,6 +29,8 @@ export interface ResumeAdmissionInput<R> {
|
|
|
28
29
|
/** borrowed-readonly — the Runner's deployment deps, read LIVE through the Runner (the store resolution reads `checkpointStore`); the one home of why it is a
|
|
29
30
|
* seat and not a captured object is {@link RunnerDepsSeat}. */
|
|
30
31
|
runner: RunnerDepsSeat;
|
|
32
|
+
/** borrowed-readonly — the Runner's session store, fixed at its construction (unlike its deps): the retention capability door judges it. */
|
|
33
|
+
sessions: SessionStore;
|
|
31
34
|
/** borrowed-readonly — the Runner's same-process parked-constraint registry; read for this token (never written here). */
|
|
32
35
|
parentConstraintRegistry: ReadonlyMap<CheckpointToken, NonNullable<InheritedGate["parentConstraints"]>>;
|
|
33
36
|
/** borrowed-readonly — the rung after admission, entered in this rung's last continuation with what it admitted. */
|
|
@@ -35,7 +38,7 @@ export interface ResumeAdmissionInput<R> {
|
|
|
35
38
|
}
|
|
36
39
|
/** What admission established — the constants every later rung reads. */
|
|
37
40
|
export interface ResumeAdmissionResult {
|
|
38
|
-
/** The caller's config, snapshotted once (own enumerable fields). */
|
|
41
|
+
/** The caller's config, snapshotted once (own enumerable fields), its MCP / A2A entries the frozen ones the doors judged. */
|
|
39
42
|
config: ResumeTaskConfig;
|
|
40
43
|
/** The trusted internals snapshot, with the parked parent chain re-supplied when this Runner spawned the leg. */
|
|
41
44
|
internals: RunInternals | undefined;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { CheckpointError, readPendingSteerQueue, refuseRetiredModeSeed, resolveCheckpointStore, validatePendingSteer } from "../checkpoint-store.js";
|
|
2
|
-
import { refuseResumeDoors } from "
|
|
2
|
+
import { assertResumeConfigRecord, checkpointStoreSeat, refuseResumeDoors } from "./prepare-config-doors.js";
|
|
3
|
+
import { asResumeConfigRefusal } from "../mode-policy.js";
|
|
3
4
|
import { describeSuppliedValue } from "./decide-continuation.js";
|
|
4
5
|
import { detachSkillLists } from "../skill-grant.js";
|
|
5
6
|
export async function resumeAdmission(input) {
|
|
6
|
-
const { token, outcome, taskConfig, runner, parentConstraintRegistry } = input;
|
|
7
|
+
const { token, outcome, taskConfig, runner, sessions, parentConstraintRegistry } = input;
|
|
7
8
|
let internals = input.internals;
|
|
8
9
|
if (outcome === null || typeof outcome !== "object") {
|
|
9
10
|
throw new CheckpointError("checkpoint.invalid_outcome", `resume outcome must be an object naming its gate (got ${outcome === null ? "null" : typeof outcome})`);
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
+
asResumeConfigRefusal("taskConfig", () => assertResumeConfigRecord(taskConfig));
|
|
13
|
+
let config = { ...taskConfig, ...(Array.isArray(taskConfig.skills) ? { skills: detachSkillLists(taskConfig.skills) } : {}) };
|
|
12
14
|
internals = internals !== undefined ? { ...internals } : undefined;
|
|
13
|
-
const store = resolveCheckpointStore(config, runner.deps);
|
|
15
|
+
const store = asResumeConfigRefusal(checkpointStoreSeat(config), () => resolveCheckpointStore(config, runner.deps));
|
|
14
16
|
if (!store) {
|
|
15
17
|
throw new CheckpointError("checkpoint.not_found", "no CheckpointStore wired — cannot resume (set RunnerDeps.checkpointStore or taskConfig.checkpointStore)");
|
|
16
18
|
}
|
|
@@ -39,7 +41,7 @@ export async function resumeAdmission(input) {
|
|
|
39
41
|
const resumeSignal = config.signal;
|
|
40
42
|
let suppliedMessage;
|
|
41
43
|
refuseRetiredModeSeed(cp.state);
|
|
42
|
-
refuseResumeDoors(config, cp.state.inheritedGate);
|
|
44
|
+
config = refuseResumeDoors(config, cp.state.inheritedGate, runner.deps, sessions);
|
|
43
45
|
const parkedSteers = readPendingSteerQueue(cp.state);
|
|
44
46
|
if (outcomeGate === "wake") {
|
|
45
47
|
suppliedMessage = outcome.message;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The resume ladder's INTERNALS-AND-CONFIG rung (E7), verbatim from `Runner.resumeStream`:
|
|
3
|
-
* the
|
|
3
|
+
* the inherited constraints' retired-member door, the principal and placement identity-continuity rungs,
|
|
4
4
|
* and the governance-window ENTRANCE check for a row that still owes a delivery.
|
|
5
5
|
*
|
|
6
6
|
* Synchronous by construction, with the ladder's ONE await at this rung handed back instead of taken: the
|
|
@@ -14,13 +14,13 @@ import type { ResumeTaskConfig, RunInternals, RunnerDepsSeat } from "./contracts
|
|
|
14
14
|
export interface ResumeInternalsAndConfigInput {
|
|
15
15
|
/** borrowed-readonly — the pending row (recorded principal, placement root, parked steers, background tasks). */
|
|
16
16
|
cp: Checkpoint;
|
|
17
|
-
/** borrowed-readonly — the config snapshot (`
|
|
17
|
+
/** borrowed-readonly — the config snapshot (`principal`). */
|
|
18
18
|
config: ResumeTaskConfig;
|
|
19
19
|
/** borrowed-readonly — the internals snapshot (`placementRoot`). */
|
|
20
20
|
internals: RunInternals | undefined;
|
|
21
21
|
/** borrowed-readonly — the ONE read of the outcome discriminant (a bare resource_limit continue owes nothing). */
|
|
22
22
|
outcomeGate: ResumeOutcome["gate"];
|
|
23
|
-
/** borrowed-readonly — the Runner's deployment deps, read LIVE through the Runner (reads `
|
|
23
|
+
/** borrowed-readonly — the Runner's deployment deps, read LIVE through the Runner (reads `usageWindowStore`, `usageWindows`); the one home of why it is a
|
|
24
24
|
* seat and not a captured object is {@link RunnerDepsSeat}. */
|
|
25
25
|
runner: RunnerDepsSeat;
|
|
26
26
|
}
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { CheckpointError, readPendingSteerQueue } from "../checkpoint-store.js";
|
|
2
|
+
import { asResumeConfigRefusal } from "../mode-policy.js";
|
|
2
3
|
import { GLOBAL_USAGE_KEY, resolveUsageWindows, usageRetryAfterMs } from "../usage-window-store.js";
|
|
3
4
|
import { placementValueOrAbsent } from "./checkpoint-scope.js";
|
|
4
|
-
import {
|
|
5
|
-
import { resolveMicroCompactKnob } from "./prepare-config-doors.js";
|
|
5
|
+
import { assertNoRetiredInheritedConstraints } from "./retired-runner-deps.js";
|
|
6
6
|
export function resumeInternalsAndConfig(input) {
|
|
7
7
|
const { cp, config, internals, outcomeGate, runner } = input;
|
|
8
8
|
let windowEntrance;
|
|
9
|
-
|
|
10
|
-
resolveMicroCompactKnob(runner.deps.microCompact);
|
|
11
|
-
if (runner.deps.lockedConfig?.keys?.includes("toolPolicy") === true && config.basePolicyForResumeEdit !== undefined) {
|
|
12
|
-
throw new CheckpointError("checkpoint.invalid_outcome", "TaskSpec.basePolicyForResumeEdit is administratively locked by this deployment (locked key \"toolPolicy\") — a task-supplied " +
|
|
13
|
-
"resume-edit policy is refused pre-CAS (the checkpoint stays pending); remove the field or change the deployment's lock configuration");
|
|
14
|
-
}
|
|
9
|
+
asResumeConfigRefusal("deps", () => assertNoRetiredInheritedConstraints(internals));
|
|
15
10
|
let recheckGovernanceWindow;
|
|
16
11
|
{
|
|
17
12
|
const rowPrincipal = cp.principal || undefined;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { RunnerDeps } from "../types.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { RunInternals } from "./contracts.js";
|
|
3
3
|
/** Runs on the caller's own argument at `new Runner` (the only point that still sees an inherited seat — construction then
|
|
4
4
|
* reads every own seat once into the plain copy the Runner keeps, `retainRunnerDeps`), and again in the pre-first-await
|
|
5
5
|
* config-doors phase and pre-CAS on a resume. */
|
|
6
6
|
export declare function assertNoRetiredRunnerDeps(deps: RunnerDeps): void;
|
|
7
|
-
/** The resume ladder's pre-claim door
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
export declare function assertNoRetiredResumeSeats(deps: RunnerDeps, config: ResumeTaskConfig, internals: RunInternals | undefined): void;
|
|
7
|
+
/** The resume ladder's pre-claim door over the inherited constraints a resume is handed: a retired member of one refuses before
|
|
8
|
+
* the claim (a refusal after it would burn the token on a store without `reopen`). The deps' retired seats and the caller
|
|
9
|
+
* policies' retired members are the config-door phase's, which a resume enters before the claim (`refuseResumeDoors`). */
|
|
10
|
+
export declare function assertNoRetiredInheritedConstraints(internals: RunInternals | undefined): void;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { assertNoRetiredKeys, assertNoRetiredToolPolicyKeys, RETIRED_HOOKS_REPLACEMENT } from "../retired-keys.js";
|
|
2
|
-
import { assertCallerPoliciesCurrent, callerPolicySeats } from "../locked-config.js";
|
|
3
2
|
const RETIRED_RUNNER_DEPS_KEYS = {
|
|
4
3
|
hooks: RETIRED_HOOKS_REPLACEMENT,
|
|
5
4
|
legacyRewindBoundaryProbe: "the rewind refusal always names both possibilities (never existed / retired whole-tree era); a deployment that holds that era's table answers the question on its own surface",
|
|
@@ -13,9 +12,7 @@ const RETIRED_RUNNER_DEPS_KEYS = {
|
|
|
13
12
|
export function assertNoRetiredRunnerDeps(deps) {
|
|
14
13
|
assertNoRetiredKeys(deps, RETIRED_RUNNER_DEPS_KEYS, "RunnerDeps");
|
|
15
14
|
}
|
|
16
|
-
export function
|
|
17
|
-
assertNoRetiredRunnerDeps(deps);
|
|
18
|
-
assertCallerPoliciesCurrent(callerPolicySeats(config, deps, deps.lockedConfig?.keys?.includes("toolPolicy") === true));
|
|
15
|
+
export function assertNoRetiredInheritedConstraints(internals) {
|
|
19
16
|
for (const constraint of internals?.inheritedGate?.parentConstraints ?? [])
|
|
20
17
|
assertNoRetiredToolPolicyKeys(constraint.policy);
|
|
21
18
|
}
|
|
@@ -8,15 +8,17 @@ import { formatHookFeedback } from "../hooks.js";
|
|
|
8
8
|
import { classicEventBase, failedHandlerClause, screenUserPrompt } from "../mods/stations.js";
|
|
9
9
|
import { buildAppliedHumanInputEvent, buildHumanInputEvent, projectHumanInput } from "../human-input-projection.js";
|
|
10
10
|
import { humanInputAttachmentsOf, readObjectiveAttachments, userAttachmentDeclarations } from "../user-attachment.js";
|
|
11
|
-
import { uuidv7 } from "../../internal/harness.js";
|
|
11
|
+
import { readToolCallArguments, uuidv7 } from "../../internal/harness.js";
|
|
12
12
|
import { ORG_ADJUDICATION_TIMEOUT_MS, settleOrgVerdictWithin } from "../permission-rule-org.js";
|
|
13
13
|
import { applyPersistedTightening, disclosedRuleSet } from "../persisted-rule-arms.js";
|
|
14
|
+
import { argsReadBy, stampArgsReading } from "../effective-path-target.js";
|
|
14
15
|
import { parkedSkillApprovalRefusal, skillRowRefusal } from "../skill-grant.js";
|
|
15
16
|
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
|
|
16
17
|
import { computeCostMicroUsd } from "../pricing.js";
|
|
17
18
|
import { mintSystemReminder } from "../reminder-mint.js";
|
|
18
19
|
import { hasDestroy } from "../remote-env.js";
|
|
19
|
-
import { advertisedWritableRootsSeat, attestationOf, exemptRootsSeat, humanRefusalSentence, policyCannotAnswer, policyRefusalMessage, refuseOutOfContractDecision } from "../tool-policy.js";
|
|
20
|
+
import { advertisedWritableRootsSeat, attestationOf, exemptRootsSeat, humanRefusalSentence, ownedReading, policyCannotAnswer, policyRefusalMessage, refuseOutOfContractDecision } from "../tool-policy.js";
|
|
21
|
+
import { failedJudgmentDeny } from "./policy-throw.js";
|
|
20
22
|
import { pathDenialCardOf } from "../../tools/fs/safety.js";
|
|
21
23
|
import { callFaceSeat, judgeParkedToolIdentity, parkedRowLiveFace, rosterEntryNamed } from "../tool-roster.js";
|
|
22
24
|
import { deliverEngineNotice } from "../types.js";
|
|
@@ -554,7 +556,18 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
554
556
|
throw new CheckpointError("checkpoint.invalid_outcome", "pending action reached the resolver with no settlement record on its decision (gateOutcome) — refusing to execute or settle a decision that carries no record");
|
|
555
557
|
}
|
|
556
558
|
const humanRewrite = wireOf("resume.questionArgsShown", pendingAction) === ASK_USER_QUESTION_TOOL_NAME ? undefined : outcome.updatedInput;
|
|
557
|
-
const
|
|
559
|
+
const liveTool = prepared.tools.find((x) => x.name === pendingAction.toolName);
|
|
560
|
+
const reading = liveTool === undefined ? undefined : ownedReading((a) => readToolCallArguments(liveTool, { type: "toolCall", id: pendingAction.toolCallId, name: pendingAction.toolName, arguments: {} }, a));
|
|
561
|
+
const beltFace = () => { const f = parkedRowLiveFace(prepared.toolRosterDeltas.current, pendingAction); if (f !== undefined && reading !== undefined)
|
|
562
|
+
stampArgsReading(f, reading); return f; };
|
|
563
|
+
const tryRead = (v) => { try {
|
|
564
|
+
return { args: reading === undefined ? v : argsReadBy(reading, v) };
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
return { args: v, unread: { error } };
|
|
568
|
+
} };
|
|
569
|
+
const decided = outcome.decision === "allow" ? tryRead(humanRewrite !== undefined ? humanRewrite : pendingAction.args) : { args: humanRewrite !== undefined ? humanRewrite : pendingAction.args };
|
|
570
|
+
const resolvedArgs = decided.args;
|
|
558
571
|
const pendingLabel = (() => { const l = prepared.tools.find((t) => t.name === pendingAction.toolName)?.label; return l !== undefined && l !== pendingAction.toolName ? { label: l } : {}; })();
|
|
559
572
|
const spelledName = pendingAction.names?.[0] ?? pendingAction.toolName;
|
|
560
573
|
const occurrences = prepared.toolOccurrences;
|
|
@@ -563,15 +576,21 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
563
576
|
occurrences.gateRound(pendingAction.toolCallId, decidedGate, frozenInputSnapshot(resolvedArgs));
|
|
564
577
|
let notExecuted = false;
|
|
565
578
|
const resultRow = (text, isError) => withRowNotExecuted(toolResultMsg(pendingAction.toolCallId, pendingAction.toolName, text, isError), notExecuted);
|
|
566
|
-
const settleEnd = async (isError, result, refusedBy) => {
|
|
579
|
+
const settleEnd = async (isError, result, refusedBy, neverRan) => {
|
|
567
580
|
if (refusedBy !== undefined)
|
|
568
581
|
occurrences.refuse(pendingAction.toolCallId, refusedBy);
|
|
569
|
-
const settled = emitSettled(occurrences, callStart, { result, isError }, { push: emit, structured: prepared.structuredProjector, mediaByteCapBytes: runner.deps.mediaByteCapBytes });
|
|
582
|
+
const settled = emitSettled(occurrences, callStart, { result, isError, ...(neverRan ? { notExecuted: true } : {}) }, { push: emit, structured: prepared.structuredProjector, mediaByteCapBytes: runner.deps.mediaByteCapBytes });
|
|
570
583
|
notExecuted = settled.notExecuted === true;
|
|
571
584
|
const gate = settled.gate ?? decidedGate;
|
|
572
585
|
const word = await resume.recordExecutionOutcome(gate);
|
|
573
586
|
settleExecutionRecord(runner.deps.onNotice, word, { toolName: pendingAction.toolName, gate, sessionId: prepared.sessionId, runId: prepared.runId, scope: resume.cp.scope, ...(resume.cp.checkpointId !== undefined ? { checkpointId: resume.cp.checkpointId } : {}) });
|
|
574
587
|
};
|
|
588
|
+
const settleUnreadable = async (error, which) => {
|
|
589
|
+
const marks = egressValue("same-principal", thrownMarksOf(error));
|
|
590
|
+
const text = formatHookFeedback(`The approved tool call "${pendingAction.toolName}" was not executed: the tool could not read ${which} — its argument preparation failed (${egressThrownText("same-principal", error)}). This approval is spent — the call has to be re-issued.`, prepared.reminderMark);
|
|
591
|
+
await settleEnd(true, { content: text, ...(marks !== undefined ? { details: marks } : {}) }, undefined, true);
|
|
592
|
+
emitCommitted(await prepared.session.appendMessage(resultRow(text, true)), "toolResult", pendingAction.toolCallId);
|
|
593
|
+
};
|
|
575
594
|
if (outcome.decision === "deny") {
|
|
576
595
|
const settlementKind = outcome.gateOutcome?.settlement?.kind;
|
|
577
596
|
const reason = settlementKind === "policy_refused"
|
|
@@ -593,6 +612,8 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
593
612
|
if (outcome.decision !== "allow") {
|
|
594
613
|
throw new CheckpointError("checkpoint.invalid_outcome", `pending action reached the resolver with decision "${String(outcome.decision)}" — only "allow" executes and only "deny" injects a denial; refusing to execute`);
|
|
595
614
|
}
|
|
615
|
+
if (decided.unread !== undefined)
|
|
616
|
+
return settleUnreadable(decided.unread.error, humanRewrite !== undefined ? "the arguments the decision edited it to" : "its arguments");
|
|
596
617
|
const screened = await prepared.approvedCallScreen?.({ toolCallId: pendingAction.toolCallId, toolName: pendingAction.toolName, args: structuredClone(resolvedArgs), decidedBy: outcome.hostDecision.decidedBy });
|
|
597
618
|
if (screened !== undefined && "refused" in screened) {
|
|
598
619
|
const hookDenial = formatHookFeedback(screened.refused, prepared.reminderMark);
|
|
@@ -600,10 +621,13 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
600
621
|
emitCommitted(await prepared.session.appendMessage(resultRow(hookDenial, true)), "toolResult", pendingAction.toolCallId);
|
|
601
622
|
return;
|
|
602
623
|
}
|
|
603
|
-
const
|
|
624
|
+
const rescreened = humanRewrite === undefined && screened !== undefined ? tryRead(screened.args) : undefined;
|
|
625
|
+
if (rescreened?.unread !== undefined)
|
|
626
|
+
return settleUnreadable(rescreened.unread.error, "the arguments a PreToolUse hook rewrote it to");
|
|
627
|
+
const executedArgs = rescreened !== undefined ? rescreened.args : resolvedArgs;
|
|
604
628
|
const unseen = !deepJsonEqual(executedArgs, pendingAction.args);
|
|
605
629
|
let beltReading;
|
|
606
|
-
const beltReq = () => ({ toolName: pendingAction.toolName, args: executedArgs, toolCallId: pendingAction.toolCallId, ...callFaceSeat(
|
|
630
|
+
const beltReq = () => ({ toolName: pendingAction.toolName, args: executedArgs, toolCallId: pendingAction.toolCallId, ...callFaceSeat(beltFace()), budget: beltBudget, ...(prepared.cwdRef !== undefined ? { cwd: prepared.cwdRef.current } : {}), ...(prepared.handsRoot !== undefined ? { root: prepared.handsRoot } : {}), ...advertisedWritableRootsSeat(prepared.advertisedWritableDirs), ...exemptRootsSeat(prepared.exemptRoots), ...(beltReading !== undefined ? { targetReading: beltReading } : {}) });
|
|
607
631
|
const unjudgeable = unseen ? chainCannotJudge(resume.cp.state.inheritedGate) : undefined;
|
|
608
632
|
if (unjudgeable !== undefined) {
|
|
609
633
|
const chainDenial = formatHookFeedback(`The approved tool call "${pendingAction.toolName}" was not executed: its input changed after the approval and the inherited ancestor chain cannot judge the changed input (${unjudgeable}). This approval is spent — the call has to be re-issued.`, prepared.reminderMark);
|
|
@@ -620,14 +644,20 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
620
644
|
const card = pathDenialCardOf(attestationOf(d, { toolCallId: pendingAction.toolCallId, toolName: pendingAction.toolName })?.pathDenial);
|
|
621
645
|
return card !== undefined ? { details: card } : {};
|
|
622
646
|
};
|
|
647
|
+
const beltCheck = async (judge, seat) => { const signal = prepared.abortController.signal; try {
|
|
648
|
+
return await judge(signal);
|
|
649
|
+
}
|
|
650
|
+
catch (err) {
|
|
651
|
+
return failedJudgmentDeny(err, signal, (e) => runner.deps.onError?.(e, { phase: "hook", sessionId: prepared.sessionId }), seat, pendingAction);
|
|
652
|
+
} };
|
|
623
653
|
const beltStamped = prepared.stampCallTarget?.(beltReq(), prepared.abortController.signal);
|
|
624
654
|
if (beltStamped !== undefined)
|
|
625
655
|
beltReading = (await beltStamped).targetReading;
|
|
626
656
|
if (unseen && prepared.basePolicyForResumeEdit) {
|
|
627
|
-
const rechecked = refuseOutOfContractDecision(await prepared.basePolicyForResumeEdit.check(beltReq(),
|
|
657
|
+
const rechecked = refuseOutOfContractDecision(await beltCheck((signal) => prepared.basePolicyForResumeEdit.check(beltReq(), signal), "the deployment's tool policy re-checking a resumed call"));
|
|
628
658
|
const personUnanswered = policyCannotAnswer(rechecked, outcome.hostDecision.decidedBy);
|
|
629
659
|
const beltUnsafe = rechecked.action === "deny" ||
|
|
630
|
-
(rechecked.updatedInput !== undefined && !deepJsonEqual(
|
|
660
|
+
(rechecked.updatedInput !== undefined && ((read) => read.unread !== undefined || !deepJsonEqual(read.args, executedArgs))(tryRead(rechecked.updatedInput))) ||
|
|
631
661
|
personUnanswered;
|
|
632
662
|
if (beltUnsafe) {
|
|
633
663
|
const why = rechecked.action === "deny"
|
|
@@ -653,7 +683,7 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
653
683
|
}
|
|
654
684
|
if (prepared.permissionRuleOrg !== undefined) {
|
|
655
685
|
const orgVerdict = prepared.permissionRuleOrg
|
|
656
|
-
.adjudicate({ toolName: pendingAction.toolName, args: executedArgs, toolCallId: pendingAction.toolCallId, ...callFaceSeat(
|
|
686
|
+
.adjudicate({ toolName: pendingAction.toolName, args: executedArgs, toolCallId: pendingAction.toolCallId, ...callFaceSeat(beltFace()) })
|
|
657
687
|
.catch(() => ({ status: "unavailable", disclosures: ["the org adjudication face threw on resume"] }));
|
|
658
688
|
let orgWaitCancelled = false;
|
|
659
689
|
const org = await settleOrgVerdictWithin(orgVerdict, { status: "unavailable", disclosures: [`the org adjudication face did not answer within ${ORG_ADJUDICATION_TIMEOUT_MS}ms (or the task ended first)`] }, {
|
|
@@ -687,7 +717,7 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
687
717
|
}
|
|
688
718
|
}
|
|
689
719
|
if (prepared.denyNarrowingPolicy) {
|
|
690
|
-
const narrowed = refuseOutOfContractDecision(await prepared.denyNarrowingPolicy.check(beltReq(),
|
|
720
|
+
const narrowed = refuseOutOfContractDecision(await beltCheck((signal) => prepared.denyNarrowingPolicy.check(beltReq(), signal), "the narrowing rules re-checking a resumed call"));
|
|
691
721
|
if (narrowed.action === "deny") {
|
|
692
722
|
const narrowedDenial = formatHookFeedback(`The approved tool call "${pendingAction.toolName}" is now denied by ${ruleSourcePhrase("narrowing")} and was not executed${narrowed.message ? `: ${narrowed.message}` : ""}.`, prepared.reminderMark);
|
|
693
723
|
await settleEnd(true, { content: narrowedDenial, ...denialCard(narrowed) }, "policy");
|
|
@@ -729,7 +759,7 @@ async function resolvePendingCall(runner, prepared, resume, emit, emitCommitted,
|
|
|
729
759
|
}
|
|
730
760
|
}
|
|
731
761
|
if (prepared.shellReadCheck !== undefined) {
|
|
732
|
-
const readCall = { toolName: pendingAction.toolName, ...callFaceSeat(
|
|
762
|
+
const readCall = { toolName: pendingAction.toolName, ...callFaceSeat(beltFace()) };
|
|
733
763
|
const judged = prepared.shellReadCheck.judge(readCall, executedArgs, prepared.cwdRef?.current, prepared.abortController.signal, {
|
|
734
764
|
toolCallId: pendingAction.toolCallId,
|
|
735
765
|
...(unseen ? { seat: "rejudge" } : {}),
|
|
@@ -2,7 +2,7 @@ import { compactionKindOf } from "../task-notification.js";
|
|
|
2
2
|
import { planRejectionClears } from "../context-edit.js";
|
|
3
3
|
import { rosterToolName } from "../tool-roster.js";
|
|
4
4
|
import { landStaleResultClears } from "./prepare-context-lane.js";
|
|
5
|
-
import { DEFAULT_COMPACTION_INSTRUCTIONS, isCompactionManualCancel, maybeCompact, mintCompactedEvent } from "../auto-compaction.js";
|
|
5
|
+
import { compactionPassReport, DEFAULT_COMPACTION_INSTRUCTIONS, isCompactionManualCancel, maybeCompact, mintCompactedEvent } from "../auto-compaction.js";
|
|
6
6
|
import { emitTrace } from "../trace.js";
|
|
7
7
|
import { isDegenerateCutMessage } from "../../brain/terminal-cause.js";
|
|
8
8
|
import { rebaseCadenceWindows } from "./turn-attachments.js";
|
|
@@ -22,6 +22,7 @@ export function runRecoveryLanes(input) {
|
|
|
22
22
|
if (callerStop.signal.aborted)
|
|
23
23
|
return false;
|
|
24
24
|
const passSignal = AbortSignal.any([prepared.abortController.signal, callerStop.signal, ...(turnSignal !== undefined ? [turnSignal] : [])]);
|
|
25
|
+
const passReport = compactionPassReport(queue, ident);
|
|
25
26
|
try {
|
|
26
27
|
const comp = await maybeCompact({
|
|
27
28
|
session: prepared.session,
|
|
@@ -50,6 +51,7 @@ export function runRecoveryLanes(input) {
|
|
|
50
51
|
...compactionRestateOptions(prepared),
|
|
51
52
|
...windowSafetyOptions(prepared.harness.getModel()),
|
|
52
53
|
...compactionHookOptions(runner, prepared, "forced", passSignal),
|
|
54
|
+
onStarted: passReport.onStarted,
|
|
53
55
|
});
|
|
54
56
|
if (comp.compacted) {
|
|
55
57
|
compactionBreaker.failures = 0;
|
|
@@ -95,13 +97,13 @@ export function runRecoveryLanes(input) {
|
|
|
95
97
|
catch (err) {
|
|
96
98
|
if (isCompactionManualCancel(err) || (turnSignal?.aborted === true && !prepared.abortController.signal.aborted)) {
|
|
97
99
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "cancelled", ts: Date.now() }));
|
|
98
|
-
queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: "forced", reason: "cancelled", ...ident() });
|
|
100
|
+
queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: "forced", reason: "cancelled", ...passReport.end, ...ident() });
|
|
99
101
|
return false;
|
|
100
102
|
}
|
|
101
103
|
compactionBreaker.failures += 1;
|
|
102
104
|
runner.deps.onError?.(asThrownError(err), { phase: "compaction", sessionId: prepared.sessionId });
|
|
103
105
|
const msg = thrownText(err);
|
|
104
|
-
queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "forced", reason: msg.length > 512 ? `${msg.slice(0, 512)}…` : msg, ...ident() });
|
|
106
|
+
queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "forced", reason: msg.length > 512 ? `${msg.slice(0, 512)}…` : msg, ...passReport.end, ...ident() });
|
|
105
107
|
return false;
|
|
106
108
|
}
|
|
107
109
|
};
|