@sema-agent/core 7.49.4 → 7.50.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 (200) hide show
  1. package/CHANGELOG.md +152 -0
  2. package/dist/agents/observer.js +3 -10
  3. package/dist/agents/peer-directory.d.ts +8 -3
  4. package/dist/agents/peer-directory.js +5 -3
  5. package/dist/agents/subagent-steps.d.ts +6 -14
  6. package/dist/agents/subagent-steps.js +3 -17
  7. package/dist/brain/stream-shared.d.ts +1 -1
  8. package/dist/core/allow-entry.d.ts +1 -1
  9. package/dist/core/allow-entry.js +1 -1
  10. package/dist/core/ask-origin.d.ts +15 -11
  11. package/dist/core/ask-origin.js +6 -14
  12. package/dist/core/auto-mode-prompt.js +6 -2
  13. package/dist/core/checkpoint-store.d.ts +6 -4
  14. package/dist/core/checkpoint-store.js +1 -1
  15. package/dist/core/context-edit.d.ts +2 -2
  16. package/dist/core/decision-receipt.d.ts +2 -2
  17. package/dist/core/decision-receipt.js +30 -11
  18. package/dist/core/delegation-frames.d.ts +66 -18
  19. package/dist/core/delegation-frames.js +22 -0
  20. package/dist/core/engine-notice.d.ts +7 -5
  21. package/dist/core/frame-settlement.d.ts +6 -1
  22. package/dist/core/gate-fold.js +19 -13
  23. package/dist/core/gate-lanes.js +12 -11
  24. package/dist/core/gate-outcome.d.ts +2 -2
  25. package/dist/core/governance-codes.js +2 -0
  26. package/dist/core/hooks.d.ts +28 -20
  27. package/dist/core/human-input-projection.js +2 -0
  28. package/dist/core/lsp-diagnostics.d.ts +3 -0
  29. package/dist/core/lsp-diagnostics.js +6 -0
  30. package/dist/core/lsp-session.d.ts +39 -17
  31. package/dist/core/lsp-session.js +118 -58
  32. package/dist/core/lsp.d.ts +83 -3
  33. package/dist/core/lsp.js +146 -16
  34. package/dist/core/mcp.js +2 -1
  35. package/dist/core/media-byte-cap.d.ts +14 -0
  36. package/dist/core/media-byte-cap.js +15 -3
  37. package/dist/core/memory-engine/consolidation-driver.d.ts +23 -1
  38. package/dist/core/memory-engine/consolidation-driver.js +54 -6
  39. package/dist/core/memory-engine/consolidation-write-gate.d.ts +46 -0
  40. package/dist/core/memory-engine/consolidation-write-gate.js +82 -0
  41. package/dist/core/memory-engine/consolidation.d.ts +17 -0
  42. package/dist/core/memory-engine/consolidation.js +1 -0
  43. package/dist/core/memory-engine/distiller.d.ts +8 -2
  44. package/dist/core/memory-engine/distiller.js +8 -6
  45. package/dist/core/memory-engine/engine.d.ts +37 -4
  46. package/dist/core/memory-engine/engine.js +127 -38
  47. package/dist/core/memory-engine/file-backend.d.ts +8 -3
  48. package/dist/core/memory-engine/file-backend.js +44 -16
  49. package/dist/core/memory-engine/index.d.ts +2 -2
  50. package/dist/core/memory-engine/index.js +1 -1
  51. package/dist/core/memory-engine/landing-admission.d.ts +65 -0
  52. package/dist/core/memory-engine/landing-admission.js +68 -0
  53. package/dist/core/memory-engine/types.d.ts +23 -0
  54. package/dist/core/mode-policy.d.ts +3 -2
  55. package/dist/core/mode-policy.js +2 -0
  56. package/dist/core/permission-rule-model.d.ts +19 -13
  57. package/dist/core/permission-rule-model.js +7 -4
  58. package/dist/core/permission-rule-provider.d.ts +11 -0
  59. package/dist/core/permission-rules.d.ts +1 -1
  60. package/dist/core/permission-rules.js +5 -2
  61. package/dist/core/persisted-rule-arms.d.ts +15 -7
  62. package/dist/core/persisted-rule-arms.js +13 -6
  63. package/dist/core/posix-mode-face.d.ts +10 -0
  64. package/dist/core/posix-mode-face.js +3 -0
  65. package/dist/core/reminder-mint.d.ts +5 -0
  66. package/dist/core/reminder-mint.js +1 -0
  67. package/dist/core/retired-keys.d.ts +8 -0
  68. package/dist/core/retired-keys.js +4 -0
  69. package/dist/core/rule-lane-reads.d.ts +4 -4
  70. package/dist/core/rule-lane-reads.js +10 -1
  71. package/dist/core/runner/construction-doors.d.ts +10 -4
  72. package/dist/core/runner/construction-doors.js +25 -2
  73. package/dist/core/runner/contracts.d.ts +20 -3
  74. package/dist/core/runner/env-capability-census.js +1 -1
  75. package/dist/core/runner/gate-exit.js +2 -1
  76. package/dist/core/runner/memory-consolidation-driver.d.ts +6 -4
  77. package/dist/core/runner/memory-consolidation-driver.js +5 -2
  78. package/dist/core/runner/memory-consolidation-write-judge.d.ts +17 -0
  79. package/dist/core/runner/memory-consolidation-write-judge.js +14 -0
  80. package/dist/core/runner/permission-rule-lanes.d.ts +16 -22
  81. package/dist/core/runner/permission-rule-lanes.js +13 -43
  82. package/dist/core/runner/person-path-rows.d.ts +244 -0
  83. package/dist/core/runner/person-path-rows.js +387 -0
  84. package/dist/core/runner/prepare-acquire-reconcile.js +8 -1
  85. package/dist/core/runner/prepare-artifact.d.ts +5 -3
  86. package/dist/core/runner/prepare-artifact.js +2 -8
  87. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -3
  88. package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
  89. package/dist/core/runner/prepare-context-lane.js +2 -2
  90. package/dist/core/runner/prepare-gate-stations.d.ts +3 -3
  91. package/dist/core/runner/prepare-gate-stations.js +1 -1
  92. package/dist/core/runner/prepare-hands-readface.d.ts +19 -10
  93. package/dist/core/runner/prepare-hands-readface.js +57 -43
  94. package/dist/core/runner/prepare-lsp.d.ts +15 -13
  95. package/dist/core/runner/prepare-lsp.js +11 -11
  96. package/dist/core/runner/prepare-policy-chain.d.ts +8 -4
  97. package/dist/core/runner/prepare-policy-chain.js +6 -7
  98. package/dist/core/runner/prepare-run-refs.js +1 -1
  99. package/dist/core/runner/prepare-task.js +24 -16
  100. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -6
  101. package/dist/core/runner/prepare-turn-wiring.js +19 -8
  102. package/dist/core/runner/read-root-grant.d.ts +1 -25
  103. package/dist/core/runner/read-root-grant.js +1 -17
  104. package/dist/core/runner/retired-runner-deps.d.ts +2 -2
  105. package/dist/core/runner/run-brain-sinks.d.ts +1 -5
  106. package/dist/core/runner/run-brain-sinks.js +2 -4
  107. package/dist/core/runner/run-harness-handlers.js +5 -4
  108. package/dist/core/runner/run-identity-wiring.d.ts +4 -4
  109. package/dist/core/runner/run-identity-wiring.js +10 -1
  110. package/dist/core/runner/run-leg.d.ts +1 -1
  111. package/dist/core/runner/run-leg.js +22 -9
  112. package/dist/core/runner/run-settle-and-teardown.d.ts +0 -4
  113. package/dist/core/runner/run-settle-and-teardown.js +7 -4
  114. package/dist/core/runner/run-terminal-adoption.d.ts +1 -1
  115. package/dist/core/runner/run-terminal-adoption.js +1 -1
  116. package/dist/core/runner/run-turn-boundary.js +2 -2
  117. package/dist/core/runner/runtask.js +8 -8
  118. package/dist/core/runner/session-file-state-replay.d.ts +14 -4
  119. package/dist/core/runner/session-file-state-replay.js +8 -0
  120. package/dist/core/runner/stream-steer-verb.js +3 -0
  121. package/dist/core/runner/tool-end-body.d.ts +5 -4
  122. package/dist/core/runner/tool-end-body.js +4 -4
  123. package/dist/core/runner/tool-output-projection.d.ts +6 -4
  124. package/dist/core/runner/tool-output-projection.js +66 -47
  125. package/dist/core/runner-deps.d.ts +6 -3
  126. package/dist/core/shared-memory/types.d.ts +2 -2
  127. package/dist/core/shell-read-silence.d.ts +23 -0
  128. package/dist/core/shell-read-silence.js +18 -0
  129. package/dist/core/synthetic-read-verdict.d.ts +80 -21
  130. package/dist/core/synthetic-read-verdict.js +89 -18
  131. package/dist/core/task-event.d.ts +113 -25
  132. package/dist/core/task-spec.d.ts +44 -0
  133. package/dist/core/task-tool-shape.d.ts +1 -1
  134. package/dist/core/tool-catalog-entries.js +16 -2
  135. package/dist/core/tool-policy.d.ts +25 -15
  136. package/dist/core/tool-policy.js +9 -13
  137. package/dist/core/trace.d.ts +3 -2
  138. package/dist/core/types.d.ts +3 -3
  139. package/dist/core/types.js +1 -1
  140. package/dist/core/untrusted-text.d.ts +2 -2
  141. package/dist/core/user-attachment.d.ts +164 -0
  142. package/dist/core/user-attachment.js +437 -0
  143. package/dist/engine/compaction/compaction.js +10 -3
  144. package/dist/engine/compaction/utils.js +6 -0
  145. package/dist/engine/execution-env/node-execution-env.d.ts +19 -1
  146. package/dist/engine/execution-env/node-execution-env.js +127 -1
  147. package/dist/engine/harness/agent-harness.d.ts +12 -2
  148. package/dist/engine/harness/agent-harness.js +15 -3
  149. package/dist/engine/harness/types.d.ts +21 -0
  150. package/dist/engine/llm/content-block-render.d.ts +15 -0
  151. package/dist/engine/llm/content-block-render.js +10 -0
  152. package/dist/engine/llm/index.d.ts +1 -0
  153. package/dist/engine/llm/index.js +1 -0
  154. package/dist/engine/llm/types.d.ts +80 -4
  155. package/dist/engine/llm/types.js +43 -1
  156. package/dist/engine/session/import-validate.js +2 -0
  157. package/dist/index.d.ts +6 -4
  158. package/dist/index.js +2 -1
  159. package/dist/internal/harness-types.d.ts +1 -1
  160. package/dist/internal/llm.d.ts +2 -2
  161. package/dist/internal/llm.js +1 -1
  162. package/dist/orchestration/workflow.d.ts +4 -5
  163. package/dist/orchestration/workflow.js +2 -2
  164. package/dist/prompts/default.d.ts +1 -1
  165. package/dist/stores/file/permission-rule-store.d.ts +13 -1
  166. package/dist/stores/file/permission-rule-store.js +40 -21
  167. package/dist/tools/artifact/artifact-tool.js +1 -1
  168. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  169. package/dist/tools/fs/dir-entries.d.ts +4 -10
  170. package/dist/tools/fs/dir-entries.js +4 -11
  171. package/dist/tools/fs/file-read-check.js +3 -3
  172. package/dist/tools/fs/fs-pdf.js +2 -4
  173. package/dist/tools/fs/fs-read.d.ts +47 -4
  174. package/dist/tools/fs/fs-read.js +63 -19
  175. package/dist/tools/fs/fs-search-tools.d.ts +3 -3
  176. package/dist/tools/fs/fs-search-tools.js +7 -2
  177. package/dist/tools/fs/fs-write.d.ts +1 -1
  178. package/dist/tools/fs/fs-write.js +7 -6
  179. package/dist/tools/fs/index.d.ts +7 -1
  180. package/dist/tools/fs/index.js +56 -34
  181. package/dist/tools/fs/read-deny-home.d.ts +19 -1
  182. package/dist/tools/fs/read-deny-home.js +32 -22
  183. package/dist/tools/fs/read-deny.d.ts +14 -0
  184. package/dist/tools/fs/read-deny.js +8 -0
  185. package/dist/tools/fs/repo-map.d.ts +3 -2
  186. package/dist/tools/fs/repo-map.js +11 -3
  187. package/dist/tools/fs/safety.d.ts +41 -2
  188. package/dist/tools/fs/safety.js +12 -3
  189. package/dist/tools/fs/shell-read-check.d.ts +12 -3
  190. package/dist/tools/fs/shell-read-check.js +28 -15
  191. package/dist/tools/fs/shell-read-device.d.ts +1 -1
  192. package/dist/tools/fs/shell-read-judge.d.ts +9 -4
  193. package/dist/tools/fs/shell-read-judge.js +1 -1
  194. package/dist/tools/loop-tick.d.ts +2 -2
  195. package/package.json +3 -1
  196. package/test/export-surface.snapshot.json +39 -1
  197. package/wire-changes/core@7.49.5.json +104 -0
  198. package/wire-changes/core@7.50.0.json +1699 -0
  199. package/dist/core/runner/persisted-path-rows.d.ts +0 -88
  200. package/dist/core/runner/persisted-path-rows.js +0 -108
