@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
@@ -3,7 +3,7 @@ export const TOOL_SPEC_MEMBERS = Object.keys({
3
3
  name: true, aliases: true, description: true, descriptionClassic: true, label: true, parameters: true, execute: true, effect: true,
4
4
  egress: true, irreversibility: true, reversibilityProbe: true, permissionSeat: true, isConcurrencySafe: true, executionMode: true,
5
5
  contentOrigin: true, offload: true, offloadThresholdChars: true, defer: true, alwaysLoad: true, prepareArguments: true,
6
- validateInput: true, approvalPreview: true, family: true, pathTarget: true, ruleFace: true, renderHints: true, compactable: true,
6
+ validateInput: true, approvalPreview: true, family: true, pathTarget: true, hostTarget: true, ruleFace: true, renderHints: true, compactable: true,
7
7
  budgetExempt: true, modelGate: true, contract: true, agentListing: true, agentModels: true, agentToolFaces: true,
8
8
  agentToolLevelAllowTools: true, agentToolLevelDenyTools: true, agentToolPool: true, agentToolInheritsMcp: true, withAgents: true, boundaryLegs: true, boundaryLegsFor: true,
9
9
  });
@@ -15,7 +15,7 @@ import type { TaskEvent } from "./task-event.js";
15
15
  import type { TaskSpec } from "./task-spec.js";
16
16
  import type { BackgroundChildEvent } from "./delegation-frames.js";
17
17
  import type { ModelRef } from "./model-seat.js";
18
- import type { ToolFamily, ToolPathTarget, ToolRenderHints, ToolRuleFace } from "./tool-face.js";
18
+ import type { ToolFamily, ToolHostTarget, ToolPathTarget, ToolRenderHints, ToolRuleFace } from "./tool-face.js";
19
19
  /**
20
20
  * Side-effect class of a tool. Used by wake/resume reconciliation: when a call was interrupted
21
21
  * before its result was recorded, the outcome is unknown, so core must decide whether re-doing it
@@ -62,12 +62,17 @@ export interface ReversibilityVerdict {
62
62
  * TIGHTENING (one more question survives one more configuration), so an over-claiming probe costs
63
63
  * its own deployment a re-confirmation and can never turn an ask into an allow.
64
64
  *
65
- * The built-in shell probe sets it for exactly one family: a listed reader naming a path outside the
66
- * session's allowed directories. That demotion HAS a clearing channel — widening the declared read
67
- * directories retires it — and where the probe can name the directory, {@link readRootCandidate} carries
68
- * it. A mandated ask WITHOUT that member has no configuration behind it: the rest of the family (an
69
- * operator `shellGate:"always"`, the tool's egress/irreversibility marks, an org demand, an out-of-root
70
- * arm with no named directory) is confirm-or-refuse, and must not be worded as though a grant answers it.
65
+ * The engine's own shell station raises a mandate for a path outside the session's allowed directories
66
+ * (read or written) and for a command whose reads it could not establish. A demotion by a path outside the
67
+ * directories HAS a clearing channel — widening the declared read directories retires it — and where the
68
+ * probe can name the directory, {@link readRootCandidate} carries it. A mandated ask WITHOUT that member has
69
+ * no configuration behind it: the rest of the family (an operator `shellGate:"always"`, the tool's
70
+ * egress/irreversibility marks, an org demand, an out-of-root arm with no named directory) is
71
+ * confirm-or-refuse, and must not be worded as though a grant answers it.
72
+ *
73
+ * WHY a matching allow rule did not clear the ask is said in the account of the finding and nowhere else:
74
+ * the card's disclosure sentence is {@link ReversibilityVerdict.reason} verbatim (the station's own sentence, for its findings).
75
+ * A mandated verdict with no `reason` is stated without one — the card names the outranked rule and stops.
71
76
  */
72
77
  mandated?: boolean;
73
78
  /**
@@ -145,7 +150,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
145
150
  aliases?: string[];
146
151
  description: string;
147
152
  /**
148
- * R2 双形轴(2026-07-18 裁):the CLASSIC-profile variant of {@link description}. CC 2.1.212
153
+ * R2 双形轴(2026-07-18 裁):the CLASSIC-profile variant of {@link description}. The reference
149
154
  * keys its tool descriptions on `LT(model_id)` (simple short form vs classic long form); sema's
150
155
  * counterpart is {@link TaskSpec.promptProfile} — default "simple" (what CC serves every BYOM
151
156
  * model id). When the run resolves to "classic" and this field is present, it REPLACES
@@ -153,11 +158,9 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
153
158
  */
154
159
  descriptionClassic?: string;
155
160
  /**
156
- * Human label for UIs. Defaults to `name`.
157
- *
158
- * ⚠️ Currently INERT (design/71 liveness sweep, 2026-06-12): mapped onto the tool object but no
159
- * runtime path or emitted event reads it — the model and TaskStream consumers only ever see
160
- * `name`. Kept for API stability; wire it into tool events or drop it before building on it.
161
+ * Human label for UIs. Defaults to `name`. When it differs from `name`, it rides the call's `tool_start` and `tool_end`
162
+ * frames as `label` (the run builds the table from the leg's mounted tools) — the advisor tool's label is its advisor
163
+ * model's id. The model only ever sees `name`.
161
164
  */
162
165
  label?: string;
