@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
@@ -6,24 +6,74 @@ import type { WorkflowHandle, WorkflowRun } from "../orchestration/workflow.js";
6
6
  import type { TaskNotificationPayload } from "./task-notification.js";
7
7
  import type { ToolResultStore } from "./tool-result-store.js";
8
8
  export type SemaTaskType = "background_bash" | "workflow" | "background_agent" | "monitor";
9
+ /** design/134 §3.3 (R3): WHO initiated a kill — recorded at the initiation site (first-marker-wins),
10
+ * because the settle-side then/catch context has already lost it. OPEN ENUM on the wire, now in the
11
+ * TYPE too (`(string & {})` keeps literal completion while admitting future values like "timeout"
12
+ * without a breaking change): consumers must tolerate unknown values and fall back to default copy.
13
+ * SINGLE SOURCE of the shape — two wire mirrors are INLINED to avoid import cycles (this module sits
14
+ * above both) and must stay in sync: types.ts `BackgroundChildEvent.stoppedBy` and
15
+ * task-notification.ts `TaskNotificationPayload.stoppedBy`. */
9
16
  export type StopSource = "user" | "parent" | "system" | (string & {});
17
+ /** design/153 §7.1: `"parked"` (background agents only today) = durably suspended on a pending
18
+ * approval checkpoint — neither live nor terminal. Every `=== "running"` liveness check treats it
19
+ * as not-running (correct: no process exists); it exits poll waits, refuses settles, and is
20
+ * reap-exempt. Downstream switches over this union gain an arm (announced, [1556]/L1.5). */
10
21
  export type SemaTaskStatus = "pending" | "running" | "parked" | "completed" | "failed" | "killed" | "cancelled";
11
22
  export type TaskRetrievalStatus = "success" | "not_ready" | "timeout";
12
23
  export interface UnifiedTaskOutput {
13
24
  task_id: string;
25
+ /** RB-92 (2026-07-25, red probe): `"unknown"` is a DECLARED member here, not a stray literal. A
26
+ * not-found lookup has no task kind to report, and the TaskStop envelope's `task_type` is required by
27
+ * the client schema — so the wrapper was already emitting `"unknown"` while the type said it could
28
+ * only be a `SemaTaskType`. Declaring it keeps the two honest with each other, and keeps `SemaTaskType`
29
+ * itself clean for every consumer that switches over real task kinds. */
14
30
  type?: SemaTaskType | "unknown";
15
31
  status?: SemaTaskStatus | string;
16
32
  retrieval_status: TaskRetrievalStatus;
17
33
  content?: string;
18
34
  error?: string;
35
+ /** RB-386② ([2090]) — machine-readable failure code on a FAILED background_agent row's poll
36
+ * details (the child's TaskResult.errorCode taxonomy — brain codes / `limit.*` / `budget.*` …).
37
+ * Additive; absent on non-failed rows, on rows whose failure carried no code, and on other lanes. */
19
38
  errorCode?: string;
39
+ /** RB-386② — retryability verdict for a FAILED background_agent row, derived at settle time by the
40
+ * same classifier the sync sub-agent report's `error_kind (retryable: …)` line uses. Additive. */
20
41
  retryable?: boolean;
42
+ /** design/134 §3.3: only present when `status === "killed"` (open enum — see {@link StopSource}). */
21
43
  stoppedBy?: StopSource;
44
+ /** server[1526] ask — the durable row's committed stop-cycle number (1.371 settle mint), served on
45
+ * durable-fallback polls so a tail consumer can key revive cycles without the notify lane.
46
+ * [1532]§三1: ALSO served by the in-process live poll/stop arms (the handle's current cycle
47
+ * projection — spawn = 1, each 1.332/tier-3 revival opens the next), same key, same meaning,
48
+ * so tail meta is complete whichever arm answers. */
22
49
  seq?: number;
50
+ /** fidelity-sweep A1: the served result is the child's PARTIAL work — it landed after a kill had
51
+ * already won the terminal race and was backfilled (produced before/while the task was stopped). */
23
52
  partial_result?: boolean;
53
+ /** P1-3(黑板 [1870] P1-3, cli/server 商定项 — 黑板 [1920]/[1921]/[1924]/[1925]):a cross-channel
54
+ * correlation key for ONE completion event. The same task's completion fans out across several
55
+ * independent channels today (a live `TaskNotificationPayload` frame, a durable inbox entry, and
56
+ * this poll projection) — a consumer today has to reconstruct "are these the same completion?" from
57
+ * weaker signals (task_id + status + timing). Minted ONCE per completion, fill-once (first writer
58
+ * wins) on the handle/record the completion is settled onto, so every read face — this poll
59
+ * projection, the notification payload, and (for background_agent) the cross-restart durable
60
+ * fallback row — serves the exact same value. Open-shape `string` (a uuidv7 in this implementation,
61
+ * not contractually required to stay one); absent when the underlying task hasn't reached a terminal
62
+ * settle yet, or on a pre-P1-3 core build that never minted one. */
24
63
  completionId?: string;
25
64
  details?: unknown;
26
65
  }
