@sema-agent/core 7.48.0 → 7.49.1

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 (421) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +38 -31
  51. package/dist/core/arg-summary.d.ts +21 -28
  52. package/dist/core/arg-summary.js +235 -88
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +94 -65
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +43 -11
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +21 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp.d.ts +4 -0
  101. package/dist/core/mcp.js +70 -43
  102. package/dist/core/memory-engine/content-origin.js +2 -14
  103. package/dist/core/memory-engine/engine.d.ts +32 -22
  104. package/dist/core/memory-engine/engine.js +103 -55
  105. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  106. package/dist/core/memory-engine/file-backend.js +37 -252
  107. package/dist/core/memory-engine/index.d.ts +1 -1
  108. package/dist/core/memory-engine/index.js +1 -1
  109. package/dist/core/memory-engine/layout.d.ts +139 -9
  110. package/dist/core/memory-engine/layout.js +350 -7
  111. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  112. package/dist/core/memory-engine/scope-contract.js +8 -0
  113. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  114. package/dist/core/memory-engine/session-incarnation.js +5 -2
  115. package/dist/core/memory-engine/types.d.ts +10 -1
  116. package/dist/core/memory.js +5 -17
  117. package/dist/core/model-seat.d.ts +4 -4
  118. package/dist/core/model-seat.js +1 -1
  119. package/dist/core/mounted-mcp.d.ts +57 -0
  120. package/dist/core/mounted-mcp.js +19 -0
  121. package/dist/core/namespaced-rule-name.d.ts +29 -0
  122. package/dist/core/namespaced-rule-name.js +52 -0
  123. package/dist/core/park-selfcheck.d.ts +1 -1
  124. package/dist/core/park-selfcheck.js +16 -6
  125. package/dist/core/path-guard-rows.d.ts +99 -0
  126. package/dist/core/path-guard-rows.js +45 -0
  127. package/dist/core/path-identity.d.ts +22 -16
  128. package/dist/core/path-identity.js +10 -10
  129. package/dist/core/path-rule-binding.d.ts +2 -1
  130. package/dist/core/path-rule-binding.js +3 -1
  131. package/dist/core/pause-registry.d.ts +16 -2
  132. package/dist/core/pause-registry.js +6 -0
  133. package/dist/core/permission-rule-consent.js +0 -7
  134. package/dist/core/permission-rule-model.d.ts +68 -24
  135. package/dist/core/permission-rule-model.js +105 -24
  136. package/dist/core/permission-rule-store.js +2 -2
  137. package/dist/core/permission-rules.d.ts +3 -30
  138. package/dist/core/permission-rules.js +4 -54
  139. package/dist/core/read-root-candidate.d.ts +1 -3
  140. package/dist/core/read-root-candidate.js +4 -15
  141. package/dist/core/real-approval.d.ts +4 -3
  142. package/dist/core/retired-keys.d.ts +13 -0
  143. package/dist/core/retired-keys.js +14 -0
  144. package/dist/core/roles.d.ts +2 -3
  145. package/dist/core/roles.js +15 -6
  146. package/dist/core/runner/assemble-result.d.ts +0 -7
  147. package/dist/core/runner/assemble-result.js +19 -31
  148. package/dist/core/runner/caller-roster.d.ts +78 -0
  149. package/dist/core/runner/caller-roster.js +219 -0
  150. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  151. package/dist/core/runner/checkpoint-scope.js +2 -2
  152. package/dist/core/runner/child-tree.js +2 -2
  153. package/dist/core/runner/contracts.d.ts +68 -35
  154. package/dist/core/runner/decide-continuation.d.ts +51 -3
  155. package/dist/core/runner/decide-continuation.js +76 -21
  156. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  157. package/dist/core/runner/denial-limit-arms.js +11 -9
  158. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  159. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  160. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  161. package/dist/core/runner/finish-reason-seat.js +40 -0
  162. package/dist/core/runner/gate-exit.d.ts +44 -32
  163. package/dist/core/runner/gate-exit.js +112 -25
  164. package/dist/core/runner/inherited-ask-grants.js +6 -4
  165. package/dist/core/runner/mcp-redial.d.ts +3 -3
  166. package/dist/core/runner/mcp-redial.js +3 -4
  167. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  168. package/dist/core/runner/permission-rule-lanes.js +5 -4
  169. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  170. package/dist/core/runner/prepare-artifact.js +2 -1
  171. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  172. package/dist/core/runner/prepare-ask-lane.js +12 -6
  173. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  174. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  175. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  176. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  177. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  178. package/dist/core/runner/prepare-config-doors.js +10 -5
  179. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  180. package/dist/core/runner/prepare-defer-classify.js +5 -3
  181. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  182. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  183. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  184. package/dist/core/runner/prepare-gate-stations.js +9 -7
  185. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  186. package/dist/core/runner/prepare-hands-readface.js +7 -7
  187. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  188. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  189. package/dist/core/runner/prepare-listings.d.ts +7 -24
  190. package/dist/core/runner/prepare-listings.js +4 -5
  191. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  192. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  193. package/dist/core/runner/prepare-memory.d.ts +6 -0
  194. package/dist/core/runner/prepare-memory.js +13 -13
  195. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  196. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  198. package/dist/core/runner/prepare-park-ask.js +17 -10
  199. package/dist/core/runner/prepare-policy-chain.js +24 -44
  200. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  201. package/dist/core/runner/prepare-project-context.js +3 -4
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  204. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  205. package/dist/core/runner/prepare-run-refs.js +2 -1
  206. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  207. package/dist/core/runner/prepare-safety-scan.js +1 -2
  208. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  209. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  210. package/dist/core/runner/prepare-task.d.ts +1 -1
  211. package/dist/core/runner/prepare-task.js +67 -56
  212. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  213. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  214. package/dist/core/runner/resume-apply.js +7 -14
  215. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  216. package/dist/core/runner/resume-internals-and-config.js +2 -2
  217. package/dist/core/runner/resume-policy-outcome.js +5 -32
  218. package/dist/core/runner/resume-review-outcome.js +4 -1
  219. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  220. package/dist/core/runner/retired-runner-deps.js +10 -1
  221. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  222. package/dist/core/runner/run-brain-sinks.js +5 -2
  223. package/dist/core/runner/run-harness-handlers.js +29 -36
  224. package/dist/core/runner/run-leg.d.ts +0 -2
  225. package/dist/core/runner/run-leg.js +32 -33
  226. package/dist/core/runner/run-terminal-adoption.js +4 -3
  227. package/dist/core/runner/runtask.js +8 -8
  228. package/dist/core/runner/session-rule-policy.js +5 -5
  229. package/dist/core/runner/stream-settle-backstop.js +7 -4
  230. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  231. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  232. package/dist/core/runner/terminal-account.d.ts +48 -0
  233. package/dist/core/runner/terminal-account.js +186 -0
  234. package/dist/core/runner/tool-end-body.d.ts +54 -17
  235. package/dist/core/runner/tool-end-body.js +27 -2
  236. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  237. package/dist/core/runner/tool-face-overlay.js +6 -4
  238. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  239. package/dist/core/runner/tool-occurrence.js +123 -0
  240. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  241. package/dist/core/runner/tool-progress-lane.js +25 -34
  242. package/dist/core/runner/tool-turn-repair-seat.d.ts +28 -4
  243. package/dist/core/runner/tool-turn-repair-seat.js +36 -13
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/secret-env.d.ts +16 -5
  249. package/dist/core/secret-env.js +23 -63
  250. package/dist/core/sensitive-path-policy.d.ts +19 -18
  251. package/dist/core/sensitive-path-policy.js +73 -49
  252. package/dist/core/session-reconcile.d.ts +3 -0
  253. package/dist/core/session-reconcile.js +5 -4
  254. package/dist/core/session-store.d.ts +5 -0
  255. package/dist/core/session-store.js +12 -0
  256. package/dist/core/session.d.ts +13 -0
  257. package/dist/core/shared-memory/normalize.d.ts +17 -4
  258. package/dist/core/shared-memory/normalize.js +7 -7
  259. package/dist/core/shell-lexer.js +5 -4
  260. package/dist/core/shell-wrapper-projection.js +1 -1
  261. package/dist/core/skill-grant.js +1 -1
  262. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  263. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  264. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  265. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  266. package/dist/core/stub-env.d.ts +2 -0
  267. package/dist/core/stub-env.js +1 -0
  268. package/dist/core/synthetic-read-verdict.js +2 -2
  269. package/dist/core/task-event.d.ts +59 -5
  270. package/dist/core/task-result.d.ts +1 -1
  271. package/dist/core/task-spec.d.ts +42 -9
  272. package/dist/core/terminal-cause.d.ts +94 -11
  273. package/dist/core/tighten-task-spec.d.ts +5 -4
  274. package/dist/core/tighten-task-spec.js +20 -25
  275. package/dist/core/tool-catalog-entries.d.ts +5 -7
  276. package/dist/core/tool-catalog-entries.js +14 -15
  277. package/dist/core/tool-face.d.ts +47 -0
  278. package/dist/core/tool-face.js +5 -0
  279. package/dist/core/tool-model-gate.d.ts +5 -5
  280. package/dist/core/tool-name-aliases.d.ts +26 -2
  281. package/dist/core/tool-name-aliases.js +13 -0
  282. package/dist/core/tool-name-list.d.ts +30 -0
  283. package/dist/core/tool-name-list.js +55 -0
  284. package/dist/core/tool-name-readings.d.ts +1 -9
  285. package/dist/core/tool-name-readings.js +1 -3
  286. package/dist/core/tool-policy.d.ts +195 -85
  287. package/dist/core/tool-policy.js +165 -380
  288. package/dist/core/tool-registry.d.ts +44 -1
  289. package/dist/core/tool-registry.js +26 -0
  290. package/dist/core/tool-roster.d.ts +19 -1
  291. package/dist/core/tool-roster.js +21 -2
  292. package/dist/core/tool-spec-members.d.ts +45 -0
  293. package/dist/core/tool-spec-members.js +169 -0
  294. package/dist/core/tool-spec.d.ts +46 -8
  295. package/dist/core/tools.d.ts +6 -2
  296. package/dist/core/tools.js +8 -4
  297. package/dist/core/untrusted-egress.js +29 -26
  298. package/dist/core/untrusted-text.d.ts +13 -10
  299. package/dist/core/untrusted-text.js +6 -44
  300. package/dist/core/workflow-journal-store.d.ts +4 -1
  301. package/dist/core/write-protect.d.ts +65 -29
  302. package/dist/core/write-protect.js +235 -177
  303. package/dist/engine/compaction/compaction.d.ts +2 -2
  304. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  305. package/dist/engine/execution-env/node-execution-env.js +16 -38
  306. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  307. package/dist/engine/execution-env/symlink-chain.js +32 -0
  308. package/dist/engine/harness/types.d.ts +7 -0
  309. package/dist/engine/llm/tool-turns.d.ts +3 -0
  310. package/dist/engine/llm/tool-turns.js +1 -0
  311. package/dist/engine/llm/types.d.ts +59 -23
  312. package/dist/engine/loop/agent-loop.js +16 -2
  313. package/dist/engine/session/memory-repo.js +11 -3
  314. package/dist/engine/session/repo-utils.d.ts +8 -0
  315. package/dist/engine/session/repo-utils.js +13 -0
  316. package/dist/index.d.ts +20 -23
  317. package/dist/index.js +17 -20
  318. package/dist/internal/harness.d.ts +1 -1
  319. package/dist/internal/harness.js +1 -1
  320. package/dist/internal/llm.d.ts +2 -2
  321. package/dist/internal/llm.js +1 -1
  322. package/dist/orchestration/governance-baseline-validity.js +1 -1
  323. package/dist/orchestration/run-spec.js +3 -3
  324. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  325. package/dist/orchestration/run-workflow-tool.js +38 -78
  326. package/dist/orchestration/workflow-governance.d.ts +21 -25
  327. package/dist/orchestration/workflow-governance.js +38 -78
  328. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  329. package/dist/orchestration/workflow-primitives.js +5 -12
  330. package/dist/orchestration/workflow-types.d.ts +1 -1
  331. package/dist/orchestration/workflow.d.ts +61 -11
  332. package/dist/orchestration/workflow.js +189 -117
  333. package/dist/scenarios/full-body.d.ts +1 -1
  334. package/dist/shell/lex.d.ts +0 -21
  335. package/dist/shell/lex.js +250 -68
  336. package/dist/shell/shell-words.d.ts +35 -0
  337. package/dist/shell/shell-words.js +65 -0
  338. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  339. package/dist/stores/file/checkpoint-store.js +5 -2
  340. package/dist/stores/file/index.d.ts +0 -8
  341. package/dist/stores/file/index.js +0 -12
  342. package/dist/stores/file/session-store.d.ts +3 -0
  343. package/dist/stores/file/session-store.js +44 -19
  344. package/dist/tools/artifact/artifact-tool.js +2 -0
  345. package/dist/tools/fs/bash-program-position.d.ts +12 -4
  346. package/dist/tools/fs/bash-program-position.js +32 -9
  347. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  348. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  349. package/dist/tools/fs/containment-face.d.ts +4 -0
  350. package/dist/tools/fs/containment-face.js +3 -0
  351. package/dist/tools/fs/fs-shared.d.ts +10 -0
  352. package/dist/tools/fs/fs-shared.js +18 -0
  353. package/dist/tools/fs/fs-write.js +4 -2
  354. package/dist/tools/fs/index.d.ts +1 -1
  355. package/dist/tools/fs/program-read-model.d.ts +46 -20
  356. package/dist/tools/fs/program-read-model.js +50 -20
  357. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  358. package/dist/tools/fs/program-read-model.rows.js +16 -15
  359. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  360. package/dist/tools/fs/read-deny-home.js +35 -49
  361. package/dist/tools/fs/read-deny.d.ts +23 -22
  362. package/dist/tools/fs/read-deny.js +114 -89
  363. package/dist/tools/fs/removal-targets.d.ts +56 -23
  364. package/dist/tools/fs/removal-targets.js +65 -87
  365. package/dist/tools/fs/safety.d.ts +29 -22
  366. package/dist/tools/fs/safety.js +17 -11
  367. package/dist/tools/fs/search.js +10 -8
  368. package/dist/tools/fs/shell-read-argv.js +1 -1
  369. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  370. package/dist/tools/fs/shell-read-bindings.js +324 -86
  371. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  372. package/dist/tools/fs/shell-read-builtins.js +43 -0
  373. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  374. package/dist/tools/fs/shell-read-check.js +67 -43
  375. package/dist/tools/fs/shell-read-establish.js +6 -6
  376. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  377. package/dist/tools/fs/shell-read-functions.js +29 -0
  378. package/dist/tools/fs/shell-read-judge.d.ts +51 -18
  379. package/dist/tools/fs/shell-read-judge.js +40 -4
  380. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  381. package/dist/tools/fs/shell-read-plan.js +118 -113
  382. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  383. package/dist/tools/fs/shell-read-start.js +16 -9
  384. package/dist/tools/fs/shell-read-word.js +4 -0
  385. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  386. package/dist/tools/fs/shell-read-workdir.js +281 -0
  387. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  388. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  389. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  390. package/dist/tools/fs/shell-reentry-text.js +3 -11
  391. package/dist/tools/task-list.d.ts +1 -2
  392. package/dist/tools/web.js +1 -1
  393. package/package.json +4 -1
  394. package/test/export-surface.snapshot.json +107 -143
  395. package/wire-changes/core@7.49.0.json +4765 -0
  396. package/dist/agents/teacher.d.ts +0 -159
  397. package/dist/agents/teacher.js +0 -577
  398. package/dist/agents/team.d.ts +0 -226
  399. package/dist/agents/team.js +0 -257
  400. package/dist/core/strategy-store.d.ts +0 -238
  401. package/dist/core/strategy-store.js +0 -253
  402. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  403. package/dist/orchestration/builtin-workflows.js +0 -159
  404. package/dist/scenarios/env.d.ts +0 -40
  405. package/dist/scenarios/env.js +0 -39
  406. package/dist/scenarios/scenario-registry.d.ts +0 -110
  407. package/dist/scenarios/scenario-registry.js +0 -140
  408. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  409. package/dist/scenarios/teacher-quickstart.js +0 -12
  410. package/dist/stores/cc/lockfile.d.ts +0 -10
  411. package/dist/stores/cc/lockfile.js +0 -98
  412. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  413. package/dist/stores/cc/mailbox-store.js +0 -255
  414. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  415. package/dist/stores/cc/roster-adapter.js +0 -117
  416. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  417. package/dist/stores/cc/sidecar-transcript.js +0 -264
  418. package/dist/stores/cc/task-list-store.d.ts +0 -2
  419. package/dist/stores/cc/task-list-store.js +0 -125
  420. package/dist/stores/file/strategy-store.d.ts +0 -97
  421. package/dist/stores/file/strategy-store.js +0 -341
