@sema-agent/core 7.55.0 → 7.57.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 (502) hide show
  1. package/CHANGELOG.md +1054 -0
  2. package/LICENSE +1 -1
  3. package/dist/agents/cascade.js +1 -1
  4. package/dist/agents/cc-peer-directory.js +1 -0
  5. package/dist/agents/child-model-seat.d.ts +0 -11
  6. package/dist/agents/child-model-seat.js +0 -3
  7. package/dist/agents/list-agents-tool.d.ts +3 -1
  8. package/dist/agents/list-agents-tool.js +7 -7
  9. package/dist/agents/org-delivery-gate.js +3 -4
  10. package/dist/agents/peer-directory.d.ts +22 -4
  11. package/dist/agents/peer-directory.js +24 -2
  12. package/dist/agents/peer-held-queue.d.ts +69 -49
  13. package/dist/agents/peer-held-queue.js +255 -106
  14. package/dist/agents/peer-session-drain.js +65 -45
  15. package/dist/agents/repair-loop.js +2 -2
  16. package/dist/agents/send-message-tool.js +7 -6
  17. package/dist/agents/subagent.d.ts +6 -4
  18. package/dist/agents/subagent.js +72 -68
  19. package/dist/agents/tool-filter.d.ts +7 -5
  20. package/dist/agents/tool-filter.js +12 -9
  21. package/dist/agents/verify.d.ts +3 -2
  22. package/dist/agents/verify.js +3 -3
  23. package/dist/brain/anthropic.js +45 -80
  24. package/dist/brain/media-degrade.d.ts +18 -7
  25. package/dist/brain/media-degrade.js +13 -2
  26. package/dist/brain/model-capability.d.ts +37 -0
  27. package/dist/brain/model-capability.js +34 -0
  28. package/dist/brain/model-presets.d.ts +2 -8
  29. package/dist/brain/model-presets.js +1 -6
  30. package/dist/brain/open-responses.js +23 -34
  31. package/dist/brain/openai.js +25 -96
  32. package/dist/brain/provider-dialect.d.ts +3 -2
  33. package/dist/brain/provider-dialect.js +2 -2
  34. package/dist/brain/reasoning-request.d.ts +96 -0
  35. package/dist/brain/reasoning-request.js +174 -0
  36. package/dist/brain/reasoning.d.ts +11 -11
  37. package/dist/brain/reasoning.js +4 -3
  38. package/dist/brain/request-params.d.ts +13 -4
  39. package/dist/brain/request-params.js +21 -5
  40. package/dist/brain/status-sink.d.ts +20 -0
  41. package/dist/brain/status-sink.js +7 -0
  42. package/dist/brain/stream-engine.d.ts +9 -0
  43. package/dist/brain/stream-engine.js +24 -10
  44. package/dist/brain/stream-shared.d.ts +5 -4
  45. package/dist/brain/stream-shared.js +4 -4
  46. package/dist/core/a2a.d.ts +2 -1
  47. package/dist/core/a2a.js +19 -13
  48. package/dist/core/agent-definition.d.ts +10 -0
  49. package/dist/core/allow-entry.d.ts +23 -23
  50. package/dist/core/allow-entry.js +42 -46
  51. package/dist/core/allow-rule-shadow.d.ts +3 -3
  52. package/dist/core/approval-object.d.ts +21 -5
  53. package/dist/core/approval-object.js +44 -17
  54. package/dist/core/ask-origin.d.ts +66 -20
  55. package/dist/core/ask-origin.js +63 -23
  56. package/dist/core/ask-question.d.ts +51 -8
  57. package/dist/core/ask-question.js +3 -4
  58. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  59. package/dist/core/ask-unresolvable-notice.js +16 -2
  60. package/dist/core/auto-compaction.d.ts +71 -6
  61. package/dist/core/auto-compaction.js +42 -26
  62. package/dist/core/background-agent-store.d.ts +6 -2
  63. package/dist/core/background-agent-store.js +1 -1
  64. package/dist/core/checkpoint-generation.d.ts +53 -0
  65. package/dist/core/checkpoint-generation.js +35 -0
  66. package/dist/core/checkpoint-queries.d.ts +180 -0
  67. package/dist/core/checkpoint-queries.js +272 -0
  68. package/dist/core/checkpoint-requirements.d.ts +19 -1
  69. package/dist/core/checkpoint-requirements.js +6 -0
  70. package/dist/core/checkpoint-store.d.ts +105 -53
  71. package/dist/core/checkpoint-store.js +43 -20
  72. package/dist/core/cross-boundary-taint.d.ts +6 -5
  73. package/dist/core/cross-boundary-taint.js +5 -5
  74. package/dist/core/decision-receipt.d.ts +37 -3
  75. package/dist/core/decision-receipt.js +17 -17
  76. package/dist/core/delegation-not-started.d.ts +6 -0
  77. package/dist/core/delegation-not-started.js +17 -0
  78. package/dist/core/engine-attestation.d.ts +93 -0
  79. package/dist/core/engine-attestation.js +70 -0
  80. package/dist/core/engine-capabilities.d.ts +4 -1
  81. package/dist/core/engine-capabilities.js +1 -1
  82. package/dist/core/engine-notice.d.ts +32 -12
  83. package/dist/core/engine-notice.js +6 -0
  84. package/dist/core/file-history-store.d.ts +104 -22
  85. package/dist/core/file-history-store.js +37 -19
  86. package/dist/core/gate-fold.d.ts +1 -1
  87. package/dist/core/gate-fold.js +22 -10
  88. package/dist/core/gate-lanes.js +73 -65
  89. package/dist/core/gate-outcome.d.ts +26 -5
  90. package/dist/core/gate-outcome.js +26 -0
  91. package/dist/core/governance-codes.d.ts +5 -1
  92. package/dist/core/governance-codes.js +6 -0
  93. package/dist/core/hooks.d.ts +19 -18
  94. package/dist/core/hooks.js +3 -1
  95. package/dist/core/host-floor.d.ts +128 -0
  96. package/dist/core/host-floor.js +206 -0
  97. package/dist/core/host-target.d.ts +38 -3
  98. package/dist/core/host-target.js +38 -5
  99. package/dist/core/mailbox-store.d.ts +62 -1
  100. package/dist/core/mailbox-store.js +59 -0
  101. package/dist/core/mcp-name-judge.d.ts +46 -0
  102. package/dist/core/mcp-name-judge.js +61 -0
  103. package/dist/core/mcp-probe.d.ts +1 -1
  104. package/dist/core/mcp-probe.js +2 -5
  105. package/dist/core/mcp.d.ts +5 -1
  106. package/dist/core/mcp.js +70 -64
  107. package/dist/core/memory-engine/consolidation-driver.js +4 -3
  108. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  109. package/dist/core/memory-engine/distiller.js +26 -17
  110. package/dist/core/memory-engine/engine.js +4 -4
  111. package/dist/core/memory-engine/layout.d.ts +60 -8
  112. package/dist/core/memory-engine/layout.js +70 -8
  113. package/dist/core/model-seat.d.ts +10 -3
  114. package/dist/core/mods/classic-events.d.ts +67 -0
  115. package/dist/core/mods/classic-events.js +1 -0
  116. package/dist/core/mods/dollar.d.ts +13 -0
  117. package/dist/core/mods/extension-call.d.ts +31 -0
  118. package/dist/core/mods/extension-call.js +43 -0
  119. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  120. package/dist/core/mods/kernel/dispatch.js +140 -69
  121. package/dist/core/mods/kernel/events.d.ts +47 -11
  122. package/dist/core/mods/kernel/events.js +66 -42
  123. package/dist/core/mods/kernel/index.d.ts +4 -4
  124. package/dist/core/mods/kernel/index.js +2 -2
  125. package/dist/core/mods/kernel/receive.d.ts +39 -5
  126. package/dist/core/mods/kernel/receive.js +290 -17
  127. package/dist/core/mods/kernel/registration.d.ts +33 -2
  128. package/dist/core/mods/kernel/registration.js +6 -7
  129. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  130. package/dist/core/mods/kernel/site-rules.js +24 -42
  131. package/dist/core/mods/spec-seats.d.ts +69 -0
  132. package/dist/core/mods/spec-seats.js +114 -0
  133. package/dist/core/mods/stations.d.ts +28 -8
  134. package/dist/core/mods/stations.js +29 -13
  135. package/dist/core/mods/tool-call.d.ts +79 -0
  136. package/dist/core/mods/tool-call.js +152 -0
  137. package/dist/core/namespaced-rule-name.d.ts +32 -38
  138. package/dist/core/namespaced-rule-name.js +29 -36
  139. package/dist/core/parent-spec-seat.d.ts +6 -1
  140. package/dist/core/parent-spec-seat.js +2 -0
  141. package/dist/core/park-selfcheck.js +3 -0
  142. package/dist/core/permission-rule-consent.d.ts +24 -3
  143. package/dist/core/permission-rule-consent.js +136 -41
  144. package/dist/core/permission-rule-model.d.ts +57 -5
  145. package/dist/core/permission-rule-model.js +90 -31
  146. package/dist/core/permission-rule-org.d.ts +6 -2
  147. package/dist/core/permission-rule-org.js +8 -4
  148. package/dist/core/permission-rule-provider.d.ts +5 -2
  149. package/dist/core/permission-rule-provider.js +41 -11
  150. package/dist/core/permission-rule-store.d.ts +3 -2
  151. package/dist/core/permission-rule-store.js +11 -2
  152. package/dist/core/permission-rule-sync.js +3 -2
  153. package/dist/core/permission-rule-syntax.d.ts +5 -4
  154. package/dist/core/permission-rule-syntax.js +2 -2
  155. package/dist/core/permission-rules.d.ts +4 -4
  156. package/dist/core/permission-rules.js +11 -20
  157. package/dist/core/persisted-rule-arms.d.ts +2 -2
  158. package/dist/core/persisted-rule-arms.js +10 -12
  159. package/dist/core/principal-name.d.ts +20 -0
  160. package/dist/core/principal-name.js +22 -0
  161. package/dist/core/prompt-section-seat.js +4 -6
  162. package/dist/core/protocol-http-auth.d.ts +40 -5
  163. package/dist/core/protocol-http-auth.js +168 -4
  164. package/dist/core/protocol-naming.d.ts +20 -0
  165. package/dist/core/protocol-naming.js +20 -3
  166. package/dist/core/read-only-shell.d.ts +20 -5
  167. package/dist/core/read-only-shell.js +29 -14
  168. package/dist/core/remote-env.d.ts +37 -1
  169. package/dist/core/remote-env.js +11 -0
  170. package/dist/core/resume-startup-cause.d.ts +24 -2
  171. package/dist/core/resume-startup-cause.js +20 -1
  172. package/dist/core/retired-keys.d.ts +16 -0
  173. package/dist/core/retired-keys.js +16 -4
  174. package/dist/core/rewrite-rejudge.d.ts +60 -0
  175. package/dist/core/rewrite-rejudge.js +36 -0
  176. package/dist/core/roles.d.ts +28 -1
  177. package/dist/core/roles.js +81 -26
  178. package/dist/core/rule-lane-reads.d.ts +20 -15
  179. package/dist/core/rule-lane-reads.js +45 -17
  180. package/dist/core/rule-owner.d.ts +3 -3
  181. package/dist/core/rule-owner.js +3 -2
  182. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  183. package/dist/core/runner/announce-once-ledger.js +5 -0
  184. package/dist/core/runner/assemble-result.d.ts +1 -0
  185. package/dist/core/runner/assemble-result.js +1 -1
  186. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  187. package/dist/core/runner/caller-roster.d.ts +16 -4
  188. package/dist/core/runner/caller-roster.js +33 -6
  189. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  190. package/dist/core/runner/capability-withheld-seat.js +24 -0
  191. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  192. package/dist/core/runner/classifier-ladder.js +3 -3
  193. package/dist/core/runner/compact-session.d.ts +10 -0
  194. package/dist/core/runner/compact-session.js +202 -0
  195. package/dist/core/runner/compaction-call-options.d.ts +2 -2
  196. package/dist/core/runner/compaction-seams.d.ts +21 -1
  197. package/dist/core/runner/compaction-seams.js +11 -8
  198. package/dist/core/runner/construction-doors.js +3 -0
  199. package/dist/core/runner/contracts.d.ts +50 -40
  200. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  201. package/dist/core/runner/cross-boundary-lane.js +40 -27
  202. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  203. package/dist/core/runner/denial-limit-arms.js +1 -1
  204. package/dist/core/runner/derived-route-fallback.d.ts +13 -0
  205. package/dist/core/runner/derived-route-fallback.js +6 -0
  206. package/dist/core/runner/env-capability-census.d.ts +3 -2
  207. package/dist/core/runner/env-capability-census.js +9 -3
  208. package/dist/core/runner/file-history-request.d.ts +18 -0
  209. package/dist/core/runner/file-history-request.js +21 -13
  210. package/dist/core/runner/file-history-restore.d.ts +45 -0
  211. package/dist/core/runner/file-history-restore.js +46 -0
  212. package/dist/core/runner/gate-exit.d.ts +3 -3
  213. package/dist/core/runner/gate-exit.js +4 -3
  214. package/dist/core/runner/image.d.ts +7 -17
  215. package/dist/core/runner/image.js +9 -60
  216. package/dist/core/runner/permission-rule-lanes.d.ts +11 -11
  217. package/dist/core/runner/permission-rule-lanes.js +39 -17
  218. package/dist/core/runner/person-path-rows.d.ts +12 -9
  219. package/dist/core/runner/person-path-rows.js +18 -7
  220. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -0
  221. package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
  222. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  223. package/dist/core/runner/prepare-ask-lane.js +5 -2
  224. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  225. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  226. package/dist/core/runner/prepare-config-doors.d.ts +35 -38
  227. package/dist/core/runner/prepare-config-doors.js +46 -28
  228. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  229. package/dist/core/runner/prepare-defer-classify.js +7 -8
  230. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  231. package/dist/core/runner/prepare-file-history.js +7 -39
  232. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  233. package/dist/core/runner/prepare-gate-stations.js +10 -1
  234. package/dist/core/runner/prepare-hands-readface.d.ts +5 -9
  235. package/dist/core/runner/prepare-hands-readface.js +17 -14
  236. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  237. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  238. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  239. package/dist/core/runner/prepare-park-ask.d.ts +2 -0
  240. package/dist/core/runner/prepare-park-ask.js +7 -7
  241. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  242. package/dist/core/runner/prepare-policy-chain.js +67 -76
  243. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  244. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  245. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  246. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  247. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  248. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  249. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  250. package/dist/core/runner/prepare-safety-scan.js +0 -17
  251. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  252. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  253. package/dist/core/runner/prepare-task.d.ts +5 -2
  254. package/dist/core/runner/prepare-task.js +48 -43
  255. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
  256. package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
  257. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  258. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  259. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  260. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  261. package/dist/core/runner/resume-admission.js +1 -1
  262. package/dist/core/runner/resume-apply.js +11 -12
  263. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  264. package/dist/core/runner/resume-claim.d.ts +4 -2
  265. package/dist/core/runner/resume-claim.js +15 -8
  266. package/dist/core/runner/retired-runner-deps.js +1 -0
  267. package/dist/core/runner/rewind-files.d.ts +12 -0
  268. package/dist/core/runner/rewind-files.js +90 -0
  269. package/dist/core/runner/run-attachment-seats.js +2 -1
  270. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  271. package/dist/core/runner/run-brain-sinks.js +4 -2
  272. package/dist/core/runner/run-harness-handlers.js +12 -4
  273. package/dist/core/runner/run-leg.d.ts +1 -1
  274. package/dist/core/runner/run-leg.js +40 -39
  275. package/dist/core/runner/run-notification-lane.d.ts +2 -0
  276. package/dist/core/runner/run-notification-lane.js +2 -2
  277. package/dist/core/runner/run-recovery-lanes.js +3 -4
  278. package/dist/core/runner/run-settle-and-teardown.js +7 -12
  279. package/dist/core/runner/run-terminal-adoption.js +3 -4
  280. package/dist/core/runner/run-turn-boundary.js +4 -15
  281. package/dist/core/runner/runtask.d.ts +10 -0
  282. package/dist/core/runner/runtask.js +35 -42
  283. package/dist/core/runner/send-message-continuation.js +1 -1
  284. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  285. package/dist/core/runner/session-read-file-states.js +28 -0
  286. package/dist/core/runner/session-rule-policy.js +4 -3
  287. package/dist/core/runner/session-verb-doors.d.ts +28 -0
  288. package/dist/core/runner/session-verb-doors.js +48 -0
  289. package/dist/core/runner/session-write-ledger.d.ts +30 -0
  290. package/dist/core/runner/session-write-ledger.js +101 -0
  291. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  292. package/dist/core/runner/shell-env-withheld.js +51 -0
  293. package/dist/core/runner/skills-seat.js +6 -2
  294. package/dist/core/runner/stream-settle-backstop.js +12 -15
  295. package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
  296. package/dist/core/runner/sub-agent-deny-lists.js +25 -17
  297. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  298. package/dist/core/runner/synthetic-tools.js +4 -1
  299. package/dist/core/runner/teardown-bounded.d.ts +1 -0
  300. package/dist/core/runner/teardown-bounded.js +1 -0
  301. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  302. package/dist/core/runner/tool-disclosure.js +1 -3
  303. package/dist/core/runner/tool-end-body.d.ts +1 -1
  304. package/dist/core/runner/tool-end-body.js +10 -9
  305. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  306. package/dist/core/runner/tool-not-executed.js +11 -0
  307. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  308. package/dist/core/runner/tool-occurrence.js +7 -0
  309. package/dist/core/runner/turn-attachments.d.ts +33 -15
  310. package/dist/core/runner/turn-attachments.js +62 -37
  311. package/dist/core/runner-deps.d.ts +7 -7
  312. package/dist/core/safety-axis-vocab.d.ts +6 -4
  313. package/dist/core/safety-axis-vocab.js +6 -5
  314. package/dist/core/safety-merge-corpus.js +11 -3
  315. package/dist/core/secret-env.d.ts +30 -3
  316. package/dist/core/secret-env.js +47 -8
  317. package/dist/core/select-model.js +3 -3
  318. package/dist/core/session-policy-store.d.ts +32 -15
  319. package/dist/core/session-policy-store.js +156 -36
  320. package/dist/core/session-store.d.ts +29 -10
  321. package/dist/core/session-store.js +51 -19
  322. package/dist/core/session.d.ts +82 -16
  323. package/dist/core/session.js +53 -0
  324. package/dist/core/shell-read-silence.d.ts +11 -12
  325. package/dist/core/shell-read-silence.js +9 -5
  326. package/dist/core/shell-run-candidates.js +3 -1
  327. package/dist/core/shell-wrapper-projection.d.ts +1 -1
  328. package/dist/core/shell-wrapper-projection.js +1 -1
  329. package/dist/core/shell-wrapper-table.d.ts +14 -7
  330. package/dist/core/shell-wrapper-table.js +5 -4
  331. package/dist/core/side-query.js +10 -1
  332. package/dist/core/skill-grant.d.ts +7 -2
  333. package/dist/core/skill-grant.js +5 -0
  334. package/dist/core/skills-directory.js +6 -2
  335. package/dist/core/store-contracts/background-agent-store-contract.js +1 -0
  336. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  337. package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
  338. package/dist/core/store-contracts/file-history-store-contract.js +40 -1
  339. package/dist/core/store-contracts/mailbox-store-contract.js +49 -1
  340. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  341. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  342. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  343. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  344. package/dist/core/store-contracts/session-store-contract.js +150 -14
  345. package/dist/core/stub-env.d.ts +2 -0
  346. package/dist/core/stub-env.js +1 -0
  347. package/dist/core/synthetic-read-verdict.js +3 -3
  348. package/dist/core/task-event.d.ts +32 -4
  349. package/dist/core/task-notification.d.ts +16 -12
  350. package/dist/core/task-registry-agent.d.ts +8 -4
  351. package/dist/core/task-registry-agent.js +14 -8
  352. package/dist/core/task-registry-shared.d.ts +35 -6
  353. package/dist/core/task-registry-shared.js +11 -0
  354. package/dist/core/task-registry.d.ts +10 -1
  355. package/dist/core/task-registry.js +12 -2
  356. package/dist/core/task-result.d.ts +18 -0
  357. package/dist/core/task-spec.d.ts +18 -13
  358. package/dist/core/tighten-task-spec.js +2 -1
  359. package/dist/core/tool-catalog-entries.d.ts +23 -0
  360. package/dist/core/tool-catalog-entries.js +14 -2
  361. package/dist/core/tool-check-reading.d.ts +11 -0
  362. package/dist/core/tool-check-reading.js +11 -6
  363. package/dist/core/tool-model-gate.d.ts +2 -2
  364. package/dist/core/tool-name-aliases.d.ts +48 -18
  365. package/dist/core/tool-name-aliases.js +36 -19
  366. package/dist/core/tool-name-readings.d.ts +6 -32
  367. package/dist/core/tool-name-readings.js +2 -9
  368. package/dist/core/tool-policy.d.ts +78 -204
  369. package/dist/core/tool-policy.js +152 -204
  370. package/dist/core/tool-result-store.js +3 -0
  371. package/dist/core/tool-roster.d.ts +14 -19
  372. package/dist/core/tool-roster.js +11 -44
  373. package/dist/core/tool-spec-members.js +7 -2
  374. package/dist/core/tool-spec.d.ts +19 -11
  375. package/dist/core/tools.js +49 -9
  376. package/dist/core/trace.d.ts +6 -3
  377. package/dist/core/trace.js +2 -1
  378. package/dist/core/types.d.ts +1 -1
  379. package/dist/core/untrusted-egress.d.ts +20 -0
  380. package/dist/core/untrusted-egress.js +77 -3
  381. package/dist/core/user-attachment.d.ts +8 -1
  382. package/dist/core/user-attachment.js +64 -4
  383. package/dist/core/wiring-manifest.d.ts +9 -0
  384. package/dist/core/wiring-manifest.js +1 -0
  385. package/dist/core/workflow-journal-store.js +1 -1
  386. package/dist/engine/compaction/compaction.js +3 -2
  387. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  388. package/dist/engine/execution-env/node-execution-env.js +11 -2
  389. package/dist/engine/harness/agent-harness.d.ts +32 -6
  390. package/dist/engine/harness/agent-harness.js +65 -9
  391. package/dist/engine/harness/types.d.ts +29 -2
  392. package/dist/engine/llm/types.d.ts +28 -11
  393. package/dist/engine/loop/agent-loop.d.ts +23 -4
  394. package/dist/engine/loop/agent-loop.js +42 -30
  395. package/dist/engine/loop/types.d.ts +16 -6
  396. package/dist/engine/session/memory-repo.d.ts +9 -2
  397. package/dist/engine/session/memory-repo.js +11 -1
  398. package/dist/engine/session/repo-utils.d.ts +6 -5
  399. package/dist/engine/session/repo-utils.js +14 -6
  400. package/dist/index.d.ts +34 -17
  401. package/dist/index.js +22 -11
  402. package/dist/internal/harness-types.d.ts +1 -1
  403. package/dist/internal/harness.d.ts +2 -1
  404. package/dist/internal/harness.js +1 -0
  405. package/dist/internal/llm.d.ts +1 -1
  406. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  407. package/dist/orchestration/run-workflow-tool.js +5 -3
  408. package/dist/orchestration/workflow.d.ts +3 -0
  409. package/dist/orchestration/workflow.js +36 -18
  410. package/dist/primitives/credential-ref.d.ts +89 -0
  411. package/dist/primitives/credential-ref.js +125 -0
  412. package/dist/primitives/index.d.ts +2 -0
  413. package/dist/primitives/index.js +1 -0
  414. package/dist/prompt-assembly/artifact.d.ts +2 -2
  415. package/dist/prompt-assembly/artifact.js +5 -3
  416. package/dist/prompt-assembly/assemble.d.ts +3 -2
  417. package/dist/prompt-assembly/assemble.js +1 -1
  418. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  419. package/dist/prompt-assembly/catalog/schema.js +34 -2
  420. package/dist/prompt-assembly/catalog/sections.js +0 -1
  421. package/dist/prompt-assembly/composer.d.ts +3 -1
  422. package/dist/prompt-assembly/composer.js +1 -1
  423. package/dist/prompt-assembly/event-registry.js +1 -0
  424. package/dist/prompt-assembly/overlay.js +3 -3
  425. package/dist/prompt-assembly/renderers.d.ts +1 -1
  426. package/dist/prompt-assembly/renderers.js +0 -3
  427. package/dist/prompt-assembly/role-base.d.ts +15 -0
  428. package/dist/prompt-assembly/role-base.js +9 -0
  429. package/dist/prompt-assembly/select.d.ts +39 -14
  430. package/dist/prompt-assembly/select.js +47 -16
  431. package/dist/prompt-assembly/sugar.d.ts +17 -11
  432. package/dist/prompt-assembly/sugar.js +8 -3
  433. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  434. package/dist/prompt-assembly/tool-catalog.js +114 -4
  435. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  436. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  437. package/dist/prompt-assembly/types.d.ts +0 -7
  438. package/dist/scenarios/full-body.d.ts +11 -11
  439. package/dist/scenarios/full-body.js +4 -3
  440. package/dist/shell/lex.js +10 -1
  441. package/dist/stores/file/adoption/adopt.js +4 -3
  442. package/dist/stores/file/adoption/marker.js +3 -2
  443. package/dist/stores/file/checkpoint-store.d.ts +21 -4
  444. package/dist/stores/file/checkpoint-store.js +38 -7
  445. package/dist/stores/file/file-history-store.js +18 -11
  446. package/dist/stores/file/index.js +2 -1
  447. package/dist/stores/file/mailbox-store.d.ts +2 -1
  448. package/dist/stores/file/mailbox-store.js +26 -1
  449. package/dist/stores/file/permission-rule-adopt.js +4 -3
  450. package/dist/stores/file/permission-rule-store.js +11 -5
  451. package/dist/stores/file/session-store.d.ts +29 -6
  452. package/dist/stores/file/session-store.js +42 -50
  453. package/dist/tools/artifact/artifact-tool.js +3 -2
  454. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  455. package/dist/tools/fs/bash-program-position.js +56 -9
  456. package/dist/tools/fs/bash-readonly-classifier.d.ts +15 -19
  457. package/dist/tools/fs/bash-readonly-classifier.js +5 -10
  458. package/dist/tools/fs/fs-bash.js +15 -8
  459. package/dist/tools/fs/fs-glob.d.ts +86 -0
  460. package/dist/tools/fs/fs-glob.js +226 -0
  461. package/dist/tools/fs/fs-read.js +14 -14
  462. package/dist/tools/fs/fs-search-tools.js +7 -7
  463. package/dist/tools/fs/pattern-kill-guard.d.ts +23 -0
  464. package/dist/tools/fs/pattern-kill-guard.js +429 -0
  465. package/dist/tools/fs/pdf.d.ts +9 -6
  466. package/dist/tools/fs/pdf.js +3 -3
  467. package/dist/tools/fs/program-read-model.d.ts +57 -7
  468. package/dist/tools/fs/program-read-model.js +11 -1
  469. package/dist/tools/fs/program-read-model.rows.js +78 -21
  470. package/dist/tools/fs/read-deny-home.js +3 -2
  471. package/dist/tools/fs/removal-targets.d.ts +17 -7
  472. package/dist/tools/fs/removal-targets.js +47 -20
  473. package/dist/tools/fs/search.d.ts +10 -0
  474. package/dist/tools/fs/search.js +20 -26
  475. package/dist/tools/fs/shell-read-argv.js +89 -12
  476. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  477. package/dist/tools/fs/shell-read-bindings.js +41 -0
  478. package/dist/tools/fs/shell-read-check.d.ts +10 -0
  479. package/dist/tools/fs/shell-read-check.js +13 -20
  480. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  481. package/dist/tools/fs/shell-read-environment.js +3 -2
  482. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  483. package/dist/tools/fs/shell-read-establish.js +19 -20
  484. package/dist/tools/fs/shell-read-identity.d.ts +12 -9
  485. package/dist/tools/fs/shell-read-identity.js +9 -4
  486. package/dist/tools/fs/shell-read-plan.js +24 -16
  487. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  488. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  489. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  490. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  491. package/dist/tools/fs/shell-reentry-text.js +40 -2
  492. package/dist/tools/todo.js +63 -63
  493. package/dist/tools/web.d.ts +19 -14
  494. package/dist/tools/web.js +46 -61
  495. package/package.json +1 -1
  496. package/test/export-surface.snapshot.json +221 -7
  497. package/wire-changes/core-stores-sql@7.57.0.json +29 -0
  498. package/wire-changes/core@7.56.0.json +3891 -0
  499. package/wire-changes/core@7.57.0.json +1487 -0
  500. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  501. package/wire-changes/mods-kernel@7.57.0.json +29 -0
  502. package/wire-changes/primitives@7.57.0.json +245 -0
