@sema-agent/core 7.54.1 → 7.55.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 (399) hide show
  1. package/CHANGELOG.md +437 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cc-peer-directory.d.ts +36 -0
  5. package/dist/agents/cc-peer-directory.js +138 -0
  6. package/dist/agents/cc-peer-wire.d.ts +105 -0
  7. package/dist/agents/cc-peer-wire.js +98 -0
  8. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  9. package/dist/agents/cc-uds-peer-channel.js +457 -0
  10. package/dist/agents/cross-session-envelope.d.ts +4 -1
  11. package/dist/agents/cross-session-envelope.js +8 -1
  12. package/dist/agents/cross-session-judge.d.ts +2 -2
  13. package/dist/agents/list-agents-tool.js +2 -1
  14. package/dist/agents/observer.d.ts +4 -5
  15. package/dist/agents/observer.js +2 -1
  16. package/dist/agents/peer-admission.d.ts +6 -0
  17. package/dist/agents/peer-admission.js +4 -1
  18. package/dist/agents/peer-directory.d.ts +43 -9
  19. package/dist/agents/peer-directory.js +66 -23
  20. package/dist/agents/peer-notices.d.ts +1 -1
  21. package/dist/agents/peer-session-drain.d.ts +3 -1
  22. package/dist/agents/peer-session-drain.js +1 -0
  23. package/dist/agents/read-inbox-tool.js +2 -1
  24. package/dist/agents/retain-ledger.d.ts +1 -1
  25. package/dist/agents/roster-store.d.ts +1 -1
  26. package/dist/agents/send-message-tool.d.ts +10 -0
  27. package/dist/agents/send-message-tool.js +34 -5
  28. package/dist/agents/subagent.d.ts +34 -79
  29. package/dist/agents/subagent.js +45 -46
  30. package/dist/agents/tool-filter.d.ts +29 -46
  31. package/dist/agents/tool-filter.js +8 -31
  32. package/dist/agents/verify.d.ts +3 -3
  33. package/dist/brain/anthropic.js +14 -9
  34. package/dist/brain/errors.d.ts +15 -0
  35. package/dist/brain/errors.js +10 -0
  36. package/dist/brain/model-presets.d.ts +4 -4
  37. package/dist/brain/open-responses.js +15 -10
  38. package/dist/brain/openai.js +17 -12
  39. package/dist/brain/provider-dialect.d.ts +39 -3
  40. package/dist/brain/provider-dialect.js +28 -0
  41. package/dist/brain/reasoning.d.ts +1 -1
  42. package/dist/brain/request-params.d.ts +55 -5
  43. package/dist/brain/request-params.js +35 -3
  44. package/dist/brain/retry.d.ts +1 -1
  45. package/dist/brain/route-adjudicator.d.ts +15 -0
  46. package/dist/brain/route-adjudicator.js +15 -0
  47. package/dist/brain/stream-engine.js +6 -5
  48. package/dist/brain/stream-shared.d.ts +1 -1
  49. package/dist/core/advisor-verdict.d.ts +120 -0
  50. package/dist/core/advisor-verdict.js +92 -0
  51. package/dist/core/agent-definition.d.ts +7 -8
  52. package/dist/core/allow-entry.d.ts +49 -23
  53. package/dist/core/allow-entry.js +57 -32
  54. package/dist/core/allow-rule-shadow.d.ts +7 -0
  55. package/dist/core/approval-object.d.ts +2 -1
  56. package/dist/core/approval-object.js +6 -6
  57. package/dist/core/ask-origin.d.ts +63 -11
  58. package/dist/core/ask-origin.js +27 -5
  59. package/dist/core/ask-question.js +10 -4
  60. package/dist/core/auto-compaction.d.ts +11 -8
  61. package/dist/core/auto-compaction.js +4 -2
  62. package/dist/core/auto-mode-arming.d.ts +2 -2
  63. package/dist/core/auto-mode-defaults.d.ts +8 -8
  64. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  65. package/dist/core/auto-mode-prompt.d.ts +1 -1
  66. package/dist/core/auto-mode.d.ts +17 -9
  67. package/dist/core/auto-mode.js +9 -6
  68. package/dist/core/background-agent-store.d.ts +3 -3
  69. package/dist/core/canonical-json.d.ts +1 -1
  70. package/dist/core/canonical-json.js +2 -2
  71. package/dist/core/checkpoint-requirements.d.ts +6 -3
  72. package/dist/core/checkpoint-requirements.js +4 -14
  73. package/dist/core/checkpoint-store.d.ts +80 -51
  74. package/dist/core/checkpoint-store.js +56 -74
  75. package/dist/core/child-clamp-seats.d.ts +6 -0
  76. package/dist/core/child-clamp-seats.js +3 -16
  77. package/dist/core/compliance.d.ts +2 -2
  78. package/dist/core/context-edit.d.ts +6 -7
  79. package/dist/core/cross-boundary-taint.d.ts +9 -3
  80. package/dist/core/cross-boundary-taint.js +5 -3
  81. package/dist/core/decision-receipt.js +2 -2
  82. package/dist/core/effective-path-target.d.ts +1 -1
  83. package/dist/core/engine-notice.d.ts +19 -5
  84. package/dist/core/exec-output-tail.d.ts +1 -1
  85. package/dist/core/file-history-retention.d.ts +1 -1
  86. package/dist/core/file-history-store.d.ts +59 -9
  87. package/dist/core/file-history-store.js +35 -17
  88. package/dist/core/gate-fold.js +3 -2
  89. package/dist/core/gate-lanes.js +12 -8
  90. package/dist/core/gate-outcome.d.ts +17 -4
  91. package/dist/core/gate-outcome.js +30 -0
  92. package/dist/core/governance-codes.d.ts +13 -3
  93. package/dist/core/governance-codes.js +10 -0
  94. package/dist/core/hands-band.d.ts +1 -1
  95. package/dist/core/hooks.d.ts +4 -4
  96. package/dist/core/host-target.d.ts +49 -0
  97. package/dist/core/host-target.js +59 -0
  98. package/dist/core/image-downsample.d.ts +1 -1
  99. package/dist/core/lsp-diagnostics.d.ts +4 -4
  100. package/dist/core/lsp.d.ts +3 -3
  101. package/dist/core/mailbox-store.d.ts +4 -0
  102. package/dist/core/mcp-connection-pool.d.ts +18 -2
  103. package/dist/core/mcp-connection-pool.js +53 -6
  104. package/dist/core/mcp-failure.d.ts +23 -4
  105. package/dist/core/mcp-failure.js +26 -11
  106. package/dist/core/mcp-listing-drift.d.ts +10 -0
  107. package/dist/core/mcp-listing-drift.js +6 -0
  108. package/dist/core/mcp-server-link.d.ts +173 -0
  109. package/dist/core/mcp-server-link.js +127 -0
  110. package/dist/core/mcp-server-spec.d.ts +4 -2
  111. package/dist/core/mcp-session-end.d.ts +26 -0
  112. package/dist/core/mcp-session-end.js +29 -0
  113. package/dist/core/mcp-startup-request.d.ts +17 -0
  114. package/dist/core/mcp-startup-request.js +17 -0
  115. package/dist/core/mcp.d.ts +13 -13
  116. package/dist/core/mcp.js +187 -162
  117. package/dist/core/media-byte-cap.d.ts +1 -1
  118. package/dist/core/memory-engine/engine.d.ts +9 -9
  119. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  120. package/dist/core/memory-engine/tools.js +4 -1
  121. package/dist/core/mode-policy.d.ts +1 -1
  122. package/dist/core/namespaced-rule-name.d.ts +33 -7
  123. package/dist/core/namespaced-rule-name.js +39 -25
  124. package/dist/core/output-style.d.ts +1 -1
  125. package/dist/core/param-rule-reach.d.ts +15 -0
  126. package/dist/core/param-rule-reach.js +30 -0
  127. package/dist/core/parent-spec-seat.d.ts +8 -1
  128. package/dist/core/parent-spec-seat.js +4 -0
  129. package/dist/core/pause-registry.d.ts +16 -5
  130. package/dist/core/pause-registry.js +6 -2
  131. package/dist/core/peer-channel.d.ts +70 -0
  132. package/dist/core/peer-channel.js +1 -0
  133. package/dist/core/permission-rule-consent.d.ts +11 -5
  134. package/dist/core/permission-rule-consent.js +37 -30
  135. package/dist/core/permission-rule-model.d.ts +233 -64
  136. package/dist/core/permission-rule-model.js +384 -85
  137. package/dist/core/permission-rule-provider.d.ts +2 -1
  138. package/dist/core/permission-rule-store.d.ts +20 -25
  139. package/dist/core/permission-rule-store.js +1 -4
  140. package/dist/core/permission-rule-sync.d.ts +11 -2
  141. package/dist/core/permission-rule-sync.js +8 -1
  142. package/dist/core/permission-rules.d.ts +49 -11
  143. package/dist/core/permission-rules.js +123 -89
  144. package/dist/core/persisted-rule-arms.d.ts +4 -2
  145. package/dist/core/present-plan-tool.js +3 -1
  146. package/dist/core/protocol-naming.d.ts +2 -2
  147. package/dist/core/read-only-shell-table.d.ts +1 -1
  148. package/dist/core/read-only-shell.d.ts +1 -1
  149. package/dist/core/roles.d.ts +6 -2
  150. package/dist/core/roles.js +45 -44
  151. package/dist/core/rule-offer-read.d.ts +53 -0
  152. package/dist/core/rule-offer-read.js +146 -0
  153. package/dist/core/rule-owner.d.ts +46 -0
  154. package/dist/core/rule-owner.js +28 -0
  155. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  156. package/dist/core/runner/advisor-instructions.js +61 -0
  157. package/dist/core/runner/advisor-tool.d.ts +33 -0
  158. package/dist/core/runner/advisor-tool.js +112 -0
  159. package/dist/core/runner/announce-once-ledger.d.ts +4 -26
  160. package/dist/core/runner/announce-once-ledger.js +14 -46
  161. package/dist/core/runner/approval-feedback.js +6 -3
  162. package/dist/core/runner/assemble-result.d.ts +1 -1
  163. package/dist/core/runner/caller-roster.d.ts +7 -0
  164. package/dist/core/runner/caller-roster.js +11 -0
  165. package/dist/core/runner/classifier-ladder.d.ts +27 -5
  166. package/dist/core/runner/classifier-ladder.js +12 -11
  167. package/dist/core/runner/compaction-restate.d.ts +10 -6
  168. package/dist/core/runner/compaction-restate.js +9 -3
  169. package/dist/core/runner/contracts.d.ts +13 -9
  170. package/dist/core/runner/conversation-segment.d.ts +28 -0
  171. package/dist/core/runner/conversation-segment.js +42 -0
  172. package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
  173. package/dist/core/runner/cross-boundary-lane.js +26 -15
  174. package/dist/core/runner/decide-continuation.d.ts +7 -4
  175. package/dist/core/runner/decide-continuation.js +2 -2
  176. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  177. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  178. package/dist/core/runner/derived-route-fallback.js +9 -7
  179. package/dist/core/runner/gate-exit.d.ts +6 -0
  180. package/dist/core/runner/gate-exit.js +7 -2
  181. package/dist/core/runner/initial-run-state.js +1 -1
  182. package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
  183. package/dist/core/runner/permission-rule-lanes.js +14 -7
  184. package/dist/core/runner/person-path-rows.js +1 -1
  185. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  186. package/dist/core/runner/prepare-advisor.js +77 -0
  187. package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
  188. package/dist/core/runner/prepare-config-doors.d.ts +6 -4
  189. package/dist/core/runner/prepare-config-doors.js +18 -12
  190. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  191. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  192. package/dist/core/runner/prepare-file-history.js +39 -39
  193. package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
  194. package/dist/core/runner/prepare-gate-stations.js +2 -7
  195. package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
  196. package/dist/core/runner/prepare-inherited-gate.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.js +7 -7
  198. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  199. package/dist/core/runner/prepare-policy-chain.js +4 -10
  200. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  201. package/dist/core/runner/prepare-project-context.js +6 -3
  202. package/dist/core/runner/prepare-prompt-inputs.js +1 -1
  203. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
  204. package/dist/core/runner/prepare-protocol-tools.js +3 -2
  205. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  206. package/dist/core/runner/prepare-safety-scan.js +8 -6
  207. package/dist/core/runner/prepare-task.js +15 -18
  208. package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
  209. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
  210. package/dist/core/runner/prepare-wiring-manifest.js +2 -2
  211. package/dist/core/runner/resume-policy-outcome.js +1 -1
  212. package/dist/core/runner/retired-runner-deps.js +1 -1
  213. package/dist/core/runner/run-attachment-seats.js +0 -1
  214. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  215. package/dist/core/runner/run-compaction-machinery.js +2 -12
  216. package/dist/core/runner/run-git-lane.d.ts +1 -0
  217. package/dist/core/runner/run-harness-handlers.js +2 -3
  218. package/dist/core/runner/run-leg.js +13 -0
  219. package/dist/core/runner/run-settle-and-teardown.js +1 -1
  220. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  221. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  222. package/dist/core/runner/run-turn-boundary.js +14 -12
  223. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  224. package/dist/core/runner/session-rule-policy.js +13 -28
  225. package/dist/core/runner/side-call-account.d.ts +32 -8
  226. package/dist/core/runner/side-call-account.js +23 -1
  227. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  228. package/dist/core/runner/sub-agent-deny-lists.js +4 -3
  229. package/dist/core/runner/synthetic-tools.d.ts +10 -13
  230. package/dist/core/runner/synthetic-tools.js +4 -2
  231. package/dist/core/runner/tool-disclosure.js +2 -1
  232. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  233. package/dist/core/runner/tool-face-overlay.js +17 -1
  234. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  235. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  236. package/dist/core/runner/turn-attachments.d.ts +60 -67
  237. package/dist/core/runner-deps.d.ts +37 -37
  238. package/dist/core/runtime-caps.d.ts +4 -4
  239. package/dist/core/safety-merge-corpus.js +17 -1
  240. package/dist/core/same-plain-value.d.ts +40 -0
  241. package/dist/core/same-plain-value.js +49 -0
  242. package/dist/core/scheduler.d.ts +1 -1
  243. package/dist/core/sensitive-path-policy.d.ts +1 -1
  244. package/dist/core/sensitive-path-policy.js +1 -1
  245. package/dist/core/session-policy-store.d.ts +77 -22
  246. package/dist/core/session-policy-store.js +56 -14
  247. package/dist/core/session-reconcile.d.ts +2 -2
  248. package/dist/core/session-store.d.ts +80 -30
  249. package/dist/core/session-store.js +118 -76
  250. package/dist/core/session.d.ts +24 -46
  251. package/dist/core/shared-memory/tools.js +3 -1
  252. package/dist/core/shared-memory/types.d.ts +1 -1
  253. package/dist/core/side-query.d.ts +10 -0
  254. package/dist/core/side-query.js +5 -0
  255. package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
  256. package/dist/core/store-contracts/file-history-store-contract.js +43 -3
  257. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  258. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  259. package/dist/core/store-contracts/session-repo-contract.js +125 -0
  260. package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
  261. package/dist/core/store-contracts/session-store-contract.js +215 -41
  262. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  263. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  264. package/dist/core/task-event.d.ts +10 -4
  265. package/dist/core/task-notification.d.ts +3 -3
  266. package/dist/core/task-registry-agent.d.ts +4 -4
  267. package/dist/core/task-registry-shared.d.ts +4 -4
  268. package/dist/core/task-registry-shared.js +1 -0
  269. package/dist/core/task-registry.d.ts +4 -4
  270. package/dist/core/task-registry.js +3 -1
  271. package/dist/core/task-result.d.ts +3 -3
  272. package/dist/core/task-spec.d.ts +52 -52
  273. package/dist/core/task-stream.d.ts +6 -6
  274. package/dist/core/task-tool-shape.d.ts +4 -4
  275. package/dist/core/tighten-task-spec.d.ts +1 -1
  276. package/dist/core/tool-catalog-entries.d.ts +19 -2
  277. package/dist/core/tool-catalog-entries.js +57 -42
  278. package/dist/core/tool-conformance.js +1 -0
  279. package/dist/core/tool-errors.d.ts +2 -2
  280. package/dist/core/tool-face-reader.js +5 -3
  281. package/dist/core/tool-face.d.ts +21 -2
  282. package/dist/core/tool-face.js +1 -1
  283. package/dist/core/tool-model-gate.d.ts +3 -3
  284. package/dist/core/tool-name-aliases.d.ts +29 -8
  285. package/dist/core/tool-name-aliases.js +27 -3
  286. package/dist/core/tool-name-readings.d.ts +5 -8
  287. package/dist/core/tool-name-readings.js +1 -2
  288. package/dist/core/tool-policy.d.ts +24 -5
  289. package/dist/core/tool-policy.js +34 -10
  290. package/dist/core/tool-registry.d.ts +14 -7
  291. package/dist/core/tool-registry.js +17 -7
  292. package/dist/core/tool-result-store.js +2 -1
  293. package/dist/core/tool-roster.d.ts +47 -18
  294. package/dist/core/tool-roster.js +53 -32
  295. package/dist/core/tool-spec-members.js +1 -1
  296. package/dist/core/tool-spec.d.ts +35 -21
  297. package/dist/core/tools.js +3 -2
  298. package/dist/core/trace.d.ts +4 -0
  299. package/dist/core/untrusted-egress.d.ts +1 -1
  300. package/dist/core/untrusted-text.d.ts +1 -1
  301. package/dist/core/warm-resume.d.ts +1 -1
  302. package/dist/core/wiring-manifest.d.ts +49 -0
  303. package/dist/core/wiring-manifest.js +13 -5
  304. package/dist/core/workflow-journal-store.d.ts +62 -0
  305. package/dist/core/workflow-journal-store.js +77 -1
  306. package/dist/core/workflow-run-store.d.ts +6 -0
  307. package/dist/core/workflow-run-store.js +2 -0
  308. package/dist/engine/compaction/compaction.d.ts +9 -9
  309. package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
  310. package/dist/engine/execution-env/node-execution-env.js +43 -22
  311. package/dist/engine/harness/agent-harness.d.ts +14 -8
  312. package/dist/engine/harness/agent-harness.js +33 -26
  313. package/dist/engine/harness/types.d.ts +29 -7
  314. package/dist/engine/harness/types.js +12 -1
  315. package/dist/engine/llm/types.d.ts +9 -9
  316. package/dist/engine/llm/validation.d.ts +4 -1
  317. package/dist/engine/llm/validation.js +13 -1
  318. package/dist/engine/loop/agent-loop.d.ts +1 -1
  319. package/dist/engine/loop/agent-loop.js +10 -8
  320. package/dist/engine/loop/types.d.ts +15 -13
  321. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  322. package/dist/engine/session/memory-repo.d.ts +10 -11
  323. package/dist/engine/session/memory-repo.js +13 -8
  324. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  325. package/dist/engine/session/parent-chain-guard.js +1 -1
  326. package/dist/engine/session/repo-utils.d.ts +31 -3
  327. package/dist/engine/session/repo-utils.js +42 -5
  328. package/dist/index.d.ts +27 -15
  329. package/dist/index.js +21 -11
  330. package/dist/internal/harness-types.d.ts +1 -1
  331. package/dist/internal/harness.d.ts +3 -3
  332. package/dist/internal/harness.js +2 -2
  333. package/dist/internal/llm.d.ts +1 -1
  334. package/dist/internal/llm.js +1 -1
  335. package/dist/orchestration/goal.js +2 -2
  336. package/dist/orchestration/run-workflow-tool.d.ts +2 -2
  337. package/dist/orchestration/run-workflow-tool.js +5 -3
  338. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  339. package/dist/orchestration/workflow-types.d.ts +18 -0
  340. package/dist/orchestration/workflow-types.js +6 -0
  341. package/dist/orchestration/workflow.d.ts +2 -13
  342. package/dist/orchestration/workflow.js +21 -31
  343. package/dist/prompt-assembly/event-registry.js +1 -0
  344. package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
  345. package/dist/prompt-assembly/tool-catalog.js +3 -0
  346. package/dist/prompts/default.d.ts +14 -14
  347. package/dist/scenarios/full-body.d.ts +4 -4
  348. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  349. package/dist/stores/file/adoption/adopt.js +24 -31
  350. package/dist/stores/file/adoption/marker.d.ts +6 -13
  351. package/dist/stores/file/adoption/marker.js +6 -15
  352. package/dist/stores/file/checkpoint-store.d.ts +3 -0
  353. package/dist/stores/file/checkpoint-store.js +9 -3
  354. package/dist/stores/file/file-history-store.d.ts +20 -19
  355. package/dist/stores/file/file-history-store.js +152 -135
  356. package/dist/stores/file/fs-atomic.d.ts +15 -0
  357. package/dist/stores/file/fs-atomic.js +89 -14
  358. package/dist/stores/file/index.d.ts +1 -1
  359. package/dist/stores/file/mailbox-store.d.ts +3 -0
  360. package/dist/stores/file/mailbox-store.js +3 -1
  361. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  362. package/dist/stores/file/permission-rule-adopt.js +15 -16
  363. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  364. package/dist/stores/file/permission-rule-store.js +21 -14
  365. package/dist/stores/file/session-policy-store.d.ts +3 -3
  366. package/dist/stores/file/session-store.d.ts +26 -11
  367. package/dist/stores/file/session-store.js +77 -40
  368. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  369. package/dist/stores/file/workflow-journal-store.js +28 -13
  370. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  371. package/dist/tools/artifact/artifact-tool.js +2 -1
  372. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  373. package/dist/tools/fs/fs-bash.d.ts +2 -2
  374. package/dist/tools/fs/fs-bash.js +3 -1
  375. package/dist/tools/fs/fs-shared.d.ts +8 -8
  376. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  377. package/dist/tools/fs/notebook.d.ts +2 -2
  378. package/dist/tools/fs/read-deny.d.ts +29 -7
  379. package/dist/tools/fs/read-deny.js +63 -22
  380. package/dist/tools/fs/removal-targets.d.ts +1 -1
  381. package/dist/tools/fs/safety.d.ts +9 -9
  382. package/dist/tools/fs/search.d.ts +6 -6
  383. package/dist/tools/fs/shell-read-check.js +6 -1
  384. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  385. package/dist/tools/fs/shell-read-judge.js +5 -2
  386. package/dist/tools/loop-tick.d.ts +2 -2
  387. package/dist/tools/scheduler-tools.js +5 -1
  388. package/dist/tools/task-list.d.ts +7 -7
  389. package/dist/tools/task-list.js +5 -1
  390. package/dist/tools/todo.js +2 -1
  391. package/dist/tools/web.d.ts +1 -1
  392. package/dist/tools/web.js +40 -37
  393. package/dist/tools/worktree.d.ts +3 -3
  394. package/dist/tools/worktree.js +3 -1
  395. package/package.json +1 -1
  396. package/test/export-surface.snapshot.json +5756 -5638
  397. package/wire-changes/core@7.55.0.json +3318 -0
  398. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  399. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -101,8 +101,12 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