@@ -7,19 +7,25 @@
7
7
  * opaque here — the runner knows only that it started and has not ended — so this lane runs a slow beat for
8
8
  * any in-flight call silent for {@link TOOL_HEARTBEAT_MS}.
9
9
  *
10
- * THE LANE OWNS TIME, the producer owns FACTS. A producer reports what it has seen (the tail, the totals),
11
- * never how long it has run: `elapsedTimeSeconds` is computed HERE from one origin per call, because the two
12
- * producers do not start their clocks together — the station registers a call when it ENTERS EXECUTION, a
13
- * shell command's own clock could only start at its spawn. With two origins a 30 s beat could be followed
14
- * moments later by a shell tick reporting 1 s, breaking the monotonicity the frame promises.
10
+ * THE CALLS IN FLIGHT ARE THE LEG'S OCCURRENCES (`tool-occurrence.ts`), not a set of this lane's own: the record
11
+ * that carries a call's start frame carries its elapsed origin, its silence clock and its wait on the person, so
12
+ * the beat can never describe a call the frames say ended, nor miss one they say started.
13
+ *
14
+ * ONE ORIGIN PER CALL, the producer owns FACTS. A producer reports what it has seen (the tail, the totals),
15
+ * never how long it has run: `elapsedTimeSeconds` is computed HERE from the occurrence's origin — its
16
+ * announcement — because a shell command's own clock could only start at its spawn. With two origins a 30 s
17
+ * beat could be followed moments later by a shell tick reporting 1 s, breaking the monotonicity the frame promises.
15
18
  *