@@ -19,7 +19,7 @@ export function prepareRunRefs(input) {
19
19
  const sinkWired = internals?.onForwardEvent !== undefined;
20
20
  const forwardEvent = sinkWired
21
21
  ? (e) => {
22
- if (e.type === "task_progress")
22
+ if (e.type === "task_progress" || e.type === "task_started")
23
23
  forwardSafely(internals, e);
24
24
  else if (spec.forwardSubagentEvents === true &&
25
25
  (e.type === "text_delta" || e.type === "text_end" || e.type === "reasoning_delta" || e.type === "tool_start" || e.type === "tool_progress" || e.type === "tool_end")) {
@@ -20,7 +20,7 @@ import { modePolicyOf, modeRequestAfterResume, refusePermissionModeDoors } from
20
20
  import { resolveOutputStyleFrame } from "../output-style.js";
21
21
  import { recordedModeSeed } from "../checkpoint-store.js";
22
22
  import { emitTrace } from "../trace.js";
23
- import { persistedPathRowsOfTask, ruleRowsDroppedNotice, ruleStoreUnreadableNotice } from "./persisted-path-rows.js";
23
+ import { personPathRowsOfTask, ruleRowsDroppedNotice, ruleStoreUnreadableNotice } from "./person-path-rows.js";
24
24
  import { STALL_FIRST_BYTE_MS, STALL_FIRST_TOKEN_MS, STALL_IDLE_MS, withBrainCallGuardrail } from "../../brain/timeout.js";
25
25
  import { OFFLOAD_TOOL_NAME } from "../tool-result-store.js";
26
26
  import { OUTPUT_TOOL_NAME, SKILL_TOOL_NAME, createOutputTool } from "./synthetic-tools.js";
@@ -102,6 +102,7 @@ import { AdvertisedWritableDirs } from "./advertised-writable-dirs.js";
102
102
  import { resolveTaskRootCanonical } from "./task-root-canonical.js";
103
103
  import { createStructuredProjector } from "./tool-output-projection.js";
104
104
  import { asThrownError, thrownText } from "../thrown-value.js";
105
+ import { createAttachmentDelivery, refuseUserAttachmentPathsWithoutWorkspace, screenUserAttachments } from "../user-attachment.js";
105
106
  function warnCompactionWindowHazard(tracer, spec, model, compModel, hostTaskId, overlay) {
106
107
  if (compModel === undefined)
107
108
  return;
@@ -291,6 +292,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
291
292
  const permissionModeSeat = refusePermissionModeDoors(spec);
292
293
  const outputStyleFrame = resolveOutputStyleFrame(spec.outputStyle);
293
294
  const allowedTools = screenAllowedToolsValue(spec.allowedTools, "TaskSpec.allowedTools");
295
+ const userAttachmentsSeat = screenUserAttachments(spec.userAttachments, { resumeLeg: resume !== undefined });
294
296
  const declaredModeAtDoor = (() => {
295
297
  const requested = modeRequestAfterResume(permissionModeSeat, recordedModeSeed(resume?.seed.inheritedGate), resume?.outcome);
296
298
  const ceiling = internals?.inheritedGate?.permissionModeCeiling?.current ?? internals?.inheritedGate?.permissionMode;
@@ -369,6 +371,8 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
369
371
  }
370
372
  const rollback = createRollbackStack((e) => deps.onError?.(e, { phase: "config", sessionId }));
371
373
  const { executionEnv, ownedEnvSeat, ownedEnvObservedAt, handsEnabled, taskRootInitial, placement } = await prepareExecutionEnv({ deps, spec, internals, resume, placementRootResolved, sessionId, forgetOnThrow, rollback });
374
+ if (!handsEnabled)
375
+ refuseUserAttachmentPathsWithoutWorkspace(userAttachmentsSeat);
372
376
  const externalContentTargetActive = executionEnv.externalContentTarget === true || resume?.seed.externalContentTarget === true;
373
377
  const abortController = new AbortController();
374
378
  if (spec.signal?.aborted)
@@ -443,19 +447,22 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
443
447
  const mountedMcpNow = mcpPool !== undefined ? () => mountedMcpOf({ declared: installedPreflight.mcp, roster: roster.tools, aggregateNames: new Set(mcp.tools.filter((t) => t.mcpRemoteName === undefined).map((t) => t.name)), pool: mcpPool.pool }) : undefined;
444
448
  const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, permissionMode, commitModeSeats, endModeCeiling, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, runClampSource, faceCheckpointSection, writeFaceCheckpointSection, skillGrantCheckpointSection, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, askSeat: doors.askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight: installedPreflight, pathRuleAnchors: { chainTop, onLeg: onLeg.chained }, checkpointSeat, checkpointScope, toolFaceSnapshot, mountsCallerTool, ...(mountedMcpNow !== undefined ? { mountedMcp: mountedMcpNow } : {}), promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, requestAllowedTools: allowedToolTables.request, 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: () => autoModeDeciderRef.current, autoModeDenialTracking: () => autoModeDenialTrackingRef.current, autoModeArming: () => autoModeArmingRef.current, agentForkDenial: () => agentForkDenial, observersActive: () => observersActive, resolvedReadFace: () => resolvedReadFace, resolvedWriteFace: () => resolvedWriteFace, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized, handsLessResolvedFace: () => handsLessResolvedFace, handsLessResolvedWriteFace: () => handsLessResolvedWriteFace, centerAdoption: () => centerAdoptionRef.current, memoryEngineSession: () => memoryEngineSession });
445
449
  bindPermissionModeSeat(permissionMode);
446
- const announceRuleStoreSkipped = ruleStoreUnreadableNotice(deps.onNotice, { sessionId, runId });
447
- const announceRuleRowsDropped = ruleRowsDroppedNotice(deps.onNotice, { sessionId, runId });
448
- const persistedPathRowsRead = persistedPathRowsOfTask({ deps, principal: spec.principal, sessionId, root: taskRootFinal, rootCanonical: taskRootCanonical, leads: headLeads, chainTop, taskId: hostTaskId, handsEnabled, onRowsDropped: announceRuleRowsDropped, signals: [abortController.signal, ...(spec.signal !== undefined ? [spec.signal] : [])], onUnread: announceRuleStoreSkipped });
449
- const persistedPathRows = persistedPathRowsRead === undefined ? { readDirectories: [], denyRows: [] } : await persistedPathRowsRead;
450
+ const personRowNotices = { onUnread: ruleStoreUnreadableNotice(deps.onNotice, { sessionId, runId }), onRowsDropped: ruleRowsDroppedNotice(deps.onNotice, { sessionId, runId }) };
451
+ const readerOf = (signals) => personPathRowsOfTask({ deps, notices: personRowNotices, principal: spec.principal, ids: { sessionId, runId, taskId: hostTaskId }, root: taskRootFinal, rootCanonical: taskRootCanonical, leads: headLeads, chainTop, occurrences: toolOccurrences, signals });
452
+ const personRows = readerOf([abortController.signal, ...(spec.signal !== undefined ? [spec.signal] : [])]);
453
+ const personRowsBeyondRun = readerOf([]);
454
+ const primed = handsEnabled ? personRows.prime() : undefined;
455
+ if (primed !== undefined)
456
+ await primed;
450
457
  const policyDenyRows = toolPolicyPathRules([installedToolPolicy, ...(inheritedParentConstraints ?? []).map((c) => c.policy)], legAnchors).filter((r) => r.faces.length > 0 && r.behavior === "deny");
451
458
  for (const r of policyDenyRows)
452
459
  if (r.unanchored !== undefined)
453
460
  emitTrace(deps.tracer, () => ({ kind: "permission.rule_store_unreadable", version: 1, taskId: hostTaskId, message: `the deny rule ${r.rule} needs a ${r.unanchored.join(" / ")} base this task does not declare — the shell's file commands and the search tools do not judge it on this leg (the gate asks)`, ts: Date.now() }));
454
- const effectivePathDenyRules = [...policyDenyRows.filter((r) => r.unanchored === undefined), ...persistedPathRows.denyRows];
461
+ const effectivePathDenyRules = policyDenyRows.filter((r) => r.unanchored === undefined);
455
462
  const writeTargetJudgeRef = {};
456
463
  const legExemptRoots = Object.freeze(dataRootSpellings(deps.memoryEngineDir));
457
464
  const legWriteGuard = { exemptRoots: legExemptRoots, rows: toolPolicyWriteGuardRows([installedToolPolicy, ...(inheritedParentConstraints ?? []).map((c) => c.policy)]) };
458
- const { roster, blockedRef, runtimeCaps, runtimeCapsFaulted, complianceDenies, complianceDegraded, agentForkDenial, observersActive, autoModeArmReason, autoModeDeciderRef, autoModeDenialTrackingRef, autoModeArmingRef, armAutoMode, selfOrchestrationActive, workflowToolsActive, workflowSizeGuideline } = await prepareCapsAndWorkflow({ spec, deps, askSeat: doors.askSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, checkpointSeat, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, parentSpecSeat, runClampSource, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, permissionMode, readDenyEntries: () => ({ entries: readDenyMatcher?.entries ?? [], ruleRows: effectivePathDenyRules }), peerLaneActive, peerSendMessageBuiltIn, runnerSelf, memoryEngineSession: () => memoryEngineSession, centerAdoption: () => centerAdoptionRef.current, delegated: delegation.isDelegatedChild });
465
+ const { roster, blockedRef, runtimeCaps, runtimeCapsFaulted, complianceDenies, complianceDegraded, agentForkDenial, observersActive, autoModeArmReason, autoModeDeciderRef, autoModeDenialTrackingRef, autoModeArmingRef, armAutoMode, selfOrchestrationActive, workflowToolsActive, workflowSizeGuideline } = await prepareCapsAndWorkflow({ spec, deps, askSeat: doors.askSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, checkpointSeat, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, parentSpecSeat, runClampSource, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, permissionMode, readDenyEntries: () => personRows.tablesReady().then(() => ({ entries: readDenyMatcher?.entries ?? [], ruleRows: pathTables?.ruleRows() ?? effectivePathDenyRules })), peerLaneActive, peerSendMessageBuiltIn, runnerSelf, memoryEngineSession: () => memoryEngineSession, centerAdoption: () => centerAdoptionRef.current, delegated: delegation.isDelegatedChild });
459
466
  const tools = roster.tools;
460
467
  const pausedRef = {};
461
468
  const undeliveredContinuationRef = { current: { parkedSteers: [], orphanTasks: [] } };
@@ -594,9 +601,10 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
594
601
  if (internals?.ownOrgAdmissionRef !== undefined && ownOrgVerdictRef.current !== undefined) {
595
602
  internals.ownOrgAdmissionRef.current = ownOrgVerdictRef.current;
596
603
  }
597
- const handsReadFaceInput = { permissionMode, denyRuleRows: effectivePathDenyRules, headLeads, writeTargetJudge: () => writeTargetJudgeRef.current, persistedReadDirectories: persistedPathRows.readDirectories, handsEnabled, executionEnv, taskRootFinal, taskRootCanonical, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGate, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, harnessRef, toolProgressRef, toolOccurrences, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
604
+ const modelFileReaderSeat = {};
605
+ const handsReadFaceInput = { permissionMode, denyRuleRows: effectivePathDenyRules, headLeads, writeTargetJudge: () => writeTargetJudgeRef.current, personRows, handsEnabled, executionEnv, taskRootFinal, taskRootCanonical, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGate, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, modelFileReaderSeat, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, harnessRef, toolProgressRef, toolOccurrences, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
598
606
  const handsReadFace = handsEnabled ? await prepareHandsMount(handsReadFaceInput) : resolveHandsLessReadFace(handsReadFaceInput);
599
- const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive, shellReadCheck, shellReadAdmission, additionalRootsCanonical, additionalReadRootsCanonical, attachmentRootCanonical, readDenyMatcher, envHandToolNames, sealReadStateSeat } = handsReadFace;
607
+ const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive, shellReadCheck, shellReadAdmission, additionalRootsCanonical, attachmentRootCanonical, readDenyMatcher, readRoots, pathTables, envHandToolNames, sealReadStateSeat } = handsReadFace;
600
608
  resolvedReadFace = handsReadFace.resolvedReadFace;
601
609
  resolvedWriteFace = handsReadFace.resolvedWriteFace;
602
610
  readDenyAdditionsNormalized = handsReadFace.readDenyAdditionsNormalized;
@@ -623,8 +631,8 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
623
631
  deps.onError?.(new Error(`Fork DENIED for principal "${spec.principal ?? ""}" by runtimeCaps.allowFork=false ` +
624
632
  `(per-principal entitlement governance, not a misconfiguration — Agent(subagent_type:"fork") will refuse honestly)`), { phase: "config", sessionId });
625
633
  }
626
- const { lspDiagnostics, nudgeLspOnEdit, lspRunIdent, managerWired: lspManagerWired } = prepareLsp({ spec, deps, executionEnv, taskRootFinal, handsEnabled, sessionId, handsCwdRef, roster, envHandToolNames });
627
- prepareArtifact({ deps, runId, taskId: hostTaskId, sessionId, agentName: internals?.explicitAgentName, onAsk: frozenOnAsk, toolOccurrences, permissionMode, executionEnv, rootCanonical: attachmentRootCanonical, additionalRootsCanonical: () => [...additionalRootsCanonical, ...additionalReadRootsCanonical], readDenyMatcher, resolvedReadFace, handsCwdRef, roster, firstPartyOffload, envHandToolNames, ...(handsReadFace.artifactStoreRef !== undefined ? { artifactStoreRef: handsReadFace.artifactStoreRef } : {}) });
634
+ const { lspDiagnostics, nudgeLspOnEdit, withheldDiagnosticsOf, lspRunIdent, managerWired: lspManagerWired } = prepareLsp({ spec, deps, executionEnv, taskRootFinal, readFace: attachmentRootCanonical !== undefined ? { rootCanonical: attachmentRootCanonical, roots: readRoots, ready: personRows.tablesReady, ...(handsCwdRef !== undefined ? { cwdRef: handsCwdRef } : {}), ...(readDenyMatcher !== undefined ? { readDeny: readDenyMatcher } : {}), ...(resolvedReadFace !== undefined ? { face: resolvedReadFace } : {}), ...(handsReadFace.readAdmission !== undefined ? { admitted: handsReadFace.readAdmission } : {}) } : undefined, sessionId, roster, envHandToolNames });
635
+ prepareArtifact({ deps, runId, taskId: hostTaskId, sessionId, agentName: internals?.explicitAgentName, onAsk: frozenOnAsk, toolOccurrences, permissionMode, executionEnv, rootCanonical: attachmentRootCanonical, additionalRootsCanonical: readRoots, readDenyMatcher, resolvedReadFace, handsCwdRef, roster, firstPartyOffload, envHandToolNames, ...(handsReadFace.artifactStoreRef !== undefined ? { artifactStoreRef: handsReadFace.artifactStoreRef } : {}) });
628
636
  if (internals?.delegationProvenance !== undefined && resume !== undefined) {
629
637
  const live = internals.delegationProvenance.ref.current;
630
638
  const seed = resume.seed.delegationProvenance;
@@ -650,7 +658,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
650
658
  }
651
659
  const projectContext = await prepareProjectContext({ deps, spec, internals, session, sessionId, hostTaskId, taskRootFinal, handsEnabled, delegation, seedContextFiles, memoryBlockFromEngine, skillGrants, allowedTools, allowedToolTables, roster, toolFaceSnapshot, onceLedger, memoryTools, memoryEngineSession, memorySearchToolsPlanned, memoryPairExcludedName, memoryPairOccupiedName, resume, skillListingBudget: doors.skillListingBudget });
652
660
  const { memoryBlock: memoryBlockWithProject, instructionSources, projectInstructionContent, skillSpecs, skillSeatOf, skillsListing, sharedMemoryPairMounted, memoryEnginePairMounted } = projectContext;
653
- const { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef } = await preparePromptInputs({ 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, sessionId, session, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}) });
661
+ const { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef } = await preparePromptInputs({ 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 } : {}) });
654
662
  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, ownWhere: internals?.ownToolListsWhere, onceLedger, sessionId });