101
101
  private readonly retainBackgroundProcesses;
102
102
  private readonly onSecretEnvScrub?;
103
103
  private readonly onNotice?;
104
- /** design/128 T1-1: lazily-created env-owned spool dir (mkdtemp under os tmp — unpredictable, never the cwd). */
104
+ /** design/128 T1-1: the env-owned spool dir (mkdtemp under os tmp — unpredictable, never the cwd). It exists only while
105
+ * {@link spoolPairs} is non-empty: the last pair's release removes it, the next mint makes a fresh one. */
105
106
  private bgSpoolDir?;
107
+ /** The `outPath` of every spool pair this env minted and has not released — the one fact the dir's lifetime reads. A
108
+ * retain-lane bg pair is never released (its files outlive the run by design), so it keeps the dir. */
109
+ private readonly spoolPairs;
106
110
  readonly backgroundCapabilities: BackgroundShellCapability["backgroundCapabilities"];
107
111
  constructor(options: {
108
112
  cwd: string;
@@ -127,7 +131,8 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
127
131
  * env lane; `TaskSpec.retainBackgroundProcesses` is the task lane, without this spooling guarantee on
128
132
  * every platform — docs/background-process-lifetime.md). The 2h bg-timeout reaper and `killBackground` still work
129
133
  * while the host lives; after host exit, cleanup is the deployment's responsibility (e.g. the TB
130
- * container teardown). v1 covers processes spawned via `execBackground` only (a detach-adopted
134
+ * container teardown) — the retained shells' spool files, and the dir holding them, are never released
135
+ * by the env (every other spool pair is, and the dir goes with the last one). v1 covers processes spawned via `execBackground` only (a detach-adopted
131
136
  * foreground exec keeps pipe stdio — best-effort survival). Incompatible with durable-suspend