@@ -7,13 +7,13 @@ import { createRapidRefillState } from "../auto-compaction.js";
7
7
  import { boundInputHashOf } from "../canonical-json.js";
8
8
  import { emitTrace } from "../trace.js";
9
9
  import { emitTaskOutcome } from "../task-outcome.js";
10
- import { runWithReasoningWireFacts } from "../../brain/status-sink.js";
10
+ import { runWithCapabilityWithheld, runWithReasoningWireFacts } from "../../brain/status-sink.js";
11
11
  import { expandTiers } from "../roles.js";
12
12
  import { announceReadDenySwap, screenSwappableDeps } from "../swappable-deps.js";
13
13
  import { runSideQuery } from "../side-query.js";
14
14
  import { PushQueue } from "../push-queue.js";
15
15
  import { TtlSessionStore } from "../session-store.js";
16
- import { errorCodeOf } from "./terminal-account.js";
16
+ import { compensateUnstarted, unstartedRowSentence } from "../resume-startup-cause.js";
17
17
  import { effectiveDelegationFacts, prepareTask } from "./prepare-task.js";
18
18
  import { SessionReadFileStates } from "./session-read-file-states.js";
19
19
  import { SessionModeSeats } from "./session-mode-seats.js";
@@ -24,6 +24,8 @@ import { PendingSessionNotifications } from "../task-notification.js";
24
24
  import { ToolDetachHub } from "../tool-detach.js";