655
663
  const { deferred, memoryBlock, toolSearch: toolSearchPolicy } = prepareDeferClassify({ spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryBlock: memoryBlockWithProject, memoryRecallSegment, onceLedger, sessionId });
656
664
  prepareMemoryEngineSession({ memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mcp, ...(mountedMcpNow !== undefined ? { mountedMcp: mountedMcpNow } : {}), sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef });
@@ -763,7 +771,7 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
763
771
  releaseSignal = () => sig.removeEventListener("abort", onExternalAbort);
764
772
  }
765
773
  }
766
- const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, grantBindingOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight: installedPreflight, pathRuleAnchors: { leg: legAnchors, chainTop }, headLeads, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, announceRuleStoreSkipped, announceRuleRowsDropped, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider: () => autoModeDeciderRef.current, readFace: () => resolvedReadFace, permissionMode, scratchpadDir: spec.envFacts?.scratchpadDir, toolRosterDeltas: rosterSeat, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
774
+ const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, grantBindingOf, permissionRuleLane, ruleLanesBeyondRun, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight: installedPreflight, pathRuleAnchors: { leg: legAnchors, chainTop }, headLeads, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, personRows, personRowsBeyondRun, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider: () => autoModeDeciderRef.current, readFace: () => resolvedReadFace, permissionMode, scratchpadDir: spec.envFacts?.scratchpadDir, toolRosterDeltas: rosterSeat, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
767
775
  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, hooks, preToolUseObservational, 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 });
