@sema-agent/core 7.7.0 → 7.9.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.
Files changed (186) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -2
  3. package/dist/agents/list-agents-tool.js +2 -3
  4. package/dist/agents/observer.js +2 -2
  5. package/dist/agents/send-message-tool.js +2 -1
  6. package/dist/agents/subagent-steps.js +5 -4
  7. package/dist/agents/subagent.d.ts +1 -1
  8. package/dist/agents/subagent.js +2 -3
  9. package/dist/core/ask-origin.d.ts +12 -1
  10. package/dist/core/ask-origin.js +5 -1
  11. package/dist/core/ask-question.js +2 -2
  12. package/dist/core/checkpoint-store.d.ts +64 -24
  13. package/dist/core/context-edit.d.ts +0 -22
  14. package/dist/core/context-edit.js +2 -11
  15. package/dist/core/engine-notice.d.ts +6 -0
  16. package/dist/core/fs-write-gate-policy.d.ts +7 -1
  17. package/dist/core/fs-write-gate-policy.js +7 -7
  18. package/dist/core/gate-fold.js +2 -2
  19. package/dist/core/gate-lanes.js +53 -26
  20. package/dist/core/gate-outcome.d.ts +8 -4
  21. package/dist/core/gate-outcome.js +2 -1
  22. package/dist/core/governance-codes.d.ts +1 -1
  23. package/dist/core/governance-codes.js +6 -0
  24. package/dist/core/hooks.d.ts +64 -33
  25. package/dist/core/hooks.js +1 -1
  26. package/dist/core/lsp.js +2 -2
  27. package/dist/core/mcp-server-spec.d.ts +17 -0
  28. package/dist/core/mcp.js +3 -1
  29. package/dist/core/memory-engine/tools.js +4 -12
  30. package/dist/core/permission-rule-consent.d.ts +29 -36
  31. package/dist/core/permission-rule-consent.js +110 -60
  32. package/dist/core/permission-rule-model.d.ts +254 -55
  33. package/dist/core/permission-rule-model.js +323 -43
  34. package/dist/core/permission-rule-org.d.ts +9 -8
  35. package/dist/core/permission-rule-org.js +6 -15
  36. package/dist/core/permission-rule-provider.d.ts +10 -6
  37. package/dist/core/permission-rule-provider.js +12 -8
  38. package/dist/core/permission-rule-session.d.ts +7 -6
  39. package/dist/core/permission-rule-session.js +29 -10
  40. package/dist/core/permission-rule-store.d.ts +40 -18
  41. package/dist/core/permission-rule-store.js +68 -42
  42. package/dist/core/permission-rule-sync.d.ts +9 -3
  43. package/dist/core/permission-rule-sync.js +29 -25
  44. package/dist/core/permission-rule-syntax.d.ts +30 -0
  45. package/dist/core/permission-rule-syntax.js +44 -0
  46. package/dist/core/permission-rules.d.ts +85 -33
  47. package/dist/core/permission-rules.js +104 -88
  48. package/dist/core/persisted-rule-arms.d.ts +56 -0
  49. package/dist/core/persisted-rule-arms.js +48 -0
  50. package/dist/core/present-plan-tool.js +3 -4
  51. package/dist/core/runner/active-skill-scope.js +7 -4
  52. package/dist/core/runner/compaction-call-options.d.ts +1 -1
  53. package/dist/core/runner/contracts.d.ts +46 -3
  54. package/dist/core/runner/permission-rule-lanes.d.ts +33 -26
  55. package/dist/core/runner/permission-rule-lanes.js +27 -21
  56. package/dist/core/runner/prepare-ask-lane.d.ts +1 -1
  57. package/dist/core/runner/prepare-caps-and-workflow.d.ts +5 -4
  58. package/dist/core/runner/prepare-caps-and-workflow.js +16 -11
  59. package/dist/core/runner/prepare-defer-classify.d.ts +5 -26
  60. package/dist/core/runner/prepare-defer-classify.js +10 -10
  61. package/dist/core/runner/prepare-delegation-surface.d.ts +5 -4
  62. package/dist/core/runner/prepare-delegation-surface.js +15 -17
  63. package/dist/core/runner/prepare-gate-stations.d.ts +4 -1
  64. package/dist/core/runner/prepare-gate-stations.js +4 -2
  65. package/dist/core/runner/prepare-hands-readface.d.ts +3 -2
  66. package/dist/core/runner/prepare-hands-readface.js +3 -2
  67. package/dist/core/runner/prepare-inherited-gate.d.ts +1 -1
  68. package/dist/core/runner/prepare-inherited-gate.js +1 -0
  69. package/dist/core/runner/prepare-lsp.d.ts +4 -3
  70. package/dist/core/runner/prepare-lsp.js +3 -2
  71. package/dist/core/runner/prepare-memory-engine-session.d.ts +4 -4
  72. package/dist/core/runner/prepare-memory-engine-session.js +4 -2
  73. package/dist/core/runner/prepare-offload-wrappers.js +7 -5
  74. package/dist/core/runner/prepare-park-ask.d.ts +4 -0
  75. package/dist/core/runner/prepare-park-ask.js +4 -1
  76. package/dist/core/runner/prepare-project-context.d.ts +5 -23
  77. package/dist/core/runner/prepare-project-context.js +7 -5
  78. package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
  79. package/dist/core/runner/prepare-protocol-tools.d.ts +5 -1
  80. package/dist/core/runner/prepare-protocol-tools.js +38 -21
  81. package/dist/core/runner/prepare-question-face.d.ts +4 -3
  82. package/dist/core/runner/prepare-question-face.js +5 -3
  83. package/dist/core/runner/prepare-run-refs.d.ts +16 -0
  84. package/dist/core/runner/prepare-run-refs.js +6 -0
  85. package/dist/core/runner/prepare-safety-scan.js +48 -2
  86. package/dist/core/runner/prepare-task.js +37 -19
  87. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +5 -2
  88. package/dist/core/runner/prepare-tool-disclosure-mount.js +3 -1
  89. package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -0
  90. package/dist/core/runner/prepare-wiring-manifest.js +3 -8
  91. package/dist/core/runner/resume-admission.d.ts +53 -0
  92. package/dist/core/runner/resume-admission.js +83 -0
  93. package/dist/core/runner/resume-apply.d.ts +50 -0
  94. package/dist/core/runner/resume-apply.js +184 -0
  95. package/dist/core/runner/resume-checkpoint-screen.d.ts +18 -0
  96. package/dist/core/runner/resume-checkpoint-screen.js +108 -0
  97. package/dist/core/runner/resume-claim.d.ts +32 -0
  98. package/dist/core/runner/resume-claim.js +27 -0
  99. package/dist/core/runner/resume-internals-and-config.d.ts +33 -0
  100. package/dist/core/runner/resume-internals-and-config.js +50 -0
  101. package/dist/core/runner/resume-policy-outcome.d.ts +31 -0
  102. package/dist/core/runner/resume-policy-outcome.js +127 -0
  103. package/dist/core/runner/resume-preflight.d.ts +40 -0
  104. package/dist/core/runner/resume-preflight.js +122 -0
  105. package/dist/core/runner/resume-review-outcome.d.ts +30 -0
  106. package/dist/core/runner/resume-review-outcome.js +88 -0
  107. package/dist/core/runner/run-harness-handlers.d.ts +46 -0
  108. package/dist/core/runner/run-harness-handlers.js +345 -0
  109. package/dist/core/runner/run-turn-boundary.d.ts +69 -0
  110. package/dist/core/runner/run-turn-boundary.js +694 -0
  111. package/dist/core/runner/runtask.d.ts +20 -0
  112. package/dist/core/runner/runtask.js +129 -1774
  113. package/dist/core/runner/session-rule-policy.js +9 -4
  114. package/dist/core/runner/synthetic-tools.js +5 -8
  115. package/dist/core/runner/tool-disclosure.d.ts +4 -0
  116. package/dist/core/runner/tool-disclosure.js +9 -5
  117. package/dist/core/runner/tool-end-body.d.ts +12 -5
  118. package/dist/core/runner/tool-end-body.js +8 -7
  119. package/dist/core/runner/tool-face-overlay.d.ts +40 -0
  120. package/dist/core/runner/tool-face-overlay.js +125 -0
  121. package/dist/core/runner/tool-output-projection.d.ts +14 -1
  122. package/dist/core/runner/tool-output-projection.js +24 -18
  123. package/dist/core/runner/turn-attachments.d.ts +2 -2
  124. package/dist/core/sensitive-path-policy.d.ts +3 -0
  125. package/dist/core/sensitive-path-policy.js +6 -5
  126. package/dist/core/shared-memory/tools.js +3 -6
  127. package/dist/core/store-contracts/checkpoint-store-contract.js +23 -0
  128. package/dist/core/store-contracts/permission-rule-sync-contract.js +29 -10
  129. package/dist/core/task-event.d.ts +10 -0
  130. package/dist/core/task-registry.js +4 -5
  131. package/dist/core/task-spec.d.ts +8 -0
  132. package/dist/core/tool-catalog-entries.d.ts +48 -0
  133. package/dist/core/tool-catalog-entries.js +174 -0
  134. package/dist/core/tool-conformance.d.ts +22 -0
  135. package/dist/core/tool-conformance.js +37 -0
  136. package/dist/core/tool-face.d.ts +171 -0
  137. package/dist/core/tool-face.js +25 -0
  138. package/dist/core/tool-policy.d.ts +24 -0
  139. package/dist/core/tool-policy.js +4 -2
  140. package/dist/core/tool-registry.d.ts +114 -0
  141. package/dist/core/tool-registry.js +114 -0
  142. package/dist/core/tool-result-budget.d.ts +0 -3
  143. package/dist/core/tool-result-budget.js +4 -3
  144. package/dist/core/tool-result-store.d.ts +0 -18
  145. package/dist/core/tool-result-store.js +2 -18
  146. package/dist/core/tool-roster.d.ts +459 -0
  147. package/dist/core/tool-roster.js +507 -0
  148. package/dist/core/tool-spec.d.ts +54 -3
  149. package/dist/core/tools.js +7 -0
  150. package/dist/core/wiring-manifest.d.ts +13 -0
  151. package/dist/core/wiring-manifest.js +2 -1
  152. package/dist/core/write-protect.d.ts +2 -1
  153. package/dist/core/write-protect.js +5 -4
  154. package/dist/engine/compaction/utils.d.ts +6 -0
  155. package/dist/engine/compaction/utils.js +19 -19
  156. package/dist/engine/loop/types.d.ts +6 -0
  157. package/dist/index.d.ts +17 -6
  158. package/dist/index.js +17 -6
  159. package/dist/orchestration/goal.js +2 -1
  160. package/dist/orchestration/run-spec.js +3 -5
  161. package/dist/orchestration/run-workflow-tool.js +2 -2
  162. package/dist/prompt-assembly/event-registry.js +3 -3
  163. package/dist/prompt-assembly/tool-catalog.d.ts +2 -2
  164. package/dist/stores/file/checkpoint-store.js +1 -1
  165. package/dist/stores/file/permission-rule-store.d.ts +28 -23
  166. package/dist/stores/file/permission-rule-store.js +64 -16
  167. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  168. package/dist/tools/fs/fs-bash.d.ts +1 -1
  169. package/dist/tools/fs/fs-bash.js +7 -11
  170. package/dist/tools/fs/fs-pdf.d.ts +1 -1
  171. package/dist/tools/fs/fs-read.js +2 -2
  172. package/dist/tools/fs/fs-search-tools.d.ts +0 -7
  173. package/dist/tools/fs/fs-search-tools.js +3 -16
  174. package/dist/tools/fs/fs-write.js +4 -6
  175. package/dist/tools/fs/notebook.d.ts +1 -1
  176. package/dist/tools/fs/repo-map.js +2 -2
  177. package/dist/tools/fs/safety.d.ts +3 -2
  178. package/dist/tools/fs/safety.js +6 -5
  179. package/dist/tools/monitor.js +2 -2
  180. package/dist/tools/scheduler-tools.js +5 -8
  181. package/dist/tools/task-list.js +5 -8
  182. package/dist/tools/todo.js +2 -2
  183. package/dist/tools/web.js +3 -6
  184. package/dist/tools/worktree.js +3 -4
  185. package/package.json +4 -1
  186. package/test/export-surface.snapshot.json +189 -17