66
+ /**
67
+ * E1 (黑板 [1937]) — the shared internal poll/stop result shape every helper below returns
68
+ * (`noTask`/`noTaskForStop`/`formatWorkflowRun`/`serveDurableAgentRow`/`pollTask`/`stopTask` and every
69
+ * per-task-kind poll/stop arm). `UnifiedTaskOutput` (the `details` face) has no isError channel of its
70
+ * own — it is a REQUIRED-field wire shape consumed by callers beyond these two tools too, so isError is
71
+ * carried as a sibling on the WRAPPER instead (trap avoidance per the E1 sweep: never smuggle isError
72
+ * through a narrower helper contract). Optional, absent/false = success — `createTaskOutputTool`/
73
+ * `createTaskStopTool` forward it onto the real `ToolReturn` at the tool boundary. Every internal helper
74
+ * keeps constructing `content`/`details` exactly as before; this only adds a place to say "and this one
75
+ * is a genuine failure" where the failure is actually detected.
76
+ */
27
77
  export type UnifiedTaskResult = {
28
78
  content: string;
29
79
  details: UnifiedTaskOutput;
@@ -40,22 +90,59 @@ export interface SemaTaskHandle {
40
90
  createdAt: number;
41
91
  updatedAt: number;
42
92
  outputFile?: string;
93
+ /** P1-3 — see {@link UnifiedTaskOutput.completionId}. Minted fill-once at this task's own settle
94
+ * point ({@link mintCompletionId}); absent until the task reaches a terminal status. */
43
95
  completionId?: string;
44
96
  }
97
+ /** P1-3(黑板 [1920]/[1921]/[1924]/[1925]) — mint a cross-channel completion correlation id ONCE per
98
+ * handle/record, fill-once (first writer wins): every settle/direct-terminal-flip site calls this
99
+ * instead of writing `completionId` directly, so no matter how many terminal-transition sites a lane
100
+ * has (settle / TaskStop bypass / backfill), the value is minted exactly once and every later caller
101
+ * (including an idempotent re-call from a bypass path that already ran) gets back the SAME id. `string`
102
+ * is intentionally loose (any object with an optional `completionId` field) so the same helper serves
103
+ * both a `RegisteredTaskHandle` and a `WorkflowRun` (orchestration/workflow.ts — a different module,
104
+ * no shared base type, same fill-once shape). */
45
105
  export declare function mintCompletionId(target: {
46
106
  completionId?: string;
47
107
  }): string;
48
108
  export interface TaskAccess {
49
109
  owner?: string;
50
110
  scope?: string;
111
+ /** design/129: the caller's SESSION id — matches session-scoped handles across turns (a fresh per-turn
112
+ * spec.taskId changes `owner`, but the session is the stable key a background child outlives turns under). */
51
113
  sessionId?: string;
52
114
  }
53
115
  export interface BackgroundBashTaskHandle extends SemaTaskHandle {
54
116
  type: "background_bash";
55
117
  env: ExecutionEnv & BackgroundShellCapability;
56
118
  shellId: BackgroundShellId;
119
+ /** (design/129 lifetime discipline, CC parity): a background bash spawned inside a SESSION
120
+ * outlives the run — CC's bg shells survive the agent turn (TB live evidence in settleKilledForOwner's
121
+ * T1-1 note) and die at the SESSION terminal. When set, owner MUST be the sessionId: skipped by the
122
+ * run-teardown settle/evict, kept alive through the dispose except-list, reaped by
123
+ * {@link TaskRegistry.reapSessionBackground}. Explicit flag only — never inferred from owner shape. */
57
124
  sessionScoped?: true;
125
+ /** Deliver-a-living-service ledger mark: the run-teardown settle sweep skipped this row under the
126
+ * retain gate (spec-level `TaskSpec.retainBackgroundProcesses` OR the env-declared capability). The
127
+ * row is the delivered daemon's ONLY management surface — while the process runs it survives the
128
+ * per-run evict (TaskOutput/TaskStop resolve through this map; the watcher must stay live to mint
129
+ * the natural-exit receipt) and rides every later run's dispose except-list on the same env
130
+ * ({@link TaskRegistry.retainedShellIds}). A terminal row evicts normally. Terminals: explicit
131
+ * TaskStop, the process's own exit (watcher settle), or env destruction (watcher env-death settle)
132
+ * — deliberately NO timed reaper (the deliverable is the living process). A retained SESSION-resident
133
+ * row is likewise exempt from the session-release reap ({@link TaskRegistry.reapSessionBackground}):
134
+ * the delivered daemon outlives its session, with the same three terminals. */
58
135
  retained?: true;
136
+ /** design/116 §7 G2b: when a watcher is attached, the registry accumulates the FULL output here (rolling
137
+ * bound) — TaskOutput then serves a RE-READABLE snapshot (CC semantics) instead of a consume-once cursor.
138
+ * `timedOut`/`timeoutSec` record a SELF-INFLICTED background-timeout kill (the env's per-shell budget
139
+ * fired), so later re-readable polls keep rendering it distinguishably from an external stop.
140
+ * `mirrorFailed` records that at least one append to the advertised output FILE failed — the terminal
141
+ * frame then discloses the file as incomplete instead of letting the launch receipt's "full output is
142
+ * appended there" promise stand over a silently partial file. */
143
+ /** RB-238 ([1937] M1): `droppedBytes`/`dropUnknown` account ENV-SIDE tail-buffer eviction disclosed by
144
+ * the poll (`bytesDroppedBeforeCursor`/`truncated`) — a loss upstream of (and distinct from) the
145
+ * registry's own `rolledChars` memory bound. Bytes counted here never reached the spool at all. */
59
146
  spool?: {
60
147
  stdout: string;
61
148
  stderr: string;
@@ -68,9 +155,18 @@ export interface BackgroundBashTaskHandle extends SemaTaskHandle {
68
155
  dropUnknown?: true;
69
156
  };
70
157
  watcher?: ReturnType<typeof setInterval>;
158
+ /** design/134 §3.3 (R3 MED, 修类不修点): same attribution pair as the agent handle — see there. */
71
159
  stopSource?: StopSource;
72
160
  stoppedBy?: StopSource;
161
+ /** The terminal-notification sink, HELD ON THE HANDLE (not only inside the watcher closure)
162
+ * so the run-teardown killed settle ({@link TaskRegistry.settleKilledForOwner}) can mint the receipt the
163
+ * watcher never will — a disposed shell polls as vanished ("nothing to notify about") and an evicted
164
+ * handle stops the watcher outright. */
73
165
  onTerminal?: (notification: TaskNotificationPayload) => void;
166
+ /** Terminal-notification once-latch (fidelity R1-3): set atomically right before the FIRST terminal
167
+ * notice is sent. A teardown settle and an in-flight watcher tick can both reach their emit point
168
+ * (the kill/poll awaits are suspension windows between the status gate and the send) — whichever
169
+ * fires first wins; every later producer stays silent. */
74
170
  terminalNotified?: true;
75
171
  }
76
172
  export interface WorkflowTaskHandle extends SemaTaskHandle {
@@ -78,37 +174,104 @@ export interface WorkflowTaskHandle extends SemaTaskHandle {
78
174
  runId: string;
79
175
  handle: WorkflowHandle<unknown>;
80
176
  store?: WorkflowRunStore;
177
+ /** γ 批 B-1 (live leg) — see {@link RegisterWorkflowInput.originatingSessionId}. */
81
178
  originatingSessionId?: string;
179
+ /** RB-215(黑板 [1870] C6,已修): design/129 session-lifetime discipline, extended to workflow — the
180
+ * ONE background kind that never had it (`background_bash`/`monitor`/`background_agent` all do).
181
+ * Unlike those three (task-scoped BY DEFAULT, `sessionScoped` an explicit opt-in via
182
+ * `TaskSpec.backgroundScope`), a workflow is unconditionally session-anchored — `originatingSessionId`
183
+ * is set at every standard mount (`prepare-task.ts`, never gated), and Workflow's whole raison d'être
184
+ * (its own guidance text) is "runs asynchronously, notifies you or is polled LATER" — there is no
185
+ * sensible "dies with this turn" mode for it to opt out into, unlike a background_agent which
186
+ * genuinely has both use cases. Set `true` whenever `originatingSessionId` is present (`registerWorkflow`).
187
+ * Read only by {@link TaskRegistry.reapSessionBackground} — the explicit, deployment-invoked session
188
+ * terminal anchor (core has no session TTL reaper of its own); NEVER by `Runner.runTask()`'s own
189
+ * per-leg teardown, whose finally block runs on every NORMAL leg completion, not just a genuine
190
+ * session end — a would-be regression caught by cross-review before this shipped (see docs/
191
+ * REVIEW-BACKLOG.md's "RB-215 复核" entry for the full incident). */
82
192
  sessionScoped?: true;
193
+ /** See {@link RegisterWorkflowInput.onServedTerminal}. Cleared after the single fire. */
83
194
  onServedTerminal?: () => void;
195
+ /** 复审 r2 MAJOR: the bounded return value, captured on the done-hook so the STORE-LESS in-memory lane's
196
+ * terminal poll can hand it over too (the launch note promises it; without a store there was no result). */
84
197
  result?: string;
198
+ /** T2A-8: the failure reason (bounded + redacted), captured on the done-hook's rejection so a store-less
199
+ * terminal poll can say WHY it failed (the store lane's formatWorkflowRun already carries run.error). */
85
200
  error?: string;
86
201
  }
202
+ /** design/151 S1a — the per-row durable write lane. The registry is the row's SINGLE writer; writes
203
+ * are serialized on a promise chain (put → bind → settle order preserved), CAS'd with the locally
204
+ * held `record.rev`, and BEST-EFFORT (a store outage degrades durability with a visible warning,
205
+ * never execution). A lost CAS or a put `already_exists` means a FOREIGN row lives under this
206
+ * handle (leftover from a dead process / another writer) — the lane poisons itself loudly instead
207
+ * of clobbering (design/151 MED-8: the writer's own rev is the anti-clobber line). */
87
208
  export interface DurableAgentLane {
88
209
  store: BackgroundAgentStore;
210
+ /** The writer's authoritative local copy (rev included — bumped only on a confirmed CAS win). */
89
211
  record: BackgroundAgentRecord;
90
212
  chain: Promise<void>;
213
+ /** True once the initial `put` landed (an outage before that retries put on the next write). */
91
214
  written: boolean;
92
215
  poisoned: boolean;
216
+ /** codex r3 F2 — true while the LATEST flush exhausted its retries (cleared by the next success).
217
+ * The lifecycle-flip probe requires it false: a row whose bind/settle never persisted must not
218
+ * have its transcript preserved-but-unreachable (the local record accumulates patches, so the
219
+ * next successful write self-heals the missing fields). */
93
220
  flushFailed: boolean;
221
+ /** codex 增量 R-4 — consecutive heartbeat re-drives of a settled flush-failed lane (reset on any
222
+ * flush success); past the ceiling the lane is abandoned loudly instead of retrying forever. */
94
223
  redrives?: number;
95
224
  }
96
225
  export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
97
226
  type: "background_agent";
227
+ /** design/115 P3: aborting this cancels the child run (TaskStop / parent teardown). */
98
228
  abort: AbortController;
229
+ /** RB-236 — lineage axes, declared (registration always spread them into the handle; readers used
230
+ * to cast). `rootSessionId` feeds {@link canAccess}'s root-session arm; the other two stay
231
+ * read-only lineage metadata on the live face (no parentSessionId access arm — see the arm's
232
+ * comment for why). [1344]② clamps `parentTaskId` register-side. */
99
233
  parentTaskId?: string;
100
234
  parentSessionId?: string;
101
235
  rootSessionId?: string;
236
+ /** design/151 S1a — the child's store session id (transcript/resume anchor), bound once the child
237
+ * session is minted ({@link TaskRegistry.bindBackgroundAgentSession}). */
102
238
  sessionId?: string;
239
+ /** design/151 S1a — the durable write lane (present iff the registration wired a store). */
103
240
  durable?: DurableAgentLane;
241
+ /** design/147 S2a — the RUNNING child run's notification injector (attached once its lane is
242
+ * live, dropped at terminal settle). A parent/sibling SendMessage delivers through this at the
243
+ * child's next turn boundary (CC in-memory pendingMessages pedestal); late calls after the run
244
+ * ends park per session inside the injector itself (the lane-teardown branch). */
104
245
  notify?: (notification: import("./task-notification.js").TaskNotificationPayload, opts?: {
105
246
  priority?: import("./task-notification.js").SystemInjectionPriority;
106
247
  }) => "queued" | "parked" | "dropped_duplicate" | Promise<"queued" | "parked" | "dropped_duplicate">;
248
+ /** design/147 S2a (codex R3 F5) — messages that arrived in the STARTUP window (row already
249
+ * running, lane not yet bound). Bounded; flushed in order by attachAgentNotify. Discarded at
250
+ * terminal settle: a run that failed during prepare never had a lane to park through, and the
251
+ * sender's completion notification (failed) prompts the resend. */
252
+ /** S2b codex F1 — park redeemability (see RegisterBackgroundAgentInput.retainedContinuation). */
107
253
  retainedContinuation?: boolean;
254
+ /** S2b RB-27② — revive-cycle stamp (see reviveBackgroundAgent): attach/settle from a resume leg
255
+ * carry it so a stale cycle's late calls no-op instead of clobbering the newer cycle. */
108
256
  reviveCycle?: number;
257
+ /** [1532]§三1 — the CURRENT stop-cycle number in settle-generation terms (spawn run = 1; each
258
+ * revival — 1.332 retained or tier-3 seeded — opens the next). Served by the LIVE poll/stop
259
+ * projection under the SAME `seq` key as the durable-fallback arm, so a tail consumer keys
260
+ * revive cycles identically whichever arm answered. Re-aligned to the settle's authoritative
261
+ * `outcome.seq` at settle time (the ledger's cycleSeq is the mint; this is its projection). */
109
262
  cycleSeq?: number;
263
+ /** design/153 §7.1 — the approval checkpoint this handle is parked on (`status:"parked"` only). */
110
264
  parkedCheckpointToken?: string;
265
+ /** design/153 §7.1 — in-process TaskStop arbitration closure, minted by the parking watcher
266
+ * (captures the checkpoint store + token; the registry itself holds no durable stores — r4 F-06).
267
+ * Resolves `true` iff the STOP won the checkpoint CAS (expire landed; resume can no longer
268
+ * consume it) — only then may the row flip killed. `false` = a resume consumed the token first.
269
+ * Absent (cross-process row, no live park context) ⇒ TaskStop refuses honestly: the durable
270
+ * approval inbox (server /decide) owns that arbitration. */
111
271
  resolveParkedStop?: () => Promise<boolean>;
272
+ /** S2b codex R5-F2 — resolvers of DIRECT (post-attach) deliveries currently awaiting the
273
+ * injector; terminal settle/stop sweep these as not_running so a never-settling adapter can
274
+ * never pin the sender's tool call. */
112
275
  inFlightDirect?: Set<(r: {
113
276
  ok: true;
114
277
  disposition: "queued" | "parked";
@@ -116,6 +279,8 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
116
279
  ok: false;
117
280
  reason: "not_found" | "not_running" | "no_channel";
118
281
  }) => void>;
282
+ /** S2a F7 — channel lifecycle: undefined = unsupported (spawner never declared), "attaching" =
283
+ * declared, lane not yet bound (buffer window), "attached" = live injector present. */
119
284
  channelState?: "attaching" | "attached";
120
285
  preAttachQueue?: Array<[
121
286
  import("./task-notification.js").TaskNotificationPayload,
@@ -130,32 +295,101 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
130
295
  reason: "not_found" | "not_running" | "no_channel";
131
296
  }) => void) | undefined)?