768
776
  const writeProtectionCheck = writeProtection.mount?.check;
769
777
  writeTargetJudgeRef.current = writeProtection.judgeWriteTarget;
@@ -781,13 +789,13 @@ export async function prepareTask(request, deps, sessions, resume, internals, ru
781
789
  const { suspendForResource, suspendForPlatformLimit, suspendForReview } = prepareBoundaryParks({ saga, spec, checkpointStore, checkpointScope, abortController, harness, session, sessions, sessionId, deps, priorLedger, maxSlices, maxSuspends, resourceTotal, priorSuspendCount, suspendChainBase, humanReviewRef, liveSpendRef, now, pausedRef, remoteEnvFailures, resourceSuspendEligible, durableSuspendInfraReady, incompleteSuspendAdapter });
782
790
  const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, checkpointScope, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, handsRoot: attachmentRootCanonical, stampCallTarget, advertisedWritableDirs, exemptRoots: legExemptRoots, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, toolMarkSources, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, ruleOffersOf, grantBindingOf, now, humanReviewRef, abortController, harness, pausedRef });
783
791
  const seatInputsFor = skillGateWiring({ tools, skillToolName: SKILL_TOOL_NAME, seatOf: skillSeatOf, mode: () => permissionMode.current, lane: skillGrantLane, onAllowed: (info) => emitTrace(deps.tracer, () => ({ kind: "permission.skill_allowed", version: 1, taskId: hostTaskId, ...info, entries: [...info.entries], ts: Date.now() })), allowEntries: { deploymentAllows: { ...allowEntryLanes.deployment, onAllowed: (info) => emitTrace(deps.tracer, () => ({ kind: "permission.allowed_tools_allowed", version: 1, taskId: hostTaskId, source: "deployment", ...info, entries: [...info.entries], ts: Date.now() })) }, requestAllows: { ...allowEntryLanes.request, onAllowed: (info) => emitTrace(deps.tracer, () => ({ kind: "permission.allowed_tools_allowed", version: 1, taskId: hostTaskId, source: "request", ...info, entries: [...info.entries], ts: Date.now() })) } } });
784
- const { approvedCallScreen } = prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, toolOccurrences, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, stampCallTarget, readDenyInForce: () => ({ tiers: handsReadFace.readDenyBuiltinTiersActive, rows: [...readDenyAdditionsNormalized.map((e) => e.pattern), ...handsReadFaceInput.denyRuleRows.filter((r) => r.faces.includes("read")).map((r) => r.rule)] }), hookEnvFace, writeProtectionCheck, shellReadCheck, readFace: () => resolvedReadFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider: autoModeDeciderRef, autoModeDenialTracking: autoModeDenialTrackingRef, askRoute: { ...wiringManifest.ask, effective: askSeatEffective(wiringManifest) }, permissionMode, toolMarkSources, ...(deps.a2a?.isolatePeers === true ? { a2aIsolatePeers: true } : {}), ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, seatInputsFor, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash, frameSettlement });
792
+ const { approvedCallScreen } = prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, toolOccurrences, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, stampCallTarget, readDenyInForce: (toolCallId) => ({ tiers: handsReadFace.readDenyBuiltinTiersActive, rows: [...readDenyAdditionsNormalized.map((e) => e.pattern), ...(pathTables?.forCall(toolCallId).ruleRows ?? handsReadFaceInput.denyRuleRows).filter((r) => r.faces.includes("read")).map((r) => r.rule)] }), hookEnvFace, writeProtectionCheck, shellReadCheck, readFace: () => resolvedReadFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider: autoModeDeciderRef, autoModeDenialTracking: autoModeDenialTrackingRef, askRoute: { ...wiringManifest.ask, effective: askSeatEffective(wiringManifest) }, permissionMode, toolMarkSources, ...(deps.a2a?.isolatePeers === true ? { a2aIsolatePeers: true } : {}), ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, seatInputsFor, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash, frameSettlement });
785
793
  const postureFrameRef = { report: (err) => deps.onError?.(err, { phase: "degraded", sessionId }) };