@@ -1,5 +1,8 @@
1
1
  import { NAMESPACED_NAME_SHAPES } from "../protocol-table.js";
2
- import { HAND_TOOL_EFFECTS } from "../../tools/fs/index.js";
2
+ import { engineCardTypes, handBandEffects } from "../tool-registry.js";
3
+ import { TOOL_CONTRACT_MAX_CHARS, TOOL_WIRE_NAME_MAX_CHARS } from "../tool-face.js";
4
+ import { callerCardIdOf, offendingResultCard, schemaKeyBoundProblem } from "../tool-roster.js";
5
+ import { toolFaceProblem } from "./tool-face-overlay.js";
3
6
  import { OFFLOAD_TOOL_NAME } from "../tool-result-store.js";
4
7
  import { PRESENT_PLAN_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME } from "../present-plan-tool.js";
5
8
  export function prepareSafetyScan(input) {
@@ -13,6 +16,49 @@ export function prepareSafetyScan(input) {
13
16
  const axisExplicitNegatives = new Map();
14
17
  const reversibilityProbes = new Map();
15
18
  for (const t of spec.tools ?? []) {
19
+ if (t.name.length > TOOL_WIRE_NAME_MAX_CHARS) {
20
+ const e = new Error(`Tool name "${t.name.slice(0, 40)}…" is invalid: ${t.name.length} characters, the roster's bound is ${TOOL_WIRE_NAME_MAX_CHARS}.`);
21
+ e.code = "config.tool_name_too_long";
22
+ throw e;
23
+ }
24
+ for (const alias of t.aliases ?? []) {
25
+ if (alias.length > TOOL_WIRE_NAME_MAX_CHARS) {
26
+ const e = new Error(`Tool alias "${alias.slice(0, 40)}…" (of "${t.name}") is invalid: ${alias.length} characters, the roster's bound is ${TOOL_WIRE_NAME_MAX_CHARS}.`);
27
+ e.code = "config.tool_name_too_long";
28
+ throw e;
29
+ }
30
+ }
31
+ if (t.contract !== undefined && (t.contract.contractId.length > TOOL_CONTRACT_MAX_CHARS || t.contract.implementationRevision.length > TOOL_CONTRACT_MAX_CHARS)) {
32
+ const e = new Error(`Tool "${t.name}" declares a contract member over ${TOOL_CONTRACT_MAX_CHARS} characters (contractId ${t.contract.contractId.length}, implementationRevision ${t.contract.implementationRevision.length}) — the roster's bound.`);
33
+ e.code = "config.tool_contract_too_long";
34
+ throw e;
35
+ }
36
+ {
37
+ const keyProblem = schemaKeyBoundProblem(t.parameters);
38
+ if (keyProblem !== undefined) {
39
+ const e = new Error(`Tool "${t.name}" cannot ride a roster row: ${keyProblem}.`);
40
+ e.code = "config.tool_schema_bound";
41
+ throw e;
42
+ }
43
+ const declared = {
44
+ ...(t.family !== undefined ? { family: t.family } : {}),
45
+ ...(t.pathTarget !== undefined ? { pathTarget: t.pathTarget } : {}),
46
+ ...(t.ruleFace !== undefined ? { ruleFace: t.ruleFace } : {}),
47
+ ...(t.renderHints !== undefined ? { renderHints: t.renderHints } : {}),
48
+ };
49
+ const faceProblem = toolFaceProblem(declared, t.parameters);
50
+ if (faceProblem !== undefined) {
51
+ const e = new Error(`Tool "${t.name}" declares a face its schema cannot carry: ${faceProblem}.`);
52
+ e.code = "config.tool_face_invalid";
53
+ throw e;
54
+ }
55
+ const foreignCard = offendingResultCard(t.renderHints, callerCardIdOf(t), engineCardTypes());
56
+ if (foreignCard !== undefined) {
57
+ const e = new Error(`Tool "${t.name}" declares a result card outside its own namespace: ${JSON.stringify(foreignCard)} (a caller card is "${callerCardIdOf(t)}/<card>"; engine cards and other contracts' namespaces are reserved).`);
58
+ e.code = "config.tool_face_invalid";
59
+ throw e;
60
+ }
61
+ }
16
62
  if (t.name.includes("__")) {
17
63
  const e = new Error(`Tool name "${t.name}" is invalid: "__" is reserved for the engine's protocol tool namespaces (${NAMESPACED_NAME_SHAPES}) and must not appear in a caller tool name.`);
18
64
  e.code = "config.tool_name_invalid";
@@ -65,7 +111,7 @@ export function prepareSafetyScan(input) {
65
111
  }
66
112
  toolEffects.set(OFFLOAD_TOOL_NAME, "read");
67
113
  if (deps.executionEnvFactory || deps.executionEnv) {
68
- for (const [name, effect] of Object.entries(HAND_TOOL_EFFECTS))
114
+ for (const [name, effect] of handBandEffects())
69
115
  toolEffects.set(name, effect);
70
116
  if (spec.handsReadOnly === true)
71
117
  toolEffects.set("Bash", "read");
@@ -71,6 +71,10 @@ import { selfOrchestrationFailClosedReason } from "../../orchestration/workflow-
71
71
  import { remainingBudgetMicroUsd } from "../checkpoint-store.js";
72
72
  import { durableParkGapFor } from "../park-selfcheck.js";
73
73
  import { deliverEngineNotice } from "../types.js";
74
+ import { ToolRosterDeltaSeat } from "../tool-roster.js";
75
+ import { faceOf } from "../tool-roster.js";
76
+ import { catalogEntriesNamed, pathTargetOf } from "../tool-registry.js";
77
+ import { createStructuredProjector } from "./tool-output-projection.js";
74
78
  function warnCompactionWindowHazard(tracer, spec, model, compModel, hostTaskId) {
75
79
  if (compModel === undefined)
76
80
  return;
@@ -363,7 +367,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
363
367
  let readDenyAdditionsNormalized = [];
364
368
  let handsLessResolvedFace;
365
369
  const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, autoModeIntent, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, autoModeSeat, handsEnabled, reportUsage, harnessRef, skillScope, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun: () => { abortController.abort(); void harness.abort(); }, runtimeCaps: () => runtimeCaps, hooks: () => hooks, preToolUseObservational: () => preToolUseObservational, hookTimeoutMs: () => hookTimeoutMs, hookEnvFace: () => hookEnvFace, autoModeDecider: () => autoModeDecider, autoModeDenialTracking: () => autoModeDenialTracking, autoModeArming: () => autoModeArming, agentForkDenial: () => agentForkDenial, observersActive: () => observersActive, resolvedReadFace: () => resolvedReadFace, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized, handsLessResolvedFace: () => handsLessResolvedFace, centerAdoption: () => centerAdoptionRef.current, memoryEngineSession: () => memoryEngineSession });
366
- const { tools, blockedRef, runtimeCaps, runtimeCapsFaulted, complianceDenies, complianceDegraded, agentForkDenial, observersActive, autoModeArmReason, autoModeDecider, autoModeDenialTracking, autoModeArming, selfOrchestrationActive, workflowToolsActive, workflowSizeGuideline } = await prepareCapsAndWorkflow({ spec, deps, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, frozenOnAsk, carrierReadFace, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, autoModeIntent, peerLaneActive, peerSendMessageBuiltIn, runnerSelf, memoryEngineSession: () => memoryEngineSession, centerAdoption: () => centerAdoptionRef.current, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized });
370
+ const { roster, blockedRef, runtimeCaps, runtimeCapsFaulted, complianceDenies, complianceDegraded, agentForkDenial, observersActive, autoModeArmReason, autoModeDecider, autoModeDenialTracking, autoModeArming, selfOrchestrationActive, workflowToolsActive, workflowSizeGuideline } = await prepareCapsAndWorkflow({ spec, deps, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, frozenOnAsk, carrierReadFace, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, autoModeIntent, peerLaneActive, peerSendMessageBuiltIn, runnerSelf, memoryEngineSession: () => memoryEngineSession, centerAdoption: () => centerAdoptionRef.current, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized });
371
+ const tools = roster.tools;
367
372
  const pausedRef = {};
368
373
  const remoteEnvFailures = [];
369
374
  const suspendLoopRef = { hit: false };
@@ -419,12 +424,13 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
419
424
  catch {
420
425
  }
421
426
  }
422
- tools.push(createOutputTool(outputRef, spec.outputSchema, compiled.strict ? compiled.modelSchema : undefined));
427
+ roster.mount(createOutputTool(outputRef, spec.outputSchema, compiled.strict ? compiled.modelSchema : undefined), { source: "synthetic", mountedBy: "optional" });
423
428
  }
424
- const { mcp, a2a, rebuildHarnessToolsRef, contentOriginWrapRef, toolCallGateArmedRef } = await prepareProtocolTools({ lockedPreflight, spec, deps, reminderMark, reminderDisclosureCounts, runId, sessionId, onceLedger, tools, remoteToolOffload, toolFaceSnapshot, toolEffects, axisExplicitNegatives, irreversibilityTier, irreversibleTools, egressTools, abortController, rollback });
429
+ const rosterSeat = new ToolRosterDeltaSeat();
430
+ const { mcp, a2a, rebuildHarnessToolsRef, contentOriginWrapRef, toolCallGateArmedRef } = await prepareProtocolTools({ lockedPreflight, spec, deps, reminderMark, reminderDisclosureCounts, runId, sessionId, onceLedger, roster, rosterSeat, remoteToolOffload, toolFaceSnapshot, toolEffects, axisExplicitNegatives, irreversibilityTier, irreversibleTools, egressTools, abortController, rollback });
425
431
  const callIssuedAtRef = {};
426
432
  const memoryWriteGateRef = {};
427
- const handsReadFaceInput = { handsEnabled, executionEnv, taskRootFinal, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGateRef, firstPartyOffload, tools, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
433
+ const handsReadFaceInput = { handsEnabled, executionEnv, taskRootFinal, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGateRef, firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
428
434
  const handsReadFace = handsEnabled ? await prepareHandsMount(handsReadFaceInput) : resolveHandsLessReadFace(handsReadFaceInput);
429
435
  const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive, additionalRootsCanonical, additionalReadRootsCanonical, attachmentRootCanonical, readDenyMatcher, envHandToolNames, sealReadStateSeat } = handsReadFace;
430
436
  resolvedReadFace = handsReadFace.resolvedReadFace;
@@ -432,16 +438,16 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
432
438
  handsLessResolvedFace = handsReadFace.handsLessResolvedFace;
433
439
  shellGatedBash = handsReadFace.shellGatedBash;
434
440
  shellGatedMonitor = handsReadFace.shellGatedMonitor;
435
- const { worktreeSessionRef } = prepareDelegationSurface({ spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, executionEnv, runnerSelf, backgroundTaskToolsActive, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, tools, toolEffects, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle });
436
- const { checkpointStore, liveQuestionFace, contentAskBindings, contentAskRoutable, lateStrandedAnswers, discloseStrandedAnswers, settleContentAskBindings, durableQuestionFace, questionToolMounted, mountedQuestionTool } = prepareQuestionFace({ frozenOnQuestion, spec, deps, runtimeCaps, resolvedInteractionPosture, resume, sessionId, tools, inheritedUnavailableAsks: () => inheritedUnavailableAsks });
441
+ const { worktreeSessionRef } = prepareDelegationSurface({ spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, executionEnv, runnerSelf, backgroundTaskToolsActive, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, roster, toolEffects, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle });
442
+ const { checkpointStore, liveQuestionFace, contentAskBindings, contentAskRoutable, lateStrandedAnswers, discloseStrandedAnswers, settleContentAskBindings, durableQuestionFace, questionToolMounted, mountedQuestionTool } = prepareQuestionFace({ frozenOnQuestion, spec, deps, runtimeCaps, resolvedInteractionPosture, resume, sessionId, roster, inheritedUnavailableAsks: () => inheritedUnavailableAsks });
437
443
  if (spec.handsReadOnly !== true) {
438
444
  const sessionScope = sessionId ?? spec.principal ?? spec.taskId ?? "default";
439
- tools.push(...createSchedulerTools(executionEnv, {
445
+ roster.mountAll(createSchedulerTools(executionEnv, {
440
446
  scope: sessionScope,
441
447
  ...(spec.principal !== undefined ? { principal: spec.principal } : {}),
442
448
  ...(sessionId !== undefined ? { sessionId } : {}),
443
449
  requestStopAfterTurn,
444
- }).map((t) => (envHandToolNames.add(t.name), t)));
450
+ }).map((t) => (envHandToolNames.add(t.name), t)), { source: "builtin", mountedBy: "scheduler" });
445
451
  }
446
452
  if (internals?.insideFork !== true &&
447
453
  runnerSelf &&
@@ -451,7 +457,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
451
457
  deps.onError?.(new Error(`Fork DENIED for principal "${spec.principal ?? ""}" by runtimeCaps.allowFork=false ` +
452
458
  `(per-principal entitlement governance, not a misconfiguration — Agent(subagent_type:"fork") will refuse honestly)`), { phase: "config", sessionId });
453
459
  }
454
- const { lspDiagnostics, nudgeLspOnEdit, lspRunIdent } = prepareLsp({ spec, deps, executionEnv, taskRootFinal, handsEnabled, sessionId, handsCwdRef, tools, envHandToolNames });
460
+ const { lspDiagnostics, nudgeLspOnEdit, lspRunIdent } = prepareLsp({ spec, deps, executionEnv, taskRootFinal, handsEnabled, sessionId, handsCwdRef, roster, envHandToolNames });
455
461
  const memoryPairNameDomain = new Set();
456
462
  for (const t of tools) {
457
463
  memoryPairNameDomain.add(t.name);
@@ -503,7 +509,10 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
503
509
  const effect = (t.effect ?? toolEffects.get(t.name) ?? "write");
504
510
  if (effect === "read")
505
511
  return false;
506
- if (t.name !== "Write" && t.name !== "Edit" && t.name !== "NotebookEdit" && t.name !== "Bash")
512
+ const face = faceOf(t);
513
+ const pt = face.pathTarget ?? pathTargetOf(t.name);
514
+ const family = face.family ?? catalogEntriesNamed(t.name)[0]?.face.family;
515
+ if (!((pt !== undefined && pt.access !== "read") || family === "shell"))
507
516
  return false;
508
517
  return !(handsEnabled && isRemoteExecutionEnv(executionEnv));
509
518
  }),
@@ -551,13 +560,22 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
551
560
  deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "config", sessionId });