25
25
  import { assertContextSettingsValue, assertContextSettingsWords, contextOverlayFor } from "../context-settings.js";
26
26
  import { createRunState } from "./initial-run-state.js";
27
+ import { SessionWriteLedger } from "./session-write-ledger.js";
28
+ import { teardownLegBudget } from "./teardown-bounded.js";
27
29
  import { emitSettled, reconciledEnd } from "./tool-end-body.js";
28
30
  import { answerFaceForRedeemedCall } from "./decide-continuation.js";
29
31
  import { createTurnBoundary } from "./run-turn-boundary.js";
@@ -62,11 +64,15 @@ import { runStopAndFinalVerify } from "./run-stop-and-final-verify.js";
62
64
  import { runRecoveryLanes } from "./run-recovery-lanes.js";
63
65
  import { runGitLane } from "./run-git-lane.js";
64
66
  import { deploymentCanRerootChild } from "./child-tree.js";
65
- import { thrownText } from "../thrown-value.js";
67
+ import { rewindSessionFiles } from "./rewind-files.js";
68
+ import { compactIdleSession } from "./compact-session.js";
69
+ import { egressThrownText } from "../untrusted-egress.js";
66
70
  export class Runner {
67
71
  deps;
68
72
  sessions;
69
73
  sessionLocks = new Map();
74
+ sessionWrites = new SessionWriteLedger();
75
+ verbLockSeats = { sessionBusy: (id) => this.sessionLocks.has(id) || this.sessionWrites.busy(id), takeSessionLock: (id) => this.acquireSessionLock(id) };
70
76
  sessionReadStates = new SessionReadFileStates();
71
77
  sessionModeSeats = new SessionModeSeats();
72
78
  pendingSessionNotifications = new PendingSessionNotifications();
@@ -95,7 +101,7 @@ export class Runner {
95
101
  version: 1,
96
102
  sessionId: context.sessionId,
97
103
  phase: context.phase,
98
- reason: (thrownText(sinkErr)).slice(0, 256),
104
+ reason: egressThrownText("same-principal", sinkErr).slice(0, 256),
99
105
  ts: Date.now(),
100
106
  }));