132
297
  ]>;
298
+ /** [c209-D] the EXPLICIT addressing name (CC Agent.name parity, validated at spawn: charset regex +
299
+ * "main" reserved). Distinct from `description` (the display/legacy-matching label): the name layer
300
+ * resolves latest-wins ("a newer agent took the name"), the description layers keep their
301
+ * running-preferred + ambiguous posture. Absent on pre-[c209] rows and unnamed spawns. */
133
302
  name?: string;
303
+ /** design/129: this child OUTLIVES its parent turn — owner is the SESSION id; the parent-teardown reap
304
+ * skips it; `reapSessionBackground` is its terminal anchor. Explicit flag, never inferred from key values
305
+ * (hostTaskId===sessionId deployments would otherwise be ambiguous). */
134
306
  sessionScoped?: true;
307
+ /** Terminal snapshot (bounded, {@link BG_AGENT_RESULT_MAX} in subagent.ts) — served by TaskOutput
308
+ * once the child finishes. */
135
309
  result?: string;
310
+ /** RB-205-B: the FULL result (bounded only by the defensive {@link BG_AGENT_RESULT_FULL_MAX} ceiling
311
+ * in subagent.ts), set ONLY when it differs from `result` — same shape as {@link WorkflowRun.resultFull}
312
+ * (workflow.ts NH-1). Before this field existed, the settle call sites pre-sliced `child.result` to
313
+ * ~2-4K chars with no disclosure — clipTaskOutput's own file-pointer/offload-friendly design at the
314
+ * poll layer was structurally unreachable because `result` itself could never be long enough to need it. */
136
315
  resultFull?: string;
316
+ /** design/158 S1 (RB-205-B 半) — the tool-result-store ref `resultFull`'s full text was spilled to,
317
+ * the FIRST time a poll's `clipTaskOutput` actually cut it (lazy write, not at settle time). Cached
318
+ * here so every LATER poll within the SAME cycle reuses the same ref instead of re-writing (the
319
+ * store's own `put` is write-once too, but re-deriving/re-calling it every poll would still cost a
320
+ * redundant round-trip on a durable backend, and a changing ref across polls would be a needless
321
+ * disclosure churn). {@link reviveBackgroundAgentLane} clears this on revive — the cycle's full text
322
+ * is gone, so a stale ref must not be reused across cycles. Ref format ties in `reviveCycle` (see
323
+ * {@link import("./task-registry-agent.js").spillClippedAgentResult}) precisely so a revived cycle's
324
+ * eventual spill lands under a DIFFERENT ref rather than colliding with (and being silently refused
325
+ * by the write-once store under) cycle 1's. */
137
326
  spillRef?: string;
138
327
  error?: string;
328
+ /** RB-386② ([2090]) — the machine-readable failure code beside `error`, threaded from the settle
329
+ * mint point (subagent.ts computes it ONCE from the child's TaskResult.errorCode taxonomy /
330
+ * extractErrorCode — single source with the sync report's classification). Served on the failed
331
+ * row's poll `details` and the failed terminal notification. Absent when no code was known. */
139
332
  errorCode?: string;
333
+ /** RB-386② — retryability verdict for a FAILED row, computed at the settle mint point by the SAME
334
+ * classifier the sync report face uses (`classifySubagentError` — error_kind ∈ rate_limit/
335
+ * overloaded/timeout/network ⇒ true, logic ⇒ false). Stored rather than re-derived so the core
336
+ * poll lane never has to import the agents-domain classifier (no new domain cycle). */
140
337
  errorRetryable?: boolean;
338
+ /** RB-405 G3 ([2135]/[2136]) — the coarse classification KIND beside `errorRetryable`
339
+ * (classifySubagentError's error_kind ∈ rate_limit/overloaded/timeout/network/logic), threaded
340
+ * from the same settle mint point and stored for the same no-domain-cycle reason as its sibling.
341
+ * Rendered on the FAILED row's poll TEXT face as the `(error_kind: …, retryable: …)` clause —
342
+ * the same field names the sync report's error_kind line already speaks. */
141
343
  errorKind?: string;
344
+ /** Ruled 2026-08-05 (governance kind follow-up): the wait hint paired with a deferred-retryable
345
+ * failure (`usage.*` codes — errorKind `"governance"`), threaded from the same settle mint point
346
+ * as its three siblings. Without it the background faces exposed `retryable:false` with no way to
347
+ * know WHEN the refusal lifts — the sync report card carried `retryAfterMs` while the bg poll/
348
+ * notification faces structurally lost it. */
142
349
  errorRetryAfterMs?: number;
350
+ /** fidelity-sweep A1: `result` arrived AFTER a kill won the status race — it is the child's partial
351
+ * work (produced before/while being stopped), backfilled by the refused settle. Poll frames label it. */
143
352
  resultIsPartial?: boolean;