16
19
  * THE CADENCE HAS ONE ENFORCEMENT POINT, same reason: a producer's timer is a SAMPLING clock, not the
17
20
  * contract. `emit` drops a frame landing inside {@link TOOL_PROGRESS_MIN_INTERVAL_MS} of that call's last.
18
21
  *
19
- * ONE RULE FOR THE BEAT: a call is beaten when nothing has been emitted FOR IT for a whole interval,
22
+ * ONE RULE FOR THE BEAT: a call is beaten when nothing has been heard FROM IT for a whole interval,
20
23
  * counting its own start as the first such event — covering both "it only just started" and "the tool
21
24
  * already ticks faster than this". The interval is the RUN's, so a first beat lands anywhere in
22
25
  * [TOOL_HEARTBEAT_MS, 2 × TOOL_HEARTBEAT_MS): the price of one timer per run, stated rather than hidden.
26
+ * And the beat reads the one activity fact: when EVERY call in flight is waiting on the person, nothing is
27
+ * working and nothing is beaten; a call back from the person is heard from at that moment, so its silence
28
+ * is counted afresh.
23
29
  *
24
30
  * THE CLOCK IS MONOTONIC: every predicate here is a DIFFERENCE of two readings (is this call due a beat, is
25
31
  * this offer inside the floor, how long has it run), and off the wall clock a backward step — NTP, a
@@ -30,6 +36,7 @@
30
36
  * every emission is fault-contained. */