552
561
  }
553
562
  }
554
- const projectContext = await prepareProjectContext({ deps, spec, internals, session, sessionId, hostTaskId, taskRootFinal, handsEnabled, delegation, seedContextFiles, memoryBlockFromEngine, skillScope, tools, toolFaceSnapshot, onceLedger, memoryTools, memoryEngineSession, memorySearchToolsPlanned, memoryPairExcludedName, memoryPairOccupiedName, resume });
563
+ const projectContext = await prepareProjectContext({ deps, spec, internals, session, sessionId, hostTaskId, taskRootFinal, handsEnabled, delegation, seedContextFiles, memoryBlockFromEngine, skillScope, roster, toolFaceSnapshot, onceLedger, memoryTools, memoryEngineSession, memorySearchToolsPlanned, memoryPairExcludedName, memoryPairOccupiedName, resume });
555
564
  const { memoryBlock: memoryBlockWithProject, instructionSources, projectInstructionContent, hasSkillManifest, skillsListing, sharedMemoryPairMounted, memoryEnginePairMounted } = projectContext;
556
565
  const { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, gitStatusRef } = await preparePromptInputs({ spec, deps, failClosedReason: selfOrchestrationFailClosedReason(spec, deps), lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical, sessionId });
557
- const { deferred, memoryBlock } = prepareDeferClassify({ spec, deps, tools, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryBlock: memoryBlockWithProject, memoryRecallSegment, onceLedger, sessionId });
558
- prepareMemoryEngineSession({ memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, tools, contentOriginWrapRef });
566
+ const { deferred, memoryBlock } = prepareDeferClassify({ spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryBlock: memoryBlockWithProject, memoryRecallSegment, onceLedger, sessionId });
567
+ prepareMemoryEngineSession({ memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef });
559
568
  const { systemPromptSeat, renderWithDate, systemBlocks, promptManifest, epochDeclaredSections, epochArtifactDigestForSnapshot, buildAssembleInputs, centerAdoptionRef } = await preparePromptAssembly({ session, deps, internals, resume, provider, userSystemPrompt, userAppendSystemPrompt, featureFlags, mcpInstructionsBlock, memoryBlock, envFacts, promptProfile, fableMitigations, tools, model, sessionId, reminderMark, onceLedger });