132
137
  * deployments (their pre-suspend dispose becomes a no-op too — do not combine).
133
138
  */
@@ -157,8 +162,8 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
157
162
  abortSignal?: AbortSignal;
158
163
  }): Promise<Result<string[], FileError>>;
159
164
  readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>>;
160
- /** RB-221: whole-file replace via same-directory staging + fsync + rename (CC 2.1.220 `Q5`,
161
- * (pretty220.js:60808, historical; not relocated in 250 — see cc-250 anchors)). The former single-step `writeFile` was an in-place O_TRUNC: an abort mid-write
165
+ /** RB-221: whole-file replace via same-directory staging + fsync + rename.
166
+ * The former single-step `writeFile` was an in-place O_TRUNC: an abort mid-write
162
167
  * (Esc during a large Write — ctx.signal reaches here directly), ENOSPC, or a crash left the target as
163
168
  * a torn prefix of the NEW content with the original unrecoverable. Post-fix contract: the target is
164
169
  * either fully old or fully new; `aborted` means it was never touched. Known semantic change (same as
@@ -251,10 +256,19 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
251
256
  * the file), while poll slicing keeps using the logical stream totalBytes; the two advance in
252
257
  * lockstep here but are NOT interchangeable after a rotation. */
253
258
  private syncSpool;