163
166
  /**
@@ -240,7 +243,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
240
243
  * gate station: PreToolUse hooks, policy, the auto-mode classifier), AFTER schema validation. A
241
244
  * refusal (`{ ok: false, message }`) is returned to the model as a typed error result and NO
242
245
  * approval card is shown for the call; `{ ok: true }` / `undefined` lets the call proceed to the
243
- * gate unchanged. Upstream form (CC 2.1.250 `validateInput` → `{result:false, message, errorCode}`,
246
+ * gate unchanged. Upstream form (`validateInput` → `{result:false, message, errorCode}`,
244
247
  * consulted ahead of the permission prompt): a call the tool would refuse on its own precondition —
245
248
  * an Edit/Write/NotebookEdit whose target file was never Read this session — used to reach the
246
249
  * operator as a card that could only ever fail; the model then retried the same failing call under
@@ -425,7 +428,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
425
428
  contentOrigin?: ToolContentOrigin;
426
429
  /**
427
430
  * Batch execution mode (design/64 §1 P1, CC reads-parallel/writes-sequential partition). When omitted,
428
- * `defineTool` derives it FAIL-CLOSED from `effect` (CC 2.1.206 `TOOL_DEFAULTS.isConcurrencySafe → false`):
431
+ * `defineTool` derives it FAIL-CLOSED from `effect` (`TOOL_DEFAULTS.isConcurrencySafe → false`):
429
432
  * `read` → `"parallel"`; `write`/`idempotent`/UNDECLARED → `"sequential"` — an unannotated tool never
430
433
  * silently rides a parallel batch, and two writes in one batch never race. Set explicitly to override.
431
434
  */
@@ -435,7 +438,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
435
438
  * refinement for a non-`"parallel"` tool — return `true` to let THIS CALL run in a parallel batch
436
439
  * (and, under `streamingToolExecution`, start in-stream). An explicit `executionMode:"parallel"`
437
440
  * needs no refinement (always safe); a throw = false (fail-closed). In the batch/stream paths the
438
- * hook receives schema-VALIDATED (coerced) args — CC 206 `parsed.data` parity; a schema-invalid
441
+ * hook receives schema-VALIDATED (coerced) args — `parsed.data` parity; a schema-invalid
439
442
  * call is judged unsafe before the hook runs. Still treat defensively (direct callers may pass raw).
440
443
  * The one real consumer is Bash's read-only classifier.
441
444
  */
@@ -475,7 +478,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
475
478
  */
476
479
  defer?: boolean;
477
480
  /**
478
- * Inline-keep override, judged FIRST in the deferral chain (CC 220 counterpart:
481
+ * Inline-keep override, judged FIRST in the deferral chain (the reference's counterpart:
479
482
  * `alwaysLoad`, declared per MCP tool via `_meta["anthropic/alwaysLoad"]`, whose `isDeferredTool`
480
483
  * checks it before every deferral arm): `true` pins this tool's full schema inline in every
481
484
  * request — it is never deferred, regardless of its own {@link defer}, {@link TaskSpec.deferTools},
@@ -508,7 +511,9 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
508
511
  * CONTRACT this tool implements, independent of its presentation text. `defineTool` attaches it
509
512
  * to the materialized tool via the catalog side-table (identity follows the OBJECT, never the
510
513
  * wire name — a caller tool shadowing a built-in name never inherits the core contract). Omitted
511
- * ⇒ the tool reports a deterministic `legacy:<shapeDigest>` contract in the assembly manifest.
514
+ * ⇒ the tool reports a deterministic `legacy:<shapeDigest>` contract in the assembly manifest. A `core.`
515
+ * id is the engine's: on a `TaskSpec.tools` spec it is refused (`config.tool_face_invalid`) unless it rides
516
+ * the contract object the engine's catalog minted (an engine definition mounted by hand) — never written by hand.
512
517
  */