560
- const { activeTools, fpRef, turnSnapshotRef, harnessTools, toolsDeltaRef, toolMaterializeStatic, deferDirectCall, staticFaceForRef, listingRideRef } = await prepareToolDisclosureMount({ spec, deps, session, resume, deferred, tools, onceLedger, mcp, promptManifest, offloadReachableToolsRef, contentOriginWrapRef, rebuildHarnessToolsRef, harnessRef });
569
+ const { activeTools, fpRef, turnSnapshotRef, harnessTools, toolsDeltaRef, toolMaterializeStatic, deferDirectCall, staticFaceForRef, listingRideRef, toolSearch } = await prepareToolDisclosureMount({ spec, deps, session, resume, deferred, tools, onceLedger, mcp, promptManifest, offloadReachableToolsRef, contentOriginWrapRef, rebuildHarnessToolsRef, harnessRef });
570
+ if (toolSearch !== undefined)
571
+ roster.mountEngineLane(toolSearch, { source: "builtin", mountedBy: "optional" });
572
+ const rosterFacts = { effects: toolEffects, egress: egressTools, irreversibilityTier, reversibilityProbes, deferred, trustedTools: new Set(spec.memory?.trustedTools ?? []) };
573
+ const toolRoster = roster.snapshot(rosterFacts);
574
+ rosterSeat.arm(toolRoster, () => roster.snapshot(rosterFacts));
575
+ const structuredProjector = createStructuredProjector({
576
+ declaredCards: toolRoster.entries.flatMap((e) => e.renderHints?.resultCards ?? []),
577
+ onUndeclared: (type) => deliverEngineNotice(deps.onNotice, { code: "config.tool_card_undeclared", message: `a tool minted a \`details.type\` card ${JSON.stringify(type)} its definition never declared — dropped from tool_end.structured (declare it on the definition's catalog row or the caller's renderHints.resultCards)`, detail: { type, sessionId, runId } }),
578
+ });
561
579
  const { agentListing, announcedListingsRef, dateChange } = prepareListings({ spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingRideRef, renderWithDate, envFacts, tzValid, userTz });