786
794
  const { microCompact, charsPerToken } = prepareContextLane({ model, deps, sessionId, runId, hostTaskId, offloadStore, toolRosterDeltas: rosterSeat, microCompactKnob, harness, batchHaltRef, gitStatusRef, postureFrameRef, requestLossyRef, trimPressureRef, contextOverlay: legContextOverlay, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}) });
787
795
  const preparedHolder = {};
788
- const { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved } = prepareTurnWiring({ deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, additionalRootsCanonical, additionalReadRootsCanonical, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, skillGrants: skillGrantLane, callerPolicy: installedToolPolicy, inheritedPolicies: (inheritedParentConstraints ?? []).map((c) => c.policy), persistedRuleLane: permissionRuleLane, orgRuleLane: permissionRuleOrgLane, stampCallTarget, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder });
796
+ const { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, syntheticReadVerdict, syntheticWriteVerdict, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved } = prepareTurnWiring({ deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, readRoots, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, skillGrants: skillGrantLane, callerPolicy: installedToolPolicy, inheritedPolicies: (inheritedParentConstraints ?? []).map((c) => c.policy), persistedRuleLane: permissionRuleLane, ruleLanesBeyondRun, orgRuleLane: permissionRuleOrgLane, stampCallTarget, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder });
789
797
  await onceLedger.settle(session, announcedListingsRef);
790
- const buildPrepared = () => ({ harness, session, sessionId, runId, registryAccess: { owner: hostTaskId, scope: taskScope }, reminderMark, reminderDisclosureCounts, fullShellReachable, approvalPosture: { get mode() { return permissionMode.current; }, askEffective: askSeatEffective(wiringManifest) }, ...(outputStyleFrame !== undefined ? { outputStyleFrame } : {}), permissionMode, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(mcpRedial !== undefined ? { mcpRedial } : {}), ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, toolOccurrences, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(attachmentRootCanonical !== undefined ? { handsRoot: attachmentRootCanonical } : {}), ...(stampCallTarget !== undefined ? { stampCallTarget } : {}), toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), exemptRoots: legExemptRoots, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, skillGrants: skillGrantLane, skillSpecs, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, endModeCeiling, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, stopForDenialLimit, suspendForReview, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}), resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, frameSettlement, ...(peerLaneRefs.boundaryRound !== undefined ? { peerBoundaryRound: peerLaneRefs.boundaryRound } : {}), gitStatusRef, postureFrameRef, listBackgroundTasks, hookIdentity, ...(sessionBoxBound !== undefined ? { sessionBox: sessionBoxBound } : {}), hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}), ...(approvedCallScreen !== undefined ? { approvedCallScreen } : {}) });
798
+ const buildPrepared = () => ({ harness, session, sessionId, runId, registryAccess: { owner: hostTaskId, scope: taskScope }, reminderMark, reminderDisclosureCounts, fullShellReachable, approvalPosture: { get mode() { return permissionMode.current; }, askEffective: askSeatEffective(wiringManifest) }, ...(outputStyleFrame !== undefined ? { outputStyleFrame } : {}), permissionMode, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(mcpRedial !== undefined ? { mcpRedial } : {}), ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, toolOccurrences, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(attachmentRootCanonical !== undefined ? { handsRoot: attachmentRootCanonical } : {}), ...(stampCallTarget !== undefined ? { stampCallTarget } : {}), toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), exemptRoots: legExemptRoots, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, skillGrants: skillGrantLane, skillSpecs, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), syntheticWriteVerdict, ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, endModeCeiling, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, stopForDenialLimit, suspendForReview, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}), resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit && withheldDiagnosticsOf ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent, withheldOf: withheldDiagnosticsOf } } : {}), stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, frameSettlement, ...(userAttachmentsSeat !== undefined ? { userAttachments: userAttachmentsSeat } : {}), attachmentDelivery: createAttachmentDelivery(), ...(modelFileReaderSeat.current !== undefined ? { modelFileReader: modelFileReaderSeat.current } : {}), syntheticReadVerdict, ...(peerLaneRefs.boundaryRound !== undefined ? { peerBoundaryRound: peerLaneRefs.boundaryRound } : {}), gitStatusRef, postureFrameRef, listBackgroundTasks, hookIdentity, ...(sessionBoxBound !== undefined ? { sessionBox: sessionBoxBound } : {}), hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}), ...(approvedCallScreen !== undefined ? { approvedCallScreen } : {}) });
791
799
  refuseLateRosterChanges(callerRoster.roster);
792
800
  rollback.commit();
793
801
  commitModeSeats(abortController.signal);
@@ -7,11 +7,12 @@ import { type TurnPromptSnapshot } from "../../prompt-assembly/turn-snapshot.js"
7
7
  import type { PromptTextDeclaration } from "../../prompts/default.js";
8
8
  import { CacheBreakDetector, type ToolFingerprintInput } from "../cache-break-detector.js";
9
9
  import type { ToolPolicy } from "../tool-policy.js";
10
- import { type SyntheticReadJudge } from "../synthetic-read-verdict.js";
10
+ import { type SyntheticReadJudge, type SyntheticWriteJudge } from "../synthetic-read-verdict.js";
11
11
  import type { RunnerDeps, TaskSpec } from "../types.js";
12
12
  import type { CwdRef } from "../../tools/fs/fs-shared.js";
13
13
  import { type ContainmentFace } from "../../tools/fs/index.js";
14
14
  import type { PlacedReadDenyMatcher } from "../../tools/fs/read-deny-home.js";
15
+ import type { ReadRootsSeat } from "./person-path-rows.js";
15
16
  import { type ReadFileState } from "../../tools/fs/safety.js";
16
17
  import type { Prepared } from "./contracts.js";