259
+ /** The one seat that opens a spool pair (foreground exec and background spawn alike), inside the env's spool dir: made on
260
+ * the first mint after the dir was last removed, so a command never runs against a dir an idle reap or a temp cleaner took. */
261
+ private mintSpoolPair;
262
+ /** The one seat that gives a spool pair back: unlinks both files (a descendant still writing keeps its fd into the unlinked
263
+ * inode — no EPIPE), forgets the pair, and removes the dir once no pair is left in it. Idempotent. */
264
+ private releaseSpoolPair;
265
+ /** Removes the spool dir (and whatever a failed unlink stranded in it) when no pair of this env lives in it. A retain-lane
266
+ * bg pair is never released, so it keeps its dir; the rest is gone with its last pair. Best-effort, never throws. */
267
+ private reapSpoolDirIfIdle;
254
268
  /** +: reclaim an EPHEMERAL spool (detach-adopted, or any non-retain bg
255
269
  * spawn — the whole unix bg lane is spool-backed now) — fold the final residue into the tails,
256
270
  * unlink both files, and drop the spool reference (later syncs become no-ops). Idempotent;
257
- * never touches design/128 retain-lane spools (no `ephemeral` flag). A still-writing detached
271
+ * never touches the spool of a design/128 retain-lane shell that has a process (no `ephemeral` flag). A still-writing detached
258
272
  * descendant keeps its fd into the unlinked inode (RB-26 posture — no EPIPE, auto-reclaim at
259
273
  * its exit). */
260
274
  private reclaimEphemeralSpool;
@@ -1,6 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { randomUUID } from "node:crypto";
3
- import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, statSync, truncateSync, unlinkSync } from "node:fs";
3
+ import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, rmSync, statSync, truncateSync, unlinkSync } from "node:fs";
4
4
  import { access, appendFile, lstat, mkdir, mkdtemp, open, readdir, readFile, readlink, rename, rm, stat, unlink, writeFile, } from "node:fs/promises";
5
5
  import { tmpdir } from "node:os";
6
6
  import { isAbsolute, join, resolve } from "node:path";