101
107
  }
@@ -158,14 +164,14 @@ export class Runner {
158
164
  const chain = prev.then(() => mine);
159
165
  this.sessionLocks.set(sessionId, chain);
160
166
  await prev.catch(() => { });
161
- return () => {
167
+ const releaseHold = () => {
162
168
  release();
163
- void chain.then(() => {
164
- if (this.sessionLocks.get(sessionId) === chain) {
165
- this.sessionLocks.delete(sessionId);
166
- }
167
- });
169
+ if (this.sessionLocks.get(sessionId) === chain)
170
+ this.sessionLocks.delete(sessionId);
168
171
  };
172
+ if (this.sessionWrites.busy(sessionId))
173
+ await this.sessionWrites.settleBeforeHold(sessionId, teardownLegBudget()).catch((err) => { releaseHold(); throw err; });
174
+ return releaseHold;
169
175
  }
170
176
  swapDeps(next) {
171
177
  const screened = screenSwappableDeps(next);
@@ -233,8 +239,10 @@ export class Runner {
233
239
  announceReadDenySwap(this.deps.onNotice, seats, this.deps);
234
240
  }
235
241
  sideQuery(spec) {
236
- return runWithReasoningWireFacts(() => { }, () => runSideQuery(spec, { brain: this.deps.brain, models: this.deps.models, roles: this.deps.roles }));
242
+ return runWithReasoningWireFacts(() => { }, () => runWithCapabilityWithheld(() => { }, () => runSideQuery(spec, { brain: this.deps.brain, models: this.deps.models, roles: this.deps.roles })));
237
243
  }
244
+ rewindFiles(request) { return rewindSessionFiles({ deps: this.deps, sessions: this.sessions, readStates: this.sessionReadStates, ...this.verbLockSeats }, request); }
245
+ compactSession(request) { return compactIdleSession({ deps: this.deps, sessions: this.sessions, ...this.verbLockSeats }, request); }
238
246
  runTaskStream(spec, resume, internals) {
239
247
  if (resume !== undefined && (typeof resume !== "object" || resume.outcome === undefined)) {
240
248
  throw new TypeError("runTaskStream: `resume` must be a ResumeRun carrying `outcome` — got a value without one. " +
@@ -282,14 +290,16 @@ export class Runner {
282
290
  return held.taken;
283
291
  };
284
292
  const namedSessionId = spec.sessionId;
293
+ const legWrites = this.sessionWrites.openLeg((err, sessionId) => this.deps.onError?.(err, { phase: "degraded", sessionId }));
285
294
  const run = (async () => {
286
- if (namedSessionId)
287
- await holdSessionLock(namedSessionId);
288
295
  try {
296
+ if (namedSessionId)
297
+ await holdSessionLock(namedSessionId);
289
298
  await this.runLocked({
290
299
  spec,
291
300
  queue,
292
301
  holdSessionLock: namedSessionId ? undefined : holdSessionLock,
302
+ legWrites,
293
303
  setResult: (r) => {
294
304
  resultValue = r;
295
305
  const pcs = internals?.inheritedGate?.parentConstraints;
@@ -332,6 +342,7 @@ export class Runner {
332
342
  });
333
343
  }
334
344
  finally {
345
+ legWrites.close();
335
346
  releaseLock?.();
336
347
  publishReady(handle);
337
348
  manualCompactRef.closed = true;
@@ -383,9 +394,9 @@ export class Runner {
383
394
  };
384
395
  }
385
396
  runLocked(input) {
386
- const { spec, queue, setResult, onSuggestions, onReady, onSuspend, manualCompactRef, taskIdRef, holdSessionLock, resume, internals, notifyRef, captureOptOutRef, mcpRedialRef, entryActor, entryTracer } = input;
397
+ const { spec, queue, setResult, onSuggestions, onReady, onSuspend, manualCompactRef, taskIdRef, holdSessionLock, legWrites, resume, internals, notifyRef, captureOptOutRef, mcpRedialRef, entryActor, entryTracer } = input;
387
398
  return runNotificationLane({
388
- spec, queue, resume, internals, taskIdRef, holdSessionLock,
399
+ spec, queue, resume, internals, taskIdRef, holdSessionLock, legWrites,
389
400
  runner: this.depsSeat, self: this, sessions: this.sessions, sessionReadStates: this.sessionReadStates, sessionModeSeats: this.sessionModeSeats, pendingSessionNotifications: this.pendingSessionNotifications,
390
401
  prepareTask,
391
402
  next: ({ prepared, injectTaskNotification, deliveredAtTurnOpen, peerInboundChainRef, modelCatalog, notificationLane, unsubscribeTaskNotifications }) => {
@@ -403,7 +414,7 @@ export class Runner {
403
414
  const { effectiveTimeoutMs, walltimeMonotonicDeadline, timeout, pushContent, ownCommittedTailRef, emitCommitted } = runClockAndContent({ spec, prepared, queue, internals, rs, ident, parentToolCallId, startedToolCallIds });
404
415
  const toolProgress = createToolProgressLane(pushContent, ident, prepared.toolOccurrences);
405
416
  prepared.toolProgressRef.current = toolProgress;
406
- const { withBrainSinks, withLegRequestSinks } = runBrainSinks({ queue, internals, rs, ident, observeReasoningWireFacts, notice: { onNotice: this.deps.onNotice, sessionId: prepared.sessionId, runId: prepared.runId } });
417
+ const { withBrainSinks, withLegRequestSinks } = runBrainSinks({ queue, internals, rs, ident, observeReasoningWireFacts, notice: { onNotice: this.deps.onNotice, sessionId: prepared.sessionId, runId: prepared.runId }, announced: prepared });
407
418
  const toolLabels = new Map(prepared.tools.flatMap((t) => (t.label !== undefined && t.label !== t.name ? [[t.name, t.label]] : [])));
408
419
  for (const orphan of prepared.wakeRecovered) {
409
420
  emitSettled(prepared.toolOccurrences, { toolCallId: orphan.toolCallId, spelledName: orphan.toolName, ...(toolLabels.has(orphan.toolName) ? { label: toolLabels.get(orphan.toolName) } : {}), args: orphan.args }, reconciledEnd(orphan), { push: (f) => queue.push({ ...f, ...ident() }), structured: prepared.structuredProjector, mediaByteCapBytes: this.deps.mediaByteCapBytes });
@@ -502,7 +513,7 @@ export class Runner {
502
513
  token, cp, resumeSignal, recheckGovernanceWindow, store, runner: this.depsSeat,
503
514
  locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry, suspendedEnvReaps: this.suspendedEnvReaps,
504
515
  next: () => resumeClaim({
505
- token, cp, store, outcomeForStore,
516
+ token, cp, store, outcomeForStore, holder: internals?.holder,
506
517
  locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry,
507
518
  next: () => this.resumeHandoff({ token, cp, store, config, internals, resumeInternals, plainPolicyOutcome, redeemedAnswer, outcomeForStore, wakeMessage, wakeHookContext, legMods, resumeSignal }),
508
519
  }),
@@ -528,37 +539,19 @@ export class Runner {
528
539
  preemptSignal: config.preemptSignal?.aborted ? undefined : config.preemptSignal,
529
540
  ...(answerFace !== undefined ? { onQuestion: answerFace } : {}),
530
541
  };
531
- const reopenFn = store.reopen?.bind(store);
542
+ const reopenUnstarted = async (reason) => ((await store.reopen(token, cp.scope, reason)) ? "reopened" : "declined");
532
543
  const recordExecutionOutcome = (gate) => store.recordExecutionOutcome(token, cp.scope, gate);
533
- const onEnvRestoreFailed = reopenFn
534
- ? async (reason) => {
535
- const reopened = await reopenFn(token, cp.scope, reason);
536
- if (!reopened) {
537
- throw new CheckpointError("checkpoint.reopen_failed", "checkpoint could not be reopened for a retry (missing, expired, or changed concurrently) — the resume failure is terminal");
538
- }
539
- }
540
- : undefined;
541
544
  if (resumeSignal?.aborted === true && consumeFlipDone) {
542
545
  throw new CheckpointError("checkpoint.resume_aborted", "the resume was aborted after its row was already claimed — the checkpoint stays consumed and the caller's rollback settles the outcome-unknown terminal (reopening here would strand a pending approval no redemption path can reach)");
543
546
  }
544
547
  if (resumeSignal?.aborted === true) {
545
- let reopenOutcome = "refused";
546
- if (onEnvRestoreFailed !== undefined) {
547
- try {
548
- await onEnvRestoreFailed("env_failed");
549
- reopenOutcome = "reopened";
550
- }
551
- catch (err) {
552
- reopenOutcome = errorCodeOf(err) === "checkpoint.reopen_failed" ? "refused" : "unknown";
553
- }
554
- }
555
- throw reopenOutcome === "reopened"
556
- ? new CheckpointError("checkpoint.resume_aborted", "the resume was aborted before the approved action could run — the checkpoint was reopened, so the same approval can be resumed with a live signal")
557
- : reopenOutcome === "refused"
558
- ? new CheckpointError("checkpoint.reopen_failed", "the resume was aborted before the approved action could run AND the store refused to reopen the checkpoint — the approval is terminally consumed and the suspended work was not executed; a retry needs a fresh approval")
559
- : new CheckpointError("checkpoint.reopen_failed", "the resume was aborted before the approved action could run and the reopen attempt FAILED IN FLIGHT — the checkpoint's state is unprovable from here: it may already be pending again. Re-read it before deciding; do NOT issue a fresh approval on the assumption the old one is dead (the approved action did NOT run either way)");
548
+ const row = await compensateUnstarted(reopenUnstarted, "env_failed");
549
+ const said = `the resume was aborted before the approved action could run — ${unstartedRowSentence(row)}`;
550
+ if (row.kind === "reopened")
551
+ throw new CheckpointError("checkpoint.resume_aborted", said);
552
+ throw new CheckpointError("checkpoint.reopen_failed", said);
560
553
  }
561
- return this.runTaskStream(spec, { cp, outcome: outcomeForStore, onEnvRestoreFailed, recordExecutionOutcome, ...(wakeMessage !== undefined ? { wakeMessage } : {}), ...(wakeHookContext !== undefined ? { wakeMessageHookContext: wakeHookContext } : {}), ...(legMods !== undefined ? { legMods } : {}) }, resumeInternals);
554
+ return this.runTaskStream(spec, { cp, outcome: outcomeForStore, reopenUnstarted, recordExecutionOutcome, ...(wakeMessage !== undefined ? { wakeMessage } : {}), ...(wakeHookContext !== undefined ? { wakeMessageHookContext: wakeHookContext } : {}), ...(legMods !== undefined ? { legMods } : {}) }, resumeInternals);
562
555
  }
563
556
  }
564
557
  export function runTask(spec, deps) {
@@ -9,7 +9,7 @@ function buildTier3ReviveSpawn(delegationForRevive, enrichSpecToolCtx) {
9
9
  prompt: req.prompt,
10
10
  run_in_background: true,
11
11
  ...(req.row.agentType !== undefined ? { subagent_type: req.row.agentType } : {}),
12
- ...(req.row.name !== undefined ? { name: req.row.name } : {}),
12
+ name: req.row.name,
13
13
  ...(req.row.model !== undefined ? { model: req.row.model } : {}),
14
14
  }, enrichSpecToolCtx({ toolCallId: `rv-${randomBytes(8).toString("hex")}`, reviveClaim: { row: req.row, rev: req.rev, ...(req.peerSeed !== undefined ? { peerSeed: req.peerSeed } : {}) } }));
15
15
  const o = (typeof out === "string" ? { content: out } : out);
@@ -39,7 +39,22 @@ import type { ReadFileState } from "../../tools/fs/safety.js";
39
39
  */
40
40
  export declare class SessionReadFileStates {
41
41
  private readonly seats;
42
+ /**
43
+ * The ONE handoff of "which files did a file-history restore of this session move" to the read state that
44
+ * must stop vouching for their old bytes — written by every restore (the run's restore seat and the
45
+ * out-of-run `Runner.rewindFiles`), read by the next leg's read face, which checks each path against the disk
46
+ * after every seeding rung and settles the batch only once its own map is adopted as the seat. A leg that
47
+ * throws before adopting, or skips the adoption, leaves the batch for the next one. Bounded like the seats
48
+ * (LRU over session ids): a dropped batch costs a refusal whose wording blames an outside edit, never an admission.
49
+ */
50
+ private readonly restored;
42
51
  private static readonly CAP;
52
+ /** Record the ABSOLUTE paths a restore of `sessionId`'s history wrote, deleted or failed to write. */
53
+ noteRestored(sessionId: string, absPaths: readonly string[]): void;
54
+ /** The paths still owed a read-state check on `sessionId` — a copy; nothing is cleared by reading. */
55
+ pendingRestored(sessionId: string): readonly string[];
56
+ /** Clear exactly the paths a leg checked and then adopted over; a path noted since stays owed. */
57
+ settleRestored(sessionId: string, checked: readonly string[]): void;
43
58
  /** The session's seat row, or undefined (cross-process / evicted / first turn) ⇒ caller replays.
44
59
  * The caller must verify the anchor against the session's CURRENT branch before using `state`. */
45
60
  get(sessionId: string): {
@@ -1,6 +1,34 @@
1
1
  export class SessionReadFileStates {
2
2
  seats = new Map();
3
+ restored = new Map();
3
4
  static CAP = 1024;
5
+ noteRestored(sessionId, absPaths) {
6
+ if (absPaths.length === 0)
7
+ return;
8
+ const batch = this.restored.get(sessionId) ?? new Set();
9
+ for (const p of absPaths)
10
+ batch.add(p);
11
+ this.restored.delete(sessionId);
12
+ this.restored.set(sessionId, batch);
13
+ while (this.restored.size > SessionReadFileStates.CAP) {
14
+ const oldest = this.restored.keys().next().value;
15
+ if (oldest === undefined)
16
+ break;
17
+ this.restored.delete(oldest);
18
+ }
19
+ }
20
+ pendingRestored(sessionId) {
21
+ return [...(this.restored.get(sessionId) ?? [])];
22
+ }
23
+ settleRestored(sessionId, checked) {
24
+ const batch = this.restored.get(sessionId);
25
+ if (batch === undefined)
26
+ return;
27
+ for (const p of checked)
28
+ batch.delete(p);
29
+ if (batch.size === 0)
30
+ this.restored.delete(sessionId);
31
+ }
4
32
  get(sessionId) {
5
33
  const seat = this.seats.get(sessionId);
6
34
  if (seat !== undefined) {
@@ -1,5 +1,5 @@
1
1
  import { canonicalizeTarget, isWinFormPath, pathFamilyOf, writeTargetPath } from "../../tools/fs/safety.js";
2
- import { SESSION_RULES_GRAMMAR, compileSessionRuleBucket, continuesLineage, earlierGrammarAnnouncer, earlierGrammarRefusalClause, readSessionRulesShape, unreadableDenyEntries } from "../session-policy-store.js";
2
+ import { SESSION_RULES_GRAMMAR, compileSessionRuleBucket, continuesLineage, earlierGrammarAnnouncer, earlierGrammarEntries, earlierGrammarRefusalClause, readSessionRulesShape, unreadableDenyEntries } from "../session-policy-store.js";
3
3
  import { compiledEntryName, judgeAllowEntries, uncoveredCommandSegment } from "../allow-entry.js";
4
4
  import { inlineUntrusted } from "../untrusted-text.js";
5
5
  import { callTargetReadingOf, pathTargetBaseOf, readCallTarget } from "../effective-path-target.js";
@@ -95,7 +95,7 @@ function compileSessionRules(rules) {
95
95
  if ("fault" in shaped) {
96
96
  const { field, got } = shaped.fault;
97
97
  const what = got === "not a rule bucket" ? "a key that is no rule bucket" : field === "" ? `a value that is ${got}, not an object of rule buckets` : `${field} holding ${got}`;
98
- return { deny: [], allow: undefined, earlier: { grammar: SESSION_RULES_GRAMMAR, toolAllow: [], toolDeny: [] }, allowDirs: undefined, pathRows: false, names: { deny: [], allow: [] }, unreadable: refuseEvery(what) };
98
+ return { deny: [], allow: undefined, earlier: { grammar: SESSION_RULES_GRAMMAR, toolAllow: [], toolDeny: [] }, announced: { toolAllow: [], toolDeny: [] }, allowDirs: undefined, pathRows: false, names: { deny: [], allow: [] }, unreadable: refuseEvery(what) };
99
99
  }
100
100
  const { toolAllow, allowDirs, grammar } = shaped.rules;
101
101
  const unreadDeny = unreadableDenyEntries(shaped.rules).length;
@@ -109,6 +109,7 @@ function compileSessionRules(rules) {
109
109
  deny,
110
110
  allow,
111
111
  earlier: { grammar, toolAllow: named(allowList, true), toolDeny: named(denyList, true) },
112
+ announced: { toolAllow: earlierGrammarEntries(shaped.rules, "toolAllow"), toolDeny: earlierGrammarEntries(shaped.rules, "toolDeny") },
112
113
  allowDirs: allowDirs !== undefined && allowDirs.length > 0 ? allowDirs : undefined,
113
114
  pathRows: [...deny, ...(allow ?? [])].some((r) => r.compiled.kind === "path"),
114
115
  names: { deny: [...deny.map((r) => compiledEntryName(r.compiled)), ...named(denyList, false)], allow: [...(allow ?? []).map((r) => compiledEntryName(r.compiled)), ...named(allowList, false)] },
@@ -128,7 +129,7 @@ export function createSessionRulePolicy(rules, opts) {
128
129
  if (compiled === undefined || compiledFor !== r) {
129
130
  compiled = compileSessionRules(r);
130
131
  for (const field of ["toolAllow", "toolDeny"])
131
- announceEarlier(compiled.earlier[field], field, compiled.earlier.grammar);
132
+ announceEarlier(compiled.announced[field], field, compiled.earlier.grammar);
132
133
  compiledFor = r;
133
134
  }
134
135
  return compiled;
@@ -0,0 +1,28 @@
1
+ import type { AcquiredSession, SessionStore } from "../session.js";
2
+ /** What the Runner lends an out-of-run verb for the session's lock. */
3
+ export interface SessionLockSeats {
4
+ /** Whether a leg of this Runner holds or awaits `sessionId`'s lock, or a write one issued to it has not settled. */
5
+ sessionBusy(sessionId: string): boolean;
6
+ /** Take `sessionId`'s lock; called synchronously after `sessionBusy` answered false, so nothing slips in between. */
7
+ takeSessionLock(sessionId: string): Promise<() => void>;
8
+ }
9
+ /**
10
+ * The request door: the request must be a plain data object — not a Proxy (its traps are the caller's code, and could
11
+ * answer the caller's read of a member differently from this one), its prototype `Object.prototype` or none (so no
12
+ * member is inherited) — judged before any member is read; its members are then taken from ONE snapshot of its own
13
+ * data properties, so no code of the request itself (a trap, a getter) runs while it is read and nothing read can
14
+ * change what is read next (an accessor member is a bad request); own keys inside the verb's closed set. `bad`
15
+ * throws the verb's own refusal; the member types are the verb's to judge on the returned snapshot.
16
+ */
17
+ export declare function readPlainRequest(request: unknown, keys: ReadonlySet<string>, bad: (what: string) => never): Record<string, unknown>;
18
+ /** A value as a refusal names it: a string clipped, a primitive spelled, anything else by its type. */
19
+ export declare function shownValue(v: unknown): string;
20
+ /**
21
+ * The idle claim: refused with `busy()` when a leg of this Runner is running or queued on the session (its state is
22
+ * not moved under it); otherwise the session's lock is claimed in this same synchronous step and held by the verb
23
+ * until it releases it, so a leg that arrives meanwhile waits for the verb.
24
+ */
25
+ export declare function claimIdleSession(seats: SessionLockSeats, sessionId: string, busy: () => Error): Promise<() => void>;
26
+ /** The session must exist — the same door and code a run with `requireExistingSession` meets. `verb` prefixes the
27
+ * message, `nothingDone` says what the verb did not do. */
28
+ export declare function acquireExistingSession(sessions: SessionStore, sessionId: string, verb: string, nothingDone: string): Promise<AcquiredSession>;
@@ -0,0 +1,48 @@
1
+ import { types } from "node:util";
2
+ import { isPlainRecord } from "../mods/kernel/receive.js";
3
+ import { readMember } from "../thrown-value.js";
4
+ export function readPlainRequest(request, keys, bad) {
5
+ if (typeof request !== "object" || request === null)
6
+ return bad(`the request must be a plain object, got ${request === null ? "null" : typeof request}`);
7
+ if (types.isProxy(request) || !isPlainRecord(request))
8
+ return bad("the request must be a plain data object (not a Proxy, and with no prototype that could supply a member)");
9
+ let descriptors;
10
+ try {
11
+ descriptors = Object.getOwnPropertyDescriptors(request);
12
+ }
13
+ catch {
14
+ return bad("the request could not be read");
15
+ }
16
+ const own = Reflect.ownKeys(descriptors);
17
+ const unknown = own.filter((k) => typeof k !== "string" || !keys.has(k));
18
+ if (unknown.length > 0)
19
+ return bad(`unknown key ${unknown.map((k) => JSON.stringify(String(k))).join(", ")}`);
20
+ const read = {};
21
+ for (const k of own) {
22
+ const d = descriptors[k];
23
+ if (!("value" in d))
24
+ return bad(`member ${JSON.stringify(k)} is an accessor, not a value`);
25
+ read[k] = d.value;
26
+ }
27
+ return read;
28
+ }
29
+ export function shownValue(v) {
30
+ return typeof v === "string" ? JSON.stringify(v.slice(0, 40)) : v === null || typeof v === "boolean" || typeof v === "number" ? String(v) : `a ${typeof v}`;
31
+ }
32
+ export function claimIdleSession(seats, sessionId, busy) {
33
+ if (seats.sessionBusy(sessionId))
34
+ throw busy();
35
+ return seats.takeSessionLock(sessionId);
36
+ }
37
+ export async function acquireExistingSession(sessions, sessionId, verb, nothingDone) {
38
+ try {
39
+ return await sessions.acquire(sessionId, { requireExisting: true });
40
+ }
41
+ catch (err) {
42
+ if (readMember(err, "code") !== "not_found")
43
+ throw err;
44
+ const e = new Error(`${verb}: session "${sessionId}" does not exist — ${nothingDone}`);
45
+ e.code = "resume.session_not_found";
46
+ throw e;
47
+ }
48
+ }
@@ -0,0 +1,30 @@
1
+ import type { SessionStorage } from "../session.js";
2
+ import type { LegWrites } from "./contracts.js";
3
+ export type { LegWrites };
4
+ export declare class SessionWriteLedger {
5
+ #private;
6
+ /** A leg's view. `report` receives the incidents (a refused write, a late settlement); a throwing sink is swallowed. */
7
+ openLeg(report: (err: Error, sessionId: string) => void): LegWrites;
8
+ /**
9
+ * The session's next hold starts here: resolves once `sessionId` has no write in flight, and throws `SessionError("conflict")`
10
+ * — the leg about to start has written nothing — when one is still unsettled after `ms`.
11
+ */
12
+ settleBeforeHold(sessionId: string, ms: number): Promise<void>;
13
+ /**
14
+ * Whether `sessionId` has a write in flight — a synchronous read. The session's next holder asks it before {@link settleBeforeHold}
15
+ * and awaits only on `true`: a session with nothing in flight takes no suspension point at its hold. The two reads sit on one tick,
16
+ * and nothing joins the set between the check and the hold's return — the previous holder's view is closed before its lock is
17
+ * released, the lock serialises holders, and a holder that is no leg (the rewind verb) issues no write through a view.
18
+ */
19
+ busy(sessionId: string): boolean;
20
+ /**
21
+ * Resolves `true` once `sessionId` has no write in flight, `false` when `ms` elapse first. The timer is not unref'd: the
22
+ * caller awaits this in foreground control flow (the teardown-bounded discipline), and it is cleared on settle.
23
+ */
24
+ drained(sessionId: string, ms: number): Promise<boolean>;
25
+ }
26
+ /**
27
+ * The acquired storage as a leg writes it: the two write members go through `leg.issue` (named by the entry type, `leaf` for a
28
+ * leaf move), every other member is the storage's own. Per leg and non-mutating (a Proxy), like the conflict watch above it.
29
+ */
30
+ export declare function writesThroughLeg(storage: SessionStorage, leg: LegWrites, sessionId: string): SessionStorage;
@@ -0,0 +1,101 @@
1
+ import { SessionError } from "../session.js";
2
+ import { thrownText } from "../thrown-value.js";
3
+ export class SessionWriteLedger {
4
+ #inFlight = new Map();
5
+ #drainWaiters = new Map();
6
+ openLeg(report) {
7
+ let closedAt;
8
+ const tell = (sessionId, message) => {
9
+ try {
10
+ report(new Error(message), sessionId);
11
+ }
12
+ catch {
13
+ }
14
+ };
15
+ return {
16
+ issue: (sessionId, what, start) => {
17
+ if (closedAt !== undefined) {
18
+ const message = `session "${sessionId}": a ${what} write was issued after its leg ended and was not started`;
19
+ tell(sessionId, message);
20
+ return Promise.reject(new SessionError("conflict", message));
21
+ }
22
+ let write;
23
+ try {
24
+ write = Promise.resolve(start());
25
+ }
26
+ catch (err) {
27
+ return Promise.reject(err);
28
+ }
29
+ this.#add(sessionId, write);
30
+ const settledLate = (outcome) => {
31
+ this.#remove(sessionId, write);
32
+ if (closedAt !== undefined)
33
+ tell(sessionId, `session "${sessionId}": a ${what} write issued by a leg that has since ended settled ${Date.now() - closedAt}ms after the leg ended — ${outcome}`);
34
+ };
35
+ write.then(() => settledLate("it landed"), (err) => settledLate(`it failed: ${thrownText(err)}`));
36
+ return write;
37
+ },
38
+ close: () => {
39
+ closedAt ??= Date.now();
40
+ },
41
+ };
42
+ }
43
+ async settleBeforeHold(sessionId, ms) {
44
+ if (await this.drained(sessionId, ms))
45
+ return;
46
+ throw new SessionError("conflict", `session "${sessionId}": a write an earlier leg of this session issued has not settled after ${ms}ms — this leg wrote nothing; retry once it settles`);
47
+ }
48
+ busy(sessionId) {
49
+ return (this.#inFlight.get(sessionId)?.size ?? 0) > 0;
50
+ }
51
+ drained(sessionId, ms) {
52
+ if (!this.busy(sessionId))
53
+ return Promise.resolve(true);
54
+ return new Promise((resolve) => {
55
+ const waiters = this.#drainWaiters.get(sessionId) ?? new Set();
56
+ this.#drainWaiters.set(sessionId, waiters);
57
+ const done = () => {
58
+ clearTimeout(timer);
59
+ waiters.delete(done);
60
+ if (waiters.size === 0 && this.#drainWaiters.get(sessionId) === waiters)
61
+ this.#drainWaiters.delete(sessionId);
62
+ resolve(true);
63
+ };
64
+ const timer = setTimeout(() => {
65
+ waiters.delete(done);
66
+ if (waiters.size === 0 && this.#drainWaiters.get(sessionId) === waiters)
67
+ this.#drainWaiters.delete(sessionId);
68
+ resolve(false);
69
+ }, ms);
70
+ waiters.add(done);
71
+ });
72
+ }
73
+ #add(sessionId, write) {
74
+ const set = this.#inFlight.get(sessionId) ?? new Set();
75
+ set.add(write);
76
+ this.#inFlight.set(sessionId, set);
77
+ }
78
+ #remove(sessionId, write) {
79
+ const set = this.#inFlight.get(sessionId);
80
+ if (set === undefined)
81
+ return;
82
+ set.delete(write);
83
+ if (set.size > 0)
84
+ return;
85
+ this.#inFlight.delete(sessionId);
86
+ for (const wake of [...(this.#drainWaiters.get(sessionId) ?? [])])
87
+ wake();
88
+ }
89
+ }
90
+ export function writesThroughLeg(storage, leg, sessionId) {
91
+ return new Proxy(storage, {
92
+ get(target, prop, receiver) {
93
+ if (prop === "appendEntry")
94
+ return (...args) => leg.issue(sessionId, args[0].type, () => target.appendEntry(...args));
95
+ if (prop === "setLeafId")
96
+ return (...args) => leg.issue(sessionId, "leaf", () => target.setLeafId(...args));
97
+ const value = Reflect.get(target, prop, receiver);
98
+ return typeof value === "function" ? value.bind(target) : value;
99
+ },
100
+ });
101
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The run's seat for `inherit_env.names_withheld`: the person whose run drives the engine's shell tool is told which
3
+ * variables of the engine's environment that shell does not receive.
4
+ *
5
+ * ONE FACT, ONE MINT. Which entries a shell child loses is decided by the execution environment's one composition
6
+ * (`inheritedHostEnv(policy, findings)` and the adapter's explicit grants), and the environment hands the result over as
7
+ * the read `ExecutionEnv.withheldEnv`. This seat reads that answer and tells it; it never recomputes it (the policy and
8
+ * the grants are the adapter's, not the run's). The split into the scrub's half and the deployment's own credentials is
9
+ * the one the operator notice uses (`withheldEnvNames`).
10
+ *
11
+ * WHEN. At the start of every call to the engine's own shell tool (its mount, judged by the catalog's mount judge), on a
12
+ * root leg (the person reads the root; the delegation fact is the hook identity's, the leg's one derivation). The answer
13
+ * is read at each such call because it can grow during a run — a credential the engine takes in when it first routes a
14
+ * model, dials a peer or builds a seat is withheld from the next child — and a call follows at least one model request.
15
+ * Told once per SESSION per answer: the digest rides the session's announced record (`advisories`), and a run-time record
16
+ * write is parked for the leg's flush like every other run-time arm of that record.
17
+ *
18
+ * An answer of `"unknown"` is told as unknown, never as silence. A value that is neither a list of findings nor
19
+ * `"unknown"` (or a read that throws) is a wiring fault: it is announced to the operator under the existing
20
+ * capability-shape code, once per run, and the person is told nothing — no reading defaults to `"unknown"`.
21
+ */
22
+ import { type EngineNotice } from "../engine-notice.js";
23
+ import type { ExecutionEnv } from "../../internal/harness.js";
24
+ import type { Prepared } from "./contracts.js";
25
+ export type WithheldShellEnvSeatInput = Pick<Prepared, "sessionId" | "runId" | "hookIdentity" | "toolRosterDeltas" | "announcedListingsRef" | "frameReceipts"> & {
26
+ readonly harness: {
27
+ readonly env: Pick<ExecutionEnv, "withheldEnv">;
28
+ };
29
+ };
30
+ /** The seat, per run. `onToolStart` never throws: a diagnostic may not be what fails a call. */
31
+ export declare function createWithheldShellEnvSeat(prepared: WithheldShellEnvSeatInput, onNotice: ((notice: EngineNotice) => void) | undefined): {
32
+ onToolStart(toolName: string): void;
33
+ };
@@ -0,0 +1,51 @@
1
+ import { deliverEngineNotice } from "../engine-notice.js";
2
+ import { withheldEnvUserNotice } from "../secret-env.js";
3
+ import { isEngineShellFace } from "../tool-catalog-entries.js";
4
+ import { toolCallFaceOf } from "../tool-roster.js";
5
+ import { announceDigest, withAnnounceDigests } from "./announce-once-ledger.js";
6
+ const isFinding = (f) => typeof f === "object" && f !== null && typeof Reflect.get(f, "key") === "string" && typeof Reflect.get(f, "kind") === "string";
7
+ function readWithheldEnv(env) {
8
+ try {
9
+ const value = env.withheldEnv;
10
+ if (value === "unknown")
11
+ return "unknown";
12
+ if (!Array.isArray(value))
13
+ return { malformed: value === null ? "null" : typeof value };
14
+ return value.every(isFinding) ? value : { malformed: "array holding a non-finding" };
15
+ }
16
+ catch {
17
+ return { malformed: "unreadable" };
18
+ }
19
+ }
20
+ export function createWithheldShellEnvSeat(prepared, onNotice) {
21
+ let shapeFaultTold = false;
22
+ return {
23
+ onToolStart(toolName) {
24
+ if (prepared.hookIdentity.isDelegatedChild || !isEngineShellFace(toolCallFaceOf(prepared.toolRosterDeltas.current, toolName)))
25
+ return;
26
+ const answer = readWithheldEnv(prepared.harness.env);
27
+ if (typeof answer === "object" && "malformed" in answer) {
28
+ if (shapeFaultTold)
29
+ return;
30
+ shapeFaultTold = true;
31
+ deliverEngineNotice(onNotice, {
32
+ code: "config.execution_env_capability_invalid",
33
+ message: `The execution environment declares withheldEnv as (${answer.malformed}), not a list of findings or "unknown". The person whose run drives its shell is told nothing about the variables that shell does not receive. Fix the adapter — this is a wiring fault, not a supported way to leave the member unanswered.`,
34
+ detail: { key: "withheldEnv", valueType: answer.malformed },
35
+ });
36
+ return;
37
+ }
38
+ const notice = withheldEnvUserNotice(answer, { sessionId: prepared.sessionId, runId: prepared.runId });
39
+ if (notice === undefined)
40
+ return;
41
+ const d = notice.detail;
42
+ const digest = announceDigest(notice.code, `${d.state}\n${[...(d.names ?? [])].sort().join("\n")}\n\n${[...(d.ownCredentials ?? [])].sort().join("\n")}`);
43
+ const record = prepared.announcedListingsRef;
44
+ if (record.advisories?.includes(digest) === true)
45
+ return;
46
+ deliverEngineNotice(onNotice, notice);
47
+ record.advisories = withAnnounceDigests(record.advisories, [digest]);
48
+ prepared.frameReceipts.listingSnapshotOwed = true;
49
+ },
50
+ };
51
+ }
@@ -39,7 +39,7 @@ export function readSkillsSeat(skills) {
39
39
  const at = `${SKILLS_SEAT}[${i}]`;
40
40
  if (typeof raw !== "object" || raw === null || Array.isArray(raw))
41
41
  throw skillsSeatRefusal(at, `must be an object { name, description, content } (got ${kindOf(raw)})`);
42
- const { name, description, content, allowedTools, disallowedTools, files: rawFiles, baseDir, ...rest } = raw;
42
+ const { name, description, content, allowedTools, disallowedTools, files: rawFiles, baseDir, mods: rawMods, ...rest } = raw;
43
43
  void rest;
44
44
  for (const [member, value] of [["name", name], ["description", description], ["content", content]]) {
45
45
  if (typeof value !== "string")
@@ -47,11 +47,15 @@ export function readSkillsSeat(skills) {
47
47
  }
48
48
  const files = readSkillFiles(rawFiles, `${at}.files`);
49
49
  skillBaseDirOf(baseDir);
50
+ if (rawMods !== undefined && !Array.isArray(rawMods))
51
+ throw skillsSeatRefusal(`${at}.mods`, `must be a list of mods registrations (got ${kindOf(rawMods)})`);
50
52
  if (seen.has(name))
51
53
  continue;
52
54
  seen.add(name);
53
55
  const [allowed, denied] = [readSkillTable(allowedTools), readSkillTable(disallowedTools)];
54
- out.push({ name, description, content, ...(allowed !== undefined ? { allowedTools: allowed } : {}), ...(denied !== undefined ? { disallowedTools: denied } : {}), ...(files !== undefined ? { files } : {}), ...(baseDir !== undefined ? { baseDir } : {}) });
56
+ const list = rawMods;
57
+ const mods = list === undefined ? undefined : Object.freeze(Array.from({ length: list.length }, (_, j) => list[j]));
58
+ out.push({ name, description, content, ...(allowed !== undefined ? { allowedTools: allowed } : {}), ...(denied !== undefined ? { disallowedTools: denied } : {}), ...(files !== undefined ? { files } : {}), ...(baseDir !== undefined ? { baseDir } : {}), ...(mods !== undefined ? { mods } : {}) });
55
59
  }
56
60
  return out;
57
61
  }