@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
package/LICENSE CHANGED
@@ -5,7 +5,7 @@ Parameters
5
5
  Licensor: clay (github.com/clayboby)
6
6
  Licensed Work: @sema-agent/core (sema-core) and the satellite packages
7
7
  published from this repository (currently
8
- @sema-agent/mods-kernel)
8
+ @sema-agent/mods-kernel, @sema-agent/primitives and @sema-agent/core-stores-sql)
9
9
  (formerly published as @sema-ai/core)
10
10
  The Licensed Work is (c) 2026 clay.
11
11
  Additional Use Grant: You may make production use of the Licensed Work for
@@ -206,7 +206,7 @@ export async function runCascade(runner, spec, config, internals) {
206
206
  return {
207
207
  taskId: spec.taskId ?? "",
208
208
  sessionId: "",
209
- result: `runCascade: the overall wall-clock budget (totalTimeoutMs ${config.totalTimeoutMs}ms) was already spent when the ladder was entered — no rung dispatched`,
209
+ result: `runCascade: the overall wall-clock budget (totalTimeoutMs ${config.totalTimeoutMs}ms) was already spent when the ladder was entered — no rung dispatched`, resultEntryIds: [],
210
210
  terminal: { kind: "failed", code: CASCADE_NO_DISPATCH_ERROR_CODE },
211
211
  stats: { tokens: 0, turns: 0, costMicroUsd: 0 },
212
212
  cascadeOutcome: "exhausted",
@@ -107,6 +107,7 @@ export function createCcPeerDirectory(opts) {
107
107
  ...(typeof r["peerProtocol"] === "number" ? { peerProtocol: r["peerProtocol"] } : {}),
108
108
  ...(features !== undefined ? { peerFeatures: features } : {}),
109
109
  sockPath,
110
+ where: "this_machine",
110
111
  });
111
112
  if (!read.ok)
112
113
  return void skip(file, "invalid_row", read.field !== undefined ? `${read.reason}: ${read.field}` : read.reason);
@@ -18,17 +18,6 @@ export declare function deploymentStatesSubagentModel(roles: ModelRoles | undefi
18
18
  * already reflects when the parent ran on it).
19
19
  */
20
20
  export declare function deploymentSubagentThinking(roles: ModelRoles | undefined): ThinkingLevel | undefined;
21
- /**
22
- * Did the deployment STATE a system prompt for its subagents — and which? The `systemPrompt` member of an
23
- * object-form `roles.subagent` entry; a string ref, a `Model` object or an entry without the member states
24
- * none. The third axis, read off the SAME seat as {@link deploymentSubagentThinking}. It has no parent rung:
25
- * a child never inherits its PARENT's system prompt, only the deployment's statement for subagents. Which
26
- * station needs to read it: one whose default persona is written onto the spec itself (the workflow lane
27
- * frames an empty `systemPrompt` with the workflow-subagent persona, so the preset must be written first, as
28
- * a custom persona to that frame); the delegation station's default rides the trusted internals channel
29
- * below the role chain, so prepare reads the preset there without this helper.
30
- */
31
- export declare function deploymentSubagentSystemPrompt(roles: ModelRoles | undefined): string | undefined;
32
21
  /**
33
22
  * The child run's THINKING seat — {@link childModelSeat}'s sister, the same rung order on the other axis
34
23
  * (#651): an EXPLICIT level for this spawn wins (the agent definition's `thinking`; a fork's explicit is the
@@ -23,9 +23,6 @@ export function deploymentStatesSubagentModel(roles) {
23
23
  export function deploymentSubagentThinking(roles) {
24
24
  return subagentRolePresets(roles)?.thinking;
25
25
  }
26
- export function deploymentSubagentSystemPrompt(roles) {
27
- return subagentRolePresets(roles)?.systemPrompt;
28
- }
29
26
  function subagentRolePresets(roles) {
30
27
  const s = roles?.subagent;
31
28
  if (s == null || typeof s === "string")
@@ -1,7 +1,7 @@
1
1
  import { Type } from "typebox";
2
2
  import type { TaskAccess } from "../core/task-registry.js";
3
3
  import { type RosterEntry } from "./roster-store.js";
4
- import { type PeerDirectory, type PeerPresence, type PeerSessionRecord } from "./peer-directory.js";
4
+ import { type PeerDirectory, type PeerPresence, type PeerSessionRecord, type PeerSessionWhere } from "./peer-directory.js";
5
5
  import type { SubagentTranscriptTier } from "../core/wiring-manifest.js";
6
6
  import { formatAgo, type AgentState, type AgentStateSource } from "../core/agent-state.js";
7
7
  import type { CheckpointSeat } from "../core/checkpoint-seat.js";
@@ -89,6 +89,8 @@ export interface ListAgentsRow {
89
89
  cwd?: string;
90
90
  /** Peer rows: the session's self-reported presence, when it reported any. */
91
91
  presence?: PeerPresence;
92
+ /** Peer rows: where the session runs, as the directory's row says it ({@link PeerSessionWhere}). */
93
+ where?: PeerSessionWhere;
92
94
  /** What SendMessage accepts: on both AGENT lanes the registry `task_id` VERBATIM (no prefixing or
93
95
  * re-minting), never the child's session id — a different domain, tabled in INTEGRATION-CORE §1.6a.
94
96
  * Peer rows carry the `session.<id>` box handle instead. */
@@ -3,7 +3,7 @@ import { defineTool } from "../core/tools.js";
3
3
  import { inlineUntrusted } from "../core/untrusted-text.js";
4
4
  import { formatPeerNameRef } from "./cross-session-ref.js";
5
5
  import { entryAccessible } from "./roster-store.js";
6
- import { mintPeerSessionCandidates, PEER_PRESENCE_MAX_CHARS, peerSessionBoxHandle } from "./peer-directory.js";
6
+ import { listPeerDirectory, mintPeerSessionCandidates, PEER_PRESENCE_MAX_CHARS, PEER_SESSION_WHERE_LABELS, peerSessionBoxHandle } from "./peer-directory.js";
7
7
  import { PEER_LANE_DEFAULTS } from "./peer-admission.js";
8
8
  import { mountRuleFace, toolFace } from "../core/tool-catalog-entries.js";
9
9
  import { thrownText } from "../core/thrown-value.js";
@@ -45,8 +45,7 @@ const PEER_ROW_STATE = {
45
45
  function peerRowState(r) {
46
46
  if (r.liveness === "dead")
47
47
  return "offline";
48
- const tempo = r.tempo;
49
- return tempo !== undefined && Object.hasOwn(PEER_ROW_STATE, tempo) ? PEER_ROW_STATE[tempo] : "unknown";
48
+ return r.tempo !== undefined ? PEER_ROW_STATE[r.tempo] : "unknown";
50
49
  }
51
50
  function renderPresence(p) {
52
51
  const parts = [...(p.agent !== undefined ? [`agent=${inlineUntrusted(p.agent, PEER_PRESENCE_MAX_CHARS)}`] : []), ...(p.intent !== undefined ? [`intent=${inlineUntrusted(p.intent, PEER_PRESENCE_MAX_CHARS)}`] : [])];
@@ -66,7 +65,7 @@ export function createListAgentsTool(opts) {
66
65
  isConcurrencySafe: () => true,
67
66
  description: `List the agents${peers ? " and peer sessions" : ""} you can message with SendMessage. ` +
68
67
  (peers
69
- ? `Peer sessions are other sessions of this engine running for the same user, shown as \`name [ref] · state · active <N> ago · <directory> · self: agent=…, intent=…\`; send to one with its name (or \`name [ref]\` ` +
68
+ ? `Peer sessions are other sessions of this engine running for the same user, shown as \`name [ref] · state · active <N> ago · <directory> · self: agent=…, intent=… · peer session <where>\` (where it runs: ${Object.values(PEER_SESSION_WHERE_LABELS).join(", or ")}); send to one with its name (or \`name [ref]\` ` +
70
69
  `when a name is ambiguous, or its \`session.<id>\` address). By default only FRESH peers are listed (working now, or active within the last ${formatAgo(windowMs)}); ` +
71
70
  `pass includeAll: true to also list stale and offline ones. A peer that is offline or unlisted still accepts messages — they are parked ` +
72
71
  `durably in its session box and delivered when it next runs. `
@@ -84,7 +83,7 @@ export function createListAgentsTool(opts) {
84
83
  let directoryFault;
85
84
  if (opts.peerDirectory !== undefined) {
86
85
  try {
87
- peerRows = await opts.peerDirectory.listPeerSessions({ scope: opts.self.scope });
86
+ peerRows = await listPeerDirectory(opts.peerDirectory, { scope: opts.self.scope });
88
87
  }
89
88
  catch (e) {
90
89
  directoryFault = thrownText(e);
@@ -108,6 +107,7 @@ export function createListAgentsTool(opts) {
108
107
  ...(r.liveness === "live" ? { lastActiveAt: r.updatedAt } : r.diedAt !== undefined ? { offlineAt: r.diedAt } : {}),
109
108
  ...(r.cwd !== undefined ? { cwd: cwdTail(r.cwd) } : {}),
110
109
  ...(presence.agent !== undefined || presence.intent !== undefined ? { presence } : {}),
110
+ where: r.where,
111
111
  });
112
112
  }
113
113
  let registryCapped = false;
@@ -172,13 +172,13 @@ export function createListAgentsTool(opts) {
172
172
  const age = r.kind !== "peer_session" ? undefined : r.lastActiveAt !== undefined ? `active ${formatAgo(now - r.lastActiveAt)} ago` : r.offlineAt !== undefined ? `offline ${formatAgo(now - r.offlineAt)} ago` : "offline";
173
173
  const activity = r.agentState !== undefined ? agentActivityClause(r.agentState) : undefined;
174
174
  const approval = r.agentState?.approval !== undefined ? agentApprovalClause(r.agentState.approval, r.agentState.readAt) : undefined;
175
- const cols = [label, r.state, age, activity, approval, r.cwd !== undefined ? inlineUntrusted(r.cwd, 64) : undefined, r.presence !== undefined ? renderPresence(r.presence) : undefined, r.kind === "peer_session" ? "peer session" : r.kind === "roster" ? rosterLabel : "agent", r.address];
175
+ const cols = [label, r.state, age, activity, approval, r.cwd !== undefined ? inlineUntrusted(r.cwd, 64) : undefined, r.presence !== undefined ? renderPresence(r.presence) : undefined, r.kind === "peer_session" ? `peer session ${PEER_SESSION_WHERE_LABELS[r.where]}` : r.kind === "roster" ? rosterLabel : "agent", r.address];
176
176
  return cols.filter((c) => c !== undefined).join(" · ");
177
177
  });
178
178
  const finishedCount = rows.filter((r) => r.state === "finished").length;
179
179
  const header = rows.length === 0 ? "No agents or peer sessions are listed right now." : `${rows.length} listed:`;
180
180
  const finishedNote = finishedCount > 0 ? `\n(${finishedCount} finished agent(s): continuable by SendMessage only ${finishedReach} — otherwise SendMessage answers with an honest refusal)` : "";
181
- const fault = (directoryFault !== undefined ? `\n(peer-session directory unreadable: ${inlineUntrusted(directoryFault, 200)} — peer rows may be missing)` : "") +
181
+ const fault = (directoryFault !== undefined ? `\n(peer-session directory unreadable: ${inlineUntrusted(directoryFault, 200)} — no peer row is listed until its host fixes it)` : "") +
182
182
  (registryCapped ? "\n(the live task list is at its 500-row window: older background agents may be missing from this listing — address them by task_id)" : "");
183
183
  let content = `${header}${lines.length > 0 ? `\n${lines.join("\n")}` : ""}${finishedNote}${fault}`;
184
184
  if (content.length > LIST_AGENTS_MAX_RESULT_CHARS)
@@ -7,9 +7,8 @@ export function principalInboxConsumerOf(deps) {
7
7
  const raw = deps.principalInboxConsumer;
8
8
  if (raw === undefined)
9
9
  return { kind: "none" };
10
- if (raw === "terminals") {
11
- throw consumerRefusal(`RunnerDeps.principalInboxConsumer "terminals" is not available yet: the shared held decision ledger is not yet available, so a letter a person refused in one terminal could be delivered by another. Declare { assistant: "<agent handle>" } or leave the seat absent.`, "terminals_unsupported");
12
- }
10
+ if (raw === "terminals")
11
+ return { kind: "terminals" };
13
12
  if (raw !== null && typeof raw === "object" && !Array.isArray(raw) && Object.getPrototypeOf(raw) === Object.prototype) {
14
13
  const keys = Reflect.ownKeys(raw);
15
14
  const handle = raw.assistant;
@@ -32,7 +31,7 @@ export function isOrgDeliveryRefusalCode(value) {
32
31
  export function mintCrossPrincipalRecord(input) {
33
32
  const { from, body, receiptId, sentAt, consumer } = input;
34
33
  if (consumer?.kind !== "terminals" && consumer?.kind !== "assistant") {
35
- throw consumerRefusal(`an organization delivery gate is minting a principal-inbox letter, but the deployment declares no principal-inbox consumer (RunnerDeps.principalInboxConsumer is absent): nobody would ever read it. Declare { assistant: "<agent handle>" }.`, "no_consumer");
34
+ throw consumerRefusal(`an organization delivery gate is minting a principal-inbox letter, but the deployment declares no principal-inbox consumer (RunnerDeps.principalInboxConsumer is absent): nobody would ever read it. Declare "terminals" or { assistant: "<agent handle>" }.`, "no_consumer");
36
35
  }
37
36
  if (typeof body.content !== "string")
38
37
  throw new TypeError("mintCrossPrincipalRecord: body.content must be a string");
@@ -22,8 +22,20 @@ export declare function peerPresenceLabelValid(v: unknown): v is string | undefi
22
22
  /** Prepare's door: `TaskSpec.peerPresence` is a plain object whose `agent` / `intent` each pass {@link peerPresenceLabelValid}
23
23
  * — else `config.peer_presence_invalid`, naming the field. */
24
24
  export declare function assertPeerPresenceValue(v: unknown): void;
25
+ /**
26
+ * WHERE a peer session runs — the directory's word, like `liveness`. `this_machine` = a process on the ACCESSOR's
27
+ * machine, said only by a directory that reads that machine ({@link PeerDirectoryAccess} names a scope, not a
28
+ * machine); `hosted` = a session a hosting service runs, reached only through the store. `pid` / `procStartMs` /
29
+ * `sockPath` ride a `this_machine` row only ({@link readPeerSessionRecord}), so none of their readers reads `where` —
30
+ * for a row of plain data members: the reader does not snapshot an accessor member, which can answer differently per read.
31
+ */
32
+ export declare const PEER_SESSION_WHERE_VALUES: readonly ["this_machine", "hosted"];
33
+ export type PeerSessionWhere = (typeof PEER_SESSION_WHERE_VALUES)[number];
34
+ /** THE wording of each value — the listing's kind column and the ambiguity error read this one table. */
35
+ export declare const PEER_SESSION_WHERE_LABELS: Readonly<Record<PeerSessionWhere, string>>;
25
36
  /** The registration row. Field set = CC's load-bearing subset + sema's `scope` axis + the sema-only
26
- * liveness/tombstone members. A host writes it; every terminal reads it through {@link readPeerSessionRecord}. */
37
+ * liveness/tombstone/where members. A host writes it; every terminal reads it through {@link readPeerSessionRecord}
38
+ * (the engine: {@link listPeerDirectory}; `peerDirectoryContract` checks a directory lists only rows it accepts). */
27
39
  export interface PeerSessionRecord {
28
40
  schemaVersion: number;
29
41
  /** The session's durable identity: its box address is `session.<sessionId>` ({@link peerSessionBoxHandle}). */
@@ -52,6 +64,8 @@ export interface PeerSessionRecord {
52
64
  liveness: PeerSessionLiveness;
53
65
  /** Present iff `liveness !== "live"`: when the row was marked dead (or the tombstone was written). */
54
66
  diedAt?: number;
67
+ /** Where the session runs ({@link PeerSessionWhere}) — the directory's word, never derived from the other members. */
68
+ where: PeerSessionWhere;
55
69
  /** The host's activity word. A stale `tempo` is the host's to clear: a row that says `active` is
56
70
  * listed as fresh regardless of its age. */
57
71
  tempo?: PeerSessionTempo;
@@ -135,10 +149,10 @@ export interface PeerLivenessProbe {
135
149
  export declare const defaultPeerLivenessProbe: PeerLivenessProbe;
136
150
  /**
137
151
  * Is the row's process alive? `false` when the pid is gone, OR when the probe knows a start time and it
138
- * disagrees with the row's (PID reuse — a different process wears the number). A row with no pid has
139
- * no process to probe and is judged by its declared liveness alone.
152
+ * disagrees with the row's (PID reuse — a different process wears the number). A row with no LOCAL process
153
+ * (no pid, or not `this_machine`: its pid is not this machine's to signal) is judged by its declared liveness alone.
140
154
  */
141
- export declare function isPeerSessionProcessAlive(record: Pick<PeerSessionRecord, "pid" | "procStartMs" | "liveness">, probe?: PeerLivenessProbe): boolean;
155
+ export declare function isPeerSessionProcessAlive(record: Pick<PeerSessionRecord, "pid" | "procStartMs" | "liveness" | "where">, probe?: PeerLivenessProbe): boolean;
142
156
  export interface PeerDirectoryAccess {
143
157
  /** The accessor's scope — rows of any other scope are never returned (§10 wall). */
144
158
  scope: string;
@@ -167,6 +181,10 @@ export interface PeerDirectory {
167
181
  */
168
182
  restorePeerSession?(record: PeerSessionRecord): boolean | Promise<boolean>;
169
183
  }
184
+ /** THE engine's read of a directory: every listed row through {@link readPeerSessionRecord}. A row it refuses
185
+ * faults the WHOLE listing (thrown, so each consumer's fault arm speaks), never a partial set — refs are minted and
186
+ * names resolved over the full set, and dropping one row would change both. */
187
+ export declare function listPeerDirectory(dir: PeerDirectory, access: PeerDirectoryAccess): Promise<PeerSessionRecord[]>;
170
188
  export interface PeerSessionCandidate {
171
189
  record: PeerSessionRecord;
172
190
  /** The listing-minted ref (6..12 hex) of this row — stable across the live/dead filter because it is
@@ -19,6 +19,12 @@ export function assertPeerPresenceValue(v) {
19
19
  e.code = "config.peer_presence_invalid";
20
20
  throw e;
21
21
  }
22
+ export const PEER_SESSION_WHERE_VALUES = Object.freeze(["this_machine", "hosted"]);
23
+ function isPeerSessionWhere(v) {
24
+ return PEER_SESSION_WHERE_VALUES.some((w) => w === v);
25
+ }
26
+ export const PEER_SESSION_WHERE_LABELS = Object.freeze({ this_machine: "on this machine", hosted: "hosted by the service" });
27
+ const MACHINE_BOUND_MEMBERS = ["pid", "procStartMs", "sockPath"];
22
28
  export const SEMA_MAILBOX_FEATURE_PREFIX = "sema_mailbox_v1_";
23
29
  export function semaMailboxFeature(storeIdentity) {
24
30
  return `${SEMA_MAILBOX_FEATURE_PREFIX}${createHash("sha256").update(storeIdentity).digest("hex").slice(0, 16)}`;
@@ -109,6 +115,12 @@ export function readPeerSessionRecord(raw) {
109
115
  const inboundPosture = r["inboundPosture"];
110
116
  if (inboundPosture !== undefined && inboundPosture !== "available" && inboundPosture !== "unavailable")
111
117
  return bad("inboundPosture");
118
+ const where = r["where"];
119
+ if (!isPeerSessionWhere(where))
120
+ return bad("where");
121
+ const misplaced = where === "this_machine" ? undefined : MACHINE_BOUND_MEMBERS.find((k) => r[k] !== undefined);
122
+ if (misplaced !== undefined)
123
+ return bad(misplaced);
112
124
  const record = {
113
125
  schemaVersion: r["schemaVersion"],
114
126
  sessionId: r["sessionId"],
@@ -125,6 +137,7 @@ export function readPeerSessionRecord(raw) {
125
137
  updatedAt: r["updatedAt"],
126
138
  liveness,
127
139
  ...(r["diedAt"] !== undefined ? { diedAt: r["diedAt"] } : {}),
140
+ where,
128
141
  ...(tempo !== undefined ? { tempo } : {}),
129
142
  ...(r["entrypoint"] !== undefined ? { entrypoint: r["entrypoint"] } : {}),
130
143
  ...(r["peerProtocol"] !== undefined ? { peerProtocol: r["peerProtocol"] } : {}),
@@ -148,7 +161,7 @@ export const defaultPeerLivenessProbe = {
148
161
  export function isPeerSessionProcessAlive(record, probe = defaultPeerLivenessProbe) {
149
162
  if (record.liveness !== "live")
150
163
  return false;
151
- if (record.pid === undefined)
164
+ if (record.pid === undefined || record.where !== "this_machine")
152
165
  return true;
153
166
  if (!probe.processExists(record.pid))
154
167
  return false;
@@ -159,6 +172,15 @@ export function isPeerSessionProcessAlive(record, probe = defaultPeerLivenessPro
159
172
  }
160
173
  return true;
161
174
  }
175
+ export async function listPeerDirectory(dir, access) {
176
+ return (await dir.listPeerSessions(access)).map((raw) => {
177
+ const read = readPeerSessionRecord(raw);
178
+ if (read.ok)
179
+ return read.record;
180
+ const id = typeof raw?.sessionId === "string" ? inlineUntrusted(raw.sessionId, 80) : "(no session id)";
181
+ throw new Error(`the directory listed a row this engine cannot read (${id}: ${read.reason}${read.field !== undefined ? `: ${read.field}` : ""}); no peer row is used until its host fixes it`);
182
+ });
183
+ }
162
184
  export function mintPeerSessionCandidates(records, self) {
163
185
  const entries = records.map((record) => ({ kind: "session", id: record.sessionId.toLowerCase(), record }));
164
186
  const selfEntry = self !== undefined && !records.some((r) => r.sessionId.toLowerCase() === self.sessionId.toLowerCase()) ? { kind: "session", id: self.sessionId.toLowerCase() } : undefined;
@@ -166,7 +188,7 @@ export function mintPeerSessionCandidates(records, self) {
166
188
  }
167
189
  function describeCandidate(c) {
168
190
  const state = c.record.liveness === "live" ? "" : c.record.liveness === "dead" ? " (offline)" : " (deleted)";
169
- return `${formatPeerNameRef(inlineUntrusted(c.record.name, 64), c.ref)}${state} → ${peerSessionBoxHandle(c.record.sessionId)}`;
191
+ return `${formatPeerNameRef(inlineUntrusted(c.record.name, 64), c.ref)}${state}, ${PEER_SESSION_WHERE_LABELS[c.record.where]} → ${peerSessionBoxHandle(c.record.sessionId)}`;
170
192
  }
171
193
  export function resolvePeerSessions(records, to, self) {
172
194
  const candidates = mintPeerSessionCandidates(records, self);
@@ -1,10 +1,12 @@
1
- import type { MailboxPeerMeta } from "../core/mailbox-store.js";
1
+ import { type MailboxPeerMeta, type MailboxDecisionOutcome, type MailboxDecision } from "../core/mailbox-store.js";
2
2
  import type { CrossSessionHoldCause, CrossSessionInboundVerdict } from "./cross-session-judge.js";
3
3
  import { type PeerDeliveryReceiptState } from "./peer-notices.js";
4
4
  /** The `cause` vocabulary of a `peer.inbound_disposition{disposition:"held"}` notice: the parity
5
5
  * judge's causes plus the drain-stage gate's TRANSIENT `rate_limited` (a bucket-wait, not a review
6
6
  * hold — it never enters the held queue; the drain stops at that seq and re-judges next pass). */
7
7
  export type PeerInboundHoldCause = CrossSessionHoldCause | "rate_limited";
8
+ /** The decisions a card can stand for: held, approved, or handed over but not yet injected. */
9
+ export type PeerCardDecision = Extract<MailboxDecision, "held" | "approved" | "delivered">;
8
10
  export interface PeerHeldEntry {
9
11
  /** The recipient box seq of the held record (its identity for the review face). */
10
12
  readonly seq: number;
@@ -21,12 +23,16 @@ export interface PeerHeldEntry {
21
23
  readonly heldAt: number;
22
24
  /** The cause last announced for this entry (re-judgment may move it). */
23
25
  cause: CrossSessionHoldCause;
24
- /** Approved by the review face while no run of the session was live: delivered at the next flush
25
- * (a re-judgment that now refuses still wins — CC `l0e`'s approve arm re-checks policy). */
26
- released?: boolean;
26
+ /** The record's decision as this queue last read or wrote it: `held`; `approved` (deliverable,
27
+ * waiting for a lease-holding pass — a re-judgment that now refuses still wins); `delivered` (this
28
+ * queue took the hand-over move and the injection is still owed; a policy that now refuses ends it as `dropped`). */
29
+ decision: PeerCardDecision;
27
30
  }
28
- export type PeerHeldSettlement = "expired" | "delivered" | "refused" | "denied" | "dropped";
29
- export type PeerHeldSettleReason = "evicted" | "deadline" | "shutdown" | "rejudge" | "approved" | "denied" | "cancelled" | "inject_failed" | "superseded";
31
+ /** How an entry left this queue. `retired` — the CARD left this process but no decision was taken: the
32
+ * record stays held in its box for the next consumer (a queue-local event no receipt announced,
33
+ * or a record another consumer settled). Every other word is the record's own final fate. */
34
+ export type PeerHeldSettlement = "expired" | "delivered" | "refused" | "denied" | "dropped" | "retired";
35
+ export type PeerHeldSettleReason = "evicted" | "deadline" | "shutdown" | "rejudge" | "approved" | "denied" | "cancelled" | "inject_failed" | "superseded" | "decided_elsewhere";
30
36
  /** The clock/timer seam (tests inject a virtual one). Handles are opaque. */
31
37
  export interface PeerClock {
32
38
  now(): number;
@@ -36,81 +42,95 @@ export interface PeerClock {
36
42
  export declare const realPeerClock: PeerClock;
37
43
  /** The live seats a bound run gives the queue. `inject` is the ONLY member that is run-scoped (a run's
38
44
  * own injection lane); the others survive the run (the receipt route rides the mailbox, the judge
39
- * reads the deployment's settings getter) and are what a headless deadline settles through. */
45
+ * reads the deployment's settings getter, the decision seat is the store) and are what a headless
46
+ * deadline settles through. */
40
47
  export interface PeerHeldQueueSink {
41
48
  /** Re-judge an entry against the recipient's CURRENT settings and mode class (CC `M`). */
42
49
  judge: (entry: PeerHeldEntry) => CrossSessionInboundVerdict;
43
- /** Deliver a released entry into the live run's model context. Absent ⇒ no run is live. Throws ⇒
44
- * the lane refused the frame (settled `dropped`, receipt sent). Returns `"deferred"` ⇒ the run is
45
- * live but this pass's delivery budget is spent: the entry stays released and goes at the next
46
- * pass's flush (the same wait a run-less approval takes). */
50
+ /** Deliver a deliverable entry into the live run's model context. Absent ⇒ no run is live. Throws ⇒
51
+ * the lane refused the frame. Returns `"deferred"` ⇒ the run is live but this pass's delivery budget
52
+ * is spent: the entry stays deliverable and goes at the next pass's flush (unless the policy refuses it first). */
47
53
  inject?: (entry: PeerHeldEntry) => void | "deferred";
54
+ /** Would {@link inject} take this entry NOW (a live pass that holds this box's lease, with budget left)?
55
+ * Asked BEFORE the hand-over move (and before a refusal ends a handed-over card), so a process that cannot
56
+ * deliver never takes a move out of `delivered`. Absent ⇒
57
+ * the presence of `inject` decides. */
58
+ canInject?: (entry: PeerHeldEntry) => boolean;
48
59
  /** The receipt to the sender (the binding routes it into the sender's box). */
49
60
  receipt: (entry: PeerHeldEntry, state: PeerDeliveryReceiptState) => void;
61
+ /** Does a receipt about this entry reach a sender? A queue-local event (eviction, shutdown, a refused
62
+ * release) is a decision about the record exactly when it does — the sender is told it is final. */
63
+ tellsSender: (entry: PeerHeldEntry) => boolean;
64
+ /** THE decision seat: the store's compare-and-set of this entry's record (`MailboxStore.moveDecision`). */
65
+ decide: (entry: PeerHeldEntry, expect: MailboxDecision | undefined, next: MailboxDecision) => Promise<MailboxDecisionOutcome>;
50
66
  /** Announce an entry entering the queue (or its cause changing on re-judgment). */
51
67
  onHeld?: (entry: PeerHeldEntry, heldCount: number, cause: CrossSessionHoldCause, reannounce: boolean) => void;
52
68
  /** Announce an entry leaving the queue. */
53
69
  onSettled?: (entry: PeerHeldEntry, settlement: PeerHeldSettlement, reason: PeerHeldSettleReason, heldCount: number) => void;
70
+ /** A decision move the store could not take (it threw): the card stays as it was and is tried again later. */
71
+ onFault?: (entry: PeerHeldEntry, error: unknown) => void;
54
72
  }
55
73
  export interface PeerHeldQueueConfig {
56
74
  sink: PeerHeldQueueSink;
57
75
  /** The resolved `dialogExpiry`: ms before a REVIEW-cause hold expires; `null` = never. */
58
76
  dialogExpiryMs: number | null;
59
77
  }
60
- export type PeerHeldSettleOutcome = "gone" | "delivered" | "released_pending" | "dropped" | "dropped_by_policy" | "denied" | "expired";
78
+ /** The approval face's answer. `decided_elsewhere` — another consumer's move won the record first (the
79
+ * card now shows that state, or left the queue when it was final); `released_pending` — approved, and a
80
+ * lease-holding pass delivers it. */
81
+ export type PeerHeldSettleOutcome = "gone" | "delivered" | "released_pending" | "dropped" | "dropped_by_policy" | "denied" | "expired" | "decided_elsewhere";
82
+ /** What {@link PeerHeldQueue.hold} did with a record the judgment holds: `held` — this call held it
83
+ * (card + `held` receipt); `adopted` — it was already held (or deliverable) and this queue now shows it
84
+ * without a receipt; `uncarded` — held, but this queue is full and no card it carries can be settled to
85
+ * make room (none would tell its sender); a final word — another consumer settled it; `gone` —
86
+ * no such record any more; `fault` — the store refused the move (reported through `onFault`). */
87
+ export type PeerHoldOutcome = "held" | "adopted" | "uncarded" | "denied" | "expired" | "refused" | "dropped" | "gone" | "fault";
61
88
  export interface PeerHeldQueue {
62
89
  /** The registry key (scope + box). */
63
90
  readonly key: string;
64
91
  /** Bind (or re-bind) the live seats. Idempotent per run; a later bind replaces an earlier one. */
65
92
  configure(cfg: PeerHeldQueueConfig): void;
66
- /** The bound run ended: approvals now park as `released`; deadlines and receipts keep working. */
93
+ /** The bound run ended: approvals now wait as `approved`; deadlines and receipts keep working. */
67
94
  detachLeg(): void;
68
95
  /** `true` once {@link configure} ran at least once (the queue can route receipts). */
69
96
  configured(): boolean;
70
- /** Park a message (CC `v` hold arm): evict-oldest when full, arm the deadline for a review cause,
71
- * announce, receipt `held`. */
72
- hold(entry: Omit<PeerHeldEntry, "heldAt" | "released">): void;
73
- /** Re-judge every entry against current settings (CC `D`): released ⇒ delivered (or parked
74
- * `released` with no live run), refused ⇒ refused with a receipt, still held ⇒ re-announced only
75
- * when the cause moved. */
76
- rejudge(): {
97
+ /**
98
+ * Hold a record (CC `v` hold arm). `decision` is the record's decision in the snapshot the caller judged:
99
+ * absent ⇒ the move absent → `held` is taken (its winner sends the `held` receipt); `held` / `approved` ⇒
100
+ * the record is already held elsewhere and this queue only shows it (an approved card is not announced).
101
+ * At the cap, settles the oldest held card that tells its sender (it is then a decision); arms the
102
+ * deadline for a hold cause a person could answer.
103
+ */
104
+ hold(entry: Omit<PeerHeldEntry, "heldAt" | "decision">, decision?: PeerCardDecision): Promise<PeerHoldOutcome>;
105
+ /** Re-judge every entry against current settings (CC `D`): deliverable ⇒ handed over (or kept with no
106
+ * live run), refused ⇒ refused with a receipt, still held ⇒ re-announced only when the cause moved.
107
+ * Every move goes through the decision seat. */
108
+ rejudge(): Promise<{
77
109
  released: number;
78
110
  refused: number;
79
111
  held: number;
80
- };
112
+ }>;
81
113
  /**
82
- * #1036 — the box is this queue's durable seat, so an entry whose record is no longer IN the box was
83
- * settled by whoever held the lease meanwhile (a takeover acked it, delivered or refused). Called by a
84
- * drain right after it claims the lease, with the seqs the claimed snapshot holds (a claim marks EVERY
85
- * unacked record, so absence is absence): such entries leave the queue as `expired` / `superseded`,
86
- * with no receipt (the owner that settled them sent one) and no decision recorded (there is no record
87
- * left to decide about). Returns how many were retired.
114
+ * Bring the cards in line with the box a lease-holding drain just read, seq → the record's decision
115
+ * (every unacked record of the box is in it, so absence is absence): a card whose record is gone was
116
+ * settled by whoever held the lease meanwhile — it leaves as `retired` / `superseded`, with no receipt;
117
+ * a card whose record another consumer settled leaves as that final state / `decided_elsewhere`, with no
118
+ * receipt (the winner sent it); a card whose record another consumer approved now shows `approved`.
119
+ * Returns how many cards left.
88
120
  */
89
- reconcile(present: ReadonlySet<number>): number;
90
- /** The review face (CC `l0e`): approve re-judges then delivers (or parks `released` with no live
91
- * run), deny/cancel drop with the matching receipt. `"gone"` when nothing is held under that seq. */
92
- settle(seq: number, decision: "approve" | "deny" | "cancel"): PeerHeldSettleOutcome;
121
+ reconcile(snapshot: ReadonlyMap<number, MailboxDecision | undefined>): number;
122
+ /** The review face (CC `l0e`): approve re-judges then delivers (or answers `released_pending` with no
123
+ * live run), deny/cancel settle with the matching receipt. `"gone"` when nothing is held under that
124
+ * seq. The answer is the store's: a move another consumer won answers `decided_elsewhere`. */
125
+ settle(seq: number, decision: "approve" | "deny" | "cancel"): Promise<PeerHeldSettleOutcome>;
126
+ /** Is a card for this seq in the queue? */
127
+ has(seq: number): boolean;
93
128
  list(): readonly PeerHeldEntry[];
94
129
  size(): number;
95
- /** CC `HBe` — a graceful shutdown settles everything still held as `expired` with receipts. */
96
- shutdown(): void;
97
- /**
98
- * #1036 — the TERMINAL DECISIONS this queue has taken about records that are still parked in
99
- * the box, seq → the settlement word. Since a held record now stays in its durable box (the box is
100
- * this queue's durable seat), a decision taken BETWEEN runs — a human's deny, a deadline, an
101
- * eviction — has to survive the run whose ledger recorded it, or the session's next run re-judges
102
- * the record from scratch and can deliver a message a person already refused. A decision is kept
103
- * only until a drain that holds the lease acks past it ({@link PeerHeldQueue.forgetDecisions}); it
104
- * is process-level, like the queue itself, and a crash loses it exactly as it loses the queue.
105
- */
106
- decisions(): ReadonlyMap<number, PeerHeldSettlement>;
107
- /** #1036 — a lease-owning drain acked these seqs out of the box: their decisions are spent. */
108
- forgetDecisions(seqs: Iterable<number>): void;
130
+ /** CC `HBe` — a graceful shutdown settles everything still held as `expired` with receipts (where a
131
+ * receipt reaches a sender; elsewhere the cards just leave this process). */
132
+ shutdown(): Promise<void>;
109
133
  }
110
- /** #1036 — how many terminal decisions about still-parked records one box's queue remembers
111
- * (see {@link PeerHeldQueue.decisions}). Several times the queue's own cap: the queue bounds what is
112
- * LIVE, this bounds what has been decided and not yet observed as consumed. */
113
- export declare const PEER_HELD_DECISION_MEMORY: number;
114
134
  export declare function createPeerHeldQueue(key: string, opts?: {
115
135
  cap?: number;
116
136
  clock?: PeerClock;