@sema-agent/core 5.19.0 → 5.21.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 (329) hide show
  1. package/CHANGELOG.md +102 -4
  2. package/dist/agents/agent-definition.d.ts +7 -0
  3. package/dist/agents/agent-transcript-tool.d.ts +30 -0
  4. package/dist/agents/builtin-agents.d.ts +60 -0
  5. package/dist/agents/cascade.d.ts +107 -0
  6. package/dist/agents/cumulative-stats.d.ts +56 -0
  7. package/dist/agents/observer.d.ts +162 -0
  8. package/dist/agents/peer-admission.d.ts +95 -0
  9. package/dist/agents/repair-loop.d.ts +226 -0
  10. package/dist/agents/retain-ledger.d.ts +141 -0
  11. package/dist/agents/roster-store.d.ts +105 -0
  12. package/dist/agents/roster-store.js +3 -0
  13. package/dist/agents/send-message-tool.d.ts +92 -0
  14. package/dist/agents/session-util.d.ts +5 -0
  15. package/dist/agents/subagent-steps.d.ts +66 -0
  16. package/dist/agents/subagent.d.ts +600 -0
  17. package/dist/agents/suspend-guard.d.ts +29 -0
  18. package/dist/agents/teacher.d.ts +75 -0
  19. package/dist/agents/team.d.ts +120 -1
  20. package/dist/agents/tool-filter.d.ts +34 -0
  21. package/dist/agents/verify.d.ts +198 -0
  22. package/dist/bench/metrics.d.ts +455 -0
  23. package/dist/brain/anthropic.d.ts +30 -0
  24. package/dist/brain/circuit-breaker.d.ts +33 -0
  25. package/dist/brain/circuit-breaker.js +14 -3
  26. package/dist/brain/context-overflow.d.ts +60 -3
  27. package/dist/brain/degrading.d.ts +67 -0
  28. package/dist/brain/errors.d.ts +42 -0
  29. package/dist/brain/failover.d.ts +15 -0
  30. package/dist/brain/media-degrade.d.ts +39 -0
  31. package/dist/brain/model-presets.d.ts +31 -0
  32. package/dist/brain/open-responses.d.ts +19 -0
  33. package/dist/brain/openai.d.ts +46 -0
  34. package/dist/brain/reasoning.d.ts +106 -1
  35. package/dist/brain/repetition.d.ts +83 -0
  36. package/dist/brain/request-params.d.ts +56 -0
  37. package/dist/brain/retry.d.ts +46 -0
  38. package/dist/brain/routing.d.ts +12 -0
  39. package/dist/brain/status-sink.d.ts +30 -1
  40. package/dist/brain/stream-engine.d.ts +147 -0
  41. package/dist/brain/stream-shared.d.ts +34 -0
  42. package/dist/brain/terminal-cause.d.ts +31 -0
  43. package/dist/brain/timeout.d.ts +108 -0
  44. package/dist/brain/timeout.js +11 -0
  45. package/dist/brain/tool-call-id.d.ts +20 -0
  46. package/dist/brain/tool-call-repair.d.ts +13 -0
  47. package/dist/config/catalog.d.ts +47 -0
  48. package/dist/config/defaults.d.ts +33 -0
  49. package/dist/core/a2a-task-state.d.ts +53 -0
  50. package/dist/core/a2a.d.ts +51 -0
  51. package/dist/core/arg-summary.d.ts +62 -0
  52. package/dist/core/ask-question.d.ts +272 -2
  53. package/dist/core/auto-compaction.d.ts +467 -0
  54. package/dist/core/auto-compaction.js +20 -6
  55. package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
  56. package/dist/core/auto-mode-prompt.d.ts +27 -0
  57. package/dist/core/auto-mode.d.ts +54 -3
  58. package/dist/core/auto-promote.d.ts +100 -0
  59. package/dist/core/background-agent-store.d.ts +293 -0
  60. package/dist/core/background-agent-store.js +5 -0
  61. package/dist/core/background-shell.d.ts +110 -0
  62. package/dist/core/cache-break-detector.d.ts +34 -0
  63. package/dist/core/canonical-json.d.ts +57 -0
  64. package/dist/core/checkpoint-store.d.ts +1574 -16
  65. package/dist/core/compliance.d.ts +30 -0
  66. package/dist/core/consolidate-scope.d.ts +75 -0
  67. package/dist/core/context-edit.d.ts +99 -0
  68. package/dist/core/context-guard.d.ts +46 -0
  69. package/dist/core/exec-gate.d.ts +44 -0
  70. package/dist/core/exec-output-tail.d.ts +61 -0
  71. package/dist/core/file-snapshot-store.d.ts +104 -0
  72. package/dist/core/fs-write-gate-policy.d.ts +36 -0
  73. package/dist/core/git-worktree-env.d.ts +31 -0
  74. package/dist/core/governance-codes.d.ts +19 -0
  75. package/dist/core/hooks.d.ts +609 -1
  76. package/dist/core/human-input-projection.d.ts +37 -0
  77. package/dist/core/human-input-projection.js +13 -0
  78. package/dist/core/image-downsample.d.ts +74 -0
  79. package/dist/core/locked-config.d.ts +37 -0
  80. package/dist/core/lsp-diagnostics.d.ts +77 -0
  81. package/dist/core/lsp-protocol.d.ts +29 -0
  82. package/dist/core/lsp-session.d.ts +60 -1
  83. package/dist/core/lsp.d.ts +150 -1
  84. package/dist/core/mailbox-store.d.ts +57 -0
  85. package/dist/core/mailbox-store.js +2 -0
  86. package/dist/core/mcp.d.ts +385 -0
  87. package/dist/core/mcp.js +58 -11
  88. package/dist/core/media-byte-cap.d.ts +21 -0
  89. package/dist/core/memory-admission.d.ts +71 -0
  90. package/dist/core/memory-engine/content-origin.d.ts +64 -0
  91. package/dist/core/memory-engine/data-plane.d.ts +43 -0
  92. package/dist/core/memory-engine/dual-root.d.ts +24 -0
  93. package/dist/core/memory-engine/engine.d.ts +230 -0
  94. package/dist/core/memory-engine/engine.js +103 -35
  95. package/dist/core/memory-engine/file-backend.d.ts +155 -0
  96. package/dist/core/memory-engine/frontmatter.d.ts +16 -0
  97. package/dist/core/memory-engine/layout.d.ts +217 -0
  98. package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
  99. package/dist/core/memory-engine/migrate.d.ts +9 -0
  100. package/dist/core/memory-engine/scan.d.ts +12 -0
  101. package/dist/core/memory-engine/scope-contract.d.ts +61 -1
  102. package/dist/core/memory-engine/sync-client.d.ts +87 -0
  103. package/dist/core/memory-engine/sync.d.ts +60 -0
  104. package/dist/core/memory-engine/tools.d.ts +41 -0
  105. package/dist/core/memory-engine/types.d.ts +188 -0
  106. package/dist/core/memory-recall.d.ts +141 -0
  107. package/dist/core/memory-vector.d.ts +20 -0
  108. package/dist/core/memory.d.ts +458 -0
  109. package/dist/core/message-utils.d.ts +6 -0
  110. package/dist/core/oracle-isolation.d.ts +69 -0
  111. package/dist/core/permission-rule-consent.d.ts +138 -0
  112. package/dist/core/permission-rule-model.d.ts +122 -0
  113. package/dist/core/permission-rule-store.d.ts +119 -3
  114. package/dist/core/permission-rules.d.ts +87 -1
  115. package/dist/core/present-plan-tool.d.ts +20 -0
  116. package/dist/core/pricing.d.ts +26 -0
  117. package/dist/core/property-harness.d.ts +86 -0
  118. package/dist/core/protocol-naming.d.ts +38 -0
  119. package/dist/core/protocol-table.d.ts +61 -0
  120. package/dist/core/push-queue.d.ts +1 -0
  121. package/dist/core/remote-env.d.ts +383 -1
  122. package/dist/core/retention-policy.d.ts +40 -0
  123. package/dist/core/retention-policy.js +21 -0
  124. package/dist/core/retention.d.ts +51 -0
  125. package/dist/core/roles.d.ts +59 -0
  126. package/dist/core/runner/active-skill-scope.d.ts +34 -0
  127. package/dist/core/runner/assemble-result.d.ts +134 -0
  128. package/dist/core/runner/compaction-call-options.d.ts +97 -1
  129. package/dist/core/runner/grounding-signal.d.ts +10 -0
  130. package/dist/core/runner/image.d.ts +17 -0
  131. package/dist/core/runner/image.js +29 -15
  132. package/dist/core/runner/memory-consolidation.d.ts +60 -0
  133. package/dist/core/runner/prepare-memory.d.ts +59 -0
  134. package/dist/core/runner/prepare-task.d.ts +1011 -2
  135. package/dist/core/runner/prepare-task.js +51 -14
  136. package/dist/core/runner/prompt-suggestions.d.ts +7 -0
  137. package/dist/core/runner/runtask.d.ts +304 -3
  138. package/dist/core/runner/runtask.js +17 -2
  139. package/dist/core/runner/session-file-state-replay.d.ts +49 -0
  140. package/dist/core/runner/session-rule-policy.d.ts +58 -0
  141. package/dist/core/runner/strict-output-schema.d.ts +18 -3
  142. package/dist/core/runner/synthetic-tools.d.ts +113 -0
  143. package/dist/core/runner/teardown-bounded.d.ts +34 -0
  144. package/dist/core/runner/tool-disclosure.d.ts +227 -0
  145. package/dist/core/runner/tool-output-projection.d.ts +6 -0
  146. package/dist/core/runner/turn-attachments.d.ts +634 -0
  147. package/dist/core/runner/usage-accounting.d.ts +32 -0
  148. package/dist/core/runtime.d.ts +9 -0
  149. package/dist/core/safe-notify.d.ts +64 -0
  150. package/dist/core/safety-axis-vocab.d.ts +23 -0
  151. package/dist/core/safety-merge-corpus.d.ts +37 -0
  152. package/dist/core/scheduler.d.ts +121 -0
  153. package/dist/core/secret-env.d.ts +32 -0
  154. package/dist/core/select-model.d.ts +15 -0
  155. package/dist/core/sensitive-path-policy.d.ts +42 -0
  156. package/dist/core/session-policy-store.d.ts +94 -0
  157. package/dist/core/session-reconcile.d.ts +80 -0
  158. package/dist/core/session-store.d.ts +85 -0
  159. package/dist/core/session.d.ts +153 -0
  160. package/dist/core/shared-memory/contract.d.ts +22 -0
  161. package/dist/core/shared-memory/normalize.d.ts +123 -2
  162. package/dist/core/shared-memory/tools.d.ts +14 -0
  163. package/dist/core/shared-memory/types.d.ts +105 -0
  164. package/dist/core/shutdown-debug.d.ts +6 -0
  165. package/dist/core/side-query.d.ts +38 -0
  166. package/dist/core/side-query.js +6 -1
  167. package/dist/core/skill-tool-specifier.d.ts +72 -0
  168. package/dist/core/skills-directory.d.ts +100 -1
  169. package/dist/core/spec-contract.d.ts +89 -0
  170. package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
  171. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
  172. package/dist/core/store-contracts/contract-harness.d.ts +20 -0
  173. package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
  174. package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
  175. package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
  176. package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
  177. package/dist/core/strategy-store.d.ts +37 -0
  178. package/dist/core/stub-env.d.ts +7 -0
  179. package/dist/core/surrogate-safe-slice.d.ts +35 -0
  180. package/dist/core/task-notification.d.ts +202 -0
  181. package/dist/core/task-outcome.d.ts +53 -0
  182. package/dist/core/task-registry-agent.d.ts +337 -1
  183. package/dist/core/task-registry-agent.js +2 -0
  184. package/dist/core/task-registry-monitor.d.ts +12 -0
  185. package/dist/core/task-registry-shared.d.ts +540 -0
  186. package/dist/core/task-registry.d.ts +343 -0
  187. package/dist/core/task-registry.js +13 -2
  188. package/dist/core/task-tool-shape.d.ts +44 -0
  189. package/dist/core/tighten-task-spec.d.ts +21 -0
  190. package/dist/core/tool-detach.d.ts +21 -0
  191. package/dist/core/tool-errors.d.ts +131 -0
  192. package/dist/core/tool-errors.js +4 -0
  193. package/dist/core/tool-name-aliases.d.ts +27 -0
  194. package/dist/core/tool-policy.d.ts +555 -0
  195. package/dist/core/tool-policy.js +3 -0
  196. package/dist/core/tool-result-budget.d.ts +32 -0
  197. package/dist/core/tool-result-store.d.ts +174 -1
  198. package/dist/core/tools.d.ts +45 -0
  199. package/dist/core/trace.d.ts +323 -0
  200. package/dist/core/types.d.ts +3859 -2
  201. package/dist/core/untrusted-egress.d.ts +8 -0
  202. package/dist/core/untrusted-text.d.ts +156 -0
  203. package/dist/core/usage-window-store.d.ts +95 -0
  204. package/dist/core/version.d.ts +1 -0
  205. package/dist/core/warm-resume.d.ts +17 -0
  206. package/dist/core/wiring-manifest.d.ts +169 -0
  207. package/dist/core/with-retry.d.ts +24 -0
  208. package/dist/core/workflow-journal-store.d.ts +160 -0
  209. package/dist/core/workflow-run-store-contract.d.ts +25 -0
  210. package/dist/core/workflow-run-store.d.ts +119 -0
  211. package/dist/core/workflow-run-store.js +2 -0
  212. package/dist/engine/compaction/compaction.d.ts +256 -1
  213. package/dist/engine/compaction/utils.d.ts +94 -0
  214. package/dist/engine/execution-env/kill-tree.d.ts +29 -0
  215. package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
  216. package/dist/engine/harness/agent-harness.d.ts +116 -0
  217. package/dist/engine/harness/agent-harness.js +3 -14
  218. package/dist/engine/harness/messages.d.ts +15 -0
  219. package/dist/engine/harness/types.d.ts +464 -2
  220. package/dist/engine/llm/diagnostics.d.ts +4 -0
  221. package/dist/engine/llm/event-stream.d.ts +3 -0
  222. package/dist/engine/llm/index.d.ts +7 -0
  223. package/dist/engine/llm/types.d.ts +500 -3
  224. package/dist/engine/llm/validation.d.ts +3 -0
  225. package/dist/engine/loop/agent-loop.d.ts +87 -2
  226. package/dist/engine/loop/runtime-deps.d.ts +7 -0
  227. package/dist/engine/loop/types.d.ts +424 -0
  228. package/dist/engine/lsp/frame-decoder.d.ts +13 -0
  229. package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
  230. package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
  231. package/dist/engine/session/import-validate.d.ts +27 -0
  232. package/dist/engine/session/log-digest.d.ts +93 -0
  233. package/dist/engine/session/memory-repo.d.ts +6 -0
  234. package/dist/engine/session/memory-storage.d.ts +2 -0
  235. package/dist/engine/session/session.d.ts +75 -0
  236. package/dist/engine/session/storage-base.d.ts +8 -0
  237. package/dist/fixtures/index.d.ts +36 -0
  238. package/dist/index.d.ts +17 -2
  239. package/dist/index.js +1 -2
  240. package/dist/internal/harness-types.d.ts +6 -0
  241. package/dist/internal/harness.d.ts +11 -0
  242. package/dist/internal/llm.d.ts +6 -0
  243. package/dist/orchestration/builtin-workflows.d.ts +53 -0
  244. package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
  245. package/dist/orchestration/goal.d.ts +57 -0
  246. package/dist/orchestration/goal.js +3 -0
  247. package/dist/orchestration/run-spec.d.ts +42 -0
  248. package/dist/orchestration/run-spec.js +4 -0
  249. package/dist/orchestration/run-workflow-tool.d.ts +169 -0
  250. package/dist/orchestration/workflow-governance.d.ts +61 -0
  251. package/dist/orchestration/workflow-meta.d.ts +28 -0
  252. package/dist/orchestration/workflow-observe.d.ts +60 -0
  253. package/dist/orchestration/workflow-primitives.d.ts +23 -1
  254. package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
  255. package/dist/orchestration/workflow-script-runner.d.ts +88 -0
  256. package/dist/orchestration/workflow-script-store.d.ts +98 -0
  257. package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
  258. package/dist/orchestration/workflow-types.d.ts +169 -2
  259. package/dist/orchestration/workflow.d.ts +358 -0
  260. package/dist/orchestration/workflow.js +13 -2
  261. package/dist/prompt-assembly/artifact-store.d.ts +33 -0
  262. package/dist/prompt-assembly/artifact.d.ts +25 -0
  263. package/dist/prompt-assembly/assemble.d.ts +20 -0
  264. package/dist/prompt-assembly/composer.d.ts +29 -0
  265. package/dist/prompt-assembly/epoch.d.ts +55 -1
  266. package/dist/prompt-assembly/event-registry.d.ts +35 -0
  267. package/dist/prompt-assembly/explain.d.ts +12 -0
  268. package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
  269. package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
  270. package/dist/prompt-assembly/types.d.ts +115 -0
  271. package/dist/prompts/coordinator.d.ts +27 -0
  272. package/dist/prompts/default.d.ts +539 -0
  273. package/dist/prompts/simple-sections.d.ts +45 -0
  274. package/dist/prompts/supervisor.d.ts +66 -0
  275. package/dist/scenarios/env.d.ts +28 -0
  276. package/dist/scenarios/full-body.d.ts +50 -0
  277. package/dist/scenarios/scenario-registry.d.ts +60 -0
  278. package/dist/scenarios/teacher-quickstart.d.ts +27 -0
  279. package/dist/server/http.d.ts +17 -0
  280. package/dist/stores/cc/lockfile.d.ts +6 -0
  281. package/dist/stores/cc/mailbox-store.d.ts +8 -0
  282. package/dist/stores/cc/roster-adapter.d.ts +4 -0
  283. package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
  284. package/dist/stores/file/background-agent-store.d.ts +24 -0
  285. package/dist/stores/file/background-agent-store.js +2 -1
  286. package/dist/stores/file/checkpoint-store.d.ts +38 -0
  287. package/dist/stores/file/file-snapshot-store.d.ts +25 -0
  288. package/dist/stores/file/fs-atomic.d.ts +155 -0
  289. package/dist/stores/file/index.d.ts +89 -0
  290. package/dist/stores/file/mailbox-store.d.ts +36 -0
  291. package/dist/stores/file/mailbox-store.js +2 -0
  292. package/dist/stores/file/memory-store.d.ts +82 -0
  293. package/dist/stores/file/permission-rule-store.d.ts +79 -0
  294. package/dist/stores/file/session-policy-store.d.ts +28 -0
  295. package/dist/stores/file/session-store.d.ts +40 -0
  296. package/dist/stores/file/shared-ledger.d.ts +83 -0
  297. package/dist/stores/file/tool-result-store.d.ts +11 -0
  298. package/dist/stores/file/usage-window-store.d.ts +18 -0
  299. package/dist/stores/file/workflow-journal-store.d.ts +100 -0
  300. package/dist/stores/file/workflow-run-store.d.ts +11 -0
  301. package/dist/stores/file/workflow-run-store.js +2 -0
  302. package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
  303. package/dist/tools/fs/encoding.d.ts +60 -0
  304. package/dist/tools/fs/fs-bash.d.ts +133 -0
  305. package/dist/tools/fs/fs-pdf.d.ts +28 -0
  306. package/dist/tools/fs/fs-search-tools.d.ts +5 -0
  307. package/dist/tools/fs/fs-shared.d.ts +360 -0
  308. package/dist/tools/fs/fs-write.d.ts +16 -0
  309. package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
  310. package/dist/tools/fs/index.d.ts +79 -0
  311. package/dist/tools/fs/notebook.d.ts +56 -0
  312. package/dist/tools/fs/pdf.d.ts +70 -0
  313. package/dist/tools/fs/pdf.js +8 -2
  314. package/dist/tools/fs/repo-map.d.ts +10 -0
  315. package/dist/tools/fs/safety.d.ts +376 -0
  316. package/dist/tools/fs/search.d.ts +131 -0
  317. package/dist/tools/loop-tick.d.ts +24 -0
  318. package/dist/tools/monitor.d.ts +55 -0
  319. package/dist/tools/scheduler-tools.d.ts +51 -0
  320. package/dist/tools/sql-adapters.d.ts +18 -0
  321. package/dist/tools/sql.d.ts +25 -0
  322. package/dist/tools/task-list.d.ts +77 -0
  323. package/dist/tools/todo.d.ts +8 -0
  324. package/dist/tools/web.d.ts +184 -0
  325. package/dist/tools/web.js +32 -5
  326. package/dist/tools/worktree.d.ts +81 -0
  327. package/package.json +2 -2
  328. package/dist/tools/gitea-issue.d.ts +0 -13
  329. package/dist/tools/gitea-issue.js +0 -75