562
580
  const lastBrainContextRef = {};
563
581
  const requestLossyRef = { current: false };
@@ -614,7 +632,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
614
632
  ...(spec.streamingToolExecution === true ? { streamingToolExecution: true } : {}),
615
633
  env: executionEnv,
616
634
  session,
617
- tools: harnessTools,
635
+ tools: [...harnessTools],
618
636
  model,
619
637
  thinkingLevel: thinking ?? "off",
620
638
  systemPrompt: systemPromptSeat.current,
@@ -652,7 +670,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
652
670
  }
653
671
  }
654
672
  const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, ownToolNames, shellGatedBash, handsCwdRef, readDenyMatcher, questionToolMounted, runtimeCaps, inheritedAncestorRules, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
655
- const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace } = prepareWiringManifest({ spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, peerLaneActive, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation });
673
+ const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace } = prepareWiringManifest({ spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, peerLaneActive, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster });
656
674
  if (fileHistoryBoundary !== undefined) {
657
675
  harness.on("tool_call", async () => {
658
676
  await fileHistoryBoundary.settle();
@@ -662,13 +680,13 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
662
680
  const { askLane } = prepareAskLane({ gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash });
663
681
  const { saga } = prepareSuspendSaga({ gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, inheritedParentConstraints, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, autoModeIntent, autoModeDecider, inheritedAdmittedOrgScopes, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter });
664
682
  const { suspendForResource, suspendForPlatformLimit, suspendForReview } = prepareBoundaryParks({ saga, spec, checkpointStore, abortController, harness, session, sessions, sessionId, deps, priorLedger, maxSlices, maxSuspends, resourceTotal, priorSuspendCount, suspendChainBase, humanReviewRef, liveSpendRef, now, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, pausedRef, remoteEnvFailures, resourceSuspendEligible, durableSuspendInfraReady, incompleteSuspendAdapter });
665
- const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedBash, shellGatedMonitor, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef });
666
- prepareGateStations({ askLane, parkAsk, tools, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedBash, shellGatedMonitor, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash });
683
+ const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedBash, shellGatedMonitor, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef });
684
+ prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, planModeRef, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, hookEnvFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedBash, shellGatedMonitor, autoModeDecider, autoModeDenialTracking, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash });
667
685
  const { microCompact, charsPerToken } = prepareContextLane({ model, deps, sessionId, runId, hostTaskId, offloadStore, microCompactKnob, harness, batchHaltRef, gitStatusRef, requestLossyRef, trimPressureRef });
668
686
  const preparedHolder = {};
669
687
  const { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveReadDenyObserved } = prepareTurnWiring({ deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, additionalRootsCanonical, additionalReadRootsCanonical, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, readDenyAdditionsNormalized, preparedHolder });