31
37
  import type { TaskEvent, TaskEventIdentity } from "../types.js";
32
38
  import type { ToolProgressLane } from "./contracts.js";
39
+ import { type ToolOccurrenceTable } from "./tool-occurrence.js";
33
40
  /** How long a tool call may stay silent before this lane beats for it, in ms. ONE SOURCE, and CC
34
41
  * 2.1.259's own per-tool heartbeat interval (`Cct`) — this engine keeps the cadence and folds the beat
35
42
  * into the one progress frame instead of minting a second shape (registered divergence). */
@@ -38,5 +45,6 @@ export declare const TOOL_HEARTBEAT_MS = 30000;
38
45
  * nowhere else so it holds across producers rather than inside each one. */
39
46
  export declare const TOOL_PROGRESS_MIN_INTERVAL_MS = 1000;
40
47
  /** Build the lane over the run's content pusher (`pushContent` — the ONE seat that puts a frame on this
41
- * run's queue and, for a sub-agent, forwards it to the parent's sink) and its identity mint. */
42
- export declare function createToolProgressLane(push: (e: TaskEvent) => void, ident: () => TaskEventIdentity): ToolProgressLane;
48
+ * run's queue and, for a sub-agent, forwards it to the parent's sink), its identity mint and the leg's
49
+ * occurrence table (the calls in flight). */
50
+ export declare function createToolProgressLane(push: (e: TaskEvent) => void, ident: () => TaskEventIdentity, occurrences: ToolOccurrenceTable): ToolProgressLane;
@@ -1,8 +1,7 @@
1
+ import { occurrenceClock } from "./tool-occurrence.js";
1
2
  export const TOOL_HEARTBEAT_MS = 30_000;
2
3
  export const TOOL_PROGRESS_MIN_INTERVAL_MS = 1_000;