@@ -336,6 +336,7 @@ export class NodeExecutionEnv {
336
336
  onSecretEnvScrub;
337
337
  onNotice;
338
338
  bgSpoolDir;
339
+ spoolPairs = new Set();
339
340
  backgroundCapabilities;
340
341
  constructor(options) {
341
342
  this.cwd = options.cwd;
@@ -465,13 +466,7 @@ export class NodeExecutionEnv {
465
466
  if (spoolPumpRef.current)
466
467
  clearInterval(spoolPumpRef.current);
467
468
  if (execSpoolRef.current && !(result.ok && result.value.detached !== undefined)) {
468
- for (const path of [execSpoolRef.current.outPath, execSpoolRef.current.errPath]) {
469
- try {
470
- unlinkSync(path);
471
- }
472
- catch {
473
- }
474
- }
469
+ this.releaseSpoolPair(execSpoolRef.current);
475
470
  execSpoolRef.current = undefined;
476
471
  }
477
472
  resolvePromise(result);
@@ -479,9 +474,7 @@ export class NodeExecutionEnv {
479
474
  let execSpoolFds;
480
475
  if (process.platform !== "win32") {
481
476
  try {
482
- if (!this.bgSpoolDir)
483
- this.bgSpoolDir = mkdtempSync(join(tmpdir(), "sema-bg-"));
484
- const pair = openSpoolPair(join(this.bgSpoolDir, `fg_${randomUUID()}`));
477
+ const pair = this.mintSpoolPair(`fg_${randomUUID()}`);
485
478
  execSpoolRef.current = { outPath: pair.outPath, errPath: pair.errPath };
486
479
  execSpoolFds = pair.fds;
487
480
  }
@@ -1309,9 +1302,7 @@ export class NodeExecutionEnv {
1309
1302
  let spoolFds;
1310
1303
  if (this.retainBackgroundProcesses || process.platform !== "win32") {
1311
1304
  try {
1312
- if (!this.bgSpoolDir)
1313
- this.bgSpoolDir = mkdtempSync(join(tmpdir(), "sema-bg-"));
1314
- const pair = openSpoolPair(join(this.bgSpoolDir, `bg_${this.bgCounter + 1}_${randomUUID()}`));
1305
+ const pair = this.mintSpoolPair(`bg_${this.bgCounter + 1}_${randomUUID()}`);
1315
1306
  spool = {
1316
1307
  outPath: pair.outPath,
1317
1308
  errPath: pair.errPath,
@@ -1345,6 +1336,8 @@ export class NodeExecutionEnv {
1345
1336
  }
1346
1337
  }
1347
1338
  }
1339
+ if (spool)
1340
+ this.releaseSpoolPair(spool);
1348
1341
  const cause = toError(error);
1349
1342
  return err(new BackgroundShellError("spawn_failed", cause.message, cause));
1350
1343
  }
@@ -1533,23 +1526,51 @@ export class NodeExecutionEnv {
1533
1526
  }
1534
1527
  }
1535
1528
  }
1529
+ mintSpoolPair(name) {
1530
+ this.bgSpoolDir ??= mkdtempSync(join(tmpdir(), "sema-bg-"));
1531
+ try {
1532
+ const pair = openSpoolPair(join(this.bgSpoolDir, name));
1533
+ this.spoolPairs.add(pair.outPath);
1534
+ return pair;
1535
+ }
1536
+ catch (error) {
1537
+ this.reapSpoolDirIfIdle();
1538
+ throw error;
1539
+ }
1540
+ }
1541
+ releaseSpoolPair(pair) {
1542
+ for (const path of [pair.outPath, pair.errPath]) {
1543
+ try {
1544
+ unlinkSync(path);
1545
+ }
1546
+ catch {
1547
+ }
1548
+ }
1549
+ this.spoolPairs.delete(pair.outPath);
1550
+ this.reapSpoolDirIfIdle();
1551
+ }
1552
+ reapSpoolDirIfIdle() {
1553
+ const dir = this.bgSpoolDir;
1554
+ if (dir === undefined || this.spoolPairs.size > 0)
1555
+ return;
1556
+ this.bgSpoolDir = undefined;
1557
+ try {
1558
+ rmSync(dir, { recursive: true, force: true });
1559
+ }
1560
+ catch {
1561
+ }
1562
+ }
1536
1563
  reclaimEphemeralSpool(entry) {
1537
1564
  if (entry.spoolPump !== undefined) {
1538
1565
  clearInterval(entry.spoolPump);
1539
1566
  entry.spoolPump = undefined;
1540
1567
  }
1541
1568
  const spool = entry.spool;
1542
- if (!spool?.ephemeral)
1569
+ if (!spool || (!spool.ephemeral && entry.child.pid !== undefined))
1543
1570
  return;
1544
1571
  this.syncSpool(entry);
1545
1572
  entry.spool = undefined;
1546
- for (const path of [spool.outPath, spool.errPath]) {
1547
- try {
1548
- unlinkSync(path);
1549
- }
1550
- catch {
1551
- }
1552
- }
1573
+ this.releaseSpoolPair(spool);
1553
1574
  }
1554
1575
  async disposeBackgroundShells(opts) {
1555
1576
  if (this.retainBackgroundProcesses)
@@ -347,6 +347,12 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
347
347
  private createTurnState;
348
348
  private createContext;
349
349
  private createStreamFn;
350
+ /** May a drain take this frame now? The one predicate of the drain, the immediate re-check and {@link pendingInjectionCount}.
351
+ * A person's or caller's frame always may. An engine-authored frame is held — a drained steer makes a request — under
352
+ * the human-halt hold ({@link engineInjectionsHeld}), and an ADVISORY is held where the loop's own work owes no request
353
+ * (`continuing` false): it rides a request, never makes one; a notification's payload is an event and may continue a
354
+ * run. Held frames stay queued: later input drains past them, an owed drain takes them, else they end with the run. */
355
+ private isDrainable;
350
356
  private drainQueuedMessages;
351
357
  /** #389 — drop these frames from the in-flight account (they went back on a queue, or they landed). */
352
358
  private unbookInFlight;
@@ -371,7 +377,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
371
377
  private validateToolNames;
372
378
  private flushPendingSessionWrites;
373
379
  /**
374
- * #506 ㋐ — write the transcript's record of a TERMINAL provider failure (CC 2.1.250 parity, `Oo`/`CIt`).
380
+ * #506 ㋐ — write the transcript's record of a TERMINAL provider failure.
375
381
  *
376
382
  * A SEPARATE object, never the live frame: `failure` is the engine's terminal error shell and every
377
383
  * other consumer of it (the run result, failover, telemetry, usage accounting) reads its real
@@ -466,7 +472,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
466
472
  * no frame whose consumption could make the cut self-defeating, so the seat's own liveness is
467
473
  * the only guard. The cut settles exactly as every S1 cut does: finished tool calls keep
468
474
  * their REAL results, never-started ones settle as paired interrupted results, the
469
- * CC-verbatim interruption marker lands.
475
+ * the interruption marker lands.
470
476
  *
471
477
  * Returns `{ turnCut, accepted }` — `turnCut` `true` iff THIS call aborted a live turn seat (an
472
478
  * in-flight provider stream / tool batch will settle as interrupted; the completion-race arm is
@@ -489,7 +495,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
489
495
  * consults the latch at its own boundary, so the stop is provably in place when the forced
490
496
  * boundary arrives (the enqueue-then-abort discipline, one lane over).
491
497
  *
492
- * Queued injection frames are deliberately NOT touched (CC 2.1.223 `control_request:"interrupt"`
498
+ * Queued injection frames are deliberately NOT touched (the reference's `control_request:"interrupt"`
493
499
  * keeps the queue and answers `still_queued` — see {@link abort}'s recorded ruling): whatever
494
500
  * the queues hold settles by the run's ordinary terminal contract for accepted-but-undelivered
495
501
  * input (durable park when a suspend seat exists, else the loud undrained accounts).
@@ -516,10 +522,10 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
516
522
  private noteTurnCutConsumed;
517
523
  /**
518
524
  * design/373 §3.3 (the final-commit-point double check) — how many queued injection frames a
519
- * boundary drain could deliver RIGHT NOW: both lanes, minus frames the current state refuses to
520
- * drain (an unwinding run drains nothing — those frames belong to the terminal account; a live
521
- * human-halt hold skips engine-authored frames). Synchronous and side-effect-free by contract:
522
- * the loop reads it between its last drain and the terminal commit, with zero awaits.
525
+ * boundary drain could deliver RIGHT NOW where the loop's own work owes none ({@link isDrainable}, `continuing` false):
526
+ * what could continue the run (an unwinding run drains nothing — its frames belong to the terminal account).
527
+ * Synchronous and side-effect-free by contract: the loop reads it between its last drain and the terminal
528
+ * commit, with zero awaits.
523
529
  */
524
530
  pendingInjectionCount(): number;
525
531
  /** design/373 §3.4-3 — the pre-request re-check's drain half (see the loop-config seam): sweep
@@ -607,7 +613,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
607
613
  followUp: number;
608
614
  };
609
615
  /**
610
- * backlog #389 (CC 2.1.223 `control_request:"interrupt"`, `CC:1064478-1064513`) — an interrupt does
616
+ * backlog #389 (`control_request:"interrupt"`) — an interrupt does
611
617
  * NOT destroy accepted user input. CC's default keeps the queue and answers `still_queued`; only an
612
618
  * explicit `cancel_queued` cancels, with a per-uuid `cancelled` receipt. This harness had the opposite
613
619
  * polarity: both queues were emptied unconditionally and the contents handed back on a result object
@@ -43,6 +43,9 @@ function createTrailingMessage(seed) {
43
43
  }
44
44
  const engineNotePayloads = new WeakMap();
45
45
  const engineAuthoredInjections = new WeakSet();
46
+ function isEngineAdvisory(m) {
47
+ return engineAuthoredInjections.has(m) && !engineNotePayloads.has(m);
48
+ }
46
49
  const userInputParkRecords = new WeakMap();
47
50
  const drainedFromLane = new WeakMap();
48
51
  const immediateClassInjections = new WeakSet();
@@ -548,28 +551,34 @@ export class AgentHarness {
548
551
  });
549
552
  };
550
553
  }
551
- async drainQueuedMessages(queue, mode) {
552
- let messages;
554
+ isDrainable(m, continuing) {
555
+ if (!engineAuthoredInjections.has(m))
556
+ return true;
557
+ if (this.engineInjectionsHeld?.() === true)
558
+ return false;
559
+ return continuing || !isEngineAdvisory(m);
560
+ }
561
+ async drainQueuedMessages(queue, mode, continuing) {
553
562
  if (this.aborting)
554
563
  return [];
555
- if (this.engineInjectionsHeld?.() === true) {
556
- messages = [];
557
- const limit = mode === "all" ? Number.POSITIVE_INFINITY : 1;
558
- for (let i = 0; i < queue.length && messages.length < limit; i++) {
559
- if (engineAuthoredInjections.has(queue[i]))
564
+ const messages = [];
565
+ let first;
566
+ let selecting = true;
567
+ for (let i = 0; i < queue.length; i++) {
568
+ const m = queue[i];
569
+ if (!this.isDrainable(m, continuing))
570
+ continue;
571
+ if (!isEngineAdvisory(m)) {
572
+ if (!selecting)
560
573
  continue;
561
- messages.push(...queue.splice(i, 1));
562
- i--;
563
- }
564
- }
565
- else {
566
- let count = mode === "all" ? queue.length : 1;
567
- if (mode !== "all" && queue.length > 1 && engineNotePayloads.has(queue[0])) {
568
- count = 1;
569
- while (count < queue.length && engineNotePayloads.has(queue[count]))
570
- count++;
574
+ if (mode !== "all" && first !== undefined && !(engineNotePayloads.has(first) && engineNotePayloads.has(m))) {
575
+ selecting = false;
576
+ continue;
577
+ }
578
+ first ??= m;
571
579
  }
572
- messages = queue.splice(0, count);
580
+ messages.push(...queue.splice(i, 1));
581
+ i--;
573
582
  }
574
583
  if (messages.length === 0) {
575
584
  return messages;
@@ -682,9 +691,9 @@ export class AgentHarness {
682
691
  return result;
683
692
  },
684
693
  afterToolCall: ({ toolCall, args, result, isError }) => this.afterToolCallHook(toolCall, args, result, isError),
685
- prepareNextTurn: async () => {
694
+ prepareNextTurn: async ({ continues }) => {
686
695
  await this.flushPendingSessionWrites();
687
- await this.emitHook({ type: "turn_boundary", model: this.model });
696
+ await this.emitHook({ type: "turn_boundary", model: this.model, continues });
688
697
  const nextTurnState = await this.createTurnState();
689
698
  setTurnState(nextTurnState);
690
699
  return {
@@ -693,7 +702,7 @@ export class AgentHarness {
693
702
  thinkingLevel: nextTurnState.thinkingLevel,
694
703
  };
695
704
  },
696
- getSteeringMessages: async () => this.drainQueuedMessages(this.steerQueue, this.steeringQueueMode),
705
+ getSteeringMessages: async (continuing) => this.drainQueuedMessages(this.steerQueue, this.steeringQueueMode, continuing),
697
706
  publishTurnInterruptSeat: (seat) => {
698
707
  if (seat !== undefined) {
699
708
  this.lastPublishedSeat = seat;
@@ -705,7 +714,7 @@ export class AgentHarness {
705
714
  recheckImmediateInjections: async (pending) => this.absorbImmediateSteering(pending),
706
715
  pendingInjectionCount: () => this.pendingInjectionCount(),
707
716
  getFollowUpMessages: async () => {
708
- const queued = await this.drainQueuedMessages(this.followUpQueue, this.followUpQueueMode);
717
+ const queued = await this.drainQueuedMessages(this.followUpQueue, this.followUpQueueMode, false);
709
718
  if (queued.length > 0)
710
719
  return queued;
711
720
  return this.stopGate ? await this.stopGate() : queued;
@@ -1160,20 +1169,18 @@ export class AgentHarness {
1160
1169
  pendingInjectionCount() {
1161
1170
  if (this.aborting)
1162
1171
  return 0;
1163
- const held = this.engineInjectionsHeld?.() === true;
1164
- const drainable = (q) => held ? q.filter((m) => !engineAuthoredInjections.has(m)).length : q.length;
1172
+ const drainable = (q) => q.filter((m) => this.isDrainable(m, false)).length;
1165
1173
  return drainable(this.steerQueue) + drainable(this.followUpQueue);
1166
1174
  }
1167
1175
  async absorbImmediateSteering(pending) {
1168
1176
  if (this.aborting)
1169
1177
  return pending;
1170
- const held = this.engineInjectionsHeld?.() === true;
1171
1178
  const taken = [];
1172
1179
  for (let i = 0; i < this.steerQueue.length; i++) {
1173
1180
  const m = this.steerQueue[i];
1174
1181
  if (!immediateClassInjections.has(m))
1175
1182
  break;
1176
- if (held && engineAuthoredInjections.has(m))
1183
+ if (!this.isDrainable(m, true))
1177
1184
  continue;
1178
1185
  taken.push(...this.steerQueue.splice(i, 1));
1179
1186
  i--;
@@ -194,7 +194,7 @@ export declare class ExecutionError extends Error {
194
194
  * TB triple-fake-green report (2026-07-13) — output produced BEFORE the failure, for the
195
195
  * ran-then-cut codes (`timeout` / `liveness_no_output` / `aborted` / `callback_error`; the last is a command that
196
196
  * started and was then killed because a host-side output callback failed — its completion was
197
- * never observed, but its captured output is real work). CC anchor (2.1.206 BashTask settle): a
197
+ * never observed, but its captured output is real work). Reference behavior (BashTask settle): a
198
198
  * timed-out command keeps ALL captured stdout/stderr and only APPENDS a "Command timed out after
199
199
  * X" line — discarding 600s of build logs forces the model to rerun blind. Optional: envs that
200
200
  * cannot capture partial output simply omit these; never-started codes
@@ -325,7 +325,7 @@ export interface ExecutionEnvExecOptions {
325
325
  */
326
326
  detachSignal?: AbortSignal;
327
327
  /**
328
- * RB-198 F1 (form-one audit, CC 220 `Zry`/`WZi.#m` parity) — when this command's OWN timeout
328
+ * RB-198 F1 (form-one audit) — when this command's OWN timeout
329
329
  * fires, an env that supports detach ADOPTS the running child as a background process (the same
330
330
  * mechanism `detachSignal` uses) instead of killing it, settling the exec with
331
331
  * `detached: {shellId, cause:"timeout"}` — a non-idempotent long command survives its own timeout
@@ -665,6 +665,14 @@ export interface AnnouncedListingSnapshot {
665
665
  models?: string[];
666
666
  mcpFailed?: AnnouncedMcpFailure[];
667
667
  advisories?: string[];
668
+ advisor?: AnnouncedAdvisorState;
669
+ }
670
+ /** What the model was told about the advisor tool, and in which SEGMENT of the conversation — the id of the branch's
671
+ * latest compaction entry when the telling was delivered, `null` before any. A record from another segment reads as
672
+ * nothing told: a compaction summarized the telling away. */
673
+ export interface AnnouncedAdvisorState {
674
+ state: "announced" | "withdrawn";
675
+ segment: string | null;
668
676
  }
669
677
  /** The same snapshot as an APPEND input (borrowed arrays; the store copies through the shape gate). */
670
678
  export interface AnnouncedListingSnapshotInput {
@@ -673,6 +681,7 @@ export interface AnnouncedListingSnapshotInput {
673
681
  models?: readonly string[];
674
682
  mcpFailed?: ReadonlyArray<AnnouncedMcpFailure>;
675
683
  advisories?: readonly string[];
684
+ advisor?: Readonly<AnnouncedAdvisorState>;
676
685
  }
677
686
  /**
678
687
  * REF-D3/D4 merge target: the active EnterWorktree session (M22 live-CC anchor —
@@ -841,8 +850,8 @@ export declare function isValidModelChange(e: {
841
850
  modelId?: unknown;
842
851
  }): boolean;
843
852
  /**
844
- * #506 ㋐ — the reserved `model` value on a transcript entry NO MODEL PRODUCED. CC-verbatim
845
- * (`"<synthetic>"`, CC 2.1.250's own single-occurrence constant), and single-occurrence here for the
853
+ * #506 ㋐ — the reserved `model` value on a transcript entry NO MODEL PRODUCED. Spelled as in the reference
854
+ * (`"<synthetic>"`, its own single-occurrence constant), and single-occurrence here for the
846
855
  * same reason: the mint site and the recognition predicate must read the same literal or the entry
847
856
  * becomes unrecognizable the first time one of them is retyped.
848
857
  *
@@ -904,6 +913,14 @@ export interface SessionMetadata {
904
913
  incarnation?: string;
905
914
  /** Fork lineage's OCCUPANT half: the source row's `incarnation` at fork time (the occupant copied, not whoever holds `forkedFrom` later); absent = unknown. */
906
915
  forkedFromIncarnation?: string;
916
+ /** WHO owns this row, recorded by the write that creates it and changed by no later write; `null` = anonymous; absent reads as `null`. */
917
+ owner?: string | null;
918
+ }
919
+ /** One row's owner, occupant (`undefined` = unknown) and active leaf (`null` = none), read in ONE read so the three answer for one row generation. */
920
+ export interface SessionHead {
921
+ readonly owner: string | null;
922
+ readonly incarnation: string | undefined;
923
+ readonly leafId: string | null;
907
924
  }
908
925
  export interface JsonlSessionMetadata extends SessionMetadata {
909
926
  cwd: string;
@@ -1050,6 +1067,8 @@ export interface SessionCreateOptions {
1050
1067
  placement?: Omit<SessionPlacementRecord, "placedAt"> & {
1051
1068
  placedAt?: number;
1052
1069
  };
1070
+ /** The owner the creating write records (absent ⇒ `null`; on a fork, absent or `null` ⇒ the copied source row's); a create over an existing id records nothing. */
1071
+ owner?: string | null;
1053
1072
  }
1054
1073
  export interface SessionForkOptions {
1055
1074
  entryId?: string;
@@ -1070,10 +1089,11 @@ export interface SessionRepo<TMetadata extends SessionMetadata = SessionMetadata
1070
1089
  * Optional — a backend that supports cross-backend session export/migration implements it.
1071
1090
  */
1072
1091
  exportEntries?(sessionId: string): Promise<SessionTreeEntry[]>;
1092
+ /** The row's {@link SessionHead} in one read (`undefined` = no row); `TtlSessionStore` has a head read and an ownership pair only over a repo that has this. */
1093
+ headOf?(sessionId: string): Promise<SessionHead | undefined>;
1073
1094
  /**
1074
- * 2c session-sync: write a verbatim entry log (produced by {@link exportEntries} on another backend) into
1075
- * `sessionId`, re-stamping ownership to `owner` (from the caller's authenticated principal — never trusted
1076
- * from the bundle). The log MUST be passed through `validateEntriesForImport` first (the single fail-closed
1095
+ * 2c session-sync: write a verbatim entry log (produced by {@link exportEntries} on another backend) into `sessionId` (the log is
1096
+ * replaced, never the row: an existing row keeps its metadata whole; an absent id is a new row recording `owner`, `undefined` ⇒ `null` — the caller's principal, never the bundle's). The log MUST be passed through `validateEntriesForImport` first (the single fail-closed
1077
1097
  * invariant gate); a durable backend persists THAT function's output, it does not re-implement the checks.
1078
1098
  * Optional.
1079
1099
  *
@@ -1160,6 +1180,8 @@ export interface TurnBoundaryEvent {
1160
1180
  type: "turn_boundary";
1161
1181
  /** The model that will run the next turn (authoritative under a mid-task model switch). */
1162
1182
  model: Model;
1183
+ /** The loop's continuation fact, as defined at {@link import("../loop/types.js").PrepareNextTurnContext.continues}. */
1184
+ continues: boolean;
1163
1185
  }
1164
1186
  export interface BeforeProviderRequestEvent {
1165
1187
  type: "before_provider_request";
@@ -212,7 +212,17 @@ export function normalizeAnnouncedListing(v) {
212
212
  const models = arm(src.models);
213
213
  const mcpFailed = failureArm(src.mcpFailed);
214
214
  const advisories = arm(src.advisories);
215
- if (agents === null || skills === null || models === null || mcpFailed === null || advisories === null)
215
+ const advisorArm = (a) => {
216
+ if (a === undefined)
217
+ return undefined;
218
+ if (typeof a !== "object" || a === null)
219
+ return null;
220
+ const { state, segment } = a;
221
+ const segmentOk = segment === null || (typeof segment === "string" && segment.length <= ANNOUNCED_LISTING_MAX_NAME_CHARS);
222
+ return (state === "announced" || state === "withdrawn") && segmentOk ? { state, segment: segment } : null;
223
+ };
224
+ const advisor = advisorArm(src.advisor);
225
+ if (agents === null || skills === null || models === null || mcpFailed === null || advisories === null || advisor === null)
216
226
  return undefined;
217
227
  return {
218
228
  ...(agents !== undefined ? { agents } : {}),
@@ -220,5 +230,6 @@ export function normalizeAnnouncedListing(v) {
220
230
  ...(models !== undefined ? { models } : {}),
221
231
  ...(mcpFailed !== undefined ? { mcpFailed } : {}),
222
232
  ...(advisories !== undefined ? { advisories } : {}),
233
+ ...(advisor !== undefined ? { advisor } : {}),
223
234
  };
224
235
  }
@@ -611,10 +611,10 @@ export interface AssistantMessage {
611
611
  /**
612
612
  * design/124 tier A: this final message was PARTIALLY FINALIZED after a mid-stream connection
613
613
  * loss/stall — the substantive streamed prefix (text and/or completed tool calls) was promoted to
614
- * final content instead of failing the turn (CC 198 queryModelStreaming parity: avoid re-billing +
614
+ * final content instead of failing the turn (avoid re-billing +
615
615
  * keep the displayed content consistent with the result). `stopReason` is synthesized from the
616
616
  * content ("toolUse" when a completed tool call streamed, else "stop"); `errorMessage` carries the
617
- * warning in CC 2.1.220's words ("Response stalled mid-stream." / "Connection closed mid-response."; gone from 2.1.245 on), visible
617
+ * warning in the reference's former words ("Response stalled mid-stream." / "Connection closed mid-response."), visible
618
618
  * to the model in the transcript. Downstream semantics (agent-loop): `partialFinalized &&
619
619
  * stopReason==="stop"` gets a BOUNDED continue nudge (an unattended run must not book the cut as an
620
620
  * incomplete success); `partialFinalized && stopReason==="toolUse"` executes normally (a truncated
@@ -877,7 +877,7 @@ export interface OpenAIResponsesCompat {
877
877
  */
878
878
  export interface AnthropicMessagesCompat {
879
879
  /**
880
- * How this endpoint takes extended thinking (CC 2.1.198 parity, design/119).
880
+ * How this endpoint takes extended thinking (design/119).
881
881
  * - `"budget"` (default, pre-Fable models): `thinking: { type: "enabled", budget_tokens }`.
882
882
  * - `"adaptive"` (Fable 5 / Opus 4.8/4.7 class): `thinking: { type: "adaptive" }` — NO
883
883
  * `budget_tokens` (these models 400 on a budget), no max_tokens bump; the intensity is carried
@@ -886,7 +886,7 @@ export interface AnthropicMessagesCompat {
886
886
  */
887
887
  thinkingMode?: "budget" | "adaptive";
888
888
  /**
889
- * Effort tiers this endpoint accepts via `output_config.effort` (CC 2.1.198 `effort` /
889
+ * Effort tiers this endpoint accepts via `output_config.effort` (the reference's `effort` /
890
890
  * `xhigh_effort` / `max_effort` capability bits collapsed into one declared set, matching the
891
891
  * `reasoningEffortLevels` pattern on {@link OpenAICompletionsCompat}). Present ⇒ the brain sends
892
892
  * `output_config: { effort }` plus the `effort-2025-11-24` beta header, clamping the requested
@@ -896,14 +896,14 @@ export interface AnthropicMessagesCompat {
896
896
  */
897
897
  effortLevels?: ThinkingLevel[];
898
898
  /**
899
- * Whether the endpoint accepts `temperature` at all. CC 2.1.198 sends temperature only to a
899
+ * Whether the endpoint accepts `temperature` at all. The reference sends temperature only to a
900
900
  * legacy allowlist — Fable-5-class models NEVER receive it (400 risk), independent of thinking
901
901
  * state. Default true (existing models unchanged); `false` drops a caller temperature
902
902
  * unconditionally, not just under extended thinking.
903
903
  */
904
904
  supportsTemperature?: boolean;
905
905
  /**
906
- * design/119 S4 (CC 2.1.198 `context_management` capability): when thinking is enabled, send
906
+ * design/119 S4 (`context_management` capability): when thinking is enabled, send
907
907
  * `context_management: { edits: [{ type: "clear_thinking_20251015", keep: "all" }] }` plus the
908
908
  * `context-management-2025-06-27` beta — an explicit opt-OUT of the server's default
909
909
  * thinking-clearing, preserving cross-turn reasoning continuity (what CC sends on first-party
@@ -912,7 +912,7 @@ export interface AnthropicMessagesCompat {
912
912
  */
913
913
  contextManagement?: boolean;
914
914
  /**
915
- * design/119 S4 (CC 2.1.198): attach the `interleaved-thinking-2025-05-14` beta on tool-enabled
915
+ * design/119 S4: attach the `interleaved-thinking-2025-05-14` beta on tool-enabled
916
916
  * requests with thinking on (thinking blocks may interleave with tool_use). Declare per endpoint;
917
917
  * absent = no beta (pre-119 behavior; a deployment could already do this via static `headers`).
918
918
  */
@@ -957,7 +957,7 @@ export interface Model<TApi extends Api = Api> {
957
957
  /**
958
958
  * Optional AUTOCOMPACT window — the window the compaction trigger and the clearStale frontier
959
959
  * are derived from when it differs from the physical request window (dual-window semantics).
960
- * CC 2.1.207 posture: its 1M sonnet keeps the PHYSICAL window at 1M while a per-model dynamic
960
+ * The reference's posture: its 1M sonnet keeps the PHYSICAL window at 1M while a per-model dynamic
961
961
  * config lowers only the autocompact window to 967000, so the reactive trigger lands at 934000
962
962
  * (= 967000 − 33000); a single window value cannot express both. Consumed by the trigger-side
963
963
  * geometry only (`editBudget`/`sanitizeCompactionSettings`/`shouldCompact` window); the request
@@ -996,7 +996,7 @@ export interface Model<TApi extends Api = Api> {
996
996
  /** Extra request HEADERS merged into the provider call. Cannot override auth / content-type / version. */
997
997
  headers?: Record<string, string>;
998
998
  /**
999
- * design/119 S3 (CC 2.1.198 parity): model-declared system-prompt guidance sections, appended to
999
+ * design/119 S3: model-declared system-prompt guidance sections, appended to
1000
1000
  * the assembled system prompt. This is the declarative home for per-model behavioral patches (CC
1001
1001
  * ships Fable-5 "mitigations" baked behind model-name checks; sema keeps the MECHANISM generic —
1002
1002
  * any Model can carry guidance — and the CONTENT as preset data, zero model-name matching in core).
@@ -1,7 +1,10 @@
1
1
  import type { Tool, ToolCall } from "./types.js";
2
2
  /** Finds the target tool and validates/coerces a model-emitted tool call. */
3
3
  export declare function validateToolCall(tools: Tool[], toolCall: ToolCall): unknown;
4
- /** VENDORED EDIT (design/115 P0): resolve canonical tool names first, then legacy aliases. */
4
+ /** The dispatcher's name resolution over one tool list, indexed once (for a caller resolving many names over the same list):
5
+ * canonical names first, then aliases (design/115 P0 order) — the first tool carrying a name, or an alias, owns it. */
6
+ export declare function toolNameIndex<T extends Tool>(tools: readonly T[] | undefined): (name: string) => T | undefined;
7
+ /** VENDORED EDIT (design/115 P0): resolve canonical tool names first, then legacy aliases ({@link toolNameIndex} for one name). */
5
8
  export declare function findToolByName<T extends Tool>(tools: readonly T[] | undefined, name: string): T | undefined;
6
9
  /** Validates tool arguments against TypeBox or plain JSON-schema parameters. */
7
10
  export declare function validateToolArguments(tool: Tool, toolCall: ToolCall): unknown;
@@ -378,8 +378,20 @@ export function validateToolCall(tools, toolCall) {
378
378
  }
379
379
  return validateToolArguments(tool, toolCall);
380
380
  }
381
+ export function toolNameIndex(tools) {
382
+ const byName = new Map();
383
+ const byAlias = new Map();
384
+ for (const t of tools ?? []) {
385
+ if (!byName.has(t.name))
386
+ byName.set(t.name, t);
387
+ for (const a of t.aliases ?? [])
388
+ if (!byAlias.has(a))
389
+ byAlias.set(a, t);
390
+ }
391
+ return (name) => byName.get(name) ?? byAlias.get(name);
392
+ }
381
393
  export function findToolByName(tools, name) {
382
- return tools?.find((t) => t.name === name) ?? tools?.find((t) => t.aliases?.includes(name));
394
+ return toolNameIndex(tools)(name);
383
395
  }
384
396
  export function validateToolArguments(tool, toolCall) {
385
397
  const args = structuredClone(toolCall.arguments);
@@ -61,7 +61,7 @@ export type LoopTerminalReason =
61
61
  * loop ended cleanly at a manufactured boundary, no reconcile owed), and which consult caught
62
62
  * it is timing, not semantics. */
63
63
  | "stop_requested"
64
- /** RB-206 (CC 220 counterpart @400176-400230, `Bxs` @397652-397674 buckets it
64
+ /** RB-206 (the reference buckets it
65
65
  * with budget_exhausted/api_error/model_error/turn_setup_failed, explicitly NOT `"completed"`): every
66
66
  * tool call in the turn was dropped as malformed AND the bounded `malformed_tool_use_retry` nudge
67
67
  * budget is used up — the model believes it acted, nothing ran, and there is no more recovery budget