670
688
  await onceLedger.settle(session, announcedListingsRef);
671
- const buildPrepared = () => ({ harness, session, sessionId, runId, reminderMark, reminderDisclosureCounts, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, brainCallGuardrailRef, gateStopRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, hookIdentity, hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
689
+ const buildPrepared = () => ({ harness, session, sessionId, runId, reminderMark, reminderDisclosureCounts, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, brainCallGuardrailRef, gateStopRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, hookIdentity, hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
672
690
  rollback.commit();
673
691
  const prepared = buildPrepared();
674
692
  preparedHolder.current = prepared;
@@ -36,7 +36,7 @@ export interface PrepareToolDisclosureMountInput {
36
36
  deferred: ReadonlySet<string>;
37
37
  /** borrowed-readonly — the run's shared roster (`Prepared.tools`): READ here — the registry build, the reserved-name
38
38
  * check, the live resolution the placeholders and the static face perform at call time. Never written by this phase. */
39
- tools: AgentTool[];
39
+ tools: readonly AgentTool[];
40
40
  /** borrowed-readonly — the once-per-session ledger's failed-server projection (current failures minus the pairs this
41
41
  * session already announced). */
42
42
  onceLedger: {
@@ -87,7 +87,10 @@ export interface PrepareToolDisclosureMountResult {
87
87
  };
88
88
  /** owned — the list the harness is built from: the roster with placeholders in the deferred slots plus ToolSearch (or the
89
89
  * roster itself when nothing is deferred). */
90
- harnessTools: AgentTool[];
90
+ harnessTools: readonly AgentTool[];
91
+ /** owned — the ToolSearch instance the deferred arm appended to the harness list (absent when nothing is deferred): the
92
+ * driver mounts it on the roster's ENGINE LANE so the roster carries every name the model can call. */
93
+ toolSearch?: AgentTool;
91
94
  /** owned — the boundary delta ref (`Prepared.toolsDeltaRef`), minted when anything is deferred OR a server failed. */
92
95
  toolsDeltaRef: Prepared["toolsDeltaRef"];
93
96
  /** owned — the effective strategy (`Prepared.toolMaterializeStatic`). */
@@ -31,6 +31,7 @@ export async function prepareToolDisclosureMount(input) {
31
31
  const fpRef = {};
32
32
  const turnSnapshotRef = {};
33
33
  let harnessTools = tools;
34
+ let toolSearchMounted;
34
35
  const failedMcpServers = onceLedger.mcpFailuresToAnnounce(mcp.statuses);
35
36
  let toolsDeltaRef;
36
37
  let toolMaterializeStatic = false;
@@ -204,6 +205,7 @@ export async function prepareToolDisclosureMount(input) {
204
205
  serializeActivation,
205
206
  });
206
207
  harnessTools = buildToolList(activeTools);
208
+ toolSearchMounted = toolSearch;
207
209
  }
208
210
  else {
209
211
  rebuildHarnessToolsRef.current = async () => {
@@ -215,5 +217,5 @@ export async function prepareToolDisclosureMount(input) {
215
217
  turnSnapshotRef.current?.refreshTools(toolsToFingerprintInputs(list));
216
218
  };
217
219
  }
218
- return { activeTools, fpRef, turnSnapshotRef, harnessTools, toolsDeltaRef, toolMaterializeStatic, deferDirectCall, staticFaceForRef, listingRideRef };
220
+ return { activeTools, fpRef, turnSnapshotRef, harnessTools, toolsDeltaRef, toolMaterializeStatic, deferDirectCall, staticFaceForRef, listingRideRef, ...(toolSearchMounted !== undefined ? { toolSearch: toolSearchMounted } : {}) };
219
221
  }
@@ -29,6 +29,7 @@ import { type OnAsk, type ToolPolicy } from "../tool-policy.js";
29
29
  import type { GateOutcome } from "../gate-outcome.js";
30
30
  import type { RunnerDeps, RuntimeCaps, TaskSpec, ToolEffect, ToolExecuteContext } from "../types.js";
31
31
  import { type UsageWindow } from "../usage-window-store.js";
32
+ import type { ToolRoster } from "../tool-roster.js";
32
33
  import { type AutoModeArmReason, type WiringManifest, type WiringManifestMcpEntry } from "../wiring-manifest.js";
33
34
  import type { AnnounceOnceSink, Prepared, PrepareResume, RunInternals, UsageGovernance } from "./contracts.js";
34
35
  export interface PrepareWiringManifestInput {
@@ -102,6 +103,9 @@ export interface PrepareWiringManifestInput {
102
103
  sessions: SessionStore;
103
104
  /** borrowed-readonly — the model gate's per-leg read face, or undefined. */
104
105
  modelGateManifest: WiringManifest["modelGate"];
106
+ /** borrowed-readonly — the leg's minted tool roster (design/388): rides the manifest's `tools` section and is the
107
+ * source of the hand band's write-capable names for the ungated-write warning (what actually MOUNTED). */
108
+ toolRoster: ToolRoster;
105
109
  /** borrowed-readonly — the arming outcome the caps phase minted (the manifest's auto-mode face). */
106
110
  autoModeArmReason: AutoModeArmReason;
107
111
  /** borrowed-readonly — the frozen preflight; only `mcp` (the declared servers the manifest face joins). */
@@ -1,5 +1,4 @@
1
1
  import { bindPeerLaneDrain } from "../../agents/peer-session-drain.js";
2
- import { HAND_TOOL_EFFECTS } from "../../tools/fs/index.js";
3
2
  import { resolveCheckpointStore } from "../checkpoint-store.js";
4
3
  import { createHookEnvCapabilities, mintHookInvocationIdentity } from "../hooks.js";
5
4
  import { isRemoteExecutionEnv, missingRestoreSurface } from "../remote-env.js";
@@ -109,14 +108,9 @@ function announceDurableGateUnavailable(args) {
109
108
  });
110
109
  }
111
110
  export function prepareWiringManifest(input) {
112
- const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, peerLaneActive, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation } = input;
111
+ const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, peerLaneActive, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster } = input;
113
112
  const onAsk = spec.onAsk ?? deps.onAsk;
114
- const handWriteTools = handsEnabled && spec.handsReadOnly !== true
115
- ? Object.keys(HAND_TOOL_EFFECTS).filter((name) => {
116
- const eff = HAND_TOOL_EFFECTS[name];
117
- return eff === "write" || eff === "idempotent";
118
- })
119
- : [];
113
+ const handWriteTools = toolRoster.entries.filter((e) => e.mountedBy === "hands" && (e.effect === "write" || e.effect === "idempotent")).map((e) => e.name);
120
114
  const hasEffectAwareGate = Boolean(policyLayers.length > 0 || (hooks?.preToolUse !== undefined && !preToolUseObservational));
121
115
  const destructiveMcpUngated = mcp.tools.some((t) => !irreversibleTools.has(t.name) && !egressTools.has(t.name) && (toolEffects.get(t.name) ?? "write") !== "read");
122
116
  const firstPartyWriteUngated = (spec.tools ?? [])
@@ -207,6 +201,7 @@ export function prepareWiringManifest(input) {
207
201
  ...(modelGateManifest !== undefined ? { modelGate: modelGateManifest } : {}),
208
202
  autoMode: { armed: autoModeArmReason === "armed", reason: autoModeArmReason },
209
203
  mcp: mcpManifestEntries(lockedPreflight.mcp, mcp.statuses),
204
+ tools: toolRoster,
210
205
  });
211
206
  peerLaneRefs.askEffective = wiringManifest.ask.effective;
212
207
  if (peerLaneActive && internals?.onTaskNotification !== undefined) {
@@ -0,0 +1,53 @@
1
+ /**
2
+ * design/393 S3 — the resume ladder's ADMISSION rung (E1) and the wake's shaping (E2), verbatim from
3
+ * `Runner.resumeStream`: the outcome container's domain, the one-read snapshots of the caller's config and
4
+ * the trusted internals bag, the store resolution, the row read and its terminal-status confirm, the
5
+ * same-process parent-constraint re-supply, then the wake pre-ladder (gate purity, pendingAction purity,
6
+ * the message's persist-time validation) and the one read of the outcome discriminant and the signal slot.
7
+ *
8
+ * Async (two store reads); every refusal throws a typed `CheckpointError` pre-CAS. It ends by handing what it
9
+ * admitted to the rung after it (`next`) in its LAST continuation — no suspension point between the
10
+ * registry read and the wake pre-ladder's first read of the row — and returns what that rung returns.
11
+ * The same seat shape the tool gate's fold uses to enter its lanes (gate-fold.ts `afterFold`).
12
+ */
13
+ import { type Checkpoint, type CheckpointStore, type CheckpointToken, type PendingSteerEntry, type ResumeOutcome } from "../checkpoint-store.js";
14
+ import type { InheritedGate, ResumeTaskConfig, RunInternals, RunnerDepsSeat } from "./contracts.js";
15
+ /** What the admission rung was called with. */
16
+ export interface ResumeAdmissionInput<R> {
17
+ /** borrowed-readonly — the checkpoint token the caller is redeeming. */
18
+ token: CheckpointToken;
19
+ /** borrowed-readonly — the caller's outcome object, read exactly where the driver read it (the container test,
20
+ * the discriminant once, the wake message once); never stored, never handed on as itself. */
21
+ outcome: ResumeOutcome;
22
+ /** borrowed-readonly — the caller's config bag; snapshotted ONCE here (own enumerable fields), the snapshot is what
23
+ * every later rung and the resumed leg read. */
24
+ taskConfig: ResumeTaskConfig;
25
+ /** borrowed-readonly — the trusted run-internals bag as the caller supplied it; shallow-snapshotted here, the
26
+ * snapshot (with the parked chain re-supplied when the registry holds it) is what the ladder reads. */
27
+ internals: RunInternals | undefined;
28
+ /** 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
+ * seat and not a captured object is {@link RunnerDepsSeat}. */
30
+ runner: RunnerDepsSeat;
31
+ /** borrowed-readonly — the Runner's same-process parked-constraint registry; read for this token (never written here). */
32
+ parentConstraintRegistry: ReadonlyMap<CheckpointToken, NonNullable<InheritedGate["parentConstraints"]>>;
33
+ /** borrowed-readonly — the rung after admission, entered in this rung's last continuation with what it admitted. */
34
+ next: (admitted: ResumeAdmissionResult) => Promise<R>;
35
+ }
36
+ /** What admission established — the constants every later rung reads. */
37
+ export interface ResumeAdmissionResult {
38
+ /** The caller's config, snapshotted once (own enumerable fields). */
39
+ config: ResumeTaskConfig;
40
+ /** The trusted internals snapshot, with the parked parent chain re-supplied when this Runner spawned the leg. */
41
+ internals: RunInternals | undefined;
42
+ /** The checkpoint store the row lives in. */
43
+ store: CheckpointStore;
44
+ /** The pending row, read once; a non-pending snapshot was refused before this result existed. */
45
+ cp: Checkpoint;
46
+ /** The ONE read of the outcome's discriminant. */
47
+ outcomeGate: ResumeOutcome["gate"];
48
+ /** The ONE read of the config's signal slot (`.aborted` stays a live read on this object). */
49
+ resumeSignal: AbortSignal | undefined;
50
+ /** The validated wake message (wake outcomes that carried one), never the caller's object. */
51
+ wakeMessage: Omit<PendingSteerEntry, "seq"> | undefined;
52
+ }
53
+ export declare function resumeAdmission<R>(input: ResumeAdmissionInput<R>): Promise<R>;
@@ -0,0 +1,83 @@
1
+ import { CheckpointError, readPendingSteerQueue, resolveCheckpointStore, validatePendingSteer } from "../checkpoint-store.js";
2
+ import { describeSuppliedValue } from "./decide-continuation.js";
3
+ export async function resumeAdmission(input) {
4
+ const { token, outcome, taskConfig, runner, parentConstraintRegistry } = input;
5
+ let internals = input.internals;
6
+ if (outcome === null || typeof outcome !== "object") {
7
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume outcome must be an object naming its gate (got ${outcome === null ? "null" : typeof outcome})`);
8
+ }
9
+ const config = typeof taskConfig === "object" && taskConfig !== null ? { ...taskConfig } : taskConfig;
10
+ internals = internals !== undefined ? { ...internals } : undefined;
11
+ const store = resolveCheckpointStore(config, runner.deps);
12
+ if (!store) {
13
+ throw new CheckpointError("checkpoint.not_found", "no CheckpointStore wired — cannot resume (set RunnerDeps.checkpointStore or taskConfig.checkpointStore)");
14
+ }
15
+ let cp = await store.get(token);
16
+ if (!cp) {
17
+ throw new CheckpointError("checkpoint.not_found", "no checkpoint found for the supplied token");
18
+ }
19
+ if (cp.status !== "pending") {
20
+ const live = await store.get(token);
21
+ if (live?.status === "pending") {
22
+ throw new CheckpointError("checkpoint.reopened_concurrently", "checkpoint changed concurrently (a resolve/reopen cycle landed between this resume's read of the row and its state check) — nothing was validated or executed; re-resume against the current state");
23
+ }
24
+ throw new CheckpointError("checkpoint.already_resolved", `checkpoint is ${describeSuppliedValue(live?.status ?? cp.status)} — the token is consumed, so this resume was neither validated nor executed (idempotent); a different outcome cannot redeem it`);
25
+ }
26
+ if ((internals?.inheritedGate?.parentConstraints?.length ?? 0) === 0) {
27
+ const parked = parentConstraintRegistry.get(token);
28
+ if (parked !== undefined) {
29
+ internals = {
30
+ ...(internals ?? {}),
31
+ inheritedGate: { ...(internals?.inheritedGate ?? {}), parentConstraints: parked },
32
+ };
33
+ }
34
+ }
35
+ let wakeMessage;
36
+ const outcomeGate = outcome.gate;
37
+ const resumeSignal = config.signal;
38
+ let suppliedMessage;
39
+ if (outcomeGate === "wake") {
40
+ suppliedMessage = outcome.message;
41
+ const gk = cp.gate.kind;
42
+ const decideEntry = gk === "human" || gk === "irreversible_ask"
43
+ ? 'a `policy_ask` outcome (decision allow/deny bound to the pending tool call)'
44
+ : gk === "needs_review"
45
+ ? 'a `dry_run_review` outcome (decision approve/reject)'
46
+ : gk === "plan_review"
47
+ ? 'a `plan_review` outcome (decision approve/edit/reject)'
48
+ : gk === "resource_limit"
49
+ ? 'a `resource_limit` outcome (decision "continue")'
50
+ : undefined;
51
+ if (gk !== "task_done") {
52
+ throw new CheckpointError("wake.gate_pending", `cannot wake: this checkpoint awaits a pending gate decision (gate "${gk}") — wake is not a decision ` +
53
+ `channel; resume it with ${decideEntry ?? "its own gate outcome"} instead`);
54
+ }
55
+ const pa = cp.pendingAction;
56
+ switch (pa.kind) {
57
+ case "task_done":
58
+ break;
59
+ case "tool_approval":
60
+ case "resource_limit":
61
+ case "review":
62
+ case "plan_review": {
63
+ throw new CheckpointError("wake.gate_pending", `cannot wake: this checkpoint still carries a pending gate-typed action (pendingAction "${pa.kind}" ` +
64
+ `on a "${gk}" gate — inconsistent row) — wake is not a decision channel; resolve it through its ` +
65
+ `own decide entry instead`);
66
+ }
67
+ default: {
68
+ const _exhaustive = pa;
69
+ void _exhaustive;
70
+ throw new CheckpointError("wake.gate_pending", `cannot wake: this checkpoint carries an unrecognized pendingAction kind "${pa.kind}" ` +
71
+ `(newer-version row?) — fail-closed: wake only serves a pure park (pendingAction "task_done")`);
72
+ }
73
+ }
74
+ if (suppliedMessage !== undefined) {
75
+ wakeMessage = validatePendingSteer(suppliedMessage);
76
+ }
77
+ else if (readPendingSteerQueue(cp.state).length === 0) {
78
+ throw new CheckpointError("wake.nothing_to_deliver", "cannot wake: no message was supplied and the checkpoint holds no parked pendingSteer — an empty " +
79
+ "wake would burn the checkpoint on a blank continuation; supply `message` or park a steer first");
80
+ }
81
+ }
82
+ return await input.next({ config, internals, store, cp, outcomeGate, resumeSignal, wakeMessage });
83
+ }
@@ -0,0 +1,50 @@
1
+ import { type Checkpoint, type PendingSteerEntry, type ResumeOutcome } from "../checkpoint-store.js";
2
+ import type { ResumeRun, ResumeTaskConfig, RunInternals, RunnerDepsSeat } from "./contracts.js";
3
+ export interface ResumeApplyInput<R> {
4
+ /** borrowed-readonly — the pending row (session id, pending call, inherited chain, ledger, hands cwd). */
5
+ cp: Checkpoint;
6
+ /** borrowed-readonly — the config snapshot (`hooks`, `taskId`, `signal`, the policy seats). */
7
+ config: ResumeTaskConfig;
8
+ /** borrowed-readonly — the internals snapshot (delegation identity facts for the screen's envelope). */
9
+ internals: RunInternals | undefined;
10
+ /** borrowed-readonly — the ONE read of the outcome discriminant. */
11
+ outcomeGate: ResumeOutcome["gate"];
12
+ /** borrowed-readonly — the validated wake message the screen judges. */
13
+ wakeMessage: Omit<PendingSteerEntry, "seq"> | undefined;
14
+ /** borrowed-readonly — the ONE signal read from admission; the screen and the edit legs are bounded by it. */
15
+ resumeSignal: AbortSignal | undefined;
16
+ /** borrowed-readonly — the window verdict to re-assert after the screen's await (undefined when unarmed). */
17
+ recheckGovernanceWindow: (() => Promise<void>) | undefined;
18
+ /** borrowed-readonly — the approval lane's twin (its edit is what the rechecks judge; the settlement is minted onto a copy). */
19
+ plainPolicyOutcome: Extract<ResumeOutcome, {
20
+ gate: "policy_ask";
21
+ }> | undefined;
22
+ /** borrowed-readonly — the review lane's twin. */
23
+ plainReviewOutcome: Extract<ResumeOutcome, {
24
+ gate: "plan_review" | "dry_run_review";
25
+ }> | undefined;
26
+ /** borrowed-readonly — the tool-less park lanes' twin. */
27
+ plainParkOutcome: Extract<ResumeOutcome, {
28
+ gate: "wake" | "resource_limit";
29
+ }> | undefined;
30
+ /** borrowed-readonly — the Runner's deployment deps, read LIVE through the Runner (reads `hooks`, `onError`, `lockedConfig`, `basePolicyForResumeEdit`, `toolPolicy` — the last three AFTER this rung's awaits); the one home of why it is a
31
+ * seat and not a captured object is {@link RunnerDepsSeat}. */
32
+ runner: RunnerDepsSeat;
33
+ /** borrowed-readonly — the orchestrator's delegation-facts fold (a lane may not name the orchestrator; the driver hands it in). */
34
+ effectiveDelegationFacts: (internals: Pick<RunInternals, "isDelegatedChild" | "insideFork"> | undefined, seedIsDelegatedChild: boolean | undefined) => {
35
+ isDelegatedChild: boolean;
36
+ };
37
+ /** borrowed-readonly — the rung after apply, entered in this rung's last continuation. */
38
+ next: (applied: ResumeApplyResult) => Promise<R>;
39
+ }
40
+ export interface ResumeApplyResult {
41
+ /** The screen's `additionalContext` for the wake message, when a screen ran and supplied one. */
42
+ wakeHookContext: string | undefined;
43
+ /** The approval lane's twin WITH its minted settlement record (undefined on every other lane). */
44
+ plainPolicyOutcome: Extract<ResumeOutcome, {
45
+ gate: "policy_ask";
46
+ }> | undefined;
47
+ /** The twin the store persists and the resumed leg reads — exactly one lane captured it. */
48
+ outcomeForStore: ResumeRun["outcome"];
49
+ }
50
+ export declare function resumeApply<R>(input: ResumeApplyInput<R>): Promise<R>;