353
+ /** design/134 §3.3 (R3): the PENDING attribution marker, written by {@link TaskRegistry.markStopSource}
354
+ * at the kill INITIATION site, strictly BEFORE the abort/status flip (once the handle leaves "running"
355
+ * the marker is refused and attribution falls back to "system"). First-marker-wins. */
144
356
  stopSource?: StopSource;
357
+ /** The LANDED attribution — set exactly when the handle goes `killed`, never rewritten afterwards
358
+ * (first-writer-wins, same discipline as the terminal status itself). Absent on natural completion/failure. */
145
359
  stoppedBy?: StopSource;
360
+ /** RB-375 A1 — the reap-time terminal notifier, hung by the spawn lanes (subagent.ts) right after
361
+ * registration: composes and sends the SAME terminal faces (observer sink + parent notification)
362
+ * the child's own unwind would, so {@link import("./task-registry.js").TaskRegistry.reapSessionBackground}
363
+ * can emit the terminal news AT REAP TIME instead of waiting on the child's unwind (which blocks on
364
+ * the in-flight tool actually honoring the abort — unbounded). The bash handle's `onTerminal` twin.
365
+ * Cleared at the accepted settle (with `notify`); invoked at most once via {@link terminalNotified}. */
146
366
  onReapTerminal?: () => void;
367
+ /** RB-375 A1 — terminal-notification once-latch (the bash/monitor `terminalNotified` twin): claimed
368
+ * by whichever side reaches its emit point first — the session-release reap sweep (synchronous send)
369
+ * or the child's own unwind (`TaskRegistry.claimAgentTerminalNotify`). The loser stays silent, so a
370
+ * reaped child never double-announces. Cleared on revive (a new stop cycle owns its own terminal). */
147
371
  terminalNotified?: true;
148
372
  }
373
+ /** design/135 G2 (Monitor): injectable timer/clock seam for the monitor watcher — the 200ms batch window
374
+ * and the timeout/storm checks must be drivable by a test without real sleeps (design/87 discipline).
375
+ * `setInterval` receives an ASYNC tick (the default adapter fires it void; a fake can await it). */
149
376
  export interface MonitorTimers {
150
377
  setInterval: (fn: () => unknown, ms: number) => unknown;
151
378
  clearInterval: (handle: unknown) => void;
152
379
  now: () => number;
153
380
  }
154
381
  export declare const defaultMonitorTimers: MonitorTimers;