@@ -27,20 +27,107 @@ import { type WiringManifest } from "../wiring-manifest.js";
27
27
  import type { ActiveWorktreeSession, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
28
28
  import type { NestedUsageAccum, RunnerDeps, TaskEvent, TaskLimits, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
29
29
  import type { RepairBundle } from "../../agents/repair-loop.js";
30
+ /**
31
+ * design/164 — validate `TaskSpec.limits` at the door and return it unchanged.
32
+ *
33
+ * Two refusals, both fail-loud (the {@link resolveStallTimeoutMs} posture: a bound nobody can evaluate is
34
+ * not a bound, and folding it to a default would silently run the task under limits nobody chose):
35
+ * - **unknown key** ⇒ `config.limit_unknown_key`. TypeScript already rejects a stale key, but a wire /
36
+ * plain-JS caller does not go through TypeScript, and the retired names (`timeoutSec` above all) used
37
+ * to be honored — accepting them silently is how a caller keeps believing a limit is armed when the
38
+ * engine has stopped reading it.
39
+ * - **unevaluable numeric value** (non-number / non-finite / negative) ⇒ `config.limit_invalid`, naming
40
+ * the key. `0` is legal on every numeric axis: on `maxTurns` it is the documented "unbounded"
41
+ * sentinel, and on the budget axes it is an exhausted window (absurd but honest).
42
+ */
30
43
  export declare function resolveTaskLimits(limits: TaskLimits | undefined): TaskLimits | undefined;
44
+ /**
45
+ * design/164 件四 — how long before an execution environment's declared `lifetimeMs` expires the engine
46
+ * stops the run and checkpoints it. The margin has to cover ONE suspend: pausing/snapshotting the
47
+ * workspace, minting the checkpoint, committing it durably, and letting the loop stop cleanly — with
48
+ * room for a slow durable store. 60s is generous for that work and small next to any real sandbox
49
+ * lifetime (the shortest tier observed in the platform survey is minutes), so it neither truncates the
50
+ * task nor risks losing the race with the platform's reclaim.
51
+ *
52
+ * It is an ENGINE constant, not a knob: an adapter that wants a wider safety band declares a shorter
53
+ * `lifetimeMs` (it owns the platform fact), and one number that every deployment shares keeps the
54
+ * checkpoint-cost calibration in one place.
55
+ */
31
56
  export declare const ENV_LIFETIME_SUSPEND_MARGIN_MS = 60000;
57
+ /**
58
+ * design/164 件五 — how long AFTER a governance window frees a `usage_window` checkpoint stays reapable-free.
59
+ * The retention TTL answers "was this abandoned?"; a usage-window suspend is not abandoned while the window
60
+ * it waits on is still full, so its deadline is pushed to `retryAfterMs + this`. One hour gives a host's
61
+ * scheduler a realistic chance to pick the resume up (a cron tick, a queue drain) before the row is
62
+ * treated as garbage — small next to the 30-day retention it is compared against, and large next to any
63
+ * polling interval a driver would sanely use.
64
+ */
32
65
  export declare const USAGE_WINDOW_REAP_MARGIN_MS: number;
66
+ /**
67
+ * design/164 件五 — the run's view of deployment usage governance, built once at prepare when
68
+ * `RunnerDeps.usageWindows` + `usageWindowStore` are both wired (absent otherwise, so every consumer is
69
+ * an explicit `!== undefined` test and an ungoverned deployment executes not one extra line).
70
+ *
71
+ * Both methods are called SEQUENTIALLY by the run loop (entry check, then one commit per turn boundary,
72
+ * then one final commit) — the delta bookkeeping in `commit` assumes that and is not a concurrency
73
+ * primitive.
74
+ */
33
75
  export interface UsageGovernance {
76
+ /** The ledger key this run is governed under — the principal, or the shared global key. */
34
77
  readonly key: string;
78
+ /** Ms the caller must wait before ANY window would admit work again, or `undefined` when none is
79
+ * exhausted as of `now`. Reads the ledger; propagates a store failure (an unreadable ceiling must not
80
+ * read as an open one). */
35
81
  check(now: number): Promise<number | undefined>;
82
+ /** Charge whatever of `cumulativeTokens` has not been charged yet. Takes the run's CUMULATIVE total
83
+ * rather than a delta so no caller can double-charge by calling twice, and so a caller that skips a
84
+ * boundary loses nothing. */
36
85
  commit(cumulativeTokens: number, now: number): Promise<void>;
37
86
  }
87
+ /**
88
+ * design/164 件四 — resolve the moment an env's lifetime EXPIRES (epoch ms), or `undefined` when the env
89
+ * declares none / cannot be aged. Split out as a pure function so the anchor rules are testable and
90
+ * stated once.
91
+ *
92
+ * Honesty of the anchor, in order of preference:
93
+ * 1. `env.lifetimeStartedAt` — the platform's own answer. The only anchor that survives an env being
94
+ * older than this run (a shared static env, or a sandbox restored from a snapshot).
95
+ * 2. `observedAt` — when this run's `executionEnvFactory` MINTED the env. Exact only for that case,
96
+ * which is why the caller passes it only then.
97
+ * 3. Nothing — an env that declares a lifetime, self-reports no start, and was not minted here. The
98
+ * lifetime is NOT enforced and the caller reports it, because the only remaining guess (task start)
99
+ * OVERSTATES the remaining lifetime, i.e. errs toward the mid-turn kill this mechanism exists to
100
+ * prevent. A silent under-estimate would be the wrong direction to fail in.
101
+ *
102
+ * An unevaluable `lifetimeMs` is refused (`config.env_lifetime_invalid`) rather than dropped — the
103
+ * `resolveTaskLimits` posture: an adapter that fumbled the units must not silently get no protection.
104
+ */
38
105
  export declare function resolveEnvLifetimeExpiry(env: ExecutionEnv, observedAt: number | undefined): {
39
106
  expiresAt: number;
40
107
  } | {
41
108
  unanchored: true;
42
109
  } | undefined;
110
+ /** design/77 §4.4: the multi-tenant scope used when a durable suspend fires for an IRREVERSIBLE tool in an
111
+ * unattended deployment that did NOT opt into `durableApproval` (so there is no caller-supplied scope). The
112
+ * checkpoint carries this scope; resume reads it back from the checkpoint (`cp.scope`), so it is
113
+ * self-consistent without needing the original `TaskSpec`. Kept distinct from any tenant key to make an
114
+ * unattended irreversible suspend auditable as such. */
43
115
  export declare const DEFAULT_IRREVERSIBLE_SCOPE = "irreversible";
116
+ /**
117
+ * design/153 §7.1 — the SINGLE derivation of a durable-suspend checkpoint's scope (both gate mint
118
+ * sites + the bg-watcher park lane's expire compensation/arbitration consume THIS; a re-derived copy
119
+ * that drifted was the exact bug the park tests caught — expire against the wrong scope silently
120
+ * no-ops). `|| DEFAULT` (not `??`): an EMPTY-string principal must not become a shared scope bucket.
121
+ *
122
+ * RB-75 (2026-07-25, red probe): that rule is stated twice in this file and was enforced on ONE of the two
123
+ * inputs — the principal half used `||`, the `durableApproval.scope` half used `??`, so an empty string
124
+ * arriving through the scope field (a config-centre / env lookup that came back blank is the realistic
125
+ * source) sailed through as the literal scope `""`. Two different tenants both landed in that one bucket,
126
+ * where `listByScope("")` reads BOTH their pending approvals — including each summary's `toolInput`
127
+ * preview of the raw arguments — and `reap("")` / `resolve(token, "")` act across both. `durableApproval.
128
+ * scope` is documented as "Multi-tenant isolation key … Required"; a blank string is the absence of an
129
+ * isolation key wearing its clothes, so both halves now fall through to the default isolation scope.
130
+ */
44
131
  export declare function checkpointScopeOf(spec: {
45
132
  durableApproval?: {
46
133
  scope?: string;
@@ -48,48 +135,121 @@ export declare function checkpointScopeOf(spec: {
48
135
  principal?: string;
49
136
  }): string;
50
137
  export { resolveCheckpointStore } from "../checkpoint-store.js";
138
+ /** Everything the run loop needs, built once by {@link prepareTask} (task setup, isolated from the loop). */
51
139
  export interface Prepared {
52
140
  harness: AgentHarness;
141
+ /** The CONCRETE built-in session (engine-internal: prepare constructs/acquires `StoredSession` itself,
142
+ * and the epoch pin path needs its `appendPromptEpoch`/`getPromptEpoch`). Public consumer faces take
143
+ * the `Session` contract instead. */
53
144
  session: StoredSession;
54
145
  sessionId: string;
146
+ /** The ISOLATION-AWARE working-tree root for this task (a worktree's cwd when `isolation: "worktree"`, else
147
+ * `deps.rootPath ?? executionEnv.cwd`) — the same value the hands/LSP/policy/restore use. The Runner's
148
+ * rewind/snapshot path MUST key off THIS, not `deps.rootPath`, or a worktree-isolated turn snapshots the base
149
+ * repo (CORE-1~9 audit MAJOR). */
55
150
  taskRootPath: string;
56
151
  model: Model;
152
+ /** Effective thinking level (explicit `spec.thinking` or the resolved role's default). */
57
153
  thinking?: ThinkingLevel;
58
154
  compModel?: Model;
59
155
  mcp: MaterializedMcp;
156
+ /** Present only when `spec.a2a` declared peers — the run loop owes it the same end-of-task dispose
157
+ * it owes {@link mcp} (no sockets are held, but a disposed mount is what makes a post-task tool
158
+ * call refuse loudly instead of dialing a peer on a dead task's behalf). */
60
159
  a2a?: MaterializedA2a;
61
160
  blockedRef: BlockedRef;
161
+ /** Holds the structured output once `submit_output` is called (when `spec.outputSchema` is set). */
62
162
  outputRef: OutputRef;
163
+ /** Fires when the task aborts (timeout / max turns / end). Passed to `ToolPolicy.check` so a
164
+ * pending human-approval gate is released instead of hanging past the deadline (F4). */
63
165
  abortController: AbortController;
166
+ /** Flipped if any session write lost the optimistic lock during the run → `errorCode = "conflict"`. */
64
167
  conflictRef: {
65
168
  hit: boolean;
66
169
  };
170
+ /** design/134 复审: tool-call ids the gate blocked (policy/hook/plan-mode deny) or suspended —
171
+ * populated only while a consumer is wired (per-tool post hooks or postToolBatch). The runner's
172
+ * batch collector DELETES on match (its tool_execution_end is the only end-event a blocked call
173
+ * emits; the tool_result-side delete in prepare-task never fires for immediate results). */
67
174
  blockedToolCalls: Set<string>;
175
+ /**
176
+ * What ended the approval a gated call was waiting on, keyed by tool-call id — written ONLY by the
177
+ * tool gate, at the one exit where an ask resolved, and read once when that call's `tool_end` frame
178
+ * is minted (the reader deletes on read; a call the gate never settled has no entry).
179
+ *
180
+ * It is a sideband and not a field on the tool RESULT because a result is not a trustworthy carrier
181
+ * for this: `details` is arbitrary tool-authored data that post-tool hooks may also replace, so a
182
+ * failing tool could stamp `settledBy:"human"` on itself and tell a consumer's audit view that a
183
+ * person approved something nobody was ever shown. Provenance has to travel on a channel only the
184
+ * adjudicating layer can write. Same reason the entries are keyed by CALL id: the gate adjudicated
185
+ * that exact call, and the frame that reads it is that call's own.
186
+ */
68
187
  approvalSettledBy: Map<string, import("../tool-policy.js").ApprovalSettledBy>;
188
+ /** Summed usage of nested sub-runs (sub-agents) spawned by this task's tools. */
69
189
  nestedStats: NestedUsageAccum;
190
+ /** RB-430-a: prepare-time rewind disclosures (conversation-only branch / no snapshot backend / no file
191
+ * env), echoed verbatim onto `TaskResult.rewindNotes`. Present only when there is something to say. */
70
192
  rewindNotes?: NonNullable<TaskResult["rewindNotes"]>;
193
+ /** design/99 §E13 — the per-task logical cwd ref when a real shell is mounted (else undefined). The Runner
194
+ * reads `cwdRef.current` after each tool to detect a `cd` move and emit `workspace_changed`. */
71
195
  cwdRef?: CwdRef;
196
+ /** design/155: the ACTIVE EnterWorktree session ref (mounted with the worktree tools; undefined without
197
+ * real write hands). runtask's settle write reads `current` for the workspace-state entry. */
72
198
  worktreeSessionRef?: {
73
199
  current?: ActiveWorktreeSession;
74
200
  };
201
+ /** design/155: the settle-write base — the canonical root + what the cwd/worktree were RESTORED to at
202
+ * prepare. runtask diffs the live refs against this at settle and appends a `workspace_state` entry
203
+ * when the state changed (skipped on a durable suspend — the checkpoint lane owns that state). */
75
204
  workspaceStateSettle?: {
76
205
  rootCanonical: string;
77
206
  restoredHandsCwd?: string;
78
207
  restoredWorktreeDir?: string;
79
208
  baselineUnknown?: boolean;
80
209
  };
210
+ /** design/99 §E6 — the DENY-NARROWING layers (session rules + skill scope, deny-only). Re-checked on RESUME
211
+ * before an approved pending tool executes, so a rule tightened during the suspend still applies. */
81
212
  denyNarrowingPolicy?: ToolPolicy;
213
+ /** RB-63: the deployment's own caller policy, re-checked on a durable resume ONLY when the approver
214
+ * rewrote the pending call's args (see the composition site for why the edit case is special). */
82
215
  basePolicyForResumeEdit?: ToolPolicy;
216
+ /** Removes the `spec.signal` abort listener on task end (else a long-lived signal leaks listeners). */
83
217
  releaseSignal: () => void;
218
+ /**
219
+ * design/174 — end-of-leg sweep for questions this leg's gate routed to a person. Called once by the
220
+ * run loop at task end, on every exit path. A binding that is still present means a person ANSWERED and
221
+ * the call never executed to collect it (aborted, batch torn down, loop threw): that answer is disclosed
222
+ * through the deployment's error sink rather than dropped, because "a human answered and it vanished" is
223
+ * precisely the failure this whole path exists to remove — it must not reappear inside the mechanism
224
+ * that removes it. Idempotent, never throws.
225
+ */
84
226
  settleContentAskBindings: () => ReadonlyArray<{
85
227
  deliveryId: string;
86
228
  toolCallId: string;
87
229
  }>;
230
+ /** Per-task prefix-cache-break detector (design/31). The fingerprint is mutated when deferred tools
231
+ * materialize (design/36) — see `cacheFingerprint`. */
88
232
  cacheBreakDetector?: CacheBreakDetector;
233
+ /** The fingerprinted prefix. `systemPrompt` is stable; `tools` is REFRESHED in place when a deferred
234
+ * tool is materialized (placeholder→full schema), so the design/31 detector sees the real tool set. */
89
235
  cacheFingerprint?: {
90
236
  systemPrompt: string;
91
237
  tools: ToolFingerprintInput[];
92
238
  };
239
+ /**
240
+ * 提示词主权批 — the labelled composition of the assembled system prompt, emitted as the
241
+ * `prompt.assembled` trace event at task start. `constitution` says who owned the safety layer:
242
+ * `"core"` (structural, the default), `"replaced"` (provider set `replaceAll` — deliberate opt-out),
243
+ * `"provider-assembled"` (migration guard: a historic provider returned a full prompt, passed through
244
+ * un-doubled + onError hint). Deployments/tests assert on this to make "which blocks were in the
245
+ * prompt" a runtime fact instead of archaeology.
246
+ */
247
+ /**
248
+ * design/173 §8.1 — this leg's EFFECTIVE wiring manifest (built once in prepare from resolved
249
+ * facts through the same derivation as the static half). runtask emits it as the
250
+ * `wiring_manifest` TaskEvent after the prepare consume point and before the leg's first
251
+ * model/tool interaction. Host/operator plane — never enters model context.
252
+ */
93
253
  wiringManifest: WiringManifest;
94
254
  promptManifest: {
95
255
  constitution: "core" | "replaced" | "provider-assembled";
@@ -98,6 +258,13 @@ export interface Prepared {
98
258
  chars: number;
99
259
  hash: string;
100
260
  }>;
261
+ /** Manifest v2 (campaign S1, additive): the compiled-IR section view (slot/carrier/cadence/
262
+ * cacheClass per section). `contentHash` is the
263
+ * digest-tiering face ([1050]②/[1057]): present ONLY on operator-declared sections (the typed
264
+ * `stableBlocks` lane, owner "deployment") as an UNSALTED full sha256 of the section text —
265
+ * the center-publish ↔ manifest end-to-end reconciliation anchor. Core-native sections (env
266
+ * facts, memory tail, user role text) stay salted-only: a plain hash of a short guessable
267
+ * block is a dictionary-preimage surface for trace readers (codex [E]). */
101
268
  sections?: Array<{
102
269
  id: string;
103
270
  slot: string;
@@ -108,15 +275,34 @@ export interface Prepared {
108
275
  hash: string;
109
276
  contentHash?: string;
110
277
  }>;
278
+ /** Campaign S2 (additive): the mounted tools plane — contract identity, durable-replay aliases,
279
+ * presentation-invariant shape digest and full wire digest per tool (initial mount face). */
111
280
  tools?: ToolManifestRow[];
281
+ /** design/148 S3 (additive, §10.2): the nine-element cache identity — digests only, no prompt
282
+ * text; backfilled once the final wire tool list exists. Live post-refresh truth rides
283
+ * `prepared.turnSnapshot`. */
112
284
  snapshot?: {
113
285
  cacheIdentity: string;
114
286
  elements: import("../../prompt-assembly/turn-snapshot.js").CacheIdentityElements;
115
287
  };
288
+ /** design/148 S3 (additive, §10.1): the run's lowering record (version/wire form/known
289
+ * intentional divergences — run-static v1, one brain serves every call). */
116
290
  lowering?: import("../../prompt-assembly/turn-snapshot.js").LoweringRecord;
291
+ /** design/168 (additive): the RESOLVED deferred-tool disclosure strategy for this leg and which
292
+ * seat chose it. Absent when nothing is deferred (there is no disclosure to describe). */
117
293
  toolDisclosure?: ToolDisclosureManifest;
118
294
  };
295
+ /** [1068] ruling a — this run's provider-declared prompt sections (epoch declaration axis),
296
+ * threaded to every compaction-boundary epoch selection so boundary re-pins hash the same
297
+ * artifact identity as the prepare-time pin. Empty on declaration-free runs. */
119
298
  epochDeclaredSections: import("../../prompt-assembly/epoch.js").EpochDeclaredSections;
299
+ /** RB-31 (design/148 S2) — the compaction-boundary center-adoption seam (undefined = no source
300
+ * wired or session not center-pinned). Returns the maybeCompact `centerAdoption` fragment or
301
+ * undefined; `apply` runs post-CAS only (auto-compaction owns the ordering). Both
302
+ * `epochDeclaredSections` and `promptOverheadTokens` on THIS object are mutated by a successful
303
+ * adoption (read them at call time, never capture early). */
304
+ /** design/148 S3 — the LIVE nine-element identity face (refreshed by deferred materialization and
305
+ * the RB-31 adoption swap); the manifest holds the prepare-time initial copy. */
120
306
  turnSnapshot?: import("../../prompt-assembly/turn-snapshot.js").TurnPromptSnapshot;
121
307
  centerCompactionCandidate?: () => {
122
308
  centerArtifactDigest?: string;
@@ -126,16 +312,62 @@ export interface Prepared {
126
312
  overheadTokensAfter: number;
127
313
  apply: (committedArtifactDigest?: string) => void;
128
314
  } | undefined;
315
+ /** Deferred-tool disclosure (design/36): the monotonic set of activated deferred-tool names. Empty
316
+ * (and no `tool_search` injected) when nothing is deferred. Mutated by BOTH disclosure lanes across
317
+ * the run — the injected `tool_search` and the RB-403 direct-call placeholder lane (default ON) —
318
+ * under ONE shared activation critical section, plus resume seeding at prepare. A leg on which the
319
+ * model never calls `tool_search` is therefore NOT quiescent. */
129
320
  activeTools: Set<string>;
321
+ /** RB-313 — the DECLARED deferred set (design/36 `classifyDeferred`, ghost names already pruned).
322
+ * Present iff the task has deferred tools at all; `deferredToolNames − activeTools` is the
323
+ * "undiscovered" census the tool_search_usage_reminder lane enumerates. Frozen at prepare time: a
324
+ * name never leaves the deferred set, it only moves into `activeTools`. */
130
325
  deferredToolNames?: ReadonlySet<string>;
326
+ /** design/168 — the RESOLVED materialization strategy this run runs under (`true` = "static":
327
+ * activation never swaps the placeholder; the real schema's only in-context carrier is the
328
+ * ToolSearch result text). Consumed by the tools_delta boundary renderer, whose "full schemas are
329
+ * loaded" wording is a statement about the tools block and is only true under swap. `false` when
330
+ * nothing is deferred (the knob is inert then). */
131
331
  toolMaterializeStatic: boolean;
332
+ /** RB-403 — is the direct-call lane mounted on this run's placeholders (`TaskSpec.deferSelfResolve`
333
+ * not disabled; default ON)? The SAME fact `createToolSearchTool` receives as `directCallEnabled`,
334
+ * surfaced here so every model-facing face that describes what happens to a call on a
335
+ * still-deferred tool reads ONE value — under the direct lane a schema-valid call executes rather
336
+ * than failing, so an absolute failure claim is only true for the opt-out posture. `false` when
337
+ * nothing is deferred (no placeholders, so the fact is inert). */
132
338
  deferDirectCall: boolean;
339
+ /** design/168 — is THIS deferred name on the static face? False under `"swap"`, and false under
340
+ * `"static"` for a tool whose declaration the result-text carrier cannot hold (the per-tool
341
+ * exemption: it materializes into the tools block instead). Read at call time — the roster is
342
+ * mutated in place by MCP refresh, so renderability is a live fact. Absent when nothing is
343
+ * deferred; a caller with no accessor has no deferred family to describe. */
133
344
  staticFaceFor?: (name: string) => boolean;
345
+ /**
346
+ * design/138 S1 — the MemoryEngine session (present iff `deps.memoryBackend` + `spec.memory.enabled`).
347
+ * `harvest` is the swallow-guarded boundary hook (task terminal in runtask + the checkpoint mint
348
+ * point in commitSuspendSaga): it runs the FULL gate set (containment/secret/caps/deletion fuse),
349
+ * commits entry patches to the backend, self-heals the derived index, and re-baselines (a second
350
+ * harvest of an unchanged session yields zero patches). It NEVER throws.
351
+ * S2-B (O-F7/C-F3): the report is NOT discarded — `harvest` hands it to the Runner-owned
352
+ * `deps.onMemoryHarvestReport` callback (with the boundary phase), and the engine itself enqueues
353
+ * the announcement-queue entry at its harvest tail (drained into the NEXT session's first inject —
354
+ * 时机①; the r1 in-run attachments lane was cut, O-F2/C-F4). `phase` defaults to "terminal" (the
355
+ * runtask call site passes nothing); the checkpoint-mint call site passes "checkpoint".
356
+ */
134
357
  memoryEngineSession?: {
358
+ /** The WRITE-plane pair (design/142 S2b: dual roots collapse to one session face; these are the
359
+ * plane that owns the write gate — the read-only plane is internal to `inject`/`harvest`). */
135
360
  engine: MemoryEngine;
136
361
  handle: MemorySessionHandle;
362
+ /** Merged injection across all planes (single-root sessions: identical to engine.inject(handle)). */
137
363
  inject: () => import("../memory-engine/engine.js").MemoryInjection;
138
364
  harvest: (phase?: "checkpoint" | "terminal") => Promise<HarvestReport | undefined>;
365
+ /**
366
+ * design/178 §3 — the session's ONE-WAY pollution face. `markPolluted` fires when an
367
+ * external-content-class tool is invoked (the prepare-time tool wrap below is the caller);
368
+ * durable + in-process, no unmark exists at any layer. `polluted` is what the harvest legs read
369
+ * (they consult it at harvest time themselves — this accessor serves observers/tests).
370
+ */
139
371
  pollution: {
140
372
  polluted: () => {
141
373
  at: number;
@@ -143,37 +375,81 @@ export interface Prepared {
143
375
  } | undefined;
144
376
  markPolluted: (reason: string) => void;
145
377
  };
378
+ /** design/178 §3 — the task's content-safety config (normalized memory spec): the allowlist for
379
+ * UNDECLARED tools and the strict execution-class upgrade. Consumed by the tool wrap only. */
146
380
  contentSafety: {
147
381
  trustedTools: ReadonlySet<string>;
148
382
  execIsExternalContent: boolean;
149
383
  };
150
384
  };
385
+ /** A per-task env minted by `RunnerDeps.executionEnvFactory` (design/48 remote seam) that THIS task owns
386
+ * and the Runner must tear down on task end. Undefined when the env came from a (caller-owned) static
387
+ * `deps.executionEnv` or the stub — those outlive the task and must NOT be destroyed here. */
151
388
  ownedEnv?: ExecutionEnv;
389
+ /** design/45: a mutable holder the durable-suspend gate writes when a policy `ask` was checkpointed
390
+ * (capture + abort). The run loop reads it to assemble `status:"suspended"`. Empty unless a suspension
391
+ * fired this run. */
152
392
  suspendRef: {
153
393
  token?: CheckpointToken;
154
394
  gate?: CheckpointGate;
155
395
  scope?: string;
156
396
  restoreMode?: "snapshot" | "park_only";
157
397
  };
398
+ /** Ruled 2026-08-05 (matrix ruling arm A): set true by the resume engine when this leg EXECUTES the
399
+ * approved pending call — the restart-loop cap then counts from a fresh base (consecutive
400
+ * no-progress suspends only). See `suspendChainBase`. */
158
401
  suspendProgressRef: {
159
402
  executedApproved: boolean;
160
403
  };
404
+ /** design/76 §2.5 (dry-run / shadow) + design/80 D-B (plan-gate): the DUAL of {@link suspendRef} for the
405
+ * REVIEW-PAUSE family — a `{kind:"needs_review"}` pause (a profile's dry-run interception committed a
406
+ * checkpoint whose predicted state-diff a human/judge must REVIEW) OR a `{kind:"plan_review"}` pause (a
407
+ * profile's plan-gate committed a checkpoint whose proposed PLAN a human must approve/edit/reject). The
408
+ * commit-side discriminant (`publishCommittedSuspend`) writes HERE for a `needs_review` OR `plan_review`
409
+ * gate and into {@link suspendRef} for every other gate kind — **never both** (else assemble-result's slot
410
+ * 8.6 `needs_review` branch is dead code, v4 MAJOR-A). The run loop reads it to assemble
411
+ * `status:"needs_review"`. Empty unless a review pause fired this run. */
161
412
  reviewRef: {
162
413
  token?: CheckpointToken;
163
414
  gate?: CheckpointGate;
164
415
  scope?: string;
165
416
  restoreMode?: "snapshot" | "park_only";
166
417
  };
418
+ /** RB-439-a: the remote-workspace lifecycle failures this run hit, appended in call order and echoed
419
+ * verbatim on `TaskResult.remoteEnvFailures`. A shared array (not a per-call return) because a suspend
420
+ * refusal is reported through the deployment's `onError` side channel and the run then continues or
421
+ * stops by its own rules — without this collector the caller's result kept no trace that a durable
422
+ * suspend was even attempted, let alone which of the eleven codes refused it. Empty unless something
423
+ * failed. Resume-leg failures do NOT land here (that leg throws out of prepare before a `Prepared`
424
+ * exists) — they ride the thrown error's `remoteEnvFailure` carrier instead. */
167
425
  remoteEnvFailures: NonNullable<TaskResult["remoteEnvFailures"]>;
426
+ /** design/72 §2.2 (B): set when a suspend was REFUSED because the task already suspended `maxSuspends`
427
+ * times (a resume/restart loop) — the run is aborted and assembles as `failed`/`suspend.loop` instead
428
+ * of minting yet another checkpoint. */
168
429
  suspendLoopRef: {
169
430
  hit: boolean;
170
431
  };
432
+ /** design/74 Slice 3c: opt-in resource-slice suspend. Present (≠ undefined) ONLY when the task opted in
433
+ * (`spec.resourceSuspend`) AND it is eligible to suspend durably (a checkpoint store, durable tool
434
+ * results, and a remote — or static caller-owned, never per-task-stub — env). The run loop calls it at a
435
+ * CLEAN turn boundary when a resource limit (turns/budget/walltime) was hit: it mints a `resource_limit`
436
+ * checkpoint + pauses the workspace + stops the loop cleanly (NOT abort). Returns true iff it committed a
437
+ * resumable checkpoint (sets `suspendRef`); false ⇒ caller falls through to normal limit handling.
438
+ * `sliceSpend` (Slice 4) is THIS slice's cost/tokens/turns, debited onto the cross-slice ledger. */
171
439
  suspendForResource?: (reason: ResourceLimitReason, sliceSpend: {
172
440
  costMicroUsd: number;
173
441
  tokens: number;
174
442
  turns: number;
175
443
  walltimeMs: number;
176
444
  }) => Promise<boolean>;
445
+ /** design/164 件四/件五: the PLATFORM-cause suspend — the same commit saga as {@link suspendForResource},
446
+ * exposed on the INFRASTRUCTURE alone (checkpoint store + durable tool results + remote/no owned env),
447
+ * WITHOUT the `spec.resourceSuspend` opt-in. The run loop calls it at a clean turn boundary when the
448
+ * execution environment is about to be reclaimed (`env_lifetime`) or a deployment usage window is
449
+ * exhausted (`usage_window`) — causes the task did not choose and cannot ask differently for, so a
450
+ * deployment that CAN keep the work has no reason to be asked whether it wants to. `hint.resumeAfterMs`
451
+ * (usage windows only) rides the gate and extends the checkpoint deadline. Returns true iff it committed
452
+ * a resumable checkpoint; false ⇒ the caller stops the run LOUDLY with the cause's terminal code. */
177
453
  suspendForPlatformLimit?: (reason: PlatformLimitReason, sliceSpend: {
178
454
  costMicroUsd: number;
179
455
  tokens: number;
@@ -182,19 +458,53 @@ export interface Prepared {
182
458
  }, hint?: {
183
459
  resumeAfterMs: number;
184
460
  }) => Promise<boolean>;
461
+ /** design/164 件四 — epoch ms at which this run must stop and checkpoint because the EXECUTION
462
+ * ENVIRONMENT's declared lifetime is about to expire (`ExecutionEnv.lifetimeMs` minus
463
+ * {@link ENV_LIFETIME_SUSPEND_MARGIN_MS}). Undefined ⇒ the env declared no lifetime (every local env,
464
+ * and any adapter on an unbounded host) or declared one the engine could not anchor — in both cases the
465
+ * boundary check is dead code, exactly as it was before design/164. Epoch, not monotonic: the anchor
466
+ * comes from the PLATFORM (an env can be older than this process), which is a wall-clock fact and the
467
+ * one domain both sides can name. */
185
468
  envLifetimeSuspendAt?: number;
469
+ /** design/164 件五 — deployment usage governance for this run, or undefined when the deployment wired
470
+ * none (or wired windows without a ledger, which is reported and not enforced). */
186
471
  usageGovernance?: UsageGovernance;
472
+ /** 1.296 件2b — epoch ms at which the loop ISSUED the current provider call (stamped by the
473
+ * per-call stall-watchdog closure, consumed+cleared by runtask's brain.call trace row as
474
+ * `callStartedAt`). Always present. */
187
475
  callIssuedAtRef: {
188
476
  current?: number;
189
477
  };
478
+ /** RB-458 — records the FIRST brain call this run's outer guardrail gave up on (see
479
+ * {@link import("../../brain/timeout.js").withBrainCallGuardrail}). Always present; `timedOut`
480
+ * stays absent unless the guardrail fired. The run loop reads it AFTER the loop settles and gives
481
+ * the task the typed terminal — the harness turns a loop throw into an error assistant message, so
482
+ * without this the cause would reach the caller only as the generic `provider.error`. */
190
483
  brainCallGuardrailRef: BrainCallGuardrailRef;
484
+ /** design/80 D-B — set by a tool calling `ctx.requestReview()` (the first-party `present_plan` tool, CC
485
+ * ExitPlanMode parity): the run loop honors it at the next CLEAN turn boundary by minting a `plan_review`
486
+ * checkpoint. `{ pending }` is set (with an optional reason) the moment a tool requests review; the boundary
487
+ * reads + clears it. First request in a batch wins (idempotent). */
191
488
  reviewRequestRef: {
192
489
  pending?: {
193
490
  reason?: string;
194
491
  };
195
492
  };
493
+ /** design/80 D-B: present (≠ undefined) ONLY when a `checkpointStore` is wired (the deployment can pause). The
494
+ * run loop calls it at a CLEAN turn boundary when `reviewRequestRef.pending` is set: it mints a `plan_review`
495
+ * checkpoint (`status:"needs_review"`, routes to `reviewRef`) + pauses the workspace + aborts the loop, reusing
496
+ * the SAME commit saga as the human/resource suspends. Returns true iff it committed a resumable checkpoint;
497
+ * false ⇒ the request could not be honored (caller drops it and continues). */
196
498
  suspendForReview?: (reason?: string) => Promise<boolean>;
499
+ /** design/74 Slice 4: the prior cross-slice {@link ResourceLedger} (from the resumed checkpoint), so the run
500
+ * loop can size this slice's effective budget = `min(maxCostUsd, remaining)`. Undefined on the first slice
501
+ * (or a non-resource task). */
197
502
  resourceLedger?: ResourceLedger;
503
+ /** design/80 D-E-core (A3): a mutable holder the run loop populates (right after `stats` exists) so the
504
+ * human/irreversible_ask suspend can debit THIS leg's live cumulative spend onto the durable approval
505
+ * ledger it attaches (the resource-slice path passes `sliceSpend` explicitly; this event-driven gate has
506
+ * no such arg, so it reads the live spend here). Read at suspend time; absent ⇒ this leg's spend is not
507
+ * debited (the prior ledger still rides for the cross-leg READ). */
198
508
  liveSpendRef: {
199
509
  get?: () => {
200
510
  costMicroUsd: number;
@@ -203,6 +513,10 @@ export interface Prepared {
203
513
  walltimeMs: number;
204
514
  };
205
515
  };
516
+ /** design/91: the per-task human-review accumulator (synchronous `resolveAsk` waits this leg + the carried
517
+ * prior-leg burden seeded from the resumed checkpoint). The run loop ADDS the durable-resume latency
518
+ * (`now() − cp.suspendedAt`) on a resume, then surfaces it as `stats.humanReview` at assembly (omitted when
519
+ * empty). **Budget-EXCLUDED** — never folded into cost/the budget gate (design/91 §1). */
206
520
  humanReviewRef: {
207
521
  count: number;
208
522
  totalWaitMs: number;
@@ -214,40 +528,123 @@ export interface Prepared {
214
528
  toolArg?: string;
215
529
  }>;
216
530
  };
531
+ /** design/91: the injectable wall-clock the run loop uses for the durable-resume human-review latency
532
+ * (`humanLatencyMs = now() − cp.suspendedAt`), so it reads the SAME clock as the suspend-side `suspendedAt`. */
217
533
  now: () => number;
534
+ /** design/45 resume: the FULL resolved tool list (real tools, never deferred placeholders) so the
535
+ * resume engine can execute a previously-suspended pending tool call directly (it bypasses the gate —
536
+ * the human already adjudicated it). Same wrapping (offload + ctx) the harness runs with. */
218
537
  tools: AgentTool[];
538
+ /** Name→effect map for every tool this task can call (design/44 §3). Used by the abort-path orphan
539
+ * reconcile (design/64 §9) to make interrupted tool_results effect-aware (read/idempotent = safe to
540
+ * repeat; write/unknown = outcome unknown). Unknown names default to `write` (conservative). */
219
541
  toolEffects: Map<string, ToolEffect>;
542
+ /** scan-1/A5 — the orphans the WAKE/CRASH reconcile closed while preparing this run (empty on a fresh or
543
+ * clean session). The run loop replays them onto the stream at run open as synthetic `tool_end` +
544
+ * `message_committed` frames, the same pair the live-abort leg mints at run close: a previous PROCESS
545
+ * died holding those calls, so this run's stream is the only place a consumer can ever learn they ended.
546
+ * Not the live-abort set — that one is reconciled inside the run and never passes through here. */
220
547
  wakeRecovered: RecoveredOrphan[];
548
+ /** Fixed per-request prompt overhead (system prompt + tool schemas, ≈chars/4 tokens). Fed to
549
+ * `maybeCompact.overheadTokens` so the compaction trigger stays accurate in the anchor-less
550
+ * regime (custom Brains that don't report usage — design/64 §26.7). */
221
551
  promptOverheadTokens: number;
552
+ /** design/169-A — accessor for the MAIN lane's latest real brain request (systemPrompt/messages/
553
+ * tools snapshot, recorded at the harness's provider seam just before each main-loop call). Fed
554
+ * to `maybeCompact.forkContext` on all three compaction lanes so the summary request can FORK the
555
+ * already-paid main prefix (CC form). `undefined` until the run's first main-loop call. Summary
556
+ * calls themselves never pass through the recorded seam (they ride the separate compaction-brain
557
+ * wrapper), so the snapshot is never polluted by a summary request. */
222
558
  lastBrainContext: () => CompactionForkContext | undefined;
559
+ /** Narrow workspace reader for compaction working-file attachments (LONGRUN-2): reads a task file
560
+ * via the SAME env the hands ran against (so remote/k8s/E2B tasks read the container's tree, not
561
+ * the control plane's). Present only when the hands are enabled — without an env there is no
562
+ * workspace to re-read. null = unreadable (deleted/binary/transport error); callers skip it. */
223
563
  readTaskFile?: (path: string) => Promise<string | null>;
564
+ /** CC post-compact restore parity (2026-07-03): the task's READ files, most recent
565
+ * first (from the hands' readFileState `lastReadAt` stamps). The compaction working-file
566
+ * attachment prefers this over the modified set — CC restores what the model RECENTLY READ,
567
+ * including untouched reference files. Present only with hands (same gate as readTaskFile).
568
+ * RB-197: seeded entries are excluded — their content lives in the system-prompt lane, which
569
+ * compaction never touches, so re-attaching them into the summary would be a duplicate. */
224
570
  recentlyReadFiles?: () => string[];
571
+ /** RB-197②(独立复审 + codex 命中,已修) — canonicalizes a raw (often relative, model-typed) path the
572
+ * SAME way the hands toolkit does (`resolveKey` against the same containment root `readTaskFile`
573
+ * uses), so `maybeCompact`'s kept-tail/instruction-source exclusions compare paths in the SAME
574
+ * coordinate `recentlyReadFiles()` already uses — without this a plain string match silently never
575
+ * fires for the common relative-vs-canonical case. Present only with hands (same gate as
576
+ * readTaskFile); absent there is no containment root to resolve against, and every path source is
577
+ * already in the same raw coordinate anyway. */
225
578
  normalizeAttachmentPath?: (raw: string) => Promise<string>;
579
+ /** RB-197②(codex 交叉复审命中,已修) — recognizes the hands Read tool's own dedup-stub markers
580
+ * ({@link isReadDedupStubResult}), so `maybeCompact`'s kept-tail scan can tell a SUBSTANTIVE Read
581
+ * result from a stub hit whose original full transmission may already be summarized away. Present
582
+ * only with hands (same gate as readTaskFile). */
226
583
  isDedupStubResult?: (resultText: string) => boolean;
584
+ /** RB-197 (form-one; CC 220 clears readFileState at its compaction landing site, @388663): wired to
585
+ * `MaybeCompactOptions.onApplied` by every compaction lane. Drops the non-seeded read-state entries
586
+ * (the summary just replaced the Read results the dedup stubs point at) and re-registers the files
587
+ * that were re-attached WHOLE. Present only with hands (same gate as readTaskFile).
588
+ * RB-197②(codex 命中,已修): `preserveReadState` carries the kept-tail-visible files that were
589
+ * deliberately skipped for re-attachment — their existing entry must survive the clear too (same
590
+ * reasoning as a seeded entry: the model's view of the file did not change). */
227
591
  onCompactionApplied?: (attachedComplete: ReadonlyArray<{
228
592
  path: string;
229
593
  content: string;
230
594
  }>, preserveReadState?: ReadonlyArray<string>) => void;
595
+ /** design/121: the live diagnostics lane (present only when the gate passed — manager w/ registry +
596
+ * write hands + not opted out). `registry` is drained by runtask at turn boundaries; `nudge` is
597
+ * called (fire-and-forget) after each successful edit/write so the language server re-analyzes. */
231
598
  lspDiagnostics?: {
232
599
  registry: import("../lsp-diagnostics.js").LspDiagnosticsRegistry;
233
600
  nudge: (rawPath: string) => void;
601
+ /** This run's key into the registry's delivered set (the registry is DEPLOYMENT-scoped — one per
602
+ * `NodeLspManager` — so "already delivered" has to be qualified by run). runtask passes it to every
603
+ * `drain` and calls `releaseRun` with it at the run's terminal. */
234
604
  runIdent: string;
235
605
  };
606
+ /** design/133 件④: the live plan-mode flag (`enter_plan_mode` flips it, run-local one-way). Exposed
607
+ * so the run loop's plan-mode attachment producer reads the SAME flag the write-deny enforces —
608
+ * never a second source of truth. Always present (`active:false` when plan mode is unused). */
236
609
  planModeRef: {
237
610
  active: boolean;
238
611
  };
612
+ /** [915] A1 (design/66 anchor revision) — the date-flip detector seam: `legDate` = the date frozen
613
+ * into this leg's system prefix; `today()` = the boundary-time LOCAL date (user-zone-bound closure).
614
+ * The run loop feeds both to the `date_change` attachment producer; the prefix itself never
615
+ * re-renders mid-leg (cache preservation, CC parity). Present only when the prompt carries a date. */
239
616
  dateChange?: {
240
617
  legDate: string;
241
618
  today: () => string;
242
619
  };
620
+ /** [A2] C-4 (design-A §4) — the loadProjectMemory snapshot's declared instruction sources
621
+ * (`ProjectMemoryLoad.instructionSources`): the probe input AND the lane's per-path baseline
622
+ * hashes for the run loop's `instructions_change` attachment. Present only when the deployment's
623
+ * loader declared a non-empty list; the lane additionally requires
624
+ * `RunnerDeps.probeInstructionSources` — either absent ⇒ zero probe calls, byte-identical. */
243
625
  instructionSources?: ReadonlyArray<{
244
626
  path: string;
245
627
  contentHash: string | null;
246
628
  }>;
629
+ /** The `workflow_size_guideline_change` lane's seam, the {@link dateChange} shape one lane over:
630
+ * `legGuideline` = the RESOLVED guideline this leg's Workflow tool card was built with (the card is
631
+ * a per-mount snapshot, so it never re-renders mid-leg — the model learns a retune from the tail
632
+ * frame instead); `current()` = the boundary-time resolved guideline, read live off
633
+ * `RunnerDeps.workflowLimits` so a deployment retuning it mid-run is observable without a re-prepare.
634
+ * Present only when the Workflow tool is actually MOUNTED — a run with no workflow card has no
635
+ * guideline to change. The direct-construction face (`RunWorkflowToolDeps.sizeGuideline`) is out of
636
+ * scope by construction: this mount never passes it, so the deps channel is the lane's only source. */
247
637
  workflowSizeGuideline?: {
248
638
  legGuideline: WorkflowSizeGuideline;
249
639
  current: () => WorkflowSizeGuideline;
250
640
  };
641
+ /** design/133 F5 (§R3 决议): boundary-time external-change scan over the ≤`maxFiles` most-recently-READ
642
+ * files. Stats each via `env.fileInfo` and reports paths whose `mtimeMs` moved past the recorded
643
+ * `lastReadAt` + 2s epsilon (CC getChangedFiles shape: readFileState needs NO new field; the agent's
644
+ * own write-backs refresh `lastReadAt`, so self-edits are immune). ENOENT evicts the readFileState
645
+ * entry (CC evict-only-on-ENOENT — transient stat failures skip, never evict) and is echoed in
646
+ * `evicted` so the caller drops its per-path dedup state in lockstep (LOW-9). Present only with
647
+ * hands; the run loop calls it ONLY when `spec.attachments.changedFiles` opted in (OFF ⇒ zero stat). */
251
648
  detectExternalChanges?: (maxFiles: number) => Promise<{
252
649
  changed: Array<{
253
650
  path: string;
@@ -255,6 +652,21 @@ export interface Prepared {
255
652
  }>;
256
653
  evicted: string[];
257
654
  }>;
655
+ /** G1 通告层 — deferred tools MATERIALIZED (design/36 rematerialize) but not yet announced at a
656
+ * turn boundary. Appended by the rematerialize diff (newly-activated names only — the announced set
657
+ * is seeded with prepare-time actives INCLUDING resume-reseeded ones, so a resume never replays);
658
+ * DRAINED by the run loop only when the `tools_delta` attachment actually survived the byte cap.
659
+ * Present when the task has deferred tools at all — OR (RB-309) when a declared MCP server failed
660
+ * to connect, so the failure is announceable even on a task whose every MCP tool went missing with it.
661
+ *
662
+ * RB-309 — the same frame's MCP arms, filled by the SAME rematerialize seam / materialize-time
663
+ * projection and drained by the same intact-survival predicate:
664
+ * - `pendingRemoved`: previously-ANNOUNCED tool names that left the live roster (a RefreshMcpTools
665
+ * re-splice whose server withdrew them). CC `removedNames`.
666
+ * - `pendingReadded`: names in `pendingRemoved`'s history that came back on a later refresh. CC
667
+ * `readdedNames`.
668
+ * - `pendingFailed`: declared servers whose connect failed at materialize (`statuses`), name/error
669
+ * neutralized + bounded at intake. CC `failedMcpServers`. */
258
670
  toolsDeltaRef?: {
259
671
  pending: string[];
260
672
  pendingRemoved: string[];
@@ -264,6 +676,16 @@ export interface Prepared {
264
676
  error?: string;
265
677
  }>;
266
678
  };
679
+ /** G1 通告层续批 (CC `agent_listing_delta` parity) — the mounted delegation tool's agent-type roster
680
+ * (read off `ToolSpec.agentListing`, filled by createSubagentTool), plus the tool's mounted name for
681
+ * the CC-verbatim headers. [c209-C]: this seam is now the roster's ONLY model-facing carrier —
682
+ * the run loop delivers the initial full frame ON THE FIRST USER TURN (prompt-adjacent) and
683
+ * boundary drift deltas after. `models` (Q4, read off `ToolSpec.agentModels`) rides the initial
684
+ * frame's tail line. `seedAnnounced` = a durable-resume leg: the run loop seeds the producer's
685
+ * announced set from the checkpoint's `announcedListings.agents` name-set when present (drift
686
+ * since suspend IS delta-announced), else the MED-3② transcript probe (delivered ⇒ seeded as
687
+ * the current entries; unconfirmed ⇒ the resume leg re-announces the initial listing). Present
688
+ * only when such a tool is mounted AND its roster is non-empty. */
267
689
  agentListing?: {
268
690
  entries: ReadonlyArray<{
269
691
  name: string;
@@ -273,34 +695,88 @@ export interface Prepared {
273
695
  seedAnnounced: boolean;
274
696
  models?: readonly string[];
275
697
  };
698
+ /** [c209-C] skills_listing counterpart of {@link agentListing} — the normalized skills METADATA
699
+ * projection (names/descriptions/attachment paths, never bodies; the exact list `createSkillTool`
700
+ * serves). Initial full `<skills>` frame on the first user turn, drift deltas at boundaries,
701
+ * same seeding contract. Present only when `spec.skills` is non-empty (post 1MB-gate). */
276
702
  skillsListing?: {
277
703
  entries: ReadonlyArray<SkillListingEntry>;
278
704
  seedAnnounced: boolean;
279
705
  };
706
+ /** [c209-C] Q5 — the run loop's live mirror of the listing frames' announced NAME-SETS (updated at
707
+ * every commit point: first-frame delivery, intact boundary survival, resume seed). Read by the
708
+ * suspend-time checkpoint serializer (`CheckpointState.announcedListings`) so a resume leg can
709
+ * diff the then-current roster/skills against what the model actually saw. Always present (empty
710
+ * object when nothing announced / no listing faces mounted). [c209-C] R2 C7: `models` mirrors the
711
+ * ANNOUNCED model catalog the same way (advanced only when a committed frame carried one), so a
712
+ * catalog change across a suspend is re-announced as a "Models available…" drift line. */
280
713
  announcedListingsRef: {
281
714
  agents?: readonly string[];
282
715
  skills?: readonly string[];
283
716
  models?: readonly string[];
284
717
  };
718
+ /** G1 通告层 — narrow post-compact getter over the process task registry: THIS run's visible
719
+ * pending/running background tasks (same owner/scope/session identity the TaskOutput/TaskStop tools
720
+ * use), as a bounded display projection (id/description/status — never handles/env/abort). Called by
721
+ * the run loop ONLY when `spec.attachments.backgroundTasks` opted in AND a compaction just landed. */
285
722
  listBackgroundTasks: () => Array<{
286
723
  id: string;
287
724
  description?: string;
288
725
  status: string;
289
726
  }>;
727
+ /** design/122 D1 — the parent-run subagent-retain ledger (present ONLY when `spec.retainSubagentSessions`
728
+ * is enabled). The Runner disposes it (abort in-flight resumes + unpin + release every retained child
729
+ * session) in the task's terminal `finally` — same UNCONDITIONAL posture as the background-agent reap:
730
+ * retain is NOT durable (a suspend leg's in-memory ledger cannot survive a re-prepare), so releasing on
731
+ * every exit path is hygiene, never a loss. */
290
732
  subagentRetain?: SubagentRetainLedger;
733
+ /** design/84 Seam C: run-scoped consecutive-`summaryProvider`-reuse counter, OWNED by the Runner and
734
+ * SHARED across both compaction call sites (within-task turn boundary + `finish()`), so the
735
+ * `maxConsecutiveProviderReuse` drift guard is enforced over the whole task — incremented when a
736
+ * compaction reused the provider's summary, reset to 0 on a real (LLM) summary. */
291
737
  compactionReuseRef: {
292
738
  consecutive: number;
293
739
  };
740
+ /** design/123 D4 — trim→compaction pressure propagation (16k live sawtooth root cause): set by the
741
+ * context hook when `trimToBudget` actually DROPPED messages from a request view (request-only trim
742
+ * + usage-anchor mismatch deflates the next boundary's estimate → the trigger and floor are both
743
+ * deceived → full-size request spikes alternate with trimmed troughs). The next turn boundary's
744
+ * `maybeCompact` consumes it as `force: true` (bypasses the auto threshold AND the §25.2 anti-thrash
745
+ * floor — "the request layer was forced to drop history" is direct evidence compaction is overdue).
746
+ * One-shot: cleared on consumption; a failed compaction does NOT re-arm it (existing breaker path).
747
+ * Content-only clears (`clearStaleToolResults`) never set it — only real message drops do. */
294
748
  trimPressureRef: {
295
749
  droppedMessages: boolean;
296
750
  };
297
751
  }
752
+ /**
753
+ * design/45 resume inputs threaded into {@link prepareTask} to continue a suspended task. The Runner
754
+ * builds it from the persisted {@link Checkpoint}: rewind the branch to the suspension leaf, skip the
755
+ * suspended batch during wake-reconcile, and re-seed the §4.bis per-task correctness state so the
756
+ * resumed run is in the **same state space** it suspended in.
757
+ */
298
758
  export interface PrepareResume {
759
+ /** The session leaf to rewind to (the suspension point) BEFORE reconcile — discards the abort's
760
+ * off-branch "Operation aborted" writes so the resume engine resolves the pending batch cleanly. */
299
761
  leafId: string;
762
+ /** Batch tool-call ids of the suspended turn — wake-reconcile SKIPS these (they are resumed, not
763
+ * crash-interrupted; closing them with `[INTERRUPTED]` would DESTROY the suspended batch, §15.2 #7). */
300
764
  suspendedBatch: ReadonlySet<string>;
765
+ /** The §4.bis correctness-state snapshot to re-seed (activeTools / outputRef / nestedStats /
766
+ * consolidationNotes / readFileState). */
301
767
  seed: CheckpointState;
768
+ /** design/72 §2.2 (B): how many times this task already suspended (the resumed checkpoint's
769
+ * `suspendCount`). The next suspend mints `priorSuspendCount + 1`; past `maxSuspends` it fails
770
+ * (`suspend.loop`) instead of re-suspending. Absent/0 ⇒ no prior suspends. */
302
771
  priorSuspendCount?: number;
772
+ /** design/74 Slice 4: the cross-slice {@link ResourceLedger} carried by the resumed `resource_limit`
773
+ * checkpoint (cumulative spend + the frozen human totals). The next slice's effective budget is
774
+ * `min(maxCostUsd, totalBudget − spent)`, and its own suspend debits onto this. Absent ⇒ the first slice. */
303
775
  priorLedger?: ResourceLedger;
776
+ /** design/91: the accumulated human-review burden carried by the resumed checkpoint
777
+ * ({@link import("../checkpoint-store.js").Checkpoint.humanReview}) — the gates resolved up to and including
778
+ * the suspend BEFORE this one. Seeds the per-task accumulator so the resumed leg ADDS this suspend's own
779
+ * latency (`now() − cp.suspendedAt`) on top, reporting the WHOLE chain's burden. Absent ⇒ no prior human time. */
304
780
  priorHumanReview?: {
305
781
  count: number;
306
782
  totalWaitMs: number;
@@ -312,30 +788,181 @@ export interface PrepareResume {
312
788
  toolArg?: string;
313
789
  }>;
314
790
  };
791
+ /** design/49 v1.5: when the suspend ran with a remote workspace, the {@link CheckpointState.workspaceHandle}
792
+ * to restore — prepare rebuilds the per-task env via `deps.executionEnvFactory` then `resumeVM(snapshotId)`
793
+ * + `postResumeInit()` (instead of running on a fresh, empty env). Threaded HERE (not via `ResumeTaskConfig`)
794
+ * so the factory stays a deployment-level `RunnerDeps` capability and never pollutes `TaskSpec` — preserving
795
+ * the "untrusted caller can't inject an env" red line (remote-env.ts:234, code-ready council round-2). */
315
796
  workspaceHandle?: import("../remote-env.js").WorkspaceHandle;
797
+ /**
798
+ * design/174 — the call id of the CONTENT ask whose answer an operator's approval was spent on, when
799
+ * that is what this leg redeems. Scoped as an id, not a leg-wide flag: an `unavailable` outcome on
800
+ * THAT call must become a coded failure (the approval bought a question nobody answered), while a NEW
801
+ * question raised later on the same leg had no approval spent on it and keeps the ordinary
802
+ * continuation. Absent when the resumed pending action is not a question.
803
+ */
316
804
  redeemedContentAskCallId?: string;
805
+ /** Digest of that question's batch — the id alone can repeat, so the pairing is what keeps a LATER
806
+ * question from inheriting the claim that an operator approved it. */
317
807
  redeemedContentAskQuestionsHash?: string;
808
+ /** codex 1360 r6 — true iff this resume will EXECUTE an approved pending tool (`tool_approval`
809
+ * checkpoint × an `allow` winner). The divergent-restore fail-closed guard keys on THIS, not on the
810
+ * batch being non-empty: a deny winner executes nothing, so a workspace-root divergence must not
811
+ * wedge the refusal (it proceeds under the path-state rebase and records the deny). */
318
812
  executesApprovedAction?: boolean;
319
813
  }
814
+ /**
815
+ * Parent effective-policy inheritance (tighten-only, {@link RunInternals.inheritedGate}): the spawning
816
+ * chain's already-evaluated FINAL gate, split into two halves —
817
+ *
818
+ * - **Data half** (`ancestorRules`, `shellGate`): serializable snapshots. Each ancestor's per-session
819
+ * permission rules ride as (sessionId, principal, rev, rules) so the child's prepare can re-read them
820
+ * LIVE (rev-monotonic — a lagging replica never loosens the snapshot) and re-compile them against the
821
+ * CHILD's own env/root/effects as extra deny-narrowing layers. `shellGate` folds by max-rank
822
+ * (off < classify < always): a child can only tighten the parent's shell doctrine, never relax it.
823
+ * - **Opaque half** (`parentConstraints`): each ancestor's live caller `ToolPolicy` plus its FROZEN
824
+ * `onAsk`, ancestors first — and, for a hook-wired ancestor, a SECOND entry: its PreToolUse screening
825
+ * face folded into a `ToolPolicy` (`createPreToolUseConstraintPolicy`), carrying its own frozen
826
+ * approver/mandate/env axes (the `preToolUse`/`hookEnv` fields below). Folded AFTER the child's own caller policy and BEFORE the trailing
827
+ * deny-narrowing re-check, each wrapper resolving its own `ask` via the ancestor's frozen approver —
828
+ * so a parent `ask` never widens into a child auto-allow, and a parent `allow{updatedInput}` rewrite
829
+ * is still re-checked by the child's narrowing layers. NOT serializable: a durable resume must
830
+ * re-supply it via `resumeStream(..., internals)` (see {@link CheckpointState.inheritedGate}).
831
+ *
832
+ * Chain assembly is single-sited in prepareTask's ctx injection (`inheritedGateForChildren`): upstream
833
+ * chain + THIS task's own contribution (its session-rule snapshot, its RESOLVED caller policy —
834
+ * `spec.toolPolicy ?? deps.toolPolicy`, the same slot its own gate enforces — + frozen onAsk, its
835
+ * effective shellGate, and — when this task resolved a PreToolUse hook — a screening entry for that
836
+ * hook, deduped by full installation so a deps-level hook is consulted once per call at any depth).
837
+ * Depth-N delegation is therefore a linear chain, each layer evaluated at most once per tool call.
838
+ */
320
839
  export interface InheritedGate {
840
+ /** Serializable ancestor session-rule snapshots (data half), ancestors first. */
321
841
  ancestorRules?: ReadonlyArray<{
322
842
  sessionId: string;
323
843
  principal?: string;
324
844
  rev: number;
325
845
  rules: SessionPermissionRules;
326
846
  }>;
847
+ /** The chain's effective shell-gate doctrine — the child folds it by max-rank with its own spec. */
327
848
  shellGate?: "off" | "always" | "classify";
849
+ /**
850
+ * Org-memory admission freeze (ruled 2026-08-05): the spawning chain's FROZEN admitted org-scope
851
+ * set — every org memory scope the parent actually mounted (deployment-origin + admitted request).
852
+ * A delegated child's REQUEST-origin org scopes must be a subset (intersection ≠ request ⇒ the
853
+ * child's prepare refuses, `memory.admission_denied`); deployment-origin scopes bypass the freeze
854
+ * (operator authority is deployment-wide). ALWAYS emitted by chain assembly (empty array = parent
855
+ * mounted no org plane), so an ABSENT field discriminates an older-shape chain — which the child
856
+ * side reads fail-closed as the empty set. Serializable (plain strings): persists on the
857
+ * checkpoint's data half and folds seed ∩ live on resume (tighten-only).
858
+ */
328
859
  admittedOrgScopes?: readonly string[];
860
+ /**
861
+ * The MONOTONIC org-governance provenance bit (adversarial round 5): `true` when any leg of this
862
+ * tree ran with an org-admission surface configured (resolver / deployment scope list) or
863
+ * inherited the bit. It never clears once set (a governed tree stays governed), and it counts as
864
+ * governance evidence at the admission door EVEN when every admitted set en route is empty — a
865
+ * governed parent's org-less child, resumed on a surface-less worker, must still refuse
866
+ * org-shaped non-v2 scopes instead of mounting them as opaque keys. Absent on trees that never
867
+ * had a governance surface (their opaque posture is untouched). Serializable; persists on checkpoints.
868
+ */
329
869
  orgAdmissionGoverned?: true;
870
+ /** Live ancestor caller-policy constraints (opaque half), ancestors first. `policy` is the ancestor's
871
+ * RESOLVED caller policy (`spec.toolPolicy ?? deps.toolPolicy` — the same slot the ancestor itself
872
+ * enforces, so a deps-level baseline is inherited too). `onAsk` is the ancestor's frozen
873
+ * `spec.onAsk ?? deps.onAsk` — an ancestor `ask` resolves at that ancestor's own approver
874
+ * (headless ⇒ deny), never at the child's. `durableMandate` is frozen at chain-assembly time when the
875
+ * ancestor ran under a durable-approval regime that would actually PARK its own plain asks — a
876
+ * `forceDurableGate` entitlement, or `durableApproval` with NO live onAsk frozen (with a live approver
877
+ * the ancestor's own plain asks resolve synchronously there, so a descendant's ask resolves at that
878
+ * same frozen `onAsk` — no mandate). It is a CONSERVATIVE descendant-side mandate: whether or not a given ask would actually
879
+ * have parked at the ancestor (the regime may be scoped), the durable-park semantics cannot be
880
+ * reconstructed in a delegated child's context — so a wrapper seeing `ask` under this flag denies
881
+ * fail-closed (tighten-only holds) instead of resolving synchronously. */
330
882
  parentConstraints?: ReadonlyArray<{
331
883
  policy: ToolPolicy;
332
884
  onAsk?: OnAsk;
333
885
  durableMandate?: boolean;
886
+ /**
887
+ * Set ONLY on an entry whose `policy` is the folded form of an ancestor's PreToolUse screening face
888
+ * (issue #33 — the face used to stop at the task that installed it, so a call the ancestor had
889
+ * refused executed one level down). It carries the raw callback for ONE purpose: identity. A
890
+ * deployment-level face (`RunnerDeps.hooks`) is resolved by every task in the tree on its own, so
891
+ * each descendant's gate already runs it in phase 1 — folding it AGAIN as an inherited constraint
892
+ * would consult the same callback twice per call at depth 1 and once more per level below. Two
893
+ * identity tests keep that at exactly one consultation per call: chain assembly does not re-append a
894
+ * face already on the chain, and a descendant substitutes a pass-through for the entry naming the
895
+ * very callback its own gate will run. A per-task face (`TaskSpec.hooks`) is a different function in
896
+ * the descendant (or absent), so it folds and travels.
897
+ *
898
+ * Identity is the only sound test here, and it is deliberately the CONSERVATIVE one: an assembly that
899
+ * hands each task a freshly bound wrapper over one underlying callback (the `runSpec` mux does this)
900
+ * produces two distinct function objects, so the descendant both folds the ancestor's entry and runs
901
+ * its own — the callback is consulted twice rather than skipped. Erring toward a second screening,
902
+ * never toward a missed one, is what makes an identity miss a cost rather than a hole.
903
+ */
334
904
  preToolUse?: Hooks["preToolUse"];
905
+ /**
906
+ * The environment this screening face was installed against — the source of the `HookEnvCapabilities`
907
+ * handed to it, compared BY REFERENCE, `undefined` when the installation had no env face. Part of the
908
+ * installation's identity for the same reason the frozen approver is (codex review, HIGH): a face that
909
+ * resolves paths through `ctx.env` answers a different question in a different environment, so an
910
+ * ancestor running against the deployment's tree and a descendant running in an isolated worktree are
911
+ * two screenings, not one. A deployment with a per-task `executionEnvFactory` therefore has its face
912
+ * consulted once per environment on the chain rather than once overall — which is the point: the
913
+ * ancestor's environment is the only place the ancestor's verdict can be reproduced.
914
+ *
915
+ * ⚠️ RECORDED BOUNDARY (delegation provenance, codex review): the approver half of the key compares
916
+ * through {@link askApproverIdentity}, which by its own contract answers "the same decision-maker",
917
+ * collapsing a `withDelegationProvenance` wrapper onto the approver it forwards to. Two installations
918
+ * whose approvers differ ONLY in the provenance they attach therefore count as one. Raw reference
919
+ * equality is not an available alternative: a delegated child's approver is ALWAYS a fresh wrapper
920
+ * over its parent's, so raw equality would collapse nothing and a deployment-level face would be
921
+ * consulted once per ancestor level on every leaf call. The exposure is bounded on the side that
922
+ * matters — the pass-through arm hands the frame to the DESCENDANT's own gate, whose approver carries
923
+ * the descendant's own provenance (strictly more context, never less). What a chain-assembly collapse
924
+ * can drop is one intermediate installation's provenance on an ask: an approver that DECIDES on
925
+ * `req.delegation` would see the surviving installation's rather than both.
926
+ */
335
927
  hookEnv?: unknown;
336
928
  }>;
337
929
  }
930
+ /**
931
+ * design/78 Slice-1 (MAJOR-3 wiring): a TRUSTED, run-scoped internal channel into {@link prepareTask}, set
932
+ * ONLY by a trusted CORE caller (`runRepairLoop` via the Runner's internal `runTaskStream` arg) — NEVER from
933
+ * a {@link TaskSpec} field (the untrusted-caller surface, design/44 §7 Q4). It is the live-state counterpart
934
+ * of {@link PrepareResume.seed}: where `resume.seed` re-seeds correctness state RESTORED from a checkpoint,
935
+ * this carries the LIVE per-task state the Runner cannot otherwise see (it lives in the caller's closure).
936
+ *
937
+ * Originally it carried only the repair loop's live {@link RepairBundle}: `runRepairLoop` is a thin composition
938
+ * OVER `runner.runTask`, so when an orthogonal durable suspend (resource/HITL) interleaves a repair attempt,
939
+ * the bundle (failureTrace/diagnostics/attemptCount/oracleTier) sits in the loop's closure and was being lost
940
+ * — the minted checkpoint serialized `repairBundle: undefined`. Threading it here lets
941
+ * {@link prepareTask}'s `serializeCheckpointState` source the LIVE bundle so a resume re-seeds `attemptCount`
942
+ * MONOTONICALLY (design/76 §2.2#1 r4 MAJOR-A). Mirrors how `nestedStats`/`resume.seed` thread trusted
943
+ * run-scoped internals through the Runner without touching `TaskSpec`.
944
+ */
945
+ /**
946
+ * R2 双形轴(clay 追加令 2026-07-18): CC 2.1.212's fable-variant prompt gate (b9e —
947
+ * `fable_5_mitigations` capability / claude-mythos-5), ORTHOGONAL to the simple/classic profile.
948
+ * sema is BYOM, so the id may carry provider prefixes ("anthropic/claude-fable-5",
949
+ * "openrouter/anthropic/claude-fable-5"): BOUNDARY-AWARE family match on the last path segment
950
+ * (codex 统一复审 F3 — raw substring classified "vendor/not-claude-fable-5" and "claude-mythos-50"
951
+ * as fable), case-normalized. Recognition set = CC's _Nr (startsWith "claude-fable-") + b9e
952
+ * (mythos-5). R3 system sections fork on the resulting fact.
953
+ */
338
954
  export declare function isFableFamilyModelId(id: string): boolean;
955
+ /**
956
+ * RB-50 (CC 2.1.220 启示①, clay 2026-07-25): the SINGLE decision point for the two prompt-shape axes.
957
+ * Both were resolved in separate places with different mechanisms — `promptProfile` off a TaskSpec field,
958
+ * `fableMitigations` off a raw model-id prefix test — so "which shape does this task speak" had no one
959
+ * place to read. CC 2.1.220's counterpart is a model-registry `capabilities` array (one table drives
960
+ * `lean_prompt` + `fable_5_mitigations` alike; anchors/2.1.220/CC-218-220-DIFF.md §2).
961
+ *
962
+ * sema stays BYOM: we cannot key off a capability table for arbitrary model ids, so the RESOLUTION RULES
963
+ * are unchanged — profile: spec > inherited internals > "simple"; mitigations: model family. This is a
964
+ * consolidation, not a behavior change (the axes stay ORTHOGONAL: neither rewrites the other).
965
+ */
339
966
  export declare function resolveModelPromptTraits(model: {
340
967
  id: string;
341
968
  }, spec: {
@@ -347,61 +974,443 @@ export declare function resolveModelPromptTraits(model: {
347
974
  fableMitigations: boolean;
348
975
  };
349
976
  export interface RunInternals {
977
+ /** The live repair bundle from a `runRepairLoop` attempt in flight (attemptCount>0). Serialized onto a
978
+ * checkpoint minted MID-attempt so a resume re-seeds it; undefined for any non-repair run. */
350
979
  repairBundle?: RepairBundle;
980
+ /**
981
+ * design/173 §8.2 — the ENGINE deliberately stripped the spawn turn's per-request `onQuestion`
982
+ * face from this leg's spec (a long-lived background/retained/revived child must not hold a
983
+ * callback torn down with the turn that spawned it). Minted ONLY by the subagent lanes'
984
+ * `stripSpawnTurnQuestionFace` helper, PAIR-PRODUCED with the strip itself — never inferred from
985
+ * spec shape. Consumed by the wiring manifest (`question.wired: "stripped_bg_lane"`) and by the
986
+ * interaction-posture door (the strip is core's correct design, not a configuration lie, so an
987
+ * `"interactive"` tree's engine-stripped legs are exempt). TRUST POSTURE (ruled 2026-08-05):
988
+ * RunInternals is a public trusted-caller parameter, so this flag is an honesty channel, not a
989
+ * security gate — a caller forging it is a deployment lying to itself; resource-face safety
990
+ * stays with its own fail-closed mechanisms.
991
+ */
351
992
  questionFaceStripped?: true;
993
+ /**
994
+ * design/173 §8.3 (review fold r2-F1) — the SPAWNING run's resolved interaction posture, carried
995
+ * into engine-built children over the trusted internals channel (never copied onto the child
996
+ * SPEC — the §8.3 rule). The child's door resolves `spec ?? THIS ?? deps`, so a root's per-run
997
+ * posture override governs its whole engine-built tree instead of every child falling back to
998
+ * the deps-level default. Filled by the delegation lanes' `childInternals` and the workflow
999
+ * spawn attribution; rides `internalsSnapshot`, so retained/revived legs keep it.
1000
+ */
352
1001
  parentInteractionPosture?: "interactive" | "headless";
1002
+ /**
1003
+ * design/153 §7.2c (件3c, r6 H-1) — the trusted post-consume hook for the PARKED-RESUME drive:
1004
+ * called by `resumeStream` after its resolve CAS WON (the token is consumed — the master
1005
+ * arbitration is decided) and BEFORE the resumed leg starts. The parked-resume caller uses it to
1006
+ * flip the reserved row `parked→running` (guarded CAS) + adopt the live handle/lane — the ONLY
1007
+ * legal site for that flip (a pre-consume flip would let TaskStop hit the plain running arm and
1008
+ * bypass the checkpoint arbitration entirely). A THROW here aborts the resume (propagates out of
1009
+ * `resumeStream`): the checkpoint is already consumed, so the caller's compensation
1010
+ * (`rollbackParkedClaim`) reads `resolved` and settles the honest failed/outcome-unknown terminal
1011
+ * — never a silent run without an adopted row. Deployment/trusted-caller channel only, mirroring
1012
+ * every other RunInternals field.
1013
+ */
353
1014
  afterCheckpointResolve?: () => Promise<void>;
1015
+ /**
1016
+ * Parent effective-policy inheritance (tighten-only): the spawning parent's already-evaluated FINAL
1017
+ * gate, threaded into a child task so the child inherits it as ADDITIONAL constraint layers — a child
1018
+ * can only ever be narrowed by this, never widened (its own session rules / skill scope / caller policy
1019
+ * still apply in full). Filled ONLY by core delegation callers (`createSubagentTool`'s execute via
1020
+ * `ToolExecuteContext.inheritedGateForChildren`, the workflow spawn legs) — NEVER a {@link TaskSpec}
1021
+ * field (the untrusted-caller surface), mirroring `inheritedManifestScope`'s ctx-injection posture.
1022
+ * Absent ⇒ no inheritance (a top-level task; fully backward-compatible).
1023
+ */
354
1024
  inheritedGate?: InheritedGate;
1025
+ /**
1026
+ * #22 (ruled 2026-08-05) — the SESSION-scoped org-admission freeze for a SAME-SESSION continuation
1027
+ * that is NOT a checkpoint resume: a retained background child revived through the in-process resume
1028
+ * leg. The checkpoint plane already freezes the session's own verdict
1029
+ * ({@link InheritedGate.ownAdmittedOrgScopes}); this leg has no checkpoint, so without a carrier it
1030
+ * re-adjudicated from scratch and a resolver whose answer WIDENED between the two legs remounted a
1031
+ * tenant layer the session had already lost.
1032
+ *
1033
+ * A REF, not a value: the revival replays a spread COPY of the spawn-time internals, so a plain field
1034
+ * could only ever carry the value that existed at spawn (always `undefined`). The prepare reads
1035
+ * `current` as its `priorOwnVerdict` — intersected with any checkpoint seed, so the fold can only ever
1036
+ * narrow — and writes this leg's own verdict back, which is ⊆ the prior one by construction.
1037
+ *
1038
+ * TRUSTED internal, filled by `createSubagentTool`'s `childInternals` (one ref per spawned child, never
1039
+ * shared across generations — a child's own children build their own). Absent ⇒ no session freeze from
1040
+ * this channel, byte-identical to a deployment with no governance surface.
1041
+ */
355
1042
  ownOrgAdmissionRef?: {
356
1043
  current: import("../memory-admission.js").OwnOrgAdmissionVerdict | undefined;
357
1044
  };
1045
+ /**
1046
+ * design/176 — this run's LATE-BOUND peer-identity carrier (a REF, same family and reason as
1047
+ * {@link ownOrgAdmissionRef}: revival replays a spread copy of spawn-time internals, and the axes
1048
+ * a run wears are born at different points — a* handle at registration, session/task at prepare's
1049
+ * session acquisition). Created at internals assembly (delegation lanes; runtask normalizes one
1050
+ * in for a top-level run); axes recorded through the single monotonic `addAxis`; the canonical
1051
+ * key freezes at the first recorded axis (h→s→t by call-site ordering). Read by the SendMessage
1052
+ * mount (sender key + hop token) and paired into children as {@link parentPeerRef}.
1053
+ */
358
1054
  peerSelfRef?: import("../../agents/peer-admission.js").PeerSelfRef;
1055
+ /**
1056
+ * design/176 — this run's INBOUND peer-chain ref: overwritten at the harness consumption boundary
1057
+ * with the chain of the peer message the model just consumed (enqueue-time writes would leak a
1058
+ * not-yet-seen message's chain into outbound sends); seeded by the L3/L4 wake legs; empty
1059
+ * otherwise. Not checkpointed in v1 (recorded honest boundary: a cross-process resume forwards
1060
+ * from an empty chain — fail-open on loop suppression only).
1061
+ */
359
1062
  peerInboundChainRef?: import("../../agents/peer-admission.js").PeerInboundChainRef;
1063
+ /**
1064
+ * design/176 — the PARENT run's peer-identity ref, PAIR-MINTED with {@link parentNotify} at every
1065
+ * trust point that binds the uplink callback (spawn assembly, the resume face's replacement): the
1066
+ * callback is opaque and the parent AXES deliberately keep the original spawner on the revive arm
1067
+ * while the callback points at the WAKER — so the uplink's admission identity can only travel
1068
+ * with the binding itself. Consumed by the SendMessage mount as `uplinkRecipient`.
1069
+ */
360
1070
  parentPeerRef?: import("../../agents/peer-admission.js").PeerSelfRef;
1071
+ /**
1072
+ * 🔴 design/97 §H.1 / design/98 §0.1 (BLOCKER3) — the workflow **nesting depth** for this run, a TRUSTED
1073
+ * cross-process channel (worker/script can NEVER set it — it is not a {@link TaskSpec} field nor a
1074
+ * `run_workflow` tool param). When a deployment initiates a workflow on behalf of a parent run that is
1075
+ * itself inside a workflow (e.g. service's `/v1/workflows`), it threads `workflowDepth = parentDepth + 1`
1076
+ * into `startWorkflow`/`runWorkflow` so the one-level nesting guard fires across the process boundary.
1077
+ * In-process nesting needs nothing here — the engine's `AsyncLocalStorage` propagates depth automatically.
1078
+ * Mirrors how `repairBundle`/`inheritedManifestScope` thread trusted run-scoped internals the Runner cannot
1079
+ * see from `spec`. Consumed by the `run_workflow` tool wiring (S8c), not by `prepareTask` itself.
1080
+ */
361
1081
  workflowDepth?: number;
1082
+ /**
1083
+ * design/110 — set ONLY by the Agent tool's fork route (`Agent(subagent_type:"fork")`, a core caller) on the
1084
+ * child it spawns: this run IS a forked child. `prepareTask` threads it to tool ctx as `insideFork` so the
1085
+ * child's own Agent tool refuses a nested fork (nesting guard — mirrors CC's "fork is not available inside a
1086
+ * forked worker"; a fork can still delegate via `Agent`, just not fork again). TRUSTED internal (NOT a
1087
+ * `TaskSpec` field — the untrusted-caller surface), mirrors `inheritedManifestScope`.
1088
+ */
362
1089
  insideFork?: boolean;
1090
+ /**
1091
+ * RB-204 P1 (codex review) — set UNCONDITIONALLY by every core spawn path (`createSubagentTool`'s
1092
+ * `childInternals` — shared by all four spawn legs sync/steer/background/fork, its persisted
1093
+ * `internalsSnapshot` for revive, and the workflow orchestrator's `spawnAttribution`), regardless
1094
+ * of whether a NAMEABLE `parentTaskId`/`parentToolCallId` exists. A directly-started workflow (no
1095
+ * launching tool call, e.g. cron-triggered) has neither of those — "no id is ever fabricated" for
1096
+ * attribution — but its spawned agents are still delegated children for consent-notice purposes.
1097
+ * Drives `isSubagent` below: do NOT use `parentTaskId` presence alone as the child-ness signal,
1098
+ * that under-covers exactly this case. TRUSTED run-scoped channel (NOT a {@link TaskSpec} field),
1099
+ * mirroring `insideFork`.
1100
+ */
363
1101
  isDelegatedChild?: boolean;
1102
+ /**
1103
+ * G1+G2 合车复审修② (1.259.0) — the DEFAULT role-base persona for a DELEGATED child, threaded by
1104
+ * `createSubagentTool`'s execute (a core caller) when neither an agent-definition `systemPrompt` nor the
1105
+ * delegation tool's `opts.systemPrompt` names one. It sits at the BOTTOM of the role-base chain —
1106
+ * `spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals.defaultSystemPrompt` — so a deployment's
1107
+ * `roles.subagent.systemPrompt` / `roles.default.systemPrompt` preset still wins (pre-G1 semantics: an
1108
+ * unset child systemPrompt let the role preset apply; G1's first cut put SUBAGENT_PROMPT at spec level
1109
+ * and silently shadowed the preset). Only when NO preset resolves does the lean SUBAGENT_PROMPT (CC 198
1110
+ * general-purpose persona, pretty.js:419977) replace the full DEFAULT_SYSTEM_PROMPT constitution base.
1111
+ * TRUSTED run-scoped channel (NOT a {@link TaskSpec} field), mirroring `insideFork`.
1112
+ */
364
1113
  defaultSystemPrompt?: string;
1114
+ /**
1115
+ * design/96 §C (S2) — GOAL MODE flag, a TRUSTED internal channel set ONLY by `runGoal` (a core caller),
1116
+ * NEVER a {@link TaskSpec} field. It drives `featureFlags.goalEnabled` → injects `GOAL_COMPLETION_GUIDANCE`.
1117
+ * Why internal (not a public `TaskSpec.goalMode`): the guidance promises "declaring done STOPS iteration and
1118
+ * surfaces" — a promise only `runGoal`'s loop makes real. A public field would let a caller inject that
1119
+ * prompt with no loop behind it (§6.3 honesty violation). `runGoal` injects the `declare_done` tool itself;
1120
+ * this flag only governs the PROMPT (codex r2 — injection-ownership split).
1121
+ */
365
1122
  goalMode?: boolean;
1123
+ /**
1124
+ * 🔴 design/77 §3 / §7 (ON-前必关) — skill→subagent manifest-scope PROPAGATION. The parent task's
1125
+ * ACTIVE skill-manifest frames, snapshotted at the moment a subagent was spawned WHILE a manifest scope
1126
+ * was live on the parent. The child's {@link prepareTask} seeds its own {@link ActiveSkillScope} from
1127
+ * these so the child inherits the parent skill's deny-narrowing — fail-closed and MONOTONIC: a child of
1128
+ * a manifested skill is AT MOST as capable as the manifest (its own manifests can only narrow further,
1129
+ * never re-grant a tool/path the parent removed).
1130
+ *
1131
+ * This is a TRUSTED, run-scoped channel filled ONLY by `createSubagentTool`'s `execute` (a core caller),
1132
+ * NEVER a {@link TaskSpec} field (TaskSpec is the untrusted-caller surface — design/44 §7 Q4). It mirrors
1133
+ * how `repairBundle`/`resume.seed` thread live per-task state the Runner cannot see from `spec`.
1134
+ *
1135
+ * Fail-closed: when the parent HAD an active manifest at spawn but the precise frames cannot be
1136
+ * snapshotted, the subagent tool threads a single DENY-ALL `unresolved` frame here rather than letting the
1137
+ * child run unmanifested — the safe path is the default. An empty/absent value = no inheritance (a
1138
+ * subagent spawned with no active parent manifest behaves exactly as before, backward-compatible).
1139
+ */
366
1140
  inheritedManifestScope?: readonly ActiveSkillFrame[];
1141
+ /**
1142
+ * design/99 §E2 — when this task runs as a SUB-AGENT spawned under a parent task's
1143
+ * tool call, the spawning tool's `ToolExecuteContext.toolCallId`. The Runner stamps it onto this task's
1144
+ * stream content events as {@link TaskEvent.parentToolCallId} so a consumer can attribute the child's live
1145
+ * content to the delegation subtree WITHOUT core merging the child stream into the parent (lightweight
1146
+ * message-identity, not stream-merge). A TRUSTED, run-scoped channel filled by a core caller
1147
+ * (`createSubagentTool`'s `execute`) — NEVER a {@link TaskSpec} field (the untrusted-caller surface),
1148
+ * mirroring `inheritedManifestScope`/`workflowDepth`. Absent for a top-level (non-delegated) task.
1149
+ */
367
1150
  parentToolCallId?: string;
1151
+ /**
1152
+ * design/99 MF-10 / BC-2 (Service AI [§I 1.5.1]) — a SUBAGENT's human display NAME, threaded at spawn so the
1153
+ * child's `task_progress` ticks carry a readable label (a Fleet child row otherwise shows the raw `taskId`).
1154
+ * Filled by `createSubagentTool`'s `execute` = the explicit `taskName`, else the selected agent-type
1155
+ * (`AgentDefinition.name`). TRUSTED run-scoped channel (NOT a {@link TaskSpec} field), mirroring
1156
+ * `parentToolCallId`. Absent for a top-level run / a bare delegation with neither label — the child's
1157
+ * `task_progress` then carries NO `name` (it keeps its taskId; it deliberately does NOT fall back to the raw
1158
+ * objective, which could leak a delegated secret — dual-review Q2). Untrusted (`taskName` is model-chosen) →
1159
+ * the consumer sanitizes via `inlineUntrusted` at emit.
1160
+ */
368
1161
  agentName?: string;
1162
+ /**
1163
+ * design/147 S3 (codex R3 label-vs-identity): the EXPLICIT `Agent({name})` spawn identity — set
1164
+ * ONLY when the spawn carried a `name` parameter, unlike {@link agentName} (a DISPLAY label:
1165
+ * description or agent-type, present on nearly every spawn). Teammate semantics (hierarchy clamp,
1166
+ * teammate addendum, uplink attribution) key on THIS field; keying on the display label made
1167
+ * every described child a "teammate" (clamp over-wide, addendum over-composed).
1168
+ */
369
1169
  explicitAgentName?: string;
1170
+ /**
1171
+ * design/99 (nested-subagent live tree) — the SPAWNING run's taskId, threaded at spawn (from the parent's
1172
+ * `ToolExecuteContext.taskId`) so this child's `task_progress` ticks carry `parentTaskId`. Lets a UI build the
1173
+ * live nested-agent tree directly (child.parentTaskId === parent.taskId) at any depth. TRUSTED run-scoped
1174
+ * channel (NOT a {@link TaskSpec} field), mirroring `parentToolCallId`. Absent for a top-level run.
1175
+ */
370
1176
  parentTaskId?: string;
1177
+ /** design/147 S2a — the spawning run's sessionId (paired with parentTaskId; see
1178
+ * ToolExecuteContext.parentSessionId). */
371
1179
  parentSessionId?: string;
1180
+ /**
1181
+ * The FLEET-task kind of this run, declared by the lane that spawned it and stamped onto every
1182
+ * `task_progress` tick the run mints (`TaskEvent`'s `taskType`). A consumer merging progress ticks
1183
+ * with task notifications into one ledger could otherwise only key on "it showed up on the fleet
1184
+ * stream, so it must be an agent" — an inference that has already produced a row for a task that
1185
+ * was never an agent. Same vocabulary as `TaskNotificationPayload.task_type`, so the merged ledger
1186
+ * has ONE type axis rather than two spellings of one.
1187
+ *
1188
+ * Set by the BACKGROUND delegation lanes (plain + fork), whose runs own a registry `a*` row, and by
1189
+ * both of the workflow orchestrator's spawn legs. A SYNCHRONOUS delegated child declares nothing —
1190
+ * it has no fleet row of any kind, so absence is a fact about the run rather than a gap in the
1191
+ * stamping. TRUSTED run-scoped channel (never a {@link TaskSpec} field).
1192
+ */
372
1193
  delegationTaskType?: import("../types.js").DelegationTaskType;
1194
+ /** δ 批 [1498]⑦/A-3 — the ROOT host session of the whole delegation tree (fixed point: the
1195
+ * spawner passes its own `ctx.rootSessionId ?? ctx.sessionId`, so depth 1 gets the host session
1196
+ * and every deeper level inherits it verbatim). `parentSessionId` is the IMMEDIATE spawner —
1197
+ * after a restart those intermediate sessions are dead ends, and a recovery face enumerating
1198
+ * "everything under this host session" needs the root anchor, not an alias walk. */
373
1199
  rootSessionId?: string;
1200
+ /**
1201
+ * RB-429 — the REGISTRY SCOPE this run's own background row lives in: the domain its registry-facing
1202
+ * tools (TaskOutput / TaskStop / SendMessage / AgentTranscript / Monitor, and the announce listing)
1203
+ * must mount in to see it. Filled by the delegation tool at spawn, which is the party that CHOSE the
1204
+ * domain when it registered the row — `ctx.principal` when the spawning run has one, else the
1205
+ * delegation mount's declared `background.scope`, and on a revival the claimed row's own scope.
1206
+ *
1207
+ * Why this is not just `principal`: a deployment may declare its domain at MOUNT time and run its
1208
+ * tasks without `TaskSpec.principal`. The row then lands in the declared domain while the child runs
1209
+ * with no principal at all, and `principal ?? "default"` sends every one of its registry-facing tools
1210
+ * to a domain the row is not in — scope is fail-closed on both access predicates, so such a child
1211
+ * cannot see its own row, its siblings, or the children it spawns. Carrying the domain as its own
1212
+ * trusted axis keeps `principal` the design/62 IDENTITY it is: the identity also keys the durable
1213
+ * approval / checkpoint namespace (`checkpointScopeOf`), the runtime-capability lookup and the MCP
1214
+ * principal header, and a mount's registry scope has no business moving any of those (an unattended
1215
+ * safety park must not migrate into the caller's opt-in approval bucket — design/153 §7.4).
1216
+ *
1217
+ * TRUSTED channel (never a {@link TaskSpec} field, never a model argument), like the parentage axes
1218
+ * above. When a deployment sets both, they agree by construction: with a principal present the
1219
+ * delegation tool resolves this axis TO that principal.
1220
+ */
374
1221
  registryScope?: string;
1222
+ /** design/148 S1 (codex F2a) — the spawning run's ADOPTED center artifact, threaded down the
1223
+ * trusted internals chain so every child in the tree composes the SAME closure (a child must
1224
+ * never spontaneously adopt the live candidate while its parent runs an older pin — that is the
1225
+ * exact mixed-version state the epoch exists to prevent). Resolved by-digest through the
1226
+ * verified store at child prepare; a miss is the same fail-loud `prompt.snapshot_unavailable`. */
375
1227
  parentCenterArtifactDigest?: string;
1228
+ /** Publish provenance companion of {@link parentCenterArtifactDigest} (audit only). */
376
1229
  parentCenterSourceRevision?: string;
1230
+ /** R2 双形轴 — parent's resolved prompt profile, inherited unless the child spec overrides. */
377
1231
  promptProfile?: "simple" | "classic";
1232
+ /**
1233
+ * design/99 (nested-subagent live tree) — an OPT-IN, DISPLAY-ONLY event sink a deployment sets on the TOP run to
1234
+ * receive a subagent's live `task_progress` ticks (which otherwise stay in the child's ISOLATED stream). Threaded
1235
+ * recursively down the delegation tree (via `ctx.forwardEvent`), so every nested subagent's ticks bubble to the
1236
+ * SAME sink. The Runner forwards ONLY `task_progress` through it; the child stream is NEVER merged into the
1237
+ * parent's MODEL context (this is purely a render channel). Absent unless the deployment opted in.
1238
+ */
378
1239
  onForwardEvent?: (event: TaskEvent) => void;
1240
+ /**
1241
+ * design/115 P2 core slice — trusted run-local system-injection sink. `Runner.runLocked` wires this to the
1242
+ * live TaskStream queue plus the current harness follow-up lane; it is not a public TaskSpec field.
1243
+ */
1244
+ /** design/116 detach: the run-local per-tool-call detach hub. runtask creates it and exposes
1245
+ * `TaskStream.detach(toolCallId)`; the hands Bash tool threads `signalFor(toolCallId)` into env.exec. */
379
1246
  detachHub?: import("../tool-detach.js").ToolDetachHub;
380
- onTaskNotification?: (notification: TaskNotificationPayload, opts?: {
1247
+ onTaskNotification?: (notification: TaskNotificationPayload,
1248
+ /** CC injection priority (design/116 §7, re-anchored 2026-08-05): every priority delivers at
1249
+ * the next turn boundary (arrival order, consecutive frames batch); "later" (default) vs
1250
+ * "next" now differs only on the park/uplink forwarding path. */
1251
+ opts?: {
381
1252
  priority?: import("../task-notification.js").SystemInjectionPriority;
382
1253
  }) => void;
1254
+ /**
1255
+ * design/147 S1a — the PARENT run's notification injector (its runtask-wrapped
1256
+ * `injectTaskNotification`), threaded into a CHILD's internals at spawn time so the child's
1257
+ * SendMessage("main") uplink lands in the parent's queue at a turn boundary (the CC
1258
+ * "delivered automatically" parent half). DELIBERATELY a separate field from
1259
+ * {@link RunInternals.onTaskNotification}: that one is "inject into THIS run" (runtask wraps it
1260
+ * as upstream-observer + own-queue), and reusing it for the child would tee every internal child
1261
+ * notification (grandchild completions, monitor events) into the parent — double delivery.
1262
+ */
383
1263
  parentNotify?: (notification: TaskNotificationPayload, opts?: {
384
1264
  priority?: import("../task-notification.js").SystemInjectionPriority;
385
1265
  }) => void;
1266
+ /**
1267
+ * design/147 S3a (codex F2) — the PARENT run's subagent-retain ledger, threaded to a CHILD so its
1268
+ * SendMessage can continue a RETAINED SIBLING (the sibling's retain entry lives on the parent's
1269
+ * ledger — without this, sibling resolution succeeds but delivery always reads not-retained).
1270
+ * TRUSTED chain; read-only use (the sibling leg resumes through the same fenced resume face).
1271
+ */
386
1272
  parentRetainLedger?: import("../../agents/retain-ledger.js").SubagentRetainLedger;
1273
+ /**
1274
+ * design/147 S2a — hands THIS run's notification injector back to the SPAWNER once the lane is
1275
+ * live (runtask calls it with its wrapped `injectTaskNotification`). The spawner stores it on the
1276
+ * child's registry handle so a parent/sibling SendMessage can deliver TO the RUNNING child at its
1277
+ * next turn boundary (CC's in-memory `pendingMessages` pedestal, anchors/2.1.212
1278
+ * messaging-runtime.md §2.5). The injector is RUN-SCOPED but fail-safe after the run: the lane's
1279
+ * teardown branch parks late payloads per session (PendingSessionNotifications), which is exactly
1280
+ * CC's durable-mailbox posture for an idle teammate (§2.4) — no separate file mailbox needed.
1281
+ * TRUSTED chain (core spawner only); never reachable from TaskSpec.
1282
+ */
387
1283
  onNotifyInjectorReady?: (inject: (notification: TaskNotificationPayload, opts?: {
388
1284
  priority?: import("../task-notification.js").SystemInjectionPriority;
389
1285
  }) => Promise<"queued" | "parked" | "dropped_duplicate">) => void;
1286
+ /**
1287
+ * design/97 CORE-6 — per-task ISOLATION hint, a TRUSTED run-scoped channel filled ONLY by a core caller
1288
+ * (the workflow's `ctx.agent` when the SCRIPT passed `{ isolation: "worktree" }` as an OPTION) — NEVER a
1289
+ * {@link TaskSpec} field (the untrusted-caller surface, design/44 §7 Q4). Forwarded to
1290
+ * {@link ExecutionEnvFactory} via {@link ExecutionEnvFactoryContext.isolation} so the trusted control-plane
1291
+ * factory mints a git-worktree-rooted env for this agent; and it makes root resolution use the worktree
1292
+ * env's own cwd (the worktree dir), bypassing `deps.rootPath`. Isolate-ONLY: the runtime never merges
1293
+ * — the orchestrator script reads each worktree's result and decides verify/merge in userland.
1294
+ * FAIL-CLOSED: a request the deployment cannot honor (no factory, or an observably non-isolated env)
1295
+ * throws at prepare time — the child never starts; there is no silent fallback to the shared tree.
1296
+ */
390
1297
  isolation?: "worktree";
1298
+ /**
1299
+ * Sub-agent cwd inheritance (CC parity, 2026-07-03): the PARENT task's effective working root,
1300
+ * filled ONLY by core delegation callers (the workflow's `ctx.agent` / `createSubagentTool`'s execute —
1301
+ * NEVER a {@link TaskSpec} field). Forwarded to {@link ExecutionEnvFactory} via
1302
+ * {@link ExecutionEnvFactoryContext.parentCwd} so a single-user/TOC factory can root the child env at the
1303
+ * parent's cwd instead of an empty per-task sandbox. `isolation: "worktree"` wins over this when both set.
1304
+ */
391
1305
  parentCwd?: string;
1306
+ /**
1307
+ * [c209-D] codex R3 — the EXPLICIT Agent.cwd request, distinct from the best-effort `parentCwd`
1308
+ * inheritance hint above: inheritance may be silently ignored by a factory (or absent without one),
1309
+ * but an explicit cwd the model asked for MUST either take effect or fail loud. prepareTask enforces
1310
+ * the contract: no `executionEnvFactory` ⇒ throw `config.cwd_unsupported`; after env creation the
1311
+ * env's actual cwd must canonically equal this path or the task fails `config.cwd_not_honored`; the
1312
+ * task root follows the env's cwd (never `deps.rootPath`) when set. Filled ONLY by core delegation
1313
+ * callers (ctx-injection posture, same as `parentCwd`).
1314
+ */
392
1315
  requestedCwd?: string;
1316
+ /**
1317
+ * Subagent steer verb (dogfood finding 2026-07-03, "中途插话"): the host run's opt-in
1318
+ * SUBAGENT-STEER-HANDLE sink. When set, `createSubagentTool` runs each child via `runTaskStream`
1319
+ * and emits a steer handle here (the model never sees the handle — same host-context-isolation
1320
+ * posture as `onWorkflowAgentSpawn`). A deployment registers it by `taskId` to route a human steer
1321
+ * into the running child (fenced-marker semantics matching the workflow agent handle). Threaded to
1322
+ * the tool ctx as {@link ToolExecuteContext.onSubagentSpawn} and recursively down the delegation
1323
+ * tree. Absent ⇒ children run non-steerable (prior behavior, zero overhead).
1324
+ * SCOPE (fable impl-review F3, recorded): only SYNC delegations emit a handle — a
1325
+ * `run_in_background` child does not (poll/stop it via TaskOutput/TaskStop); wiring the background
1326
+ * lane is a recorded follow-up, not an oversight a deployment should discover at runtime.
1327
+ */
393
1328
  onSubagentSpawn?: (handle: import("../../agents/subagent.js").SubagentSteerHandle) => void;
1329
+ /**
1330
+ * design/97 CORE-8 (③) — a TRUSTED run-scoped tool-ACTIVITY sink, filled ONLY by a core caller (the workflow's
1331
+ * `ctx.agent`, to render a per-agent "last N tool calls" drill-down). Called synchronously at each tool start +
1332
+ * end with structural data (name/phase/ids) — NEVER args/output (those carry untrusted/host data). NEVER a
1333
+ * {@link TaskSpec} field. Absent ⇒ no activity capture (default).
1334
+ *
1335
+ * **v1 scope (audit MINOR)**: reaches activity on a FRESH run only — the durable-resume entry (`resumeStream`)
1336
+ * does not thread `internals`, so a resumed leg emits no activity. The workflow display is unaffected (its
1337
+ * agents fail-on-suspend rather than durably resume).
1338
+ */
394
1339
  onActivity?: (activity: ToolActivity) => void;
1340
+ /**
1341
+ * RB-393① (黑板 [2107]②) — a TRUSTED run-scoped WORKSPACE-observation sink, filled ONLY by a core caller
1342
+ * (the workflow's `ctx.agent` / `ctx.agentStream`, to record an isolated agent's worktree directory on the
1343
+ * persisted run record). NEVER a {@link TaskSpec} field — same posture as {@link onActivity}.
1344
+ *
1345
+ * WHY the engine must hand this out: for `isolation: "worktree"` the worktree path is minted INSIDE
1346
+ * {@link RunnerDeps.executionEnvFactory} and lands only on the per-task env's `cwd`; no runner-outward face
1347
+ * (TaskEvent union / TaskStream / TaskResult) carries it back. An orchestrator therefore could not record
1348
+ * WHERE its isolated agent worked — the recovery path after an interrupted run had to enumerate the
1349
+ * worktrees directory and guess, which is exactly the contradiction [2113] recorded against the
1350
+ * "isolate-only, userland decides verify/merge" intent.
1351
+ *
1352
+ * Called at most ONCE per prepared run with the task's FINAL working root (see {@link ResolvedWorkspace}),
1353
+ * after the durable-resume restore may have re-rooted it. Observe-only: a throwing sink is swallowed (an
1354
+ * observation must never fault a prepare that already minted a workspace).
1355
+ *
1356
+ * **v1 scope**: same as {@link onActivity} — a FRESH run only; the durable-resume entry (`resumeStream`)
1357
+ * threads no `internals`, so a resumed leg reports nothing.
1358
+ */
395
1359
  onWorkspaceResolved?: (workspace: ResolvedWorkspace) => void;
396
1360
  }
1361
+ /**
1362
+ * RB-393① — the payload of {@link RunInternals.onWorkspaceResolved}: the working root this task actually
1363
+ * runs on, plus whether that root is the task's OWN isolated workspace.
1364
+ *
1365
+ * `isolated: true` means "`cwd` is this agent's own git worktree": it is reported only when
1366
+ * {@link RunInternals.isolation} was requested AND the fail-closed worktree enforcement accepted the env, so a
1367
+ * consumer may treat the path as private to this agent (safe to diff / merge / remove in userland). A
1368
+ * non-isolated run reports its plain root with `isolated: false` — the observation face stays complete, while
1369
+ * the honest non-claim keeps a consumer from mistaking a SHARED tree for its own worktree.
1370
+ */
397
1371
  export interface ResolvedWorkspace {
1372
+ /** The task's effective working root — the same value every fence / LSP / prompt consumer uses. */
398
1373
  cwd: string;
1374
+ /** True only for an accepted `isolation: "worktree"` request (⇒ `cwd` is this agent's own worktree). */
399
1375
  isolated: boolean;
400
1376
  }
1377
+ /**
1378
+ * From the resumed/active transcript, the batch position of `currentId` (design/45 §4.ter): the tool-call
1379
+ * ids of the assistant message that issued it (the batch), and the subset already resolved (executed
1380
+ * before the suspend — #1..k-1). ID-based, not positional (council Question #1): immune to reordering.
1381
+ */
401
1382
  export declare function batchContextAt(messages: AgentMessage[], currentId: string): {
402
1383
  batchToolCallIds: string[];
403
1384
  completedCallIds: string[];
404
1385
  };
1386
+ /**
1387
+ * codex 1360 r2-r4 — rebase one checkpointed absolute path from the OLD workspace root onto the RESTORED
1388
+ * one (divergent `resumeVM`). POSIX-ONLY by contract: every remote lane's `mountPath` is a container
1389
+ * path (e2b/k8s/ssh/adb/local-docker are all Linux targets), so a backslash ANYWHERE in the inputs marks
1390
+ * the value outside this function's domain and it returns `p` UNCHANGED — an un-rebased path is honestly
1391
+ * observable (the divergence observation already fired) while a WRONGLY-rebased one silently corrupts
1392
+ * cwd/read-state (r4: drive-root and cross-family recomposition are not implementable without a Windows
1393
+ * path model no lane needs). Trailing slashes are tolerated (from="/app/" must not weld the suffix);
1394
+ * bare "/" keeps filesystem-root semantics; a path outside `from` (incl. the prefix-sibling
1395
+ * "/application" vs "/app") returns unchanged. Exported for direct unit pinning.
1396
+ */
405
1397
  export declare function rebaseWorkspacePath(p: string, fromRaw: string, toRaw: string): string;
1398
+ /**
1399
+ * RB-439-c — {@link rebaseWorkspacePath} over a SET of accepted spellings of the old root: the first
1400
+ * prefix that actually matches wins, and a path under none of them is returned unchanged.
1401
+ *
1402
+ * The set exists because "the old root" has no single spelling. `WorkspaceHandle.mountPath` is whatever the
1403
+ * adapter called the mount, while the persisted paths being migrated were spelled by whoever produced them
1404
+ * (a `cd` the env canonicalized, a Read key resolved through realpath). On a target where the root has an
1405
+ * equivalent alias (`/var` ↔ `/private/var`) those disagree while naming the same directory, and a
1406
+ * single-prefix rebase then matched nothing and silently left the resumed shell in the pre-suspend tree —
1407
+ * under a disclosure that said the task follows the restored root. Order is caller-chosen (the checkpointed
1408
+ * spelling first, its canonical form second) and only matters if one prefix is a prefix of another, in
1409
+ * which case the earlier — more specific — spelling is the intended one. Exported for direct unit pinning.
1410
+ */
406
1411
  export declare function rebaseWorkspacePathAcross(p: string, froms: readonly string[], to: string): string;
407
- export declare function prepareTask(spec: TaskSpec, deps: RunnerDeps, sessions: SessionStore, resume?: PrepareResume, internals?: RunInternals, runnerSelf?: Runner): Promise<Prepared>;
1412
+ export declare function prepareTask(spec: TaskSpec, deps: RunnerDeps, sessions: SessionStore, resume?: PrepareResume, internals?: RunInternals,
1413
+ /** design/98 §3.1 (S8c): a TRUSTED self-reference to the Runner, passed by the Runner itself (never a
1414
+ * TaskSpec field) so the `run_workflow` tool can execute child tasks via `runner.runTask`. Undefined when
1415
+ * prepareTask is exercised standalone (then run_workflow is simply not mounted). */
1416
+ runnerSelf?: Runner): Promise<Prepared>;