3
- const monotonicNow = () => (typeof performance !== "undefined" ? performance.now() : Date.now());
4
- export function createToolProgressLane(push, ident) {
5
- const inFlight = new Map();
4
+ export function createToolProgressLane(push, ident, occurrences) {
6
5
  let timer;
7
6
  const arm = () => {
8
7
  if (timer !== undefined)
@@ -10,51 +9,43 @@ export function createToolProgressLane(push, ident) {
10
9
  timer = setInterval(beat, TOOL_HEARTBEAT_MS);
11
10
  timer.unref?.();
12
11
  };
12
+ const disarm = () => {
13
+ if (timer === undefined)
14
+ return;
15
+ clearInterval(timer);
16
+ timer = undefined;
17
+ };
18
+ occurrences.onOpen(arm);
13
19
  const emit = (body) => {
14
- const now = monotonicNow();
15
- let live = inFlight.get(body.toolCallId);
16
- if (live === undefined) {
17
- live = { toolName: body.toolName, startedAt: now, lastAt: now - TOOL_PROGRESS_MIN_INTERVAL_MS };
18
- inFlight.set(body.toolCallId, live);
19
- arm();
20
- }
21
- if (now - live.lastAt < TOOL_PROGRESS_MIN_INTERVAL_MS)
20
+ const now = occurrenceClock();
21
+ const unseen = occurrences.get(body.toolCallId) === undefined;
22
+ const occ = occurrences.ensure({ toolCallId: body.toolCallId, spelledName: body.toolName, args: undefined });
23
+ if (!unseen && now - occ.lastHeardAt < TOOL_PROGRESS_MIN_INTERVAL_MS)
22
24
  return;
23
- live.lastAt = now;
25
+ occurrences.heard(occ.toolCallId);
24
26
  try {
25
- push({ type: "tool_progress", ...body, elapsedTimeSeconds: Math.floor((now - live.startedAt) / 1000), ...ident() });
27
+ push({ type: "tool_progress", ...body, elapsedTimeSeconds: Math.floor((now - occ.startedAt) / 1000), ...ident() });
26
28
  }
27
29
  catch {
28
30
  }
29
31
  };
30
32
  function beat() {
31
- const now = monotonicNow();
32
- for (const [toolCallId, live] of inFlight) {
33
- if (now - live.lastAt < TOOL_HEARTBEAT_MS)
33
+ const now = occurrenceClock();
34
+ const inFlight = occurrences.live().filter((o) => o.beating);
35
+ if (inFlight.length === 0)
36
+ return disarm();
37
+ if (inFlight.every((o) => o.awaitingUser > 0))
38
+ return;
39
+ for (const o of inFlight) {
40
+ if (now - o.lastHeardAt < TOOL_HEARTBEAT_MS)
34
41
  continue;
35
- emit({ toolCallId, toolName: live.toolName });
42
+ emit({ toolCallId: o.toolCallId, toolName: o.spelledName });
36
43
  }
37
44
  }
38
- const disarm = () => {
39
- if (timer === undefined)
40
- return;
41
- clearInterval(timer);
42
- timer = undefined;
43
- };
44
45
  return {
45
46
  emit,
46
- noteStart(toolCallId, toolName) {
47
- const startedAt = monotonicNow();
48
- inFlight.set(toolCallId, { toolName, startedAt, lastAt: startedAt });
49
- arm();
50
- },
51
- noteEnd(toolCallId) {
52
- inFlight.delete(toolCallId);
53
- if (inFlight.size === 0)
54
- disarm();
55
- },
56
47
  clear() {
57
- inFlight.clear();
48
+ occurrences.quiesce();
58
49
  disarm();
59
50
  },
60
51
  };
@@ -1,15 +1,39 @@
1
1
  import type { EngineNotice } from "../engine-notice.js";
2
- import { type ToolTurnIncompleteCause, type ToolTurnRepair } from "../../internal/llm.js";
2
+ import { type ToolTurnRepair } from "../../internal/llm.js";
3
3
  /** The notice's attribution ids — the same pair, for the same reason, as the fold seat's. */
4
4
  export interface ToolTurnRepairSeatIds {
5
5
  sessionId: string;
6
6
  runId: string;
7
7
  }
8
+ /** What the message says became of a turn that dropped calls: the run ended on it (`model_output_invalid`), or the next
9
+ * request asks the model to re-issue them. */
10
+ export type ToolTurnOutcome = "terminal" | "reissued";
11
+ /** One thing the person is told, per cause. A dropped-call cause carries the outcome when its message states one (else
12
+ * `undefined`: nothing is said about the run's fate); the others have none. */
13
+ export type ToolTurnIncompleteItem = {
14
+ cause: "truncated";
15
+ count: number;
16
+ outcome: ToolTurnOutcome | undefined;
17
+ } | {
18
+ cause: "unnamed";
19
+ count: number;
20
+ outcome: ToolTurnOutcome | undefined;
21
+ } | {
22
+ cause: "bad_frame";
23
+ count: number;
24
+ } | {
25
+ cause: "missing_result_synthesized";
26
+ count: number;
27
+ toolCallIds: readonly string[];
28
+ };
29
+ /** Does a turn's content carry a tool call? A tool-calling turn GUARANTEES a next request (its results go back to the
30
+ * model): the engine's one continuation fact — the harness's boundary gates and the dropped-call line read it here. */
31
+ export declare function turnCarriesToolCall(content: unknown): boolean;
8
32
  /** The person's line for one cause — once per run per cause, whichever observer saw it first. */
9
33
  export interface ToolTurnIncompleteSeat {
10
- /** Announce `count` items of `cause` (and, for a missing result, the calls) unless this run already said it. */
11
- announce(cause: ToolTurnIncompleteCause, count: number, toolCallIds?: readonly string[]): void;
12
- /** Observe one assistant message: announces each stream drop it reports (`streamDropsOf`). */
34
+ /** Announce `item` unless this run already said its cause. */
35
+ announce(item: ToolTurnIncompleteItem): void;
36
+ /** Observe one assistant message: announces each stream drop it reports (`streamDropsOf`), worded by what became of the turn. */
13
37
  observe(message: {
14
38
  readonly diagnostics?: unknown;
15
39
  }): void;
@@ -1,6 +1,8 @@
1
1
  import { deliverEngineNotice } from "../engine-notice.js";
2
2
  import { isProviderEchoShape } from "../../brain/errors.js";
3
3
  import { streamDropsOf } from "../../internal/llm.js";
4
+ import { readMember } from "../thrown-value.js";
5
+ import { modelOutputInvalidOfMessage } from "./terminal-account.js";
4
6
  const FORM_SENTENCE = {
5
7
  trailing_text: "a block after an assistant's tool calls was moved ahead of them",
6
8
  late_result: "a result recorded later was moved up behind its call",
@@ -9,30 +11,51 @@ const FORM_SENTENCE = {
9
11
  duplicate_call: "a second call with the same id in one assistant message was left out (its results answer the first)",
10
12
  orphan_result: "a result that answers no call before it was left out",
11
13
  };
14
+ const afterDroppedCalls = (outcome) => outcome === "reissued" ? "; the model was asked to re-issue them" : outcome === "terminal" ? "; the run ended with this turn (model_output_invalid)" : "";
12
15
  const INCOMPLETE_SENTENCE = {
13
- truncated: (n) => `${n} tool call(s) the model made were cut off before their arguments were complete, so they did not run; the model was asked to re-issue them`,
14
- unnamed: (n) => `${n} tool call(s) the model made arrived with no tool name, so they did not run; the model was asked to re-issue them`,
15
- bad_frame: (n) => `${n} frame(s) of the model's streamed response could not be read and were dropped, so the response may be missing content; the model was told`,
16
- missing_result_synthesized: (n) => `${n} earlier tool call(s) have no recorded result, so the model was told their outcome is unknown`,
16
+ truncated: (i) => `${i.count} tool call(s) the model made were cut off before their arguments were complete, so they did not run${afterDroppedCalls(i.outcome)}`,
17
+ unnamed: (i) => `${i.count} tool call(s) the model made arrived with no tool name, so they did not run${afterDroppedCalls(i.outcome)}`,
18
+ bad_frame: (i) => `${i.count} frame(s) of the model's streamed response could not be read and were dropped, so the response may be missing content; the model was told`,
19
+ missing_result_synthesized: (i) => `${i.count} earlier tool call(s) have no recorded result, so the model was told their outcome is unknown`,
17
20
  };
21
+ export function turnCarriesToolCall(content) {
22
+ try {
23
+ return Array.isArray(content) && content.some((c) => c?.type === "toolCall");
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ function outcomeOf(message) {
30
+ const stop = readMember(message, "stopReason");
31
+ if (stop === "error")
32
+ return modelOutputInvalidOfMessage(message) !== undefined ? "terminal" : undefined;
33
+ if (stop === "aborted")
34
+ return undefined;
35
+ return turnCarriesToolCall(readMember(message, "content")) || stop === "toolUse" || stop === "length" ? "reissued" : undefined;
36
+ }
18
37
  export function createToolTurnIncompleteSeat(onNotice, ids) {
19
38
  const announced = new Set();
20
- const announce = (cause, count, toolCallIds) => {
21
- if (announced.has(cause))
39
+ const announce = (item) => {
40
+ if (announced.has(item.cause))
22
41
  return;
23
- announced.add(cause);
24
- const shown = (toolCallIds ?? []).filter((id) => isProviderEchoShape(id));
42
+ announced.add(item.cause);
43
+ const shown = "toolCallIds" in item ? item.toolCallIds.filter((id) => isProviderEchoShape(id)) : [];
25
44
  deliverEngineNotice(onNotice, {
26
45
  code: "task.tool_turn_incomplete",
27
- message: `${INCOMPLETE_SENTENCE[cause](count)}. Announced once per run for this cause.`,
28
- detail: { cause, count, ...(shown.length > 0 ? { toolCallIds: shown } : {}), sessionId: ids.sessionId, runId: ids.runId },
46
+ message: `${INCOMPLETE_SENTENCE[item.cause](item)}. Announced once per run for this cause.`,
47
+ detail: { cause: item.cause, count: item.count, ...("outcome" in item && item.outcome !== undefined ? { outcome: item.outcome } : {}), ...(shown.length > 0 ? { toolCallIds: shown } : {}), sessionId: ids.sessionId, runId: ids.runId },
29
48
  });
30
49
  };
31
50
  return {
32
51
  announce,
33
52
  observe(message) {
34
- for (const drop of streamDropsOf(message))
35
- announce(drop.cause, drop.count);
53
+ const drops = streamDropsOf(message);
54
+ if (drops.length === 0)
55
+ return;
56
+ const outcome = outcomeOf(message);
57
+ for (const drop of drops)
58
+ announce(drop.cause === "bad_frame" ? { cause: "bad_frame", count: drop.count } : { cause: drop.cause, count: drop.count, outcome });
36
59
  },
37
60
  };
38
61
  }
@@ -42,7 +65,7 @@ export function createToolTurnRepairSeat(onNotice, ids) {
42
65
  return (repairs) => {
43
66
  const missing = repairs.filter((repair) => repair.form === "missing_result" && repair.beforeRun !== true).flatMap((repair) => repair.toolCallIds);
44
67
  if (missing.length > 0)
45
- incomplete.announce("missing_result_synthesized", missing.length, missing);
68
+ incomplete.announce({ cause: "missing_result_synthesized", count: missing.length, toolCallIds: missing });
46
69
  const fresh = repairs.filter((repair) => {
47
70
  const key = `${repair.form}\u0000${[...repair.toolCallIds].sort().join("\u0000")}`;
48
71
  if (announced.has(key))
@@ -983,7 +983,7 @@ export declare const MCP_INSTRUCTIONS_MAX_CHARS: number;
983
983
  * re-derived here. The earlier shape did re-derive it — a local `sanitizeUntrustedText` pre-pass with
984
984
  * the DEFAULT (reminder-only) tag set, measured against the cap — and that mirror silently stopped
985
985
  * matching once the fence widened its neutralization to the whole authority-envelope family: each
986
- * widened-family tag occurrence adds a ZWSP the pre-count never saw, so a server could land its text
986
+ * widened-family tag occurrence adds an entity the pre-count never saw, so a server could land its text
987
987
  * in the `(cap − N, cap]` window and get the body clipped with the honesty note withheld, N being its
988
988
  * own choice of tag count. One measurement, taken where the cut happens, is the only shape that cannot
989
989
  * drift.
@@ -22,20 +22,32 @@
22
22
  */
23
23
  import type { ExecutionEnv } from "../../internal/harness.js";
24
24
  import type { RunnerDeps } from "../runner-deps.js";
25
+ import type { TaskSpec } from "../task-spec.js";
25
26
  import type { ToolRoster } from "../tool-roster.js";
27
+ import type { ToolPolicy } from "../tool-policy.js";
26
28
  import { type WriteProtectionMount } from "../write-protect.js";
27
29
  import type { ShellReadBoundary } from "../../tools/fs/shell-read-judge.js";
28
- /** The leg's mount plus the same judge over a bare ABSOLUTE target — what the shell station asks about each write target
29
- * a command names (`ShellReadBoundary.writeProtectionJudge`): `true` ⇔ a row covers it. */
30
- export interface LegWriteProtection extends WriteProtectionMount {
31
- readonly judgeTarget: NonNullable<ShellReadBoundary["writeProtectionJudge"]>;
30
+ /** The leg's write judgment, read by its two readers: the gate's tighten over the always-on table (`mount`, absent when that
31
+ * table is empty) and the shell station's ONE question about each write target a command names (`judgeWriteTarget`, over
32
+ * the table and the chain's guarded write rows together; absent when neither has a row). */
33
+ export interface LegWriteProtection {
34
+ readonly mount: WriteProtectionMount | undefined;
35
+ readonly judgeWriteTarget: ShellReadBoundary["writeTargetJudge"];
36
+ }
37
+ /** The leg's write-guard seats: its one exempt root (the leg's single resolution of `RunnerDeps.memoryEngineDir`, the same
38
+ * list every policy adjudication of the leg is stamped with) and the chain policies' guarded write rows. */
39
+ export interface LegWriteGuard {
40
+ readonly exemptRoots: readonly string[];
41
+ readonly rows: ToolPolicy["writeGuardRows"];
32
42
  }
33
43
  export declare function mountWriteProtection(input: {
34
44
  /** borrowed-readonly — the deployment seats: the table (`writeProtectedPaths`; absent ⇒ the default
35
- * table, `[]` ⇒ opted out), the data root the memory library is materialized under
36
- * (`memoryEngineDir`; absent ⇒ the resolver's env/default chain), the configuration root the host
37
- * declared (`agentConfigDir`) and the operator sink. */
38
- deps: Pick<RunnerDeps, "writeProtectedPaths" | "memoryEngineDir" | "agentConfigDir" | "onNotice">;
45
+ * table, `[]` ⇒ opted out), the configuration root the host declared (`agentConfigDir`) and the operator sink. */
46
+ deps: Pick<RunnerDeps, "writeProtectedPaths" | "agentConfigDir" | "onNotice">;
47
+ /** borrowed-readonly — the leg's one exempt root and the chain's guarded write rows ({@link LegWriteGuard}). */
48
+ guard: LegWriteGuard;
49
+ /** borrowed-readonly — the request's own rows (already judged at the task layer's door). */
50
+ spec: Pick<TaskSpec, "writeProtectedAdditions">;
39
51
  /** The HANDS' environment, or `undefined` with no hands — the driver's own predicate, not a second
40
52
  * reading of the env seats, so the judge sees exactly the environment the write tools do. */
41
53
  env: ExecutionEnv | undefined;
@@ -45,4 +57,4 @@ export declare function mountWriteProtection(input: {
45
57
  roster: ToolRoster;
46
58
  sessionId: string;
47
59
  runId: string;
48
- }): LegWriteProtection | undefined;
60
+ }): LegWriteProtection;
@@ -1,11 +1,13 @@
1
1
  import { deliverEngineNotice } from "../engine-notice.js";
2
+ import { unionAddOnly } from "../child-clamp-seats.js";
2
3
  import { protectivePathTargetOf } from "../tool-registry.js";
3
- import { compileWriteProtection, writeProtectionMountOver } from "../write-protect.js";
4
+ import { compileLegWriteJudgment, resolveWriteProtectedTable, writeProtectionMountOver } from "../write-protect.js";
4
5
  const ABSENCE_REASON = { symlink: "unresolved-symlink", target: "unresolvable-target" };
5
6
  export function mountWriteProtection(input) {
6
7
  const announced = new Set();
7
- const matcher = compileWriteProtection(input.deps.writeProtectedPaths, {
8
- ...(input.deps.memoryEngineDir !== undefined ? { dataRoot: input.deps.memoryEngineDir } : {}),
8
+ const judgment = compileLegWriteJudgment(unionAddOnly("writeProtectedAdditions", resolveWriteProtectedTable(input.deps.writeProtectedPaths), input.spec.writeProtectedAdditions), {
9
+ exemptRoots: input.guard.exemptRoots,
10
+ ...(input.guard.rows !== undefined ? { guardRows: input.guard.rows } : {}),
9
11
  ...(input.deps.agentConfigDir !== undefined ? { agentConfigDir: input.deps.agentConfigDir } : {}),
10
12
  ...(input.env !== undefined ? { env: input.env } : {}),
11
13
  rootPath: input.rootPath,
@@ -15,22 +17,23 @@ export function mountWriteProtection(input) {
15
17
  return;
16
18
  announced.add(reason);
17
19
  deliverEngineNotice(input.deps.onNotice, {
18
- code: "config.write_protection_unresolved",
19
- message: `This run's write-protection judge could not resolve a write target in its execution environment ` +
20
- `(${reason === ABSENCE_REASON.symlink ? "a symlink whose real target is unknowable" : "the environment refused or errored on the spelling"}: ${absence.cause}). ` +
21
- `A view that cannot answer does not vote, so that write was judged by its SPELLING against the table and nothing else — ` +
22
- `a target reaching a protected path only through an alias, a bind mount or a ".." walk is cleared. Nothing about this run was ` +
23
- `refused because of it, and nothing here is a defect in the write itself: an environment that cannot answer path questions is a ` +
24
- `deployment fact. Announced once per leg per reason; later writes of the same shape are judged the same way, silently.`,
20
+ code: "config.path_view_unresolved",
21
+ message: `This run's write-protection judge did not get an answer from its execution environment for one lookup of a write's judgment ` +
22
+ `(${reason === ABSENCE_REASON.symlink ? "a symlink whose real target is unknowable" : "the environment refused, errored or did not answer in time"}: ${absence.cause}). ` +
23
+ `A write whose target's real destination (or link chain) could not be determined is refused where the table has rows — the ` +
24
+ `table cannot say it is not a protected path; a root whose key did not come back exempts and places nothing; guarded write rows ` +
25
+ `a deployment's policy did not return are held, so the writes they could guard are not placed. Every row a source that did ` +
26
+ `answer met stays met. An environment that cannot answer path questions is a deployment fact: fix the environment (or the ` +
27
+ `link) and the same writes are judged again. Announced once per leg per reason; later writes of the same shape are judged ` +
28
+ `the same way, silently.`,
25
29
  detail: { reason, cause: absence.cause, sessionId: input.sessionId, runId: input.runId },
26
30
  });
27
31
  },
28
32
  });
29
- if (matcher === undefined)
30
- return undefined;
31
- const mount = { ...writeProtectionMountOver(matcher, input.rootPath), judgeTarget: async (target, opts) => (await matcher.judge(target, { ...(opts?.signal !== undefined ? { signal: opts.signal } : {}), ...(opts?.canonical === true ? { canonical: true } : {}) })).kind === "hit" };
32
- if (mount.targetView !== "spelling-only")
33
- return mount;
33
+ const matcher = judgment.matcher;
34
+ const leg = { mount: matcher === undefined ? undefined : writeProtectionMountOver(matcher, input.rootPath), judgeWriteTarget: judgment.judgeWriteTarget };
35
+ if (leg.mount === undefined || leg.mount.targetView !== "spelling-only")
36
+ return leg;
34
37
  const covered = input.roster.entries
35
38
  .filter((e) => [e.name, ...e.aliases].some((name) => {
36
39
  const target = protectivePathTargetOf({ toolName: name, args: {}, face: e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {} });
@@ -39,7 +42,7 @@ export function mountWriteProtection(input) {
39
42
  .map((e) => e.name)
40
43
  .sort();
41
44
  if (covered.length === 0)
42
- return mount;
45
+ return leg;
43
46
  deliverEngineNotice(input.deps.onNotice, {
44
47
  code: "config.write_protection_target_view_absent",
45
48
  message: `This run mounted path-confinable write tools [${covered.join(", ")}] while its write-protection judge has NO execution environment, ` +
@@ -50,5 +53,5 @@ export function mountWriteProtection(input) {
50
53
  `writeProtection.targetView.`,
51
54
  detail: { tools: covered, sessionId: input.sessionId, runId: input.runId },
52
55
  });
53
- return mount;
56
+ return leg;
54
57
  }
@@ -249,8 +249,9 @@ export interface RunnerDeps {
249
249
  * approval flows the ordinary ask-resolution chain — classifier, blanket `onAsk`, durable park —
250
250
  * with no `requiresRealApproval` mandate). Absent =
251
251
  * {@link import("./write-protect.js").WRITE_PROTECTED_DEFAULT_TABLE} (the CC triple verbatim +
252
- * the two argued sema rows). This key IS the whole-table escape hatch, deployment seat ONLY (no
253
- * TaskSpec twin, no governed-workflow channel): `[]` = no table (explicit and legal); a non-empty
252
+ * the two argued sema rows). This key IS the whole-table escape hatch, deployment seat ONLY — the
253
+ * task layer's twin is add-only ({@link TaskSpec.writeProtectedAdditions}: its rows UNION this
254
+ * table and can remove none), and no governed-workflow channel reaches either: `[]` = no table (explicit and legal); a non-empty
254
255
  * list REPLACES the built-in table whole (compose additions as
255
256
  * `[...WRITE_PROTECTED_DEFAULT_TABLE, …]`; drop rows by filtering the exported table — the
256
257
  * visible/deletable admin face). Bad values refuse loudly at prepare (#123): garbage shapes,
@@ -355,14 +356,6 @@ export interface RunnerDeps {
355
356
  memoryCaptureRecordStore?: (plane: {
356
357
  controlDir: string;
357
358
  }) => import("./memory-engine/layout.js").SessionCaptureRecordStore;
358
- /** which occupant of a session id is running now (a purge may delete a session tree and the
359
- * id be handed out again; without this seat a standing opt-out or pollution record binds the NEXT
360
- * occupant too). An opaque token, STABLE for one occupant's life, DIFFERENT for the next, only
361
- * ever compared ({@link import("./memory-engine/layout.js").sessionRecordBindsIncarnation}).
362
- * ABSENT ⇒ records bind by id (the pre-incarnation bytes); an empty or throwing answer reads the same. */
363
- memorySessionIncarnation?: (session: {
364
- sessionId: string;
365
- }) => string | undefined;
366
359
  /**
367
360
  * design/339 §6.1 — the v3 memory-consolidation switch, threaded verbatim to the engine seat
368
361
  * ({@link import("../core/memory-engine/engine.js").MemoryEngineOptions.consolidation} — same
@@ -689,7 +682,8 @@ export interface RunnerDeps {
689
682
  * denied capability that the spec explicitly requests refuses the prepare loudly
690
683
  * (`config.compliance_denied`, or `config.compliance_required` when the refusal came from the
691
684
  * resolver fault rather than an adjudicated posture). `undefined` (no resolver / no posture for
692
- * the principal) = no compliance restriction — existing deployments are untouched.
685
+ * the principal) = no compliance restriction from the deployment — existing deployments are untouched. The run's deny
686
+ * set is this posture's UNION the request's own denies ({@link TaskSpec.complianceAdditionalDenies}, add-only).
693
687
  */
694
688
  compliancePostureResolver?: (principal: string | undefined) => import("./compliance.js").CompliancePosture | undefined | Promise<import("./compliance.js").CompliancePosture | undefined>;
695
689
  /**
@@ -1031,12 +1025,8 @@ export interface RunnerDeps {
1031
1025
  /** B5/F2 + design/140 §6 1a — the script-persistence / named-registry seam, threaded into the auto-mounted
1032
1026
  * run_workflow tool: every invocation's resolved script is persisted (iterate via `{scriptPath}`), `{name}`
1033
1027
  * resolves a saved workflow, and a registration's `defaultArgs` merge under the call-time args. Opt-in
1034
- * (absent ⇒ inline `script` + built-in names only). */
1028
+ * (absent ⇒ inline `script` only — the engine ships no built-in named workflows). */
1035
1029
  workflowScriptStore?: import("../orchestration/workflow-script-store.js").WorkflowScriptStore;
1036
- /** design/140 §6 1c — `false` removes the BUILT-IN named workflows (`discussion`, …) from the
1037
- * auto-mounted run_workflow tool (the `builtinAgents:false` analog; default ON). A deployment
1038
- * `workflowScriptStore` registration of the same name shadows a built-in regardless. */
1039
- builtinWorkflows?: boolean;
1040
1030
  /**
1041
1031
  * design/97 CORE-9 (Part B) — a TRUSTED deployment sink for the steerable handle of every agent an LLM-authored
1042
1032
  * (`run_workflow` tool) workflow spawns. When set, the tool's `agent()` primitive runs each agent STEERABLE and
@@ -1044,12 +1034,12 @@ export interface RunnerDeps {
1044
1034
  * the handle — no host-context leak into the runner); the deployment registers it by `runId`+`label` to route a
1045
1035
  * human/cross-replica steer to `handle.steer(...)`. Unset ⇒ agents run non-steerable (no overhead). Opt-in.
1046
1036
  *
1047
- * **Interaction with {@link workflowJournalStore}**: a steerable agent runs via
1048
- * `agentStream`, whose results ARE RECORDED in the journal since 1.355 (complete read-face: the journal
1049
- * API / diagnostics coordinate show every agent) but are NEVER REPLAYED — `resumeFromRunId` on a
1050
- * steerable workflow still re-runs agents LIVE (steer input is not deterministic; a cache would replay
1051
- * a result the operator steered). Pre-1.355 the stream lane recorded NOTHING — with both deps set the
1052
- * journal read empty on every workflow (the zero-write case), silently.
1037
+ * **Interaction with {@link workflowJournalStore}**: a steerable agent runs via `agentStream`, which reads the
1038
+ * resume journal exactly as the non-steerable lane does — recorded under the same call key, replayed by the same
1039
+ * unchanged-prefix rule. A completed agent a `resumeFromRunId` replays is emitted here as an already-settled
1040
+ * handle: `result()` resolves at once to the journaled result, `steer()` is refused `steering.not_running`.
1041
+ * A result the operator steered replays as what it was — the run's record of the work, like any model answer
1042
+ * that would come out differently if asked again.
1053
1043
  */
1054
1044
  onWorkflowAgentSpawn?: (handle: import("../orchestration/workflow.js").WorkflowAgentHandle) => void;
1055
1045
  /** design/72 §2.2 (B): deployment default for the suspend-loop cap (see `TaskSpec.maxSuspends`).
@@ -6,18 +6,25 @@
6
6
  * deleted whole, never rewritten; `"all"` and a `string[]` allow list are the caller's explicit alternatives
7
7
  * ({@link inheritedHostEnv}). One judgment per variable ({@link classifySecretEnvEntry}), the first rule that answers:
8
8
  * 1. exempt — git's environment config and the proxy variables, handed on as written ({@link isExemptEnvName});
9
- * 2. `exact-name` — a known credential name ({@link CREDENTIAL_ENV_NAMES});
9
+ * 2. `exact-name` — a known credential name (the vocabulary's exact env names);
10
10
  * 3. `prefix-rule` — the OpenTelemetry settings ({@link OTEL_ENV_RE});
11
11
  * 4. `namespace-rule` — a credential word as any segment of a name in the engine's own `SEMA_` namespace;
12
- * 5. `name-rule` — a credential-shaped name ({@link nameIsCredentialShaped}) off {@link NON_SECRET_ENV_EXACT_NAMES};
13
- * 6. `value-rule` — a value that carries a credential ({@link valueCarriesCredential}).
14
- * {@link isSecretEnvKey} and {@link scrubSecretEnv} both answer with this one judgment. The exempt families, the
12
+ * 5. `name-rule` — a credential-shaped name ({@link nameIsCredentialShaped}) off the vocabulary's non-secret exact names;
13
+ * 6. `value-rule` — a value that carries a credential ({@link looksLikeCredentialValue}).
14
+ * {@link isSecretEnvKey} and {@link scrubSecretEnv} both answer with this one judgment; rules 2–5 are its name half
15
+ * ({@link isSensitiveName}), rule 6 its value half, and rule 1 the env-entry exemption read before both. The exempt families, the
15
16
  * credential names, the name shape and the value predicate follow the reference implementation's subprocess-env scrub
16
17
  * as written, three ways stricter: plural `TOKENS` is a credential word unless a count word touches it, the GitHub
17
18
  * token names are not held back from the name shape, and the name shape always runs.
18
19
  */
19
- import type { RedactionConfidence, RedactionSource } from "./arg-summary.js";
20
+ import { type RedactionConfidence, type RedactionSource } from "./credential-vocabulary.js";
20
21
  import { type EngineNotice } from "./engine-notice.js";
22
+ /** Does a value carry a credential? A URL userinfo (after every `scheme://`, and a leading `//`) with a password or a
23
+ * token-like user; a scheme-less `user:password@host`; a credential assignment; a webhook URL; a Sonar login; a
24
+ * private-key header; an `Authorization` header, `token …`, `Bearer …` or `Basic …` with credential-shaped content.
25
+ * Reads the first {@link VALUE_SCAN_LIMIT} code units. The value half of the judgment, exported apart from the env
26
+ * entry's exemptions ({@link isExemptEnvName}): a caller holding a value that is no environment variable asks this. */
27
+ export declare function looksLikeCredentialValue(value: string): boolean;
21
28
  /** Which rule withheld an entry. */
22
29
  export type SecretEnvFindingKind = "exact-name" | "name-rule" | "namespace-rule" | "prefix-rule" | "value-rule";
23
30
  /** One env entry the `"scrub"` policy withheld (deleted): its name — never its value, so the record is loggable —, the
@@ -28,6 +35,10 @@ export interface SecretEnvFinding {
28
35
  confidence: RedactionConfidence;
29
36
  source: RedactionSource;
30
37
  }
38
+ /** Does `key` name a credential? The name half of the judgment ({@link sensitiveNameKind}), exported apart from the env
39
+ * entry's exemptions ({@link isExemptEnvName}): a caller holding a key that is no environment variable (a member of a
40
+ * record) asks this, and an exempt name is no exception there. */
41
+ export declare function isSensitiveName(key: string): boolean;
31
42
  /** Does the `"scrub"` policy withhold `key`? With `value`, exactly the answer {@link scrubSecretEnv} gives for that
32
43
  * entry; without it, the answer for its name alone (the value rule then has nothing to read). */
33
44
  export declare function isSecretEnvKey(key: string, value?: string): boolean;