382
+ /** design/135 G2: Monitor watch — background_bash's near kin, but the watcher streams stdout LINES as
383
+ * batched event notifications instead of firing one terminal notify. Spool stays re-readable (TaskOutput). */
155
384
  export interface MonitorTaskHandle extends SemaTaskHandle {
156
385
  type: "monitor";
157
386
  env: ExecutionEnv & BackgroundShellCapability;
158
387
  shellId: BackgroundShellId;
388
+ /** RB-238/RB-239/RB-240 ([1937] M1-M3) spool honesty fields: `droppedBytes`/`dropUnknown` = env-side
389
+ * tail-buffer eviction (see the bash handle's twin); `dropNotified` = the once-latch for the event-stream
390
+ * disclosure (terminal frames disclose unconditionally); `drainFailed` = the stop-time final drain poll
391
+ * failed, so the spool may be missing the last window; `timedOut`/`timeoutSec` = the env's own
392
+ * background time budget killed the process (bash-lane parity — renders distinguishably from a stop). */
159
393
  spool: {
160
394
  stdout: string;
161
395
  stderr: string;
@@ -168,8 +402,18 @@ export interface MonitorTaskHandle extends SemaTaskHandle {
168
402
  timedOut?: boolean;
169
403
  timeoutSec?: number;
170
404
  };
405
+ /** Partial (newline-less) stdout tail awaiting completion — a line becomes an event only once terminated. */
171
406
  lineBuf: string;
407
+ /** Per-batch monotonic counter → unique notification dedup keys (see task-notification.ts). */
172
408
  seq: number;
409
+ /** RB-334 (CC `PCo`/`TIs` 220:403278-403321): the TWO-LEVEL event-storm control's state.
410
+ * Level 1 = a token bucket (`stormTokens` out of `stormBurst`, refilled one per
411
+ * `stormRefillIntervalMs`): a batch that cannot consume a token is SUPPRESSED (its lines stay in the
412
+ * re-readable spool) and counted in `suppressedBatches`; the next batch that DOES consume one first
413
+ * emits the disclosure frame naming that count. Level 2 = kill, and only for a monitor that stayed
414
+ * continuously over budget since `overloadSince` for MONITOR_STORM_KILL_AFTER_MS.
415
+ * `lastSuppressedAt` clears `overloadSince` once the pressure is old enough (CC's `OCo * 3` rule) —
416
+ * a short burst every few minutes must never accumulate into a kill. */
173
417
  stormTokens: number;
174
418
  stormBurst: number;
175
419
  stormRefillIntervalMs: number;
@@ -179,24 +423,65 @@ export interface MonitorTaskHandle extends SemaTaskHandle {
179
423
  lastSuppressedAt?: number;
180
424
  batchWindowMs: number;
181
425
  maxBatchesPerMinute: number;
426
+ /** Session-level residency (design/129 sessionScoped semantics): reaped by `reapSessionBackground`,
427
+ * skipped by the per-run `clearBackgroundForOwner`, and NEVER timeout-killed by the watcher. */
182
428
  persistent?: true;
183
429
  sessionScoped?: true;
430
+ /** Deliver-a-living-service ledger mark — same semantics as the bash handle's `retained` (see there). */
184
431
  retained?: true;
432
+ /** Non-persistent only: watcher-enforced hard deadline (epoch ms on the injected clock).
433
+ * (CC parity): this deadline — not the parent run — is the watch's lifetime anchor.
434
+ * A monitor's life = min(timeout, process exit, TaskStop); a persistent one is SESSION-anchored.
435
+ * NEITHER is run-anchored: the run teardown leaves an in-window watch alive (settle/evict/dispose
436
+ * all skip it) so between-turns events keep flowing through the pending lane. */
185
437
  deadlineAt?: number;
186
438
  timeoutMs?: number;
187
439
  watcher?: unknown;
440
+ /** RB-239 ([1937] M2): a watcher tick is suspended on its pollBackground await RIGHT NOW. The stop-time
441
+ * final drain must skip its own poll then (that in-flight tick already consumed the env cursor — and a
442
+ * never-resolving adapter must not pin TaskStop). Set/cleared in lockstep with the tick's re-entrancy
443
+ * guard. */
188
444
  tickInFlight?: true;
189
445
  timers: MonitorTimers;
190
446
  onEvent?: (n: TaskNotificationPayload) => void;
191
447
  stopSource?: StopSource;
192
448
  stoppedBy?: StopSource;
449
+ /** Terminal-notification once-latch — same discipline as the bash handle (fidelity R1-3). Only the
450
+ * TERMINAL frame is latched; "event" frames are unaffected. */
193
451
  terminalNotified?: true;
452
+ /** design/158 S2 (RB-364 半) — the offload store a ROLLED-OFF spool middle spills to, captured at
453
+ * REGISTRATION time (RegisterMonitorInput's additive field), not per-poll like the background_agent
454
+ * lane's `TaskPollOptions.toolResultStore` (S1): the roll happens inside the watcher tick — an async
455
+ * timer callback with no per-call "access" to thread a store through — so registration is the only
456
+ * point that has one to hang on the handle. Absent ⇒ legal degrade: `rollSpoolText`'s `onDrop` hook
457
+ * is simply never wired, byte-identical to pre-S2 rolling (design/158 §2.2). */
194
458
  toolResultStore?: ToolResultStore;
459
+ /** design/158 S2 — the session id spilled refs are scoped under (same `TaskAccess.sessionId` role as
460
+ * every other `buildToolResultRef` call site); captured at registration for the same reason as
461
+ * `toolResultStore` above. */
195
462
  spillSessionId?: string;
463
+ /** design/158 S2 — next segment index to mint for the STDOUT dropped-middle ref chain (0-based;
464
+ * design/158 §3 "方案 a": a ref PER dropped segment, chained by index, rather than one ref with an
465
+ * append primitive — ToolResultStore's contract is write-once with no append). stdout and stderr get
466
+ * INDEPENDENT counters (this field vs `spillErrSegCount`) so each stream's own segments concatenate
467
+ * back in original byte order without interleaving the other stream's drops between them. */
196
468
  spillSegCount?: number;
469
+ /** design/158 S2 — the STDERR twin of {@link spillSegCount}. */
197
470
  spillErrSegCount?: number;
471
+ /** design/158 S2 — cumulative chars (UTF-16 code units, `string.length`) handed to `store.put`
472
+ * across every segment this handle has spilled so far (both streams combined) — the per-handle
473
+ * disk-cap accounting ({@link import("./task-registry-monitor.js")} reads `MONITOR_SPILL_CAP_CHARS`
474
+ * against this). RB-396-b: the field used to be named `spillBytesUsed` while the ledger counted
475
+ * chars — renamed to the axis it really measures (see the constant's own doc for why chars). */
198
476
  spillCharsUsed?: number;
477
+ /** design/158 S2 — the per-handle spill cap (`MONITOR_SPILL_CAP_CHARS`) was reached; further
478
+ * rolled-off middles are no longer spilled (already-written segments stay readable — "earlier
479
+ * segments retained"). One-time latch; the poll disclosure reads it to stop claiming full ref
480
+ * coverage. */
199
481
  spillCapped?: true;
482
+ /** design/158 S2 — at least one `store.put` for this handle rejected or threw. One-time latch; the
483
+ * poll disclosure downgrades its wording once this is set (never claims the ref chain is complete —
484
+ * the fire-and-forget write may have silently failed; see task-registry-monitor.ts's spill helper). */
200
485
  spillFailed?: true;
201
486
  }
202
487
  export type RegisteredTaskHandle = BackgroundBashTaskHandle | WorkflowTaskHandle | BackgroundAgentTaskHandle | MonitorTaskHandle;
@@ -205,15 +490,27 @@ export interface RegisterMonitorInput extends TaskAccess {
205
490
  env: ExecutionEnv & BackgroundShellCapability;
206
491
  description?: string;
207
492
  toolUseId?: string;
493
+ /** Session-level residency: no watcher timeout; reaped by session release (design/129 semantics —
494
+ * when set, `owner` MUST be the session id and `sessionScoped` should be set too). */
208
495
  persistent?: boolean;
496
+ /** design/129 explicit-flag discipline: session-scoped access matching + session-terminal reap. */
209
497
  sessionScoped?: true;
498
+ /** Non-persistent watch deadline (ms). The tool clamps to [1, 3_600_000], default 300_000. */
210
499
  timeoutMs?: number;
500
+ /** The event sink — each stdout-line batch AND the single terminal state fires exactly one payload. */
211
501
  onEvent?: (n: TaskNotificationPayload) => void;
502
+ /** design/87: injectable timers/clock (tests drive ticks + time manually; default = real timers). */
212
503
  timers?: MonitorTimers;
504
+ /** Batch window (ms, default 200): lines arriving within one tick coalesce into one notification. */
213
505
  batchWindowMs?: number;
506
+ /** RB-334: the SUSTAINED batch rate the storm bucket refills at (default 50/min). Exceeding it is
507
+ * suppression, not death — see `stormBurst` and MONITOR_STORM_KILL_AFTER_MS. */
214
508
  maxBatchesPerMinute?: number;
509
+ /** RB-334: burst capacity of the storm bucket (default MONITOR_STORM_BURST = CC's 10). */
215
510
  stormBurst?: number;
216
511
  now?: number;
512
+ /** design/158 S2 (RB-364 半) — the offload store a rolled-off spool middle spills to (see
513
+ * {@link MonitorTaskHandle.toolResultStore}). Absent ⇒ legal degrade, byte-identical rolling. */
217
514
  toolResultStore?: ToolResultStore;
218
515
  }
219
516
  export interface RegisterWorkflowInput extends TaskAccess {
@@ -223,28 +520,109 @@ export interface RegisterWorkflowInput extends TaskAccess {
223
520
  description?: string;
224
521
  toolUseId?: string;
225
522
  now?: number;
523
+ /** γ 批 B-1 (live leg): the ORIGINATING session id — anchors the in-process handle to its session
524
+ * so a later turn of the SAME session (fresh per-turn owner) reaches it through `canAccess`'s
525
+ * workflow session arm, mirroring the durable predicate. A workflow is a SESSION-level asset
526
+ * (its completion notification routes to the session) — deliberately unlike a background agent's
527
+ * live handle, whose sibling-turn invisibility is a channel-discipline ruling (§3.1c). */
226
528
  originatingSessionId?: string;
529
+ /**
530
+ * Fired AT MOST ONCE when a `pollTask` through THIS registry entry (= the originating
531
+ * session's own lane; cross-session store-fallback polls don't fire it) serves a TERMINAL snapshot.
532
+ * The RunWorkflow tool wires it to {@link import("../orchestration/run-workflow-tool.js").WorkflowCompletionNotifier.ackServed}
533
+ * so the deployment can drop the now-redundant completion-inbox entry. Errors are swallowed.
534
+ */
227
535
  onServedTerminal?: () => void;
228
536
  }
537
+ /** T2A-7 (2026-07-05 soak): one blocked-poll step, CLAMPED to the caller's deadline — a small timeoutMs
538
+ * (e.g. 10ms) must not sleep the full 400ms step (~40× overshoot, and the overshoot window even served a
539
+ * late terminal as success). `undefined` deadline keeps the plain step (callers without a deadline). */
229
540
  export declare const sleepPollStep: (deadline: number | undefined, signal?: AbortSignal) => Promise<void>;
230
541
  export declare const sleepMs: (ms: number, signal?: AbortSignal) => Promise<void>;
542
+ /** design/135 G2 Monitor defaults (CC schema: 200ms batch window; timeout default 5min / max 60min).
543
+ * `MONITOR_MAX_BATCHES_PER_MINUTE` = the SUSTAINED batch rate the storm bucket refills at
544
+ * (RB-334: CC `TIs(bIs=10, OCo=2000)` 220:403284/403421-403423 refills 1 token per 2000ms = 30/min;
545
+ * sema keeps its own 50/min figure — the sema batch window is the same 200ms, so the two are the same
546
+ * order of magnitude — and derives the refill interval from it, see `stormRefillIntervalMs`). */
231
547
  export declare const MONITOR_BATCH_WINDOW_MS = 200;
232
548
  export declare const MONITOR_DEFAULT_TIMEOUT_MS = 300000;
233
549
  export declare const MONITOR_MAX_TIMEOUT_MS = 3600000;
234
550
  export declare const MONITOR_MAX_BATCHES_PER_MINUTE = 50;
551
+ /** RB-334 (CC `bIs` 220:403421): burst capacity of the storm token bucket — how many batches may fire
552
+ * back-to-back before the SUPPRESSION level engages. CC value, adopted verbatim. */
235
553
  export declare const MONITOR_STORM_BURST = 10;
554
+ /** RB-334 (CC `FN_` 220:403423): how long a monitor must stay CONTINUOUSLY over budget before the
555
+ * second level (kill) fires. CC value, adopted verbatim. */
236
556
  export declare const MONITOR_STORM_KILL_AFTER_MS = 30000;
557
+ /** RB-334 (CC `bdd` 220:403427): the partial-line accumulator bound. sema's `lineBuf` had NO bound —
558
+ * a monitored process emitting megabytes without a single newline grew it without limit (the spool's
559
+ * own roll never covered it). Keep the TAIL (the newest bytes are the ones a watch is about). */
237
560
  export declare const MONITOR_LINE_BUF_CAP = 1048576;
561
+ /** RB-239 ([1937] M2): the monitor event-result clip, shared by the watcher's batch/terminal emits and
562
+ * the stop-time drain emit (one clip, one truncation wording). */
238
563
  export declare function clipMonitorEvent(s: string): string;
564
+ /** RB-334 (CC `DCo` leg): per-line clip applied to the `lines[]` a batch carries. Spool untouched. */
239
565
  export declare function clipMonitorLine(s: string): string;
566
+ /**
567
+ * RB-335 (CC `rFs` 220:507725-507743, all six branches verbatim): the ONE terminal-notification summary
568
+ * HEAD for a background command / monitor watch. Every terminal frame in the bash and monitor lanes
569
+ * composes its summary as `terminalTaskSummary(...)` plus this lane's own honest detail clause — the
570
+ * pre-RB-335 code had six hand-written phrasings whose comment claimed "no CC sample for those faces"
571
+ * while 220 carries a verbatim sample for every one of them (the `failed` branch was the concrete
572
+ * mismatch: sema said `failed (exit code N)`, CC says `failed with exit code N`).
573
+ */
240
574
  export declare function terminalTaskSummary(kind: "bash" | "monitor", label: string, status: "completed" | "failed" | "killed", exitCode?: number): string;
241
575
  export declare const TASK_OUTPUT_MAX_CHARS = 160000;
576
+ /**
577
+ * CC `FHl` shape (pretty.js:458012-458016) when the task has an on-disk output file: TAIL-keep (a
578
+ * background command's latest output is the valuable end) behind a `[Truncated. Full output: <path>]`
579
+ * pointer so the model can Read the full spool. Without a file (workflow/agent results), keep the
580
+ * legacy head+tail middle-omission — there is no path to point at, and the head often carries status.
581
+ * RB-198 F4: the clip arithmetic itself moved to the shared {@link clipWithFilePointer} (a second caller,
582
+ * the foreground Bash tool, needed the SAME already-hardened RB-85/RB-112/RB-122 logic) — this wrapper
583
+ * only supplies the task-output budget.
584
+ */
242
585
  export declare function clipTaskOutput(s: string, fullOutputPath?: string): string;
243
586
  export declare function statusFromBackground(status: string, exitCode?: number): SemaTaskStatus;
587
+ /** Rolling middle-drop bound for the bash spool, shared by the watcher's per-tick accumulate and the
588
+ * teardown settle's terminal flush: keep head+tail halves within `cap`, account the dropped middle in
589
+ * `rolledChars` (the honesty counter the poll face reports as permanently-dropped bytes).
590
+ *
591
+ * design/158 S2 (RB-364 半): `onDrop`, when given, is called SYNCHRONOUSLY (before this function
592
+ * returns) with exactly the middle substring being dropped — the ONE place that substring is ever
593
+ * materialized, so a caller wanting to preserve it (the monitor lane's spill-to-offload-store) does not
594
+ * need to re-derive the same slice arithmetic a second time. Every EXISTING caller (the background_bash
595
+ * lane, task-registry.ts) omits the 4th argument, so their behavior — return value AND `rolledChars`
596
+ * accounting — is untouched byte-for-byte; the callback is a pure side-channel hook. */
244
597
  export declare function rollSpoolText(spool: {
245
598
  rolledChars: number;
246
599
  }, s: string, cap: number, onDrop?: (dropped: string) => void): string;
600
+ /** design/158 S2 (RB-364 半) — per-monitor-handle hard cap on cumulative CHARS (UTF-16 code units)
601
+ * spilled to the offload store (design/158 §3's S3 half, pulled forward alongside S2). Once a
602
+ * handle's running total reaches this, further rolled-off middles are simply not spilled —
603
+ * already-written segments stay readable (the poll disclosure says "earlier segments retained"),
604
+ * matching the pre-S2 loss shape for whatever is dropped PAST the cap. Exported so the boundary is a
605
+ * testable contract, not a buried literal.
606
+ *
607
+ * RB-396-b (回溯复查批, [c209-C] R2 C4① char/byte 同名异轴族): the constant used to be named
608
+ * `..._BYTES` while the ledger added `dropped.length` — chars, up to ~3× fewer than UTF-8 bytes on
609
+ * multibyte content. CHARS is the axis kept (name changed, arithmetic untouched) because it is the
610
+ * offload store family's own coordinate (`InMemoryToolResultStore.maxTotalChars` evicts by
611
+ * `content.length`; `ToolResultSlice.totalChars`) and the spool's `rolledChars` axis — one unit
612
+ * end-to-end; a `Buffer.byteLength` ledger here would sit crosswise to the store's own cap. */
247
613
  export declare const MONITOR_SPILL_CAP_CHARS: number;
614
+ /** RB-238 ([1937] M1): fold one poll's env-side-loss disclosure into the spool's account. The env's
615
+ * tail buffer evicts its HEAD under pressure (node-execution-env 8MB bound) — those bytes are gone
616
+ * before any watcher ever saw them, which is a different loss than the registry-side `rolledChars`
617
+ * middle-drop. `bytesDroppedBeforeCursor` only counts bytes dropped before an unconsumed cursor, so
618
+ * summing successive polls never double-counts; an env that says only `truncated` (no byte figure)
619
+ * degrades to the unquantified flag. Shared by ALL THREE consumers of a background poll — the monitor
620
+ * watcher, the bash watcher, and the blocking pollBackgroundBash leg (one class, one arithmetic).
621
+ * The blocked-wait leg used to keep its own hand-rolled `dropped += bytesDroppedBeforeCursor ?? 0`
622
+ * accumulator, which ignored `truncated` outright: an env that discloses the loss WITHOUT a byte
623
+ * figure produced ZERO disclosure on that leg. It routes through here now — the header's former
624
+ * "already accounted this on its own" claim was describing exactly the half-accounting that made the
625
+ * degraded shape invisible. */
248
626
  export declare function accountDroppedBytes(spool: {
249
627
  droppedBytes?: number;
250
628
  dropUnknown?: true;
@@ -252,10 +630,19 @@ export declare function accountDroppedBytes(spool: {
252
630
  truncated?: boolean;
253
631
  bytesDroppedBeforeCursor?: number;
254
632
  }): void;
633
+ /** RB-238 ([1937] M1) — the POLL-FACE wording for env-side loss (the terminal/event-frame wording is
634
+ * {@link droppedGapNote}'s; the two faces differ by design and always have). One function so the two
635
+ * quantified/unquantified branches cannot drift between the three legs that render it: the monitor
636
+ * re-readable spool, the bash re-readable spool, and the bash blocked wait. Trailing newline included
637
+ * (it is a banner LINE above the stdout heading); "" when nothing was dropped. */
255
638
  export declare function spoolDropNote(acct: {
256
639
  droppedBytes?: number;
257
640
  dropUnknown?: true;
258
641
  }): string;
642
+ /** The re-readable spool fields {@link renderSpoolBody} reads — the intersection of the bash handle's
643
+ * optional `spool` and the monitor handle's mandatory one (both carry supersets: `mirrorFailed` is
644
+ * bash-only, `drainFailed`/`dropNotified` monitor-only). Declared as a named shape, not inlined, so
645
+ * the renderer's contract is one thing both lanes are checked against. */
259
646
  export interface RenderableSpool {
260
647
  stdout: string;
261
648
  stderr: string;
@@ -266,27 +653,82 @@ export interface RenderableSpool {
266
653
  droppedBytes?: number;
267
654
  dropUnknown?: true;
268
655
  }
656
+ /** The per-lane inputs {@link renderSpoolBody} cannot derive from the spool itself.
657
+ * `rolledExtraClause` / `drainNote` are PRE-RENDERED STRINGS, deliberately not booleans or a lane
658
+ * discriminator: the renderer must stay ignorant of which lane called it, otherwise the two monitor-only
659
+ * disclosures (design/158 S2 spill refs; RB-239 stop-time drain failure) come back as in-renderer
660
+ * branches on a kind switch — the exact shape that let the two hand-copied renderers drift in the first
661
+ * place. Both are "" on a lane that has no such disclosure. */
269
662
  export interface SpoolBodyOptions {
663
+ /** The handle is still running (drives the "running" display status). */
270
664
  running: boolean;
665
+ /** Fallback display status for a non-running handle with no recorded exit code. */
271
666
  handleStatus: SemaTaskStatus;
667
+ /** The lane's filter+clip projection, applied to stdout and stderr alike. */
272
668
  shape: (text: string) => string;
669
+ /** Appended INSIDE the roll note, before its newline ("" when the lane has no extra clause). */
273
670
  rolledExtraClause: string;
671
+ /** A full banner line (own trailing newline) rendered after the drop note, or "". */
274
672
  drainNote: string;
275
673
  }
674
+ /** RB-238/RB-239/RB-240 ([1937] M1-M3) — the ONE renderer for a re-readable spool's TaskOutput body,
675
+ * shared by the monitor lane (pollMonitorLane) and the bash spool lane (pollBackgroundBash).
676
+ *
677
+ * Both faces were hand-copied twins carrying three real disclosure bugs' worth of wording (env-side
678
+ * eviction vs registry roll are SEPARATE notes, never merged; a self-inflicted background-timeout kill
679
+ * renders distinguishably from an external stop; a spool with a disclosed gap must stop advertising
680
+ * itself as "full") — kept in sync by a comment on each side telling the reader to make the same edit
681
+ * twice. The heading rule is the load-bearing one: any disclosed gap (env-side drop OR a failed
682
+ * stop-time drain) downgrades the heading, so a caller cannot add a gap note and forget the heading.
683
+ *
684
+ * NOT used by the blocked-wait leg: that face is a consume-once "new stdout" increment with its own
685
+ * wording ("accumulated char(s) dropped from the middle during the blocked wait"), an intentional
686
+ * divergence — it shares {@link accountDroppedBytes} + {@link spoolDropNote}, not this. */
276
687
  export declare function renderSpoolBody(spool: RenderableSpool, opts: SpoolBodyOptions): string;
688
+ /** RB-238: the honesty suffix for frames over a spool with env-side loss. Empty when nothing dropped. */
277
689
  export declare function droppedGapNote(spool: {
278
690
  droppedBytes?: number;
279
691
  dropUnknown?: true;
280
692
  }): string;
693
+ /** RB-238: the event-stream disclosure rides the FIRST batch after a loss is observed (once-latch —
694
+ * a chatty watch must not repeat the note on every batch; terminal frames disclose unconditionally). */
281
695
  export declare function firstDropNote(spool: {
282
696
  droppedBytes?: number;
283
697
  dropUnknown?: true;
284
698
  dropNotified?: true;
285
699
  }): string;
700
+ /** RB-244 ([1937] T1): ONE wording for "you stopped nothing" across every already-terminal stop face —
701
+ * the in-process bash/monitor/agent arms and the durable-row fallback previously split: the durable
702
+ * arm answered honestly while the in-process arms claimed `Terminated <id>.` over work that finished
703
+ * (or was killed) on its own. CC 220 refuses the call outright (`Task X is not running (status: …)`,
704
+ * 220:468231-468236); sema keeps the idempotent no-op posture (stopWorkflow / durable-arm precedent,
705
+ * no isError) but the receipt must tell the truth. */
286
706
  export declare function alreadyTerminalStopNote(id: string, status: string): string;
707
+ /** design/115 review B1 → β 批 A-2: register-side fail-fast, now on BOTH axes — `canAccess` is
708
+ * default-deny, so a handle missing either axis would be unreachable by every caller (a dead row
709
+ * is worse than a loud registration error). The production chain always sets both (hostTaskId +
710
+ * principal-or-"default"); a direct registry caller declares its access domain explicitly
711
+ * (`scope: "default"` is the single-tenant spelling — explicit, never implied). */
287
712
  export declare function assertOwnership(input: TaskAccess, site: string): void;
713
+ /** γ 批 B-1 (2026-07-22, [1510] 同窗) — POSITIVE-MATCH form, one polarity with `canAccess`/
714
+ * `canAccessAgentRecord` (β 批 A-2): scope must match, then the caller must HIT an arm — owner
715
+ * (the spawning task) or SESSION (the run's `originatingSessionId`). The session arm is the B-1
716
+ * HIGH fix: the completion notification routes back to the originating SESSION, but per-turn
717
+ * taskIds die with their turn — before this arm, a later turn of the same session could not poll
718
+ * or stop its own workflow (default-deny functional breakage, [1502] R4 sibling). The old form's
719
+ * `access.owner === undefined ⇒ pass` scope-only residue is gone with the same β polarity ruling
720
+ * (design/136 §2.3 S-1 定谳 posture, now positive-match on every arm). Exported: the run-workflow
721
+ * tool's resume-ownership recheck and a deployment's serving layer apply the SAME predicate. */
288
722
  export declare function canAccessWorkflowRun(run: Pick<WorkflowRun, "scope" | "sourceTaskId" | "originatingSessionId">, access: TaskAccess): boolean;
289
723
  export declare function formatWorkflowRun(run: WorkflowRun): UnifiedTaskResult;
724
+ /** design/157 B13 一期定稿(二期细察补充 §「私有成员解法」)——the kernel-面 seam the MON/WF lane free
725
+ * functions call through instead of `this`: exactly the 5 members `startMonitorWatcher`/`stopMonitor`/
726
+ * `registerMonitor`/`registerWorkflow` actually reach into (`this.*` 耦合 grep 逐方法统计,见 B13 档).
727
+ * Does NOT include `fireServedTerminal` (WF-private helper, only called from within `pollWorkflow`
728
+ * itself — travels with the lane, never crosses the core seam) nor any AGENT-domain member (二期 extends
729
+ * this as `DurableAgentCore` per B13 §「私有成员解法」). The TaskRegistry class satisfies this via a
730
+ * `#coreView`-style cached object (`private readonly core: RegistryCore`), declared AFTER `handles` so
731
+ * the eager `handles` field reference below sees an already-initialized Map. */
290
732
  export interface RegistryCore {
291
733
  handles: Map<string, RegisteredTaskHandle>;
292
734
  mintTaskId(type: SemaTaskType): string;
@@ -294,20 +736,62 @@ export interface RegistryCore {
294
736
  notifyTerminalOnce(handle: BackgroundBashTaskHandle | MonitorTaskHandle, send: () => void): void;
295
737
  pokeBgQuiescence(owner: string | undefined): void;
296
738
  }
739
+ /** codex S1a F2 — writer-lease renewal period for armed durable rows (see ensureDurableHeartbeat).
740
+ * Exported so deployments size `staleRunningMaxAgeMs` against it (recommend ≥10× this). */
297
741
  export declare const DURABLE_AGENT_HEARTBEAT_MS = 60000;
742
+ /** design/151 S1a (codex F3): the durable fallback consults the store ONLY for handle-shaped ids —
743
+ * a NAME (the fuzzy stop leg) or a foreign-domain id must not take a store round-trip, and a store
744
+ * outage must never block the local name-resolution ladder. Mint form: `a` + 16 hex; the revive
745
+ * leg re-registers the same form.
746
+ * EXPORTED ([1518] server ask): a serving layer's fallback needs the SAME shape gate before its
747
+ * durable arm (a bare exact-key miss lets padded/legacy/name-shaped ids leak into live branches —
748
+ * the server 1.250 HIGH) — one shared regex kills the drift, roster-normalize precedent. */
298
749
  export declare const DURABLE_AGENT_HANDLE_RE: RegExp;
750
+ /** Synthetic settle error the subagent reap path passes after a stop/parent teardown. It is NOT a
751
+ * real child error — settleBackgroundAgent never stores it (status "killed" + stoppedBy already say
752
+ * it); exported so the subagent call sites and the registry agree on the exact sentinel. */
299
753
  export declare const BG_AGENT_REAP_STOP_ERROR = "stopped (parent task ended or TaskStop)";
754
+ /** CC206-B 欠账 — TaskStop name addressing, CC `XN` verbatim (206:574955-574962): NFKC-normalize, strip
755
+ * control/format chars (whitespace-class ones survive), trim, lowercase, whitespace runs → hyphens. Both
756
+ * the query and the candidate label go through this, so "Fix Tests" addresses "fix tests".
757
+ * [c209-D] codex R4: EXPORTED — SendMessage's "main" reserved lane must use the SAME canonicalization
758
+ * as this resolver, or an NFKC-equivalent spelling (fullwidth "main") skips the reserved lane and
759
+ * reaches the description layers. One normalizer, every name face. */
300
760
  export declare function normalizeAgentName(s: string): string;
761
+ /** CC `gtr` (fable 复审 F1 — 亲核 @16169850: NOT plain Levenshtein but OSA / restricted
762
+ * Damerau-Levenshtein, WITH the adjacent-transposition term `o[i][s]=min(o[i][s], o[i-2][s-2]+1)`
763
+ * when `e[i-1]===t[s-2] && e[i-2]===t[s-1]`). The transposition matters: a typo like "tset"→"test"
764
+ * is distance 1 (CC has a Did-you-mean), plain Levenshtein would call it 2. */
301
765
  export declare function editDistance(a: string, b: string): number;
766
+ /** CC `htr` shape (206:519814-519827): candidates within Levenshtein ≤2 (length-diff ≤2 pre-filter),
767
+ * best-first; the single best is the "Did you mean" suggestion (`htr(e, keys, 1)[0]`, 206:575196). */
302
768
  export declare function closestName(query: string, candidates: Iterable<string>): string | undefined;
769
+ /** β 批 A-2 (clay 裁定 2026-07-22, 一步到位): DEFAULT-DENY on BOTH axes — the old predicate skipped
770
+ * a missing axis (owner-less handle = readable by everyone in scope; scope-less handle = readable
771
+ * across scopes), splitting polarity with `canAccessAgentRecord` and re-opening the session-axis
772
+ * class cli/server just swept. Registration now REQUIRES both axes ({@link assertOwnership}), so a
773
+ * missing axis here is a broken invariant, answered with denial, never a pass. */
303
774
  export declare function canAccess(handle: SemaTaskHandle, access: TaskAccess): boolean;
775
+ /** design/157 B13 二期(B13 档预调研 §4.2/§4.3 定稿)— the durable-agent lane's widened core seam.
776
+ * Extends {@link RegistryCore} with EXACTLY the 5 extra members the AGENT lane's `this.*` census
777
+ * reached (73 处/9 成员,扣车道内互调后落在这 5 个上,见 B13 档「二期细察补充」)。
778
+ * `durableAgentWrite`/`ensureDurableHeartbeat`/`settleBackgroundAgent` are NOT here — they are lane
779
+ * members themselves (车道内直接函数调用;类上只留转发或不留)。The class satisfies this via the
780
+ * same cached-view field, upgraded with lazy getter/setter proxies (an IIFE capturing `this`) so
781
+ * field declaration ORDER no longer constrains it — `writerId`/`reapingHandles` 등 are read at
782
+ * call time, after construction completes. */
304
783
  export interface DurableAgentCore extends RegistryCore {
305
784
  readonly writerId: string;
306
785
  readonly reapingHandles: Set<string>;
307
786
  readonly claimingHandles: Set<string>;
787
+ /** get/set proxy — `ensureDurableHeartbeatLane` both reads AND writes the timer slot. */
308
788
  durableHeartbeatTimer: ReturnType<typeof setInterval> | undefined;
309
789
  readonly deliverConfirmTimeoutMs: number;
310
790
  }
791
+ /** design/153 §7.2c (件3b) — the compensable reservation ticket {@link TaskRegistry.claimParkedAgent}
792
+ * returns: everything {@link TaskRegistry.rollbackParkedClaim} and the 件3c consume flip need to
793
+ * proceed or compensate. `row` is the PRE-RESERVATION snapshot (restored verbatim on rollback);
794
+ * `reservedRev` is the row's rev AFTER the reservation CAS (the next guarded write binds to it). */
311
795
  export interface ParkedClaimTicket {
312
796
  handle: string;
313
797
  scope: string;
@@ -316,29 +800,85 @@ export interface ParkedClaimTicket {
316
800
  reservedRev: number;
317
801
  row: import("./background-agent-store.js").BackgroundAgentRecord;
318
802
  }
803
+ /** P1-3 独立复审第三轮(已修) — sibling of {@link mintCompletionId} for a caller that must compute the
804
+ * value BEFORE it is safe to commit (a CAS not yet known to win): fill-once with an EXTERNALLY-chosen
805
+ * value instead of generating a fresh one. Exists because `rollbackParkedClaim`'s original fix minted
806
+ * directly onto the live handle before its durable CAS was confirmed — a losing CAS then left a
807
+ * non-terminal ("parked") handle carrying a completionId nothing ever cleared, which a later legitimate
808
+ * parked→running flip (`consumeParkedFlip`) silently carried into an unrelated real completion via
809
+ * `mintCompletionId`'s own fill-once guard (independently reproduced end-to-end). The fix: compute the
810
+ * candidate once, use it in the durable payload immediately (that write is fine — it only takes effect
811
+ * if its own CAS wins), and commit it to the live handle ONLY from the call that already knows the CAS
812
+ * won. */
319
813
  export declare function commitCompletionIdIfEmpty(target: {
320
814
  completionId?: string;
321
815
  }, value: string): string;
322
816
  export interface RegisterBackgroundAgentInput extends TaskAccess {
817
+ /** design/153 §7.2d (件3c) — parked-resume registration shape: the handle is born PARKED (the
818
+ * pre-consume window keeps the live face's checkpoint arbitration; the consume flip
819
+ * {@link TaskRegistry.adoptParkedResume} is the only path to running). Pass the ticket's token
820
+ * and a stop-arbitration closure alongside. Also licenses replacing an in-process PARKED prior
821
+ * handle of the same id (the planned park→resume handoff; lane poisoned like the terminal replace). */
323
822
  initialStatus?: "parked";
823
+ /** design/153 §7.2d — the parked checkpoint token this parked-born handle waits on. */
324
824
  parkedCheckpointToken?: string;
825
+ /** design/153 §7.2d — the TaskStop arbitration closure for the parked-born handle (expire CAS). */
325
826
  resolveParkedStop?: () => Promise<boolean>;
827
+ /** design/147 S2a (codex R5 F7) — declare that the spawner WILL attach a mid-run delivery
828
+ * channel (attachAgentNotify) once the child's lane binds. Only declared-"attaching" rows buffer
829
+ * startup-window messages; an undeclared row refuses `no_channel` IMMEDIATELY — a spawner that
830
+ * never attaches must not collect acknowledged-then-discarded messages (silent loss). */
326
831
  deliveryChannel?: "attaching";
832
+ /** S2b RB-27① codex F1 — the spawner DECLARES whether a parked message is redeemable: true when
833
+ * the child's session outlives the run (retain ledger or session-scoped registration), so a
834
+ * continuation can drain the park. A non-retained row must NOT hand out parked acknowledgements
835
+ * (the session is released right after settle — the park would be irrecoverable): its
836
+ * lane-dead race window reads as `not_running` instead, steering the sender to the settled path. */
327
837
  retainedContinuation?: boolean;
328
838
  description?: string;
839
+ /** [c209-D] explicit addressing name (CC Agent.name parity) — the CALLER validates it (charset +
840
+ * reserved "main") before registration; the registry stores it verbatim. Duplicate names are legal
841
+ * (latest-wins at resolution; older rows stay task_id-addressable). */
329
842
  name?: string;
843
+ /** [1358]/[1336]A — the RESOLVED subagent type ("general-purpose"/"fork"/a roster name), persisted
844
+ * so a REVIVE cycle's observer frames can reproduce the row's TYPE column (never the description). */
330
845
  agentType?: string;
846
+ /** [1371]② — the spawn frame's parent linkage, persisted so a REVIVE cycle's spawn frame nests the
847
+ * revived row exactly like the first spawn did. The caller passes the SAME values it emitted on the
848
+ * original frame (parentTaskId already [1344]②-clamped there; parentSessionId always-on). */
331
849
  parentTaskId?: string;
332
850
  parentSessionId?: string;
851
+ /** δ 批 [1498]⑦ — the ROOT host session of the delegation tree (fixed point down the trusted
852
+ * internals chain; equals parentSessionId at depth 1). Persisted on the handle, the durable row
853
+ * and the roster so recovery faces enumerate the whole tree under the root without alias walks. */
333
854
  rootSessionId?: string;
855
+ /** design/151 S3b — revival lookup keys (CC meta-sidecar shape): the RESOLVED model id and the
856
+ * team name, persisted on the durable row so a tier-3 revival rebuilds the spec the way a fresh
857
+ * named-teammate spawn would. Lookup keys only, never a serialized spec. */
334
858
  model?: string;
335
859
  teamName?: string;
336
860
  toolUseId?: string;
337
861
  abort: AbortController;
338
862
  now?: number;
863
+ /** design/129: register as session-scoped (owner MUST be the sessionId; see the handle flag). */
339
864
  sessionScoped?: true;
865
+ /** design/151 S1a (LOW-12): caller-supplied handle — the tier-3 revival leg (S3) re-registers the
866
+ * SAME durable handle so the row stays continuous across restarts. Collision with a live in-memory
867
+ * row throws (registerBackgroundBash parity). Absent ⇒ mint. */
340
868
  id?: string;
869
+ /** design/151 S1a: the durable execution-row ledger. Present (with BOTH owner and scope — the
870
+ * durable predicate is fail-closed on both axes) ⇒ this registration writes a durable row
871
+ * (put → bind → settle, a serialized best-effort single-writer lane); absent ⇒ the pre-151
872
+ * in-memory-only lifecycle, byte for byte. */
341
873
  store?: BackgroundAgentStore;
874
+ /** design/151 §7.2 (X-2/F-7) — tier-3 revival lane seeding: the CLAIMED durable row (identity
875
+ * inherited verbatim, status running, writerId = this instance) and its post-claim rev. Present
876
+ * ⇒ the durable lane starts from this snapshot with `written: true` and SKIPS the initial put
877
+ * (the claim-CAS already committed the row); every later write CASes against `rev`, so the first
878
+ * settle moves the claim forward instead of losing to it. Also authorizes REPLACING a leftover
879
+ * TERMINAL in-memory handle of the same id (the pre-revival cycle's row survives ~1h of terminal
880
+ * GC): its stale lane is silenced first — a queued/re-driven write from it carries the pre-claim
881
+ * rev under this process's own writerId, and the adopt path would clobber the claim. */
342
882
  durableSeed?: {
343
883
  record: BackgroundAgentRecord;
344
884
  rev: number;