17
18
  export interface PrepareTurnWiringInput {
@@ -66,11 +67,10 @@ export interface PrepareTurnWiringInput {
66
67
  executionEnv: ExecutionEnv;
67
68
  /** borrowed-readonly — the canonical attachment root, or undefined (the readers' containment fence). */
68
69
  attachmentRootCanonical: string | undefined;
69
- /** borrowed-readonly — the canonical extra write roots (the fence's root set). */
70
- additionalRootsCanonical: ReadonlyArray<string>;
71
- /** borrowed-readonly — the canonical extra read roots (the fence's root set). */
72
- additionalReadRootsCanonical: ReadonlyArray<string>;
73
- /** borrowed-readonly — the compiled read-deny judge, or undefined (the reader's withheld arm). */
70
+ /** borrowed-readonly — the read face's root set beside the attachment root, read per use: the write roots, the read
71
+ * roots with the run's grants, the person's read directories as the run read them last (no call: `ready` first). */
72
+ readRoots: (() => readonly string[]) & Pick<ReadRootsSeat, "ready">;
73
+ /** borrowed-readonly — the run's read deny table (its latest; these readers are no call), or undefined (the reader's withheld arm). */
74
74
  readDenyMatcher: PlacedReadDenyMatcher | undefined;
75
75
  /** borrowed-readonly — the resolved read face, or undefined (the fence's ninth argument). */
76
76
  resolvedReadFace: ContainmentFace | undefined;
@@ -90,6 +90,11 @@ export interface PrepareTurnWiringInput {
90
90
  inheritedPolicies: readonly ToolPolicy[];
91
91
  /** borrowed-readonly — the person's persisted-rule lane, or undefined (a layer of the judge). */
92
92
  persistedRuleLane: Prepared["persistedRuleLane"];
93
+ /** borrowed-readonly — the person's and the org's lanes over the reader the run's cut does not end (the write face is asked after it). */
94
+ ruleLanesBeyondRun: {
95
+ readonly personal: Prepared["persistedRuleLane"];
96
+ readonly org: Prepared["permissionRuleOrg"];
97
+ };
93
98
  /** borrowed-readonly — the org rule lane, or undefined (a layer of the judge). */
94
99
  orgRuleLane: Prepared["permissionRuleOrg"];
95
100
  /** borrowed-readonly — the leg's target-reading stamp, or undefined (hands-less): the visibility judge stamps its request. */
@@ -157,6 +162,8 @@ export interface PrepareTurnWiringResult {
157
162
  /** owned — the run's ONE synthetic-Read deny judge over every layer that can refuse a model's `Read` (the
158
163
  * changed-files door reads it; a face that delivers a file the model did not ask for reads the same one). */
159
164
  syntheticReadVerdict: SyntheticReadJudge;
165
+ /** owned — the same layers' WRITE face (`Prepared.syntheticWriteVerdict`): an `ask` is an objection there. */
166
+ syntheticWriteVerdict: SyntheticWriteJudge;
160
167
  /** owned — the post-compact background-task listing (`Prepared.listBackgroundTasks`). */
161
168
  listBackgroundTasks: Prepared["listBackgroundTasks"];
162
169
  /** owned — the compaction-boundary center adoption candidate, or undefined (no source, or no adoption). */
@@ -4,7 +4,8 @@ import { artifactDeclarations } from "../../prompt-assembly/artifact.js";
4
4
  import { buildTurnPromptSnapshot } from "../../prompt-assembly/turn-snapshot.js";
5
5
  import { CacheBreakDetector, toolsToFingerprintInputs } from "../cache-break-detector.js";
6
6
  import { defaultTaskRegistry } from "../task-registry.js";
7
- import { createSyntheticReadJudge } from "../synthetic-read-verdict.js";
7
+ import { createSyntheticReadJudge, createSyntheticWriteJudge } from "../synthetic-read-verdict.js";
8
+ import { toolCallFaceOf } from "../tool-roster.js";
8
9
  import { ORG_ADJUDICATION_TIMEOUT_MS } from "../permission-rule-org.js";
9
10
  import { decodeTextBytes } from "../../tools/fs/encoding.js";
10
11
  import { applyContextShrinkToReadFileState, isReadDedupStubResult } from "../../tools/fs/index.js";
@@ -13,7 +14,7 @@ import { PROMPT_HASH_SALT } from "./prompt-hash-salt.js";
13
14
  import { CHANGED_FILES_MTIME_EPS_MS } from "./turn-attachments.js";
14
15
  import { thrownText } from "../thrown-value.js";
15
16
  export function prepareTurnWiring(input) {
16
- const { 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, skillGrants, callerPolicy, inheritedPolicies, persistedRuleLane, orgRuleLane, stampCallTarget, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder } = input;
17
+ const { deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, readRoots, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, skillGrants, callerPolicy, inheritedPolicies, persistedRuleLane, ruleLanesBeyondRun, orgRuleLane, stampCallTarget, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder } = input;
17
18
  const cacheBreakDetector = deps.cacheBreakDetection === false ? undefined : new CacheBreakDetector();
18
19
  const cacheFingerprint = cacheBreakDetector
19
20
  ? { systemPrompt: systemPromptSeat.current, tools: toolsToFingerprintInputs(harnessTools) }
@@ -51,7 +52,10 @@ export function prepareTurnWiring(input) {
51
52
  try {
52
53
  let key = path;
53
54
  if (attachmentRootCanonical !== undefined) {
54
- const rk = await resolveKey(executionEnv, attachmentRootCanonical, path, undefined, undefined, [...additionalRootsCanonical, ...additionalReadRootsCanonical], undefined, readDenyMatcher, resolvedReadFace);
55
+ await readRoots.ready(abortController.signal);
56
+ if (abortController.signal.aborted)
57
+ return null;
58
+ const rk = await resolveKey(executionEnv, attachmentRootCanonical, path, abortController.signal, undefined, readRoots(), undefined, readDenyMatcher, resolvedReadFace);
55
59
  if (!rk.ok) {
56
60
  announceAttachmentSkip(path, rk.violation.message);
57
61
  if (rk.violation.code === "read_path_denied" && rk.violation.pattern !== undefined) {
@@ -61,7 +65,7 @@ export function prepareTurnWiring(input) {
61
65
  }
62
66
  key = rk.key;
63
67
  }
64
- const r = await executionEnv.readBinaryFile(key);
68
+ const r = await executionEnv.readBinaryFile(key, abortController.signal);
65
69
  if (!r.ok) {
66
70
  announceAttachmentSkip(path, r.error.message);
67
71
  return null;
@@ -84,7 +88,10 @@ export function prepareTurnWiring(input) {
84
88
  if (attachmentRootCanonical === undefined)
85
89
  return path;
86
90
  try {
87
- const rk = await resolveKey(executionEnv, attachmentRootCanonical, path, undefined, handsCwdRef?.current, [...additionalRootsCanonical, ...additionalReadRootsCanonical], undefined, undefined, resolvedReadFace);
91
+ await readRoots.ready(abortController.signal);
92
+ if (abortController.signal.aborted)
93
+ return path;
94
+ const rk = await resolveKey(executionEnv, attachmentRootCanonical, path, abortController.signal, handsCwdRef?.current, readRoots(), undefined, undefined, resolvedReadFace);
88
95
  return rk.ok ? rk.key : path;
89
96
  }
90
97
  catch {
@@ -102,7 +109,7 @@ export function prepareTurnWiring(input) {
102
109
  const onCompactionApplied = handsEnabled && readFileStateForCheckpoint
103
110
  ? (attachedComplete, preserveReadState) => applyContextShrinkToReadFileState(readFileStateForCheckpoint, { kind: "summarized", attachedComplete, ...(preserveReadState !== undefined ? { preserveKeys: preserveReadState } : {}) })
104
111
  : undefined;
105
- const syntheticReadVerdict = createSyntheticReadJudge({
112
+ const syntheticLayers = {
106
113
  skillGrants,
107
114
  ...(denyNarrowingPolicy !== undefined ? { denyNarrowingPolicy } : {}),
108
115
  ...(callerPolicy !== undefined ? { callerPolicy } : {}),
@@ -110,7 +117,11 @@ export function prepareTurnWiring(input) {
110
117
  ...(persistedRuleLane !== undefined ? { persistedRuleLane } : {}),
111
118
  ...(orgRuleLane !== undefined ? { orgRuleLane } : {}),
112
119
  ...(stampCallTarget !== undefined ? { stampCallTarget } : {}),
113
- signal: abortController.signal,
120
+ };
121
+ const syntheticReadVerdict = createSyntheticReadJudge({ ...syntheticLayers, signal: abortController.signal });
122
+ const syntheticWriteVerdict = createSyntheticWriteJudge({ ...syntheticLayers, ...(ruleLanesBeyondRun.personal !== undefined ? { persistedRuleLane: ruleLanesBeyondRun.personal } : {}), ...(ruleLanesBeyondRun.org !== undefined ? { orgRuleLane: ruleLanesBeyondRun.org } : {}) }, () => {
123
+ const p = preparedHolder.current;
124
+ return { face: toolCallFaceOf(p?.toolRoster, "Write"), cwd: p?.cwdRef?.current, root: p?.handsRoot, advertisedWritableDirs: p?.advertisedWritableDirs, exemptRoots: p?.exemptRoots };
114
125
  });
115
126
  const changedFilesReadDenied = async (paths) => {
116
127
  const deadlineAt = Date.now() + ORG_ADJUDICATION_TIMEOUT_MS;
@@ -204,5 +215,5 @@ export function prepareTurnWiring(input) {
204
215
  const effectiveReadFaceObserved = carrierReadFace();
205
216
  const effectiveWriteFaceObserved = carrierWriteFace();
206
217
  const effectiveReadDenyObserved = readDenyAdditionsNormalized.length > 0 ? readDenyAdditionsNormalized.map((e) => ({ ...e })) : undefined;
207
- return { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, syntheticReadVerdict, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved };
218
+ return { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, syntheticReadVerdict, syntheticWriteVerdict, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved };
208
219
  }
@@ -1,40 +1,16 @@
1
1
  /** The run's IN-FLIGHT read-root grant: the one place a screened grant ({@link ReadRootGrantScreen}) widens this run's
2
2
  * read directories (through the hands phase's {@link GrantReadRoot}, built by {@link readRootGrantOver}), the one
3
- * composer of the two notices, and the home of the store-isolation rule both root admission points judge by (the
4
- * Artifact phase's mount and the grant) — machinery both phases reach down for. */
3
+ * composer of the two notices; the grant judges by the store-isolation rule ({@link rootAdmittingArtifactStore}). */
5
4
  import type { ExecutionEnv } from "../../internal/harness.js";
6
5
  import type { ReadRootGrantCandidate } from "../types.js";
7
6
  import type { ReadRootGrantScreen } from "../read-root-grant-screen.js";
8
7
  import { type RunnerDeps } from "../types.js";
9
- /**
10
- * THE store-isolation rule, one judgment for every root admission point (the Artifact mount over the prepare-time
11
- * roots, an in-flight read-root grant over the granted root): a root that CONTAINS the local artifact store, lies
12
- * INSIDE it, or IS it hands the file tools the store's ledger and stored files. Returns the first such root, or
13
- * undefined.
14
- *
15
- * `storePhysical` is the store's physical path on THIS process's filesystem (`physicalPathOfExisting`, resolved
16
- * once per run by the Artifact phase); a root is the execution env's canonical key. The judgment touches no
17
- * filesystem — the grant runs after the approver's wait under the call's cut, and a synchronous lookup on a stalled
18
- * store mount would block the event loop past that cut. The two are compared as identities only when both spell the
19
- * same family (`within` reads both under the root's family); a root of the other family names a filesystem the store
20
- * cannot be on, and no claim is made against it.
21
- */
22
- export declare function rootAdmittingArtifactStore(storePhysical: string, rootsCanonical: readonly string[]): string | undefined;
23
8
  /** The run's cell holding the local artifact store a granted root must never admit (its physical path, as the
24
9
  * Artifact phase resolved it): minted with the grant by the hands phase, written by the Artifact phase (the one
25
10
  * reader of the hosting seat) once the declaration validates. */
26
11
  export interface ArtifactStoreRef {
27
12
  current: string | undefined;
28
- /** The person's STANDING read grants — their persisted `Read(//dir/**)` rows, joined to the live read set at prepare —
29
- * held to the in-flight grant's store rule by {@link withdrawStandingGrantsAdmitting} once the store is known. */
30
- standing?: {
31
- readonly keys: readonly string[];
32
- readonly readRoots: string[];
33
- };
34
13
  }
35
- /** The store rule applied to the standing grants: each one that admits `storePhysical` leaves the live read set (so no
36
- * read face reaches the store through it); returns the withdrawn keys, for the caller to announce. */
37
- export declare function withdrawStandingGrantsAdmitting(storePhysical: string, ref: ArtifactStoreRef): string[];
38
14
  /** Why the run's station applied no grant: the spelling did not resolve (or its lookup was cut), it no longer
39
15
  * resolves to itself (a directory swapped for a link while the card waited), or it would admit the local artifact
40
16
  * store (the store-isolation rule the Artifact phase judges its mount by). */
@@ -2,23 +2,7 @@ import { deliverEngineNotice } from "../types.js";
2
2
  import { READ_ROOT_CANDIDATE_DIR_MAX } from "../read-root-candidate.js";
3
3
  import { DEFAULT_GATE_AWAIT_TIMEOUT_MS } from "../gate-bounded-await.js";
4
4
  import { thrownText } from "../thrown-value.js";
5
- import { pathFamilyOf, withinAnyRoot } from "../../tools/fs/safety.js";
6
- export function rootAdmittingArtifactStore(storePhysical, rootsCanonical) {
7
- const storeFamily = pathFamilyOf({ root: storePhysical });
8
- return rootsCanonical.find((root) => pathFamilyOf({ root }) === storeFamily && (withinAnyRoot([root], storePhysical) || withinAnyRoot([storePhysical], root)));
9
- }
10
- export function withdrawStandingGrantsAdmitting(storePhysical, ref) {
11
- const standing = ref.standing;
12
- if (standing === undefined)
13
- return [];
14
- const withdrawn = standing.keys.filter((key) => rootAdmittingArtifactStore(storePhysical, [key]) !== undefined);
15
- for (const key of withdrawn) {
16
- const at = standing.readRoots.indexOf(key);
17
- if (at >= 0)
18
- standing.readRoots.splice(at, 1);
19
- }
20
- return withdrawn;
21
- }
5
+ import { rootAdmittingArtifactStore } from "../../tools/fs/safety.js";
22
6
  export function readRootGrantOver(seats) {
23
7
  const { env, writeRoots, readRoots, artifactStore } = seats;
24
8
  return async (candidate, signal) => {
@@ -1,7 +1,7 @@
1
1
  import type { RunnerDeps } from "../types.js";
2
2
  import type { ResumeTaskConfig, RunInternals } from "./contracts.js";
3
- /** Runs on the caller's own argument at `new Runner` (the only point that still sees an inherited or
4
- * non-enumerable seat — construction spreads deps into plain objects), and again in the pre-first-await
3
+ /** Runs on the caller's own argument at `new Runner` (the only point that still sees an inherited seat — construction then
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
7
  /** The resume ladder's pre-claim door: the retired seats of the deps, then the retired members of the caller policies this
@@ -6,7 +6,7 @@ import type { RunInternals, RunState } from "./contracts.js";
6
6
  export interface RunBrainSinksInput {
7
7
  /** borrowed-mutable — the run's event queue: the `status` frames. */
8
8
  queue: PushQueue<TaskEvent>;
9
- /** borrowed-readonly — the trusted run-scoped channel: `agentName` (the display name), `onStatusEvent` (the second sink). */
9
+ /** borrowed-readonly — the trusted run-scoped channel: `onStatusEvent` (the second sink). */
10
10
  internals: RunInternals | undefined;
11
11
  /** borrowed-readonly — the run's mutable state, read for the telemetry frames' tracer and task id. */
12
12
  rs: RunState;
@@ -16,16 +16,12 @@ export interface RunBrainSinksInput {
16
16
  parentToolCallId?: string;
17
17
  sourceTaskId?: string;
18
18
  };
19
- /** borrowed-readonly — the spawning tool call's id when this task runs AS A SUB-AGENT; absent on a top-level run. */
20
- parentToolCallId: string | undefined;
21
19
  /** borrowed-readonly — the reasoning lane's wire-facts consumer, the third sink the composition installs. */
22
20
  observeReasoningWireFacts: (facts: ReasoningWireFacts) => void;
23
21
  /** borrowed-readonly — the notice sink and the leg's ids; the fourth sink's announcer is minted from them. */
24
22
  notice: ExtraBodyDroppedSeatInput;
25
23
  }
26
24
  export interface RunBrainSinksResult {
27
- /** The subagent's human display name for its `task_progress` ticks, or undefined. */
28
- subagentName: string | undefined;
29
25
  /** Compose the three brain ALS sinks around a brain-driving call. */
30
26
  withBrainSinks: <T>(fn: () => Promise<T>) => Promise<T>;
31
27
  withExtraBodyDroppedSink: <T>(fn: () => Promise<T>) => Promise<T>;
@@ -2,10 +2,8 @@ import { runWithBrainTelemetry, runWithReasoningWireFacts, runWithStatusSink } f
2
2
  import { createExtraBodyDroppedScope } from "./extra-body-dropped-seat.js";
3
3
  import { createSafeNotifier, observeThenableRejection } from "../safe-notify.js";
4
4
  import { emitTrace } from "../trace.js";
5
- import { inlineUntrusted } from "../untrusted-text.js";
6
5
  export function runBrainSinks(input) {
7
- const { queue, internals, rs, ident, parentToolCallId, observeReasoningWireFacts, notice } = input;
8
- const subagentName = parentToolCallId !== undefined && internals?.agentName !== undefined ? inlineUntrusted(internals.agentName.slice(0, 320), 80) : undefined;
6
+ const { queue, internals, rs, ident, observeReasoningWireFacts, notice } = input;
9
7
  const statusSinkNotifier = createSafeNotifier({
10
8
  onError: (f) => console.warn(`[sema-core] ${f.site}: run-internals status sink threw (contained; further failures counted, not re-disclosed): ${f.error.message}`),
11
9
  });
@@ -62,5 +60,5 @@ export function runBrainSinks(input) {
62
60
  : { kind: "vision.placeholder", version: 1, taskId: rs.telemetry.taskId, count: t.count, ts: Date.now() });
63
61
  };
64
62
  const withBrainSinks = (fn) => runWithStatusSink(statusEmit, () => runWithBrainTelemetry(telemetryEmit, () => runWithReasoningWireFacts(observeReasoningWireFacts, fn)));
65
- return { subagentName, withBrainSinks, withExtraBodyDroppedSink: createExtraBodyDroppedScope(notice) };
63
+ return { withBrainSinks, withExtraBodyDroppedSink: createExtraBodyDroppedScope(notice) };
66
64
  }
@@ -1,5 +1,6 @@
1
1
  import { observeThenableRejection } from "../safe-notify.js";
2
2
  import { forwardSafely } from "./forward-sink.js";
3
+ import { emitsChildRowFrames } from "../delegation-frames.js";
3
4
  import { emitTrace } from "../trace.js";
4
5
  import { primaryActivityArg } from "../arg-summary.js";
5
6
  import { redactSecrets } from "../untrusted-egress.js";
@@ -22,8 +23,8 @@ export function createHarnessHandlers(input) {
22
23
  const toolCallIdFoldSeat = createToolCallIdFoldSeat(deps.runnerHooks.onNotice, { sessionId: prepared.sessionId, runId: prepared.runId });
23
24
  const toolTurnIncompleteSeat = createToolTurnIncompleteSeat(deps.runnerHooks.onNotice, { sessionId: prepared.sessionId, runId: prepared.runId });
24
25
  const finishReasonSeat = createFinishReasonSeat(deps.runnerHooks.onNotice, { sessionId: prepared.sessionId, runId: prepared.runId });
25
- const { spec, queue, internals, ident, parentToolCallId, subagentName, pushContent, emitCommitted, startedToolCallIds, toolStartAt, toolProgress, writeFamilyOf, toolLabels, postToolBatchHook, batchArgs, internalsNotifier } = deps;
26
- const frames = { push: (f) => pushContent({ ...f, ...ident() }), structured: prepared.structuredProjector };
26
+ const { spec, queue, internals, ident, pushContent, emitCommitted, startedToolCallIds, toolStartAt, toolProgress, writeFamilyOf, toolLabels, postToolBatchHook, batchArgs, internalsNotifier, mediaByteCapBytes } = deps;
27
+ const frames = { push: (f) => pushContent({ ...f, ...ident() }), structured: prepared.structuredProjector, mediaByteCapBytes };
27
28
  const startOf = (e) => {
28
29
  const label = toolLabels.get(e.toolName);
29
30
  return { toolCallId: e.toolCallId, spelledName: e.toolName, wireName: rosterToolName(prepared.toolRosterDeltas.current, e.toolName), ...(label !== undefined ? { label } : {}), args: e.args };
@@ -306,14 +307,14 @@ export function createHarnessHandlers(input) {
306
307
  rs.turn.turnUsageMissing = false;
307
308
  rs.turn.turnStopReason = undefined;
308
309
  rs.turn.turnResponseModel = undefined;
309
- if (parentToolCallId !== undefined) {
310
+ if (emitsChildRowFrames(prepared.hookIdentity)) {
310
311
  const progress = {
311
312
  type: "task_progress",
312
313
  taskId: rs.telemetry.taskId,
313
314
  ...(internals?.delegationTaskType !== undefined ? { taskType: internals.delegationTaskType } : {}),
314
315
  ...(internals?.cycleSeq !== undefined ? { seq: internals.cycleSeq } : {}),
315
316
  ...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
316
- ...(subagentName ? { name: subagentName } : {}),
317
+ ...(prepared.hookIdentity.agentName ? { name: prepared.hookIdentity.agentName } : {}),
317
318
  ...(internals?.explicitAgentName !== undefined ? { spawnName: internals.explicitAgentName } : {}),
318
319
  model: prepared.model.id,
319
320
  usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - rs.telemetry.taskStart },
@@ -8,14 +8,14 @@ import type { CaptureOptOutRef, LiveHandle, ManualCompactRef, McpRedialRef, Noti
8
8
  export interface RunIdentityWiringInput {
9
9
  /** borrowed-readonly — the task spec: the task id and the memory / notification seats it names. */
10
10
  spec: TaskSpec;
11
- /** borrowed-mutable — the run's event queue: the manifest, roster-delta, compaction_outcome and redelivered
12
- * task_notification frames. */
11
+ /** borrowed-mutable — the run's event queue: the manifest, roster-delta, task_started, compaction_outcome and
12
+ * redelivered task_notification frames. */
13
13
  queue: PushQueue<TaskEvent>;
14
14
  /** borrowed-mutable — the leg's prepared seat: the harness sinks (`onUndrainedEngineNotes`, `engineInjectionsHeld`,
15
15
  * `onUndrainedUserInputs`, `onEngineNoteConsumed`) are installed, `nextTurn` is appended to; the ids, the identity
16
16
  * envelope, the hold refs, the memory session and the listing / roster faces are read. */
17
17
  prepared: Prepared;
18
- /** borrowed-readonly — the trusted run-scoped channel: `parentToolCallId`, `onNotifyInjectorReady`. */
18
+ /** borrowed-readonly — the trusted run-scoped channel: `parentToolCallId`, `onNotifyInjectorReady`, the spawner's delegation facts. */
19
19
  internals: RunInternals | undefined;
20
20
  /** borrowed-mutable — the stream layer's backstop carrier: the memory scopes, the edited-files reader and the
21
21
  * owed delegation terminal are published here the moment they exist. */
@@ -58,7 +58,7 @@ export interface RunIdentityWiringResult {
58
58
  parentToolCallId?: string;
59
59
  sourceTaskId?: string;
60
60
  };
61
- /** The delegation-lifecycle emission closure both stations share (spawn here, terminal in the driver). */
61
+ /** The delegation-lifecycle emission closure both phases share (spawn here, terminal in the driver). */
62
62
  emitDelegationLifecycle: (event: import("../types.js").DelegationLifecycleEvent) => void;
63
63
  /** The loop-liveness latch and the two attribution seats (ended / userInterrupted / userHalted). */
64
64
  loopLatch: {
@@ -1,5 +1,7 @@
1
1
  import { uuidv7 } from "../../internal/harness.js";
2
2
  import { createSafeNotifier, observeThenableRejection } from "../safe-notify.js";
3
+ import { forwardSafely } from "./forward-sink.js";
4
+ import { emitsChildRowFrames, taskStartedFrame } from "../delegation-frames.js";
3
5
  import { recordFrameReceipt, toolResultReceiptKey } from "../frame-settlement.js";
4
6
  import { discloseDroppedPending, renderTaskNotificationXml, taskNotificationDedupKey } from "../task-notification.js";
5
7
  import { buildAppliedHumanInputEvent } from "../human-input-projection.js";
@@ -35,7 +37,12 @@ export function runIdentityWiring(input) {
35
37
  return;
36
38
  deliverDelegationLifecycle(runner.deps.onDelegationLifecycle, event, delegationLifecycleNotifier, "runtask.onDelegationLifecycle");
37
39
  };
38
- emitDelegationLifecycle({ phase: "spawn", identity: prepared.hookIdentity });
40
+ if (emitsChildRowFrames(prepared.hookIdentity) && prepared.hookIdentity.legKind !== "resume") {
41
+ const started = taskStartedFrame({ taskId: runSourceTaskId, sessionId: prepared.sessionId, model: prepared.model.id, identity: prepared.hookIdentity }, internals, ident());
42
+ queue.push(started);
43
+ forwardSafely(internals, started);
44
+ emitDelegationLifecycle({ phase: "spawn", identity: prepared.hookIdentity });
45
+ }
39
46
  if (taskIdRef !== undefined && prepared.hookIdentity.isDelegatedChild && runner.deps.onDelegationLifecycle !== undefined) {
40
47
  taskIdRef.delegationTerminalOwed = prepared.hookIdentity;
41
48
  }
@@ -79,6 +86,8 @@ export function runIdentityWiring(input) {
79
86
  queue.push({ ...buildAppliedHumanInputEvent({ carrier: "steer", source: "steer", sessionSeq: nextHumanInputSeq(prepared.harness), inputId: steer.inputId, actor: steer.actor, principal: spec.principal }), eventId: uuidv7(), ...identity });
80
87
  };
81
88
  prepared.harness.onFrameCommitted = (carrier, entryId) => {
89
+ if (carrier.kind === "attachment")
90
+ return void prepared.attachmentDelivery.settle(carrier.inputId, carrier.ordinal);
82
91
  const seam = prepared.frameSettlement;
83
92
  if (seam.awaiting.size === 0)
84
93
  return;
@@ -82,7 +82,7 @@ export interface RunLegInput<R> {
82
82
  unsubBoundary: () => void;
83
83
  /** borrowed-readonly — the git lane's harness-event release, called third. */
84
84
  unsub: () => void;
85
- /** borrowed-readonly — the Runner's deployment deps, read LIVE (`onError`, `hooks`, `onNotice`, `allowImageUrl`; the resumed
85
+ /** borrowed-readonly — the Runner's deployment deps, read LIVE (`onError`, `hooks`, `onNotice`, `allowImageUrl`, `mediaByteCapBytes`; the resumed
86
86
  * decision's resolver files its execution record's word through `onNotice` too); the one home of why it is a seat and not a
87
87
  * captured object is {@link RunnerDepsSeat}. */
88
88
  runner: RunnerDepsSeat;