513
518
  contract?: {
514
519
  /** Stable versioned id, e.g. `core.read@2` (built-ins) or `acme.deploy@1` (caller tools). */
@@ -548,6 +553,15 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
548
553
  * tool that merely takes a built-in's NAME inherits nothing).
549
554
  */
550
555
  pathTarget?: ToolPathTarget;
556
+ /**
557
+ * The parameter that names the URL this tool's call reaches ({@link ToolHostTarget}), for a tool whose own name host rules are
558
+ * written for (the engine's fetch tool name, `WebFetch`). Host rules on that name are then judged on the host this URL names:
559
+ * a deny or an ask reaches the tool whatever it declares (the catalog's slot is the protective floor), an allow only when it
560
+ * declares its own slot here (a tool that merely takes the name inherits nothing). Refused (`config.tool_face_invalid`) on a
561
+ * tool under any other name, an alias included — a host rule's grammar belongs to the rule's tool name, so the slot would never
562
+ * be read — and together with {@link pathTarget} (a face names one protected target). The `param` must be a top-level property.
563
+ */
564
+ hostTarget?: ToolHostTarget;
551
565
  /**
552
566
  * design/388 §2.2 ③ — the parameter vocabulary a permission rule (`Tool(param:pattern)`) may name.
553
567
  * DERIVED from the schema when absent (the scalar top-level parameters plus the path target's
@@ -590,7 +604,7 @@ export type ToolReturn = string | {
590
604
  * Producer side of the tool-result 双面契约: `content` is the MODEL face (may carry model-directed
591
605
  * framing/trailers), `details` is the HOST face (per-tool structured Output). Hosts render from the
592
606
  * structured face and never re-parse the model face — see the `tool_end.structured` JSDoc
593
- * (CC 2.1.207 @765495, CC207-CORE-SWEEP P2-3) for the full contract. */
607
+ * (P2-3) for the full contract. */
594
608
  details?: unknown;
595
609
  /** Hint the agent to stop after this tool batch. */
596
610
  terminate?: boolean;
@@ -1200,7 +1214,7 @@ export interface ToolExecuteContext {
1200
1214
  sessionId: string;
1201
1215
  } | undefined;
1202
1216
  /**
1203
- * RB-201 FO-3 (form-one audit, CC 220 `Ipd`/`ein` parity) — the auto-mode classifier decider ARMED
1217
+ * RB-201 FO-3 (form-one audit) — the auto-mode classifier decider ARMED
1204
1218
  * for THIS task (auto-mode intent ∧ `RunnerDeps.autoMode` present ∧ `RuntimeCaps.autoMode !== false`
1205
1219
  * — see {@link TaskSpec.permissionMode}; the same
1206
1220
  * instance `runToolGate`'s per-call ask review already consults, carrying its own live breaker
@@ -1342,7 +1356,7 @@ export interface ToolExecuteContext {
1342
1356
  */
1343
1357
  insideFork?: boolean;
1344
1358
  /**
1345
- * OBS-2 (CC 2.1.206 observer parity) — present iff this run's principal resolved
1359
+ * OBS-2 — present iff this run's principal resolved
1346
1360
  * {@link RuntimeCaps.allowObservers}` === true` (EXPLICIT opt-in, default OFF — see the polarity
1347
1361
  * note there). The delegation tool honors {@link AgentDefinition.observer} declarations only under
1348
1362
  * this flag; absent ⇒ declarations resolve to unobserved with NO warn (the gate, not a mistake).
@@ -3,7 +3,7 @@ import { formatToolError, formatZodValidationError } from "./tool-errors.js";
3
3
  import { readMember } from "./thrown-value.js";
4
4
  import { frozenToolSpec } from "./tool-spec-members.js";
5
5
  import { carryDelegationName } from "./delegation-name.js";
6
- import { attachToolContract } from "../prompt-assembly/tool-catalog.js";
6
+ import { attachToolContract, contractOriginOf } from "../prompt-assembly/tool-catalog.js";
7
7
  function normalizeContent(ret) {
8
8
  if (typeof ret === "string") {
9
9
  return { content: [{ type: "text", text: ret }], details: undefined, terminate: false, isError: false };
@@ -98,6 +98,7 @@ function buildProduct(spec, owner, options) {
98
98
  ...(spec.boundaryLegs !== undefined ? { boundaryLegs: spec.boundaryLegs } : {}),
99
99
  ...(spec.boundaryLegsFor !== undefined ? { boundaryLegsFor: spec.boundaryLegsFor } : {}),
100
100
  ...(spec.pathTarget !== undefined ? { pathTarget: spec.pathTarget } : {}),
101
+ ...(spec.hostTarget !== undefined ? { hostTarget: spec.hostTarget } : {}),
101
102
  ...(spec.ruleFace !== undefined ? { ruleFace: spec.ruleFace } : {}),
102
103
  ...(spec.renderHints !== undefined ? { renderHints: spec.renderHints } : {}),
103
104
  ...(spec.compactable === true ? { compactable: true } : {}),
@@ -143,7 +144,7 @@ function buildProduct(spec, owner, options) {
143
144
  attachToolContract(tool, {
144
145
  contractId: spec.contract.contractId,
145
146
  implementationRevision: spec.contract.implementationRevision,
146
- origin: spec.contract.contractId.startsWith("core.") ? "core" : "caller",
147
+ origin: contractOriginOf(spec.contract.contractId),
147
148
  ...(spec.aliases && spec.aliases.length > 0 ? { aliases: spec.aliases } : {}),
148
149
  });
149
150
  }
@@ -339,6 +339,10 @@ export type TraceEvent = {
339
339
  * by them.
340
340
  */
341
341
  turn?: number;
342
+ /** Which call beside the loop this row is: a `SideCallLane` word (the closed set lives with the account,
343
+ * `runner/side-call-account.ts`). Present exactly when {@link turn} is absent — the one writer of side-call rows
344
+ * stamps it; a main-loop row carries `turn` and no `lane`. */
345
+ lane?: string;
342
346
  /** Normalized prompt tokens that MISSED the cache (Anthropic-protocol `input_tokens`
343
347
  * shape) — disjoint from `cacheRead`/`cacheWrite`. Carried the cache-inclusive total up to 2.13.x. */
344
348
  promptTokens: number;
@@ -9,7 +9,7 @@ export { summarizeRedactions } from "./redaction-passes.js";
9
9
  * that tier. What a tool RETURNS is its content, read by the model that asked for it, and is not redacted (CC redacts
10
10
  * nothing there either); what is redacted is what the engine itself words or carries: errors, summaries, run rows.
11
11
  *
12
- * Two tiers, because the faces have two audiences (CC 2.1.212 alignment):
12
+ * Two tiers, because the faces have two audiences:
13
13
  * - **`same-principal`** — the model, the script and the host that launched the work (tool results, workflow agent
14
14
  * outputs / results / errors, run rows behind the scope-gated observe API, host error lanes): the credential
15
15
  * vocabulary only. Paths and URLs in a worker's answer are the caller's OWN machine's paths — redacting them killed the
@@ -138,7 +138,7 @@ export interface EnvelopeShapedScan {
138
138
  export declare function scanEnvelopeShaped(text: string): EnvelopeShapedScan;
139
139
  /**
140
140
  * Defuse a caller-declared occurrence of ONE specific envelope tag (opening AND closing) inside
141
- * content, CC `zZe` @8339092 verbatim: ``t.replace(new RegExp(`<(?=/?${e}(?:[>\\s/]|$))`, "gi"), "<\\")``.
141
+ * content, the reference's replacement: ``t.replace(new RegExp(`<(?=/?${e}(?:[>\\s/]|$))`, "gi"), "<\\")``.
142
142
  *
143
143
  * Homed here (beside {@link ENGINE_ENVELOPES}) rather than in the observer module that first needed
144
144
  * it: "escape one named envelope tag" is a containment primitive, and the registry's guard column
@@ -5,7 +5,7 @@ import type { TaskResult, TaskSpec } from "./types.js";
5
5
  * session, then run a continuation on the fork. Fork-first is the safe path (design/114 §3.2):
6
6
  * - **idempotent** — each call branches a FRESH session, so resuming twice can't corrupt the source's linear
7
7
  * history (vs `runTask({sessionId})` reuse, which appends two divergent continuations onto one history);
8
- * - **orphan-safe** — the fork drops an in-flight tool call (`settledForkOptions`), so a continuation of an agent
8
+ * - **orphan-safe** — the fork drops an in-flight tool call (`settledForkOptions`, the judge a store's `fork` shares; a package-root export), so a continuation of an agent
9
9
  * that died mid-tool-call gets a clean point rather than inheriting an `[INTERRUPTED]` orphan;
10
10
  * - **fail-loud** — a missing source returns `null`; it NEVER silently starts a fresh EMPTY run the way
11
11
  * `runTask({sessionId})` would via create-on-miss (the "looks warm, actually fresh" trap). Cross-restart /
@@ -472,6 +472,39 @@ export interface WiringManifest {
472
472
  * derivation, never a state. Out of {@link configFingerprint}: the request word is a per-task seat (`mods` reasoning).
473
473
  */
474
474
  fileHistory?: "on" | "disabled";
475
+ /**
476
+ * EFFECTIVE half only, ALWAYS present on an engine-minted effective manifest: did this leg read the deployment's project context, and if not,
477
+ * which half kept it out — one word per state. `"on"` — its prepare called `RunnerDeps.loadProjectMemory` (what the seam answered, content or
478
+ * nothing, is the deployment's). `"disabled"` — a seam is wired and the request turned it off (`TaskSpec.projectMemory: "disabled"`).
479
+ * `"absent"` — no seam is wired (the manifest's word for a seat nothing supplied, as `ask` / `question` spell it), whatever the request said.
480
+ * The member missing = an older mint or an external derivation, never a state. Out of {@link configFingerprint}: the request word is a
481
+ * per-task seat (`fileHistory` reasoning).
482
+ */
483
+ projectMemory?: "on" | "disabled" | "absent";
484
+ /**
485
+ * EFFECTIVE half only, ALWAYS present on an engine-minted effective manifest: are the legs THIS leg delegates (sync,
486
+ * background, forked, workflow, retained, resumed and observer-sidecar legs, at any depth) bound by a rule written to this
487
+ * leg's session AFTER they started. `childrenReadLive: true` ⇔ the leg enforces its own session-rule layer (a
488
+ * `sessionPolicyStore` is wired and the task carries a `sessionId`) and so hands that session's key on to the legs it
489
+ * delegates, each of which re-reads the row at every tool gate: a rule written mid-run binds the agent's next call, whether
490
+ * or not the session had a row when the agent was spawned. `false` ⇒ no layer, so no key is handed on (no store wired, or
491
+ * the task names no session). ABSENT = an older engine: assume nothing. A statement about the DEPS-VISIBLE assembly — a
492
+ * delegation tool mounted over a Runner with no store of its own cannot re-read (it announces
493
+ * `config.session_rules_unreadable` and keeps the spawn-time snapshot). Leg-local (excluded from {@link configFingerprint}:
494
+ * `sessionId` is a per-task seat); the leg-start snapshot, like the rest of this object.
495
+ */
496
+ sessionRules?: {
497
+ childrenReadLive: boolean;
498
+ };
499
+ /**
500
+ * EFFECTIVE half only — the advisor tool on this leg, as the leg STARTED (a snapshot: a switch-off that lands later in the
501
+ * leg is not in it; a host reads the conversation's current state off the transcript, `advisorHoldOf`). Present ⇔ the leg's
502
+ * spec names an advisor model. `requested` = the ref as given (a Model's `id`; absent when the deployment switch ignored it
503
+ * unread); `main` = the leg's resolved model; `state` `on` (with `model`, the resolved advisor), `held` (the conversation
504
+ * switched it off; `hold` = the cause) or `not_attached` (`reason`; `routeCode` on `route_refused`). Out of
505
+ * {@link configFingerprint}: a per-task seat.
506
+ */
507
+ advisor?: WiringAdvisorFact;
475
508
  /** EFFECTIVE half only — a short, non-sensitive fingerprint (sha256 prefix over the canonical
476
509
  * JSON of this manifest's own resolved facts; every field here is an enum/boolean/count, no
477
510
  * secrets) so an operator can correlate legs that ran under the same resolved assembly. */
@@ -573,6 +606,22 @@ export interface WiringFacts {
573
606
  autoConsolidationOnRecommendation?: boolean;
574
607
  /** Effective half only — the file-history phase's word ({@link WiringManifest.fileHistory}); the engine always passes it. */
575
608
  fileHistory?: "on" | "disabled";
609
+ /** Effective half only — the project-context phase's word ({@link WiringManifest.projectMemory}); the engine always passes it. */
610
+ projectMemory?: WiringManifest["projectMemory"];
611
+ /** Effective half only — {@link WiringManifest.sessionRules}`.childrenReadLive`: this leg's session-rule layer published its key for its children's chain. Read off that wiring, never a constant. */
612
+ sessionRulesChildrenReadLive?: boolean;
613
+ /** Effective half only — the advisor phase's answer ({@link WiringManifest.advisor}), relayed, never re-derived. */
614
+ advisor?: WiringAdvisorFact;
615
+ }
616
+ /** {@link WiringManifest.advisor}. */
617
+ export interface WiringAdvisorFact {
618
+ requested?: string;
619
+ main: string;
620
+ state: "on" | "not_attached" | "held";
621
+ model?: string;
622
+ reason?: import("./advisor-verdict.js").AdvisorNotAttachedReason;
623
+ routeCode?: import("../internal/llm.js").RouteRefusalCode;
624
+ hold?: import("./advisor-verdict.js").AdvisorHold;
576
625
  }
577
626
  /** Named view of the deps seats the static half reads (a `Pick` of the real {@link RunnerDeps} —
578
627
  * single-source shapes, no parallel hand-copied interface). */
@@ -150,11 +150,16 @@ function readHandsFact(fact) {
150
150
  }
151
151
  return mounted ? { mounted } : { mounted, reason };
152
152
  }
153
- function readFileHistoryFact(word) {
154
- if (word !== "on" && word !== "disabled")
155
- throw new Error(`the file-history wiring fact ${JSON.stringify(word)} is not one of on|disabled`);
153
+ function readWordFact(word, words, label) {
154
+ if (!words.includes(word))
155
+ throw new Error(`the ${label} wiring fact ${JSON.stringify(word)} is not one of ${words.join("|")}`);
156
156
  return word;
157
157
  }
158
+ function readSessionRulesFact(fact) {
159
+ if (typeof fact !== "boolean")
160
+ throw new Error(`the session-rules wiring fact ${JSON.stringify(fact)} is not a boolean`);
161
+ return { childrenReadLive: fact };
162
+ }
158
163
  export function deriveWiringManifest(facts) {
159
164
  if (facts.half === "static" && facts.leg !== undefined) {
160
165
  throw new Error("a static wiring manifest has no leg — leg identity is an effective-half fact");
@@ -219,14 +224,17 @@ export function deriveWiringManifest(facts) {
219
224
  ? { readDeny: { builtinTiers: [...facts.readDenyBuiltinTiersActive] } }
220
225
  : {}),
221
226
  ...(facts.half === "effective" && facts.autoConsolidationOnRecommendation === true ? { autoConsolidation: { onRecommendation: true } } : {}),
222
- ...(facts.half === "effective" && facts.fileHistory !== undefined ? { fileHistory: readFileHistoryFact(facts.fileHistory) } : {}),
227
+ ...(facts.half === "effective" && facts.fileHistory !== undefined ? { fileHistory: readWordFact(facts.fileHistory, ["on", "disabled"], "file-history") } : {}),
228
+ ...(facts.half === "effective" && facts.projectMemory !== undefined ? { projectMemory: readWordFact(facts.projectMemory, ["on", "disabled", "absent"], "project-memory") } : {}),
229
+ ...(facts.half === "effective" && facts.sessionRulesChildrenReadLive !== undefined ? { sessionRules: readSessionRulesFact(facts.sessionRulesChildrenReadLive) } : {}),
230
+ ...(facts.half === "effective" && facts.advisor !== undefined ? { advisor: { ...facts.advisor, ...(facts.advisor.hold !== undefined ? { hold: { ...facts.advisor.hold } } : {}) } } : {}),
223
231
  ...(facts.half === "effective" && facts.teamRole !== undefined ? { teamRole: facts.teamRole } : {}),
224
232
  ...(facts.half === "effective" && facts.peerPresence !== undefined && (facts.peerPresence.agent !== undefined || facts.peerPresence.intent !== undefined)
225
233
  ? { peerPresence: { ...(facts.peerPresence.agent !== undefined ? { agent: facts.peerPresence.agent } : {}), ...(facts.peerPresence.intent !== undefined ? { intent: facts.peerPresence.intent } : {}) } }
226
234
  : {}),
227
235
  };
228
236
  if (facts.half === "effective") {
229
- const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, mods: _mods, teamRole: _teamRole, peerPresence: _peerPresence, fileHistory: _fileHistory, permissionMode: _permissionMode, ...assembly } = manifest;
237
+ const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, mods: _mods, teamRole: _teamRole, peerPresence: _peerPresence, fileHistory: _fileHistory, projectMemory: _projectMemory, permissionMode: _permissionMode, sessionRules: _sessionRules, advisor: _advisor, ...assembly } = manifest;
230
238
  const { provenance: _askSeat, ...askForHash } = assembly.ask;
231
239
  const { provenance: _questionSeat, ...questionForHash } = assembly.question;
232
240
  manifest.configFingerprint = createHash("sha256")
@@ -1,4 +1,5 @@
1
1
  import type { TaskResult } from "./types.js";
2
+ import { type CorruptBodyForm } from "./store-contracts/read-back-shape-contract.js";
2
3
  /**
3
4
  * design/97 CORE-7 — one recorded `ctx.agent` result in a workflow's RESUME journal. Unlike the observation-only
4
5
  * {@link WorkflowRunStore} (best-effort, swallowed on throw), the journal is LOAD-BEARING: a resume replays the
@@ -30,6 +31,67 @@ export type WorkflowJournalEntry = {
30
31
  }>;
31
32
  };
32
33
  };
34
+ /** What {@link readWorkflowJournalEntry} answers: the entry, or the corrupt form the row takes plus a clause
35
+ * naming what is wrong with it (worded to follow "journal entry #N"; it quotes no stored value). */
36
+ export type WorkflowJournalEntryReading = {
37
+ entry: WorkflowJournalEntry;
38
+ } | {
39
+ corrupt: CorruptBodyForm;
40
+ why: string;
41
+ };
42
+ /**
43
+ * The ONE reading of a journal row read back from a store: which arm it is, and whether the arm carries what a
44
+ * resume reads from it — an object result, or a paused terminal with its checkpoint token (the payload's other
45
+ * members, `sessionId` / `gate` / `stats` among them, are not judged here). `raw` is the DECODED LOGICAL ROW — an object carrying
46
+ * `callKey` and exactly one of `result` / `parked`; how a backend encodes that row on its medium (a JSONL
47
+ * line with its own `scope` / `ordinal` members, a SQL column holding an envelope) is the backend's format
48
+ * and is decoded before this is asked. Members other than those three are not read and are not carried into
49
+ * the entry, which is minted fresh from them.
50
+ *
51
+ * Corrupt, by form:
52
+ * - `not-an-object` — the row is not an object;
53
+ * - `missing-required` — no `callKey`; neither arm; a parked arm whose result carries no `terminal`, or
54
+ * whose paused terminal carries no `token`;
55
+ * - `wrong-type` — a non-string `callKey`; BOTH arms (the union admits one); a `result` that is not an
56
+ * object; a `parked` that is not an object; a parked arm whose terminal is not `paused`, or whose token
57
+ * is not a non-empty string.
58
+ *
59
+ * The parked arm's paused terminal and its checkpoint token are judged here because the type requires them
60
+ * and the arm is load-bearing: a row that says it parked but holds no paused result with a token can neither
61
+ * be driven nor be replayed as a finished call, and answering it as either would let a resume run that
62
+ * ordinal again beside the child pinned under its pending checkpoint. Whether a COMPLETED result carries a
63
+ * terminal cause the engine can replay is the resume's own admission (a journal written before
64
+ * `TaskResult.terminal` is incompatible, not damaged).
65
+ */
66
+ export declare function readWorkflowJournalEntry(raw: unknown): WorkflowJournalEntryReading;
67
+ /**
68
+ * Clamp an externally-supplied run identifier before it lands in a persisted field or an error message:
69
+ * `resumeFromRunId` is LLM-controlled text and a resume claim's `holder` is store-supplied, so neither may
70
+ * carry control characters / unbounded length into a record a human or a model reads.
71
+ */
72
+ export declare function clampRunIdText(raw: string): string;
73
+ /** The code of {@link WorkflowJournalIncompatibleError} — the word the journal store kit asserts on a refused `load`. */
74
+ export declare const JOURNAL_INCOMPATIBLE_ERROR_CODE = "workflow.journal_incompatible";
75
+ /** A resume journal entry the resume cannot admit is INCOMPATIBLE, and the resume is refused before any work is
76
+ * dispatched: a row whose result carries no terminal cause (a journal written before `TaskResult.terminal`), or
77
+ * a row {@link readWorkflowJournalEntry} reads as corrupt — refused by the engine's admission, or by a store's
78
+ * own `load` (the journal store kit holds a backend's refused `load` to this code). The alternative (letting the
79
+ * entry diverge into a live re-run) would execute the already-completed prefix again, side effects included.
80
+ *
81
+ * `entry` is the row as read: when the journal reader finds it corrupt, the message carries that reader's clause
82
+ * (fixed text that quotes no stored value), so no caller-supplied text reaches it; absent, or a row the reader
83
+ * admits, the clause is the missing terminal cause. A backend whose own medium holds a line that is not one of the
84
+ * run's records refuses with {@link WorkflowJournalIncompatibleError.ledgerLine}. `ordinal` is `-1` when the refusal
85
+ * names no entry ordinal: a row with no readable call key, or a ledger line. The run id is clamped here. */
86
+ export declare class WorkflowJournalIncompatibleError extends Error {
87
+ readonly ordinal: number;
88
+ readonly code = "workflow.journal_incompatible";
89
+ readonly fromRunId: string;
90
+ constructor(fromRunId: string, ordinal: number, entry?: unknown);
91
+ /** The refusal for line `line` (1-based) of a backend's ledger that is not one of the run's records, judged `form`
92
+ * by the backend's line reader: dropping it would leave whatever it held looking never journaled. */
93
+ static ledgerLine(fromRunId: string, line: number, form: CorruptBodyForm): WorkflowJournalIncompatibleError;
94
+ }
33
95
  /** REF-D5: the resume-claim key triple — ONE shape for the interface pair and every implementation
34
96
  * (it was re-inlined seven times; a key-field rename must red every leg at once). */
35
97
  export interface ResumeClaimArgs {
@@ -1,4 +1,72 @@
1
1
  import { terminalProjection } from "./runner/terminal-projection.js";
2
+ import { CORRUPT_BODY_FORMS } from "./store-contracts/read-back-shape-contract.js";
3
+ const isRecordShaped = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
4
+ const ownMember = (o, key) => (Object.hasOwn(o, key) ? o[key] : undefined);
5
+ export function readWorkflowJournalEntry(raw) {
6
+ if (!isRecordShaped(raw))
7
+ return { corrupt: "not-an-object", why: "is not a journal entry (not an object)" };
8
+ const callKey = ownMember(raw, "callKey");
9
+ if (callKey === undefined)
10
+ return { corrupt: "missing-required", why: "carries no call key" };
11
+ if (typeof callKey !== "string")
12
+ return { corrupt: "wrong-type", why: "has a call key that is not a string" };
13
+ const result = ownMember(raw, "result");
14
+ const parked = ownMember(raw, "parked");
15
+ if (result === undefined && parked === undefined)
16
+ return { corrupt: "missing-required", why: "carries neither a result nor a parked arm" };
17
+ if (result !== undefined && parked !== undefined)
18
+ return { corrupt: "wrong-type", why: "carries both a result and a parked arm" };
19
+ if (parked === undefined) {
20
+ if (!isRecordShaped(result))
21
+ return { corrupt: "wrong-type", why: "has a result that is not an object" };
22
+ return { entry: { callKey, result: result } };
23
+ }
24
+ if (!isRecordShaped(parked))
25
+ return { corrupt: "wrong-type", why: "is recorded as parked but its parked arm is not an object" };
26
+ const terminal = ownMember(parked, "terminal");
27
+ if (terminal === undefined)
28
+ return { corrupt: "missing-required", why: "is recorded as parked but its parked result carries no terminal" };
29
+ if (!isRecordShaped(terminal) || ownMember(terminal, "kind") !== "paused") {
30
+ return { corrupt: "wrong-type", why: "is recorded as parked but its terminal is not a paused one" };
31
+ }
32
+ const token = ownMember(terminal, "token");
33
+ if (token === undefined)
34
+ return { corrupt: "missing-required", why: "is recorded as parked but its paused terminal carries no checkpoint token" };
35
+ if (typeof token !== "string" || token.length === 0)
36
+ return { corrupt: "wrong-type", why: "is recorded as parked but its paused terminal carries no checkpoint token" };
37
+ return { entry: { callKey, parked: parked } };
38
+ }
39
+ export function clampRunIdText(raw) {
40
+ return raw.replace(/[^A-Za-z0-9_.:-]/g, "").slice(0, 64);
41
+ }
42
+ export const JOURNAL_INCOMPATIBLE_ERROR_CODE = "workflow.journal_incompatible";
43
+ export class WorkflowJournalIncompatibleError extends Error {
44
+ ordinal;
45
+ code = JOURNAL_INCOMPATIBLE_ERROR_CODE;
46
+ fromRunId;
47
+ constructor(fromRunId, ordinal, entry) {
48
+ const runIdText = clampRunIdText(fromRunId);
49
+ super(`workflow run "${runIdText}": ${refusedSubjectOf(ordinal, entry)} — this journal cannot be resumed. ${REPAIR_COST}`);
50
+ this.ordinal = ordinal;
51
+ this.fromRunId = runIdText;
52
+ this.name = "WorkflowJournalIncompatibleError";
53
+ }
54
+ static ledgerLine(fromRunId, line, form) {
55
+ return new WorkflowJournalIncompatibleError(fromRunId, -1, { [LEDGER_LINE]: { line, form } });
56
+ }
57
+ }
58
+ const REPAIR_COST = "Deleting what is damaged does not repair it (whatever goes missing runs again, live); restoring it needs a copy of the ledger kept outside the engine; a fresh run executes every step again, side effects included.";
59
+ const LEDGER_LINE = Symbol("ledgerLine");
60
+ function refusedSubjectOf(ordinal, entry) {
61
+ const at = isRecordShaped(entry) ? entry[LEDGER_LINE] : undefined;
62
+ if (at !== undefined) {
63
+ const line = Number.isSafeInteger(at.line) && at.line > 0 ? at.line : "?";
64
+ const form = CORRUPT_BODY_FORMS.includes(at.form) ? at.form : "unreadable";
65
+ return `ledger line ${String(line)} is not one of the run's records (${String(form)})`;
66
+ }
67
+ const read = entry === undefined ? undefined : readWorkflowJournalEntry(entry);
68
+ return `journal entry #${ordinal} ${read !== undefined && "corrupt" in read ? read.why : "carries no terminal cause (a journal written before TaskResult.terminal, or a malformed entry)"}`;
69
+ }
2
70
  export const MAX_JOURNAL_RESULT_BYTES = 5 * 1024 * 1024;
3
71
  export function oversizeJournalResult(serialized) {
4
72
  return Buffer.byteLength(serialized, "utf8") > MAX_JOURNAL_RESULT_BYTES;
@@ -80,7 +148,15 @@ export class InMemoryWorkflowJournalStore {
80
148
  const rec = this.runs.get(runId);
81
149
  if (!rec || rec.scope !== scope)
82
150
  return [];
83
- return [...rec.byOrdinal.entries()].sort((a, b) => a[0] - b[0]).map(([, e]) => snapshot(e));
151
+ const out = [];
152
+ for (const [ordinal, e] of [...rec.byOrdinal.entries()].sort((a, b) => a[0] - b[0])) {
153
+ const row = snapshot(e);
154
+ const read = readWorkflowJournalEntry(row);
155
+ if ("corrupt" in read)
156
+ throw new WorkflowJournalIncompatibleError(runId, ordinal, row);
157
+ out.push(read.entry);
158
+ }
159
+ return out;
84
160
  }
85
161
  async append(runId, scope, entry) {
86
162
  assertJournalEntryFits(entry);
@@ -46,6 +46,12 @@ export interface WorkflowRunSummary {
46
46
  description?: string;
47
47
  /** Lifecycle status ({@link WorkflowRun.status}): running / completed / failed. */
48
48
  status: WorkflowRunStatus;
49
+ /** `true` while the run is still `running` AND at least one leg is parked at an approval gate — somebody is being
50
+ * waited on while `status` still says `running` ({@link runParkedOf}). ABSENT otherwise, never `false`: a run
51
+ * that has since suspended on the park reads `failed` + `errorCode: "workflow.agent_parked"` (that code is its
52
+ * "awaiting approval" word; a consumer shows both arms the same way), and a settled record never carries it.
53
+ * DERIVED from the agent rows on every projection — not stored on the run, so no second copy to drift. */
54
+ parked?: true;
49
55
  /** The MACHINE code of the failure that ended the run ({@link WorkflowRun.errorCode}) — the same word,
50
56
  * in the same vocabulary, that the full run carries; never re-derived and never a second taxonomy.
51
57
  * The fourth member of the same family as {@link agentFailures} / {@link budgetOvershoot} /
@@ -1,3 +1,4 @@
1
+ import { runParkedOf } from "../orchestration/workflow-types.js";
1
2
  import { assertRetentionPolicy } from "./retention-policy.js";
2
3
  export function summarizeWorkflowRun(run) {
3
4
  const latestPhase = run.phases.at(-1);
@@ -8,6 +9,7 @@ export function summarizeWorkflowRun(run) {
8
9
  ...(run.name !== undefined ? { name: run.name } : {}),
9
10
  ...(run.description !== undefined ? { description: run.description } : {}),
10
11
  status: run.status,
12
+ ...(runParkedOf(run) ? { parked: true } : {}),
11
13
  ...(run.errorCode !== undefined ? { errorCode: run.errorCode } : {}),
12
14
  ...(run.agentFailures !== undefined ? { agentFailures: run.agentFailures } : {}),
13
15
  ...(run.budgetOvershoot !== undefined ? { budgetOvershoot: { ...run.budgetOvershoot } } : {}),
@@ -17,7 +17,7 @@ export interface CompactionDetails {
17
17
  */
18
18
  modifiedFilesByRecency?: string[];
19
19
  /**
20
- * Invoked-skill retention area (CC 2.1.207 parity): the skills invoked in the COMPACTED range
20
+ * Invoked-skill retention area: the skills invoked in the COMPACTED range
21
21
  * (merged over the previous compaction's retained set), most recent invocation first, already
22
22
  * budgeted (per-skill truncation marker + total-area skip semantics — see compaction/utils.ts).
23
23
  * Rendered onto the compaction summary message by `buildSessionContext`; kept OUT of the summary
@@ -131,7 +131,7 @@ export declare const DEFAULT_CLAMP_TOLERANCE = 0.1;
131
131
  * [new user]`, and a within-turn boundary keeps `[emitting assistant][its tool results]` because
132
132
  * a trailing tool-result batch pulls the floor back to its call site.
133
133
  *
134
- * That is the CC posture, arrived at through a different knob. CC 2.1.223's LOCAL threshold
134
+ * That is the CC posture, arrived at through a different knob. the reference's LOCAL threshold
135
135
  * compaction always routes to the reactive pipeline (`y9s` :432704 — the `GNo` full-compaction
136
136
  * branch with `messagesToKeep: []` :431788 is reached only for a remote/in-process runner, and a
137
137
  * `source:"auto"` window makes the local threshold not fire at all, `hky` :432687 / `aYe` :242816).
@@ -159,7 +159,7 @@ export declare const DEFAULT_COMPACTION_SETTINGS: CompactionSettings;
159
159
  * never split (estimate vs cut-point vs defense); per-model override via `Model.charsPerToken`.
160
160
  *
161
161
  * 4 → 3 (design/374 slice 4, ruled 2026-08-28) — this is a RE-ANCHORING, not a divergence.
162
- * CC's coefficient is a two-branch function, not a constant: `sf(model)` (cli250.js, `Z6` table) is
162
+ * CC's coefficient is a two-branch function, not a constant: `sf(model)` is
163
163
  * `Z6.has(family) ? 4 : 3`
164
164
  * where `Z6` lists exactly the OLD families (claude-3.x, opus-4-0/4-1/4-5/4-6, sonnet-4-0/4-5/4-6,
165
165
  * haiku-4-5). **3 is CC's DEFAULT branch; 4 is the whitelist hit** — and CC's own current generation
@@ -189,7 +189,7 @@ export declare function calculateContextTokens(usage: Usage): number;
189
189
  *
190
190
  * design/123 D1 stale-anchor note (fable-m2, same-family point): this scans RAW session entries, so
191
191
  * unlike `buildSessionContext` (which shallow-strips the usage of kept-tail assistants replayed
192
- * across a compaction boundary — the anchor "naturally disappears", CC 198 parity) it CAN still see
192
+ * across a compaction boundary — the anchor "naturally disappears") it CAN still see
193
193
  * a pre-compaction anchor. Any consumer using this across a compaction boundary must treat such an
194
194
  * anchor as STALE: it reflects the pre-compaction request and overestimates the post-compaction
195
195
  * context. (Currently exported with no in-repo production consumer.)
@@ -265,7 +265,7 @@ export declare const SUMMARIZATION_SYSTEM_PROMPT = "You are a context summarizat
265
265
  */
266
266
  export declare function contextInstructionFilesSection(contextInstructionFiles?: string): string;
267
267
  /**
268
- * design/169-A (CC 220 :516490-516516 / :387325-387336) — the CC-form FORK context for a summary
268
+ * design/169-A — the CC-form FORK context for a summary
269
269
  * request: the main lane's latest REAL request. When present (and the summary model IS the main
270
270
  * model), the summary request is the main conversation itself — same `systemPrompt` bytes, same
271
271
  * message-list byte PREFIX, same tools — plus ONE appended user-role instruction message. The
@@ -310,7 +310,7 @@ export declare function extractForkSummaryEnvelope(text: string): string | undef
310
310
  * messages above, un-serialized) + the fork-only instruction-file authority clause (see
311
311
  * {@link FORK_CONTEXT_INSTRUCTION_AUTHORITY}) + the fork-only summary envelope (see
312
312
  * {@link FORK_SUMMARY_ENVELOPE_DEMAND}; the independent form keeps its envelope-free contract).
313
- * Instructions inject in the same CC-verbatim shape as the independent form so every channel keeps
313
+ * Instructions inject in the same shape as the independent form so every channel keeps
314
314
  * one injection grammar. */
315
315
  export declare function forkSummarizationInstruction(customInstructions?: string, contextInstructionFiles?: string): string;
316
316
  /**
@@ -327,7 +327,7 @@ export declare function forkSummarizationInstruction(customInstructions?: string
327
327
  * base = settings.summaryOutputBudgetTokens ?? settings.reserveTokens (explicit knob wins)
328
328
  * effective = min(base, summary model's max output) (never budget output
329
329
  * the model can't emit)
330
- * CC contrast (2.1.207): CC's summary output cap is purely model-derived (its summary call runs at
330
+ * Contrast: the reference's summary output cap is purely model-derived (its summary call runs at
331
331
  * the model's max output) and fully separate from the trigger deduction — the `min(model.maxTokens,…)`
332
332
  * leg IS that posture. The base deliberately stays reserve-derived rather than jumping to the raw
333
333
  * model max: sema (unlike CC) clamps the summarization INPUT pre-send, and the clamp budgets
@@ -396,7 +396,7 @@ export interface SummarizationClampDryRun {
396
396
  * "prior summary + new increment", not the original history.
397
397
  */
398
398
  export declare function dryRunSummarizationClamp(preparation: CompactionPreparation, model: Model, customInstructions?: string, charsPerToken?: number): SummarizationClampDryRun;
399
- /** CC 198 jNl — verbatim marker inserted where the oldest conversation groups were dropped. */
399
+ /** The marker inserted where the oldest conversation groups were dropped. */
400
400
  export declare const COMPACTION_PTL_RETRY_MARKER = "[earlier conversation truncated for compaction retry]";
401
401
  /** Generate or update a conversation summary for compaction.
402
402
  * `summaryBudgetTokens` — the OUTPUT budget base (history leg = 0.8× it). Callers going through
@@ -488,6 +488,6 @@ export declare function compact(preparation: CompactionPreparation, model: Model
488
488
  * the main model; an independent compaction model has no main prefix to share. */
489
489
  forkContext?: CompactionForkContext): Promise<Result<CompactionResult, CompactionError>>;
490
490
  /** The prefix leg's base prompt, with the caller's instructions injected in the SAME shape the
491
- * history leg uses (`\n\nAdditional Instructions:\n${…}`, CC 198 verbatim). Single source so the
491
+ * history leg uses (`\n\nAdditional Instructions:\n${…}`). Single source so the
492
492
  * dry-run clamp charges exactly what the real call sends. */
493
493
  export declare function turnPrefixSummarizationPrompt(customInstructions?: string): string;