@sema-agent/core 7.51.2 → 7.53.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 (446) hide show
  1. package/CHANGELOG.md +698 -2
  2. package/README.md +3 -1
  3. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  4. package/dist/agents/cascade.js +4 -0
  5. package/dist/agents/cross-session-envelope.d.ts +8 -0
  6. package/dist/agents/cross-session-envelope.js +6 -0
  7. package/dist/agents/cross-session-judge.d.ts +21 -1
  8. package/dist/agents/cross-session-judge.js +8 -0
  9. package/dist/agents/cross-session-ref.d.ts +5 -0
  10. package/dist/agents/cross-session-ref.js +1 -0
  11. package/dist/agents/cumulative-stats.d.ts +3 -0
  12. package/dist/agents/cumulative-stats.js +3 -0
  13. package/dist/agents/list-agents-tool.d.ts +1 -1
  14. package/dist/agents/org-delivery-gate.d.ts +122 -0
  15. package/dist/agents/org-delivery-gate.js +69 -0
  16. package/dist/agents/peer-held-queue.d.ts +9 -4
  17. package/dist/agents/peer-held-queue.js +6 -5
  18. package/dist/agents/peer-session-drain.d.ts +35 -5
  19. package/dist/agents/peer-session-drain.js +271 -180
  20. package/dist/agents/read-inbox-tool.d.ts +8 -1
  21. package/dist/agents/read-inbox-tool.js +5 -1
  22. package/dist/agents/repair-loop.js +4 -0
  23. package/dist/agents/send-message-tool.d.ts +11 -16
  24. package/dist/agents/send-message-tool.js +11 -13
  25. package/dist/agents/subagent.d.ts +3 -0
  26. package/dist/agents/subagent.js +105 -76
  27. package/dist/agents/tool-filter.d.ts +58 -13
  28. package/dist/agents/tool-filter.js +34 -14
  29. package/dist/bench/metrics.d.ts +1 -0
  30. package/dist/brain/anthropic.d.ts +6 -1
  31. package/dist/brain/anthropic.js +17 -13
  32. package/dist/brain/model-presets.d.ts +4 -5
  33. package/dist/brain/model-presets.js +6 -5
  34. package/dist/brain/open-responses.js +16 -12
  35. package/dist/brain/openai.js +16 -12
  36. package/dist/brain/request-params.d.ts +12 -33
  37. package/dist/brain/request-params.js +5 -2
  38. package/dist/brain/request-route.d.ts +9 -8
  39. package/dist/brain/request-route.js +1 -0
  40. package/dist/brain/route-adjudicator.d.ts +123 -47
  41. package/dist/brain/route-adjudicator.js +171 -42
  42. package/dist/brain/route-conformance.js +2 -2
  43. package/dist/brain/routing.d.ts +24 -1
  44. package/dist/brain/routing.js +54 -19
  45. package/dist/brain/status-sink.d.ts +18 -0
  46. package/dist/brain/status-sink.js +7 -0
  47. package/dist/brain/timeout.js +5 -4
  48. package/dist/core/a2a.d.ts +5 -2
  49. package/dist/core/a2a.js +30 -13
  50. package/dist/core/allow-entry.d.ts +42 -9
  51. package/dist/core/allow-entry.js +25 -18
  52. package/dist/core/auto-compaction.d.ts +80 -20
  53. package/dist/core/auto-compaction.js +65 -18
  54. package/dist/core/auto-promote.d.ts +2 -1
  55. package/dist/core/auto-promote.js +2 -2
  56. package/dist/core/caller-tool-name.d.ts +9 -0
  57. package/dist/core/caller-tool-name.js +13 -0
  58. package/dist/core/checkpoint-requirements.d.ts +7 -1
  59. package/dist/core/checkpoint-requirements.js +2 -0
  60. package/dist/core/checkpoint-store.d.ts +57 -24
  61. package/dist/core/checkpoint-store.js +3 -3
  62. package/dist/core/child-clamp-seats.d.ts +6 -0
  63. package/dist/core/child-clamp-seats.js +2 -1
  64. package/dist/core/compliance.js +3 -1
  65. package/dist/core/credential-vocabulary.d.ts +33 -8
  66. package/dist/core/credential-vocabulary.js +32 -7
  67. package/dist/core/decision-receipt.d.ts +2 -2
  68. package/dist/core/delegation-frames.d.ts +9 -2
  69. package/dist/core/delegation-name.d.ts +18 -0
  70. package/dist/core/delegation-name.js +47 -0
  71. package/dist/core/effective-path-target.d.ts +25 -6
  72. package/dist/core/effective-path-target.js +24 -2
  73. package/dist/core/engine-capabilities.d.ts +8 -1
  74. package/dist/core/engine-capabilities.js +1 -1
  75. package/dist/core/engine-notice.d.ts +49 -21
  76. package/dist/core/frontmatter-fence.d.ts +10 -0
  77. package/dist/core/frontmatter-fence.js +6 -0
  78. package/dist/core/gate-fold.js +8 -25
  79. package/dist/core/gate-lanes.js +358 -274
  80. package/dist/core/gate-outcome.d.ts +11 -6
  81. package/dist/core/governance-codes.d.ts +11 -4
  82. package/dist/core/governance-codes.js +12 -3
  83. package/dist/core/hands-band-screen.d.ts +7 -0
  84. package/dist/core/hands-band-screen.js +32 -0
  85. package/dist/core/hooks.d.ts +283 -739
  86. package/dist/core/hooks.js +100 -193
  87. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  88. package/dist/{tools/fs → core}/image-admission.js +24 -6
  89. package/dist/core/locked-config.d.ts +84 -32
  90. package/dist/core/locked-config.js +128 -42
  91. package/dist/core/mcp-connection-pool.d.ts +4 -1
  92. package/dist/core/mcp-connection-pool.js +7 -2
  93. package/dist/core/mcp-probe.d.ts +12 -9
  94. package/dist/core/mcp-probe.js +3 -3
  95. package/dist/core/mcp-server-spec.d.ts +104 -10
  96. package/dist/core/mcp-server-spec.js +183 -33
  97. package/dist/core/mcp.d.ts +31 -20
  98. package/dist/core/mcp.js +66 -56
  99. package/dist/core/memory-engine/data-plane.js +5 -1
  100. package/dist/core/memory-engine/distiller.js +16 -2
  101. package/dist/core/memory-engine/engine.d.ts +22 -30
  102. package/dist/core/memory-engine/engine.js +16 -10
  103. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  104. package/dist/core/memory-engine/frontmatter.js +19 -16
  105. package/dist/core/memory.d.ts +2 -2
  106. package/dist/core/mode-policy.d.ts +5 -16
  107. package/dist/core/mode-policy.js +7 -19
  108. package/dist/core/model-seat.d.ts +4 -1
  109. package/dist/core/mods/dollar.d.ts +109 -0
  110. package/dist/core/mods/dollar.js +154 -0
  111. package/dist/core/mods/host.d.ts +23 -0
  112. package/dist/core/mods/host.js +21 -0
  113. package/dist/core/mods/kernel/budget.d.ts +43 -0
  114. package/dist/core/mods/kernel/budget.js +83 -0
  115. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  116. package/dist/core/mods/kernel/dispatch.js +699 -0
  117. package/dist/core/mods/kernel/events.d.ts +245 -0
  118. package/dist/core/mods/kernel/events.js +210 -0
  119. package/dist/core/mods/kernel/index.d.ts +6 -0
  120. package/dist/core/mods/kernel/index.js +5 -0
  121. package/dist/core/mods/kernel/receive.d.ts +94 -0
  122. package/dist/core/mods/kernel/receive.js +188 -0
  123. package/dist/core/mods/kernel/registration.d.ts +131 -0
  124. package/dist/core/mods/kernel/registration.js +102 -0
  125. package/dist/core/mods/kernel/site-rules.d.ts +149 -0
  126. package/dist/core/mods/kernel/site-rules.js +296 -0
  127. package/dist/core/mods/stations.d.ts +344 -0
  128. package/dist/core/mods/stations.js +437 -0
  129. package/dist/core/mounted-mcp.d.ts +57 -0
  130. package/dist/core/mounted-mcp.js +71 -2
  131. package/dist/core/own-property-receipt.d.ts +13 -0
  132. package/dist/core/own-property-receipt.js +13 -23
  133. package/dist/core/parent-spec-seat.d.ts +18 -7
  134. package/dist/core/parent-spec-seat.js +6 -2
  135. package/dist/core/path-identity.js +2 -1
  136. package/dist/core/permission-rule-model.d.ts +58 -9
  137. package/dist/core/permission-rule-model.js +81 -7
  138. package/dist/core/permission-rule-org.d.ts +163 -33
  139. package/dist/core/permission-rule-org.js +205 -71
  140. package/dist/core/permission-rule-syntax.d.ts +15 -0
  141. package/dist/core/permission-rule-syntax.js +24 -16
  142. package/dist/core/permission-rules.d.ts +14 -2
  143. package/dist/core/permission-rules.js +63 -23
  144. package/dist/core/prompt-section-seat.d.ts +15 -27
  145. package/dist/core/prompt-section-seat.js +73 -40
  146. package/dist/core/protocol-http-auth.d.ts +3 -1
  147. package/dist/core/protocol-http-auth.js +2 -0
  148. package/dist/core/reminder-mint.d.ts +2 -2
  149. package/dist/core/remote-env.d.ts +24 -12
  150. package/dist/core/remote-env.js +1 -0
  151. package/dist/core/resume-startup-cause.d.ts +16 -1
  152. package/dist/core/resume-startup-cause.js +4 -1
  153. package/dist/core/retention.js +7 -2
  154. package/dist/core/retired-keys.d.ts +12 -2
  155. package/dist/core/retired-keys.js +15 -1
  156. package/dist/core/roles.js +60 -10
  157. package/dist/core/rule-lane-reads.js +1 -1
  158. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  159. package/dist/core/runner/announce-once-ledger.js +22 -0
  160. package/dist/core/runner/assemble-result.d.ts +9 -0
  161. package/dist/core/runner/assemble-result.js +3 -1
  162. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  163. package/dist/core/runner/call-hook-stations.js +58 -42
  164. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  165. package/dist/core/runner/caller-stop-gate.js +7 -0
  166. package/dist/core/runner/compaction-seams.d.ts +8 -22
  167. package/dist/core/runner/compaction-seams.js +28 -53
  168. package/dist/core/runner/construction-doors.js +11 -1
  169. package/dist/core/runner/contracts.d.ts +86 -83
  170. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  171. package/dist/core/runner/credential-origin-seat.js +19 -0
  172. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  173. package/dist/core/runner/gate-exit.d.ts +47 -36
  174. package/dist/core/runner/gate-exit.js +12 -5
  175. package/dist/core/runner/image.js +1 -2
  176. package/dist/core/runner/inline-image.js +1 -1
  177. package/dist/core/runner/mcp-redial.d.ts +52 -10
  178. package/dist/core/runner/mcp-redial.js +38 -9
  179. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  180. package/dist/core/runner/notice-seat-input.js +1 -0
  181. package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
  182. package/dist/core/runner/permission-rule-lanes.js +22 -10
  183. package/dist/core/runner/person-path-rows.d.ts +3 -1
  184. package/dist/core/runner/person-path-rows.js +3 -2
  185. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  186. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  187. package/dist/core/runner/prepare-ask-lane.js +6 -15
  188. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  189. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  190. package/dist/core/runner/prepare-config-doors.d.ts +52 -1
  191. package/dist/core/runner/prepare-config-doors.js +168 -143
  192. package/dist/core/runner/prepare-defer-classify.js +7 -11
  193. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  194. package/dist/core/runner/prepare-delegation-surface.js +7 -5
  195. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  196. package/dist/core/runner/prepare-gate-stations.js +11 -10
  197. package/dist/core/runner/prepare-hands-readface.d.ts +1 -1
  198. package/dist/core/runner/prepare-hands-readface.js +2 -1
  199. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  200. package/dist/core/runner/prepare-inherited-gate.js +10 -23
  201. package/dist/core/runner/prepare-listings.d.ts +1 -1
  202. package/dist/core/runner/prepare-listings.js +4 -2
  203. package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
  204. package/dist/core/runner/prepare-memory-engine-session.js +20 -7
  205. package/dist/core/runner/prepare-memory.d.ts +3 -2
  206. package/dist/core/runner/prepare-memory.js +6 -2
  207. package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
  208. package/dist/core/runner/prepare-offload-wrappers.js +2 -1
  209. package/dist/core/runner/prepare-park-ask.js +10 -14
  210. package/dist/core/runner/prepare-policy-chain.d.ts +17 -15
  211. package/dist/core/runner/prepare-policy-chain.js +104 -109
  212. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  213. package/dist/core/runner/prepare-project-context.js +11 -12
  214. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  215. package/dist/core/runner/prepare-prompt-assembly.js +138 -101
  216. package/dist/core/runner/prepare-prompt-inputs.d.ts +28 -23
  217. package/dist/core/runner/prepare-prompt-inputs.js +11 -10
  218. package/dist/core/runner/prepare-protocol-tools.d.ts +11 -7
  219. package/dist/core/runner/prepare-protocol-tools.js +20 -13
  220. package/dist/core/runner/prepare-question-face.d.ts +4 -2
  221. package/dist/core/runner/prepare-question-face.js +4 -3
  222. package/dist/core/runner/prepare-safety-scan.js +6 -10
  223. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  224. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  225. package/dist/core/runner/prepare-task.js +41 -23
  226. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  227. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  228. package/dist/core/runner/prepare-wiring-manifest.d.ts +13 -9
  229. package/dist/core/runner/prepare-wiring-manifest.js +14 -11
  230. package/dist/core/runner/resume-admission.d.ts +4 -1
  231. package/dist/core/runner/resume-admission.js +7 -5
  232. package/dist/core/runner/resume-apply.d.ts +5 -2
  233. package/dist/core/runner/resume-apply.js +24 -42
  234. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  235. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  236. package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
  237. package/dist/core/runner/resume-internals-and-config.js +3 -8
  238. package/dist/core/runner/resume-preflight.js +38 -16
  239. package/dist/core/runner/retired-runner-deps.d.ts +5 -6
  240. package/dist/core/runner/retired-runner-deps.js +4 -5
  241. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  242. package/dist/core/runner/run-brain-sinks.js +5 -1
  243. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  244. package/dist/core/runner/run-compaction-machinery.js +7 -33
  245. package/dist/core/runner/run-harness-handlers.js +4 -2
  246. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  247. package/dist/core/runner/run-identity-wiring.js +3 -2
  248. package/dist/core/runner/run-leg.js +103 -95
  249. package/dist/core/runner/run-notification-lane.js +1 -0
  250. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  251. package/dist/core/runner/run-recovery-lanes.js +14 -11
  252. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  253. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  254. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  255. package/dist/core/runner/run-terminal-adoption.js +34 -22
  256. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  257. package/dist/core/runner/run-turn-boundary.js +32 -37
  258. package/dist/core/runner/runtask.d.ts +6 -7
  259. package/dist/core/runner/runtask.js +15 -73
  260. package/dist/core/runner/session-rule-policy.d.ts +5 -5
  261. package/dist/core/runner/session-rule-policy.js +13 -8
  262. package/dist/core/runner/side-call-account.d.ts +68 -0
  263. package/dist/core/runner/side-call-account.js +61 -0
  264. package/dist/core/runner/skills-seat.d.ts +15 -0
  265. package/dist/core/runner/skills-seat.js +57 -0
  266. package/dist/core/runner/stream-halt-verbs.js +12 -17
  267. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  268. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  269. package/dist/core/runner/stream-steer-verb.js +20 -38
  270. package/dist/core/runner/sub-agent-deny-lists.d.ts +124 -23
  271. package/dist/core/runner/sub-agent-deny-lists.js +230 -71
  272. package/dist/core/runner/synthetic-tools.d.ts +5 -2
  273. package/dist/core/runner/synthetic-tools.js +2 -12
  274. package/dist/core/runner/tool-end-body.d.ts +5 -6
  275. package/dist/core/runner/tool-end-body.js +6 -4
  276. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  277. package/dist/core/runner/tool-not-executed.js +30 -0
  278. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  279. package/dist/core/runner/tool-occurrence.js +5 -5
  280. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  281. package/dist/core/runner-deps.d.ts +43 -36
  282. package/dist/core/safety-merge-corpus.js +18 -2
  283. package/dist/core/secret-env.d.ts +88 -20
  284. package/dist/core/secret-env.js +192 -38
  285. package/dist/core/session-policy-store.d.ts +71 -16
  286. package/dist/core/session-policy-store.js +138 -28
  287. package/dist/core/session-reconcile.d.ts +4 -0
  288. package/dist/core/session-reconcile.js +2 -1
  289. package/dist/core/shell-read-silence.js +3 -32
  290. package/dist/core/side-query.d.ts +5 -3
  291. package/dist/core/skill-grant.d.ts +3 -2
  292. package/dist/core/skill-grant.js +17 -9
  293. package/dist/core/skills-directory.d.ts +31 -11
  294. package/dist/core/skills-directory.js +655 -104
  295. package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
  296. package/dist/core/task-event.d.ts +49 -3
  297. package/dist/core/task-notification.js +2 -2
  298. package/dist/core/task-result.d.ts +8 -0
  299. package/dist/core/task-spec.d.ts +20 -19
  300. package/dist/core/task-stream.d.ts +14 -4
  301. package/dist/core/tighten-task-spec.d.ts +4 -3
  302. package/dist/core/tighten-task-spec.js +2 -4
  303. package/dist/core/tool-check-reading.d.ts +74 -0
  304. package/dist/core/tool-check-reading.js +80 -0
  305. package/dist/core/tool-policy.d.ts +62 -18
  306. package/dist/core/tool-policy.js +86 -15
  307. package/dist/core/tool-registry.d.ts +20 -0
  308. package/dist/core/tool-registry.js +4 -0
  309. package/dist/core/tool-spec.d.ts +10 -6
  310. package/dist/core/tools.js +2 -0
  311. package/dist/core/trace.d.ts +51 -32
  312. package/dist/core/types.d.ts +2 -2
  313. package/dist/core/types.js +1 -1
  314. package/dist/core/unc-spelling.d.ts +10 -0
  315. package/dist/core/unc-spelling.js +3 -0
  316. package/dist/core/untrusted-egress.d.ts +8 -0
  317. package/dist/core/untrusted-egress.js +4 -1
  318. package/dist/core/untrusted-text.d.ts +16 -0
  319. package/dist/core/untrusted-text.js +7 -2
  320. package/dist/core/user-attachment.d.ts +25 -4
  321. package/dist/core/user-attachment.js +63 -42
  322. package/dist/core/wiring-manifest.d.ts +18 -15
  323. package/dist/core/wiring-manifest.js +2 -2
  324. package/dist/engine/compaction/utils.js +1 -2
  325. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  326. package/dist/engine/execution-env/symlink-chain.js +1 -1
  327. package/dist/engine/harness/agent-harness.d.ts +1 -1
  328. package/dist/engine/harness/agent-harness.js +5 -4
  329. package/dist/engine/harness/types.d.ts +20 -16
  330. package/dist/engine/harness/types.js +7 -1
  331. package/dist/engine/llm/types.d.ts +12 -7
  332. package/dist/engine/loop/agent-loop.d.ts +12 -1
  333. package/dist/engine/loop/agent-loop.js +18 -6
  334. package/dist/engine/loop/types.d.ts +8 -2
  335. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  336. package/dist/engine/session/import-validate.js +3 -10
  337. package/dist/engine/session/session.d.ts +4 -4
  338. package/dist/engine/session/session.js +4 -4
  339. package/dist/index.d.ts +33 -23
  340. package/dist/index.js +23 -15
  341. package/dist/internal/harness.d.ts +2 -1
  342. package/dist/internal/harness.js +2 -1
  343. package/dist/orchestration/goal.d.ts +24 -1
  344. package/dist/orchestration/goal.js +3 -2
  345. package/dist/orchestration/run-spec.d.ts +4 -6
  346. package/dist/orchestration/run-spec.js +39 -63
  347. package/dist/orchestration/run-workflow-tool.js +1 -2
  348. package/dist/orchestration/workflow.d.ts +11 -3
  349. package/dist/orchestration/workflow.js +11 -2
  350. package/dist/prompt-assembly/artifact-store.d.ts +72 -56
  351. package/dist/prompt-assembly/artifact-store.js +60 -52
  352. package/dist/prompt-assembly/artifact.d.ts +90 -76
  353. package/dist/prompt-assembly/artifact.js +197 -145
  354. package/dist/prompt-assembly/assemble.d.ts +36 -29
  355. package/dist/prompt-assembly/assemble.js +34 -220
  356. package/dist/prompt-assembly/bands.d.ts +20 -0
  357. package/dist/prompt-assembly/bands.js +18 -0
  358. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  359. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  360. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  361. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  362. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  363. package/dist/prompt-assembly/catalog/index.js +60 -0
  364. package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
  365. package/dist/prompt-assembly/catalog/memory.js +6 -0
  366. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  367. package/dist/prompt-assembly/catalog/modes.js +137 -0
  368. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  369. package/dist/prompt-assembly/catalog/role.js +157 -0
  370. package/dist/prompt-assembly/catalog/schema.d.ts +138 -0
  371. package/dist/prompt-assembly/catalog/schema.js +25 -0
  372. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  373. package/dist/prompt-assembly/catalog/sections.js +98 -0
  374. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  375. package/dist/prompt-assembly/catalog/team.js +258 -0
  376. package/dist/prompt-assembly/composer.d.ts +26 -28
  377. package/dist/prompt-assembly/composer.js +124 -46
  378. package/dist/prompt-assembly/epoch.d.ts +89 -79
  379. package/dist/prompt-assembly/epoch.js +115 -142
  380. package/dist/prompt-assembly/explain.d.ts +58 -34
  381. package/dist/prompt-assembly/explain.js +21 -24
  382. package/dist/prompt-assembly/overlay.d.ts +137 -0
  383. package/dist/prompt-assembly/overlay.js +339 -0
  384. package/dist/prompt-assembly/renderers.d.ts +21 -0
  385. package/dist/prompt-assembly/renderers.js +39 -0
  386. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  387. package/dist/prompt-assembly/section-usage.js +1 -1
  388. package/dist/prompt-assembly/select.d.ts +71 -0
  389. package/dist/prompt-assembly/select.js +106 -0
  390. package/dist/prompt-assembly/sugar.d.ts +31 -0
  391. package/dist/prompt-assembly/sugar.js +20 -0
  392. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  393. package/dist/prompt-assembly/types.d.ts +45 -148
  394. package/dist/prompts/coordinator.d.ts +2 -21
  395. package/dist/prompts/coordinator.js +3 -255
  396. package/dist/prompts/cowork.d.ts +27 -16
  397. package/dist/prompts/cowork.js +2 -23
  398. package/dist/prompts/default.d.ts +38 -511
  399. package/dist/prompts/default.js +20 -288
  400. package/dist/prompts/supervisor.d.ts +6 -71
  401. package/dist/prompts/supervisor.js +6 -117
  402. package/dist/stores/file/permission-rule-store.d.ts +1 -1
  403. package/dist/stores/file/permission-rule-store.js +2 -1
  404. package/dist/tools/artifact/artifact-tool.js +4 -3
  405. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  406. package/dist/tools/fs/dir-entries.d.ts +4 -2
  407. package/dist/tools/fs/dir-entries.js +16 -4
  408. package/dist/tools/fs/fs-bash.d.ts +1 -1
  409. package/dist/tools/fs/fs-bash.js +22 -11
  410. package/dist/tools/fs/fs-pdf.js +17 -13
  411. package/dist/tools/fs/fs-read.js +4 -3
  412. package/dist/tools/fs/fs-shared.d.ts +1 -10
  413. package/dist/tools/fs/fs-shared.js +3 -4
  414. package/dist/tools/fs/fs-write.js +2 -1
  415. package/dist/tools/fs/notebook.js +1 -1
  416. package/dist/tools/fs/pdf.d.ts +20 -10
  417. package/dist/tools/fs/pdf.js +19 -10
  418. package/dist/tools/fs/program-read-model.d.ts +68 -8
  419. package/dist/tools/fs/program-read-model.js +112 -33
  420. package/dist/tools/fs/program-read-model.rows.js +30 -10
  421. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  422. package/dist/tools/fs/read-deny-home.js +28 -27
  423. package/dist/tools/fs/read-deny.d.ts +41 -11
  424. package/dist/tools/fs/read-deny.js +51 -5
  425. package/dist/tools/fs/safety.d.ts +4 -26
  426. package/dist/tools/fs/safety.js +10 -32
  427. package/dist/tools/fs/search.js +15 -10
  428. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  429. package/dist/tools/fs/shell-read-argv.js +118 -38
  430. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  431. package/dist/tools/fs/shell-read-establish.js +11 -61
  432. package/dist/tools/fs/shell-read-identity.js +6 -3
  433. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  434. package/dist/tools/fs/shell-read-judge.js +18 -4
  435. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  436. package/dist/tools/web.js +1 -1
  437. package/package.json +13 -1
  438. package/test/export-surface.snapshot.json +306 -103
  439. package/wire-changes/core@7.52.0.json +5859 -0
  440. package/wire-changes/core@7.53.0.json +1946 -0
  441. package/dist/core/hook-seats.d.ts +0 -66
  442. package/dist/core/hook-seats.js +0 -37
  443. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  444. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  445. package/dist/prompts/simple-sections.d.ts +0 -58
  446. package/dist/prompts/simple-sections.js +0 -43
@@ -47,7 +47,10 @@
47
47
  * The NAME lane is the same shape for the tools of `NAME_RULE_FACES` (the `Skill` tool): a `Skill(<name>)` / `Skill(<prefix>:*)`
48
48
  * deny or ask — the reference's own spelling — compiles through the same validator (the model's name grammar) and is judged on the
49
49
  * one string the call names (`nameRuleSubjectOf`) with `nameRuleAdmits`, the reader the persisted rule store uses. The parameter
50
- * spelling `Skill(skill:<name>)` those tools used to take is retired: refused loudly, its sentence naming the CC form.
50
+ * spelling `Skill(skill:<name>)` those tools used to take is retired: refused loudly, its sentence naming the CC form. A KEYED
51
+ * value tool (`Artifact(action:<word>)`) takes the same lane for content keyed by its own parameter (`nameGrammarReads`); its
52
+ * other arguments stay on the generic `param:pattern` lane. A call of it that names no value for the key as the tool reads it
53
+ * is refused by the key's deny or ask rule (`keyedValueAbsentReason`, the persisted lane's reading).
51
54
  *
52
55
  * 🔴 与 CC 的有意差(design/127 r2):
53
56
  * - CC 参数级 generic 道无 allow lane(gnn 只有 deny/ask)—— 我们同样,且整个 policy 无 allow 臂。
@@ -73,7 +76,13 @@ export interface PermissionRuleIssue {
73
76
  rule: string;
74
77
  /** `invalid.*` = 语法/语义错;`unsupported.*` = CC 合法但 v1 不支持的 lane(独立
75
78
  * 分类,绝不静默 no-op —— `Bash(npm run:*)` 被当 generic 参数规则接受后永不匹配是最危险的失败形态)。 */
76
- code: "invalid.empty_tool" | "invalid.paren" | "invalid.param_split" | "invalid.primary_field" | "invalid.cap_exceeded"
79
+ code: "invalid.empty_tool" | "invalid.paren"
80
+ /** A rule the rule syntax reads no rule in (`ruleSpellingOf`) whose name is the reason: blanks around the rule, a
81
+ * character outside a tool name's spelling (a variation selector, a filler, a zero-width space), a blank or an invisible
82
+ * character before the `(`, a leading `-`. Refused — the lenient reading would deny a tool under another spelling, or none.
83
+ * Also a rule whose tool name the syntax reads as the wildcard `*` (`*`, `*()`, `*(*)`): a rule reaches the tool it
84
+ * names, and `*` names none. */
85
+ | "invalid.tool_name" | "invalid.param_split" | "invalid.primary_field" | "invalid.cap_exceeded"
77
86
  /** An ALLOW rule (any spelling): a policy fold says deny / ask only — "this does not need asking" is the allow
78
87
  * layer's (`TaskSpec.allowedTools`, `RunnerDeps.allowedTools`). One issue per allow rule. */
79
88
  | "unsupported.allow"
@@ -120,6 +129,9 @@ export interface PermissionRuleCaps {
120
129
  * 的热路径成本上界。 */
121
130
  maxScalarValueChars: number;
122
131
  }
132
+ /** The caps a rule set is held to unless the caller names its own — `maxRules` is the ONE bound on how many rules a set
133
+ * carries, read by the compiler here and by the org layer's list judgment (which refuses a longer list before it is copied). */
134
+ export declare const DEFAULT_CAPS: Readonly<PermissionRuleCaps>;
123
135
  export interface PermissionRulePolicyOptions {
124
136
  /** Invalid/unsupported rules: `"throw"`(default — 部署作者写错要立刻知道)aggregates ALL issues
125
137
  * into one error; `"skip"` drops them (pair with {@link validatePermissionRules} for a report, and/or
@@ -1,10 +1,11 @@
1
1
  import { attest } from "./tool-policy.js";
2
2
  import { MCP_NAMESPACE, protocolOf } from "./protocol-table.js";
3
3
  import { catalogRuleFaceOf, isShellFaceToolName, pathTargetOf } from "./tool-registry.js";
4
- import { indexOfUnescaped, lastIndexOfUnescaped, parsePermissionRule } from "./permission-rule-syntax.js";
5
- import { COMMAND_RULE_TOOL, NAME_RULE_FACES, PATH_RULE_BASE_LABEL, PATH_RULE_FACES, callPathFaceOf, isUsablePathBase, laneToolNamesOf, nameRuleAdmits, nameRuleSubjectOf, parseRuleText, programRunReachOf, ruleBasesNeeded, ruleToolGrammarOf } from "./permission-rule-model.js";
4
+ import { indexOfUnescaped, lastIndexOfUnescaped, parsePermissionRule, ruleSpellingOf } from "./permission-rule-syntax.js";
5
+ import { COMMAND_RULE_TOOL, NAME_RULE_FACES, PATH_RULE_BASE_LABEL, PATH_RULE_FACES, callPathFaceOf, isUsablePathBase, keyedValueAbsentReason, laneToolNamesOf, nameGrammarReads, nameRuleAdmits, nameRuleSubjectOf, parseRuleText, programRunReachOf, ruleBasesNeeded } from "./permission-rule-model.js";
6
6
  import { pathFamilyOf } from "../tools/fs/safety.js";
7
- import { callTargetReadingOf, callTargetViewsOf } from "./effective-path-target.js";
7
+ import { argsAsTheToolReads, callTargetReadingOf, callTargetViewsOf } from "./effective-path-target.js";
8
+ import { canonicalize, UNCANONICALIZABLE } from "./canonical-json.js";
8
9
  import { bindPathRules, judgeRuleRows, policyAnchors, rowsWhereTheyLead } from "./path-rule-binding.js";
9
10
  import { ruleDenialSentence } from "./rule-denial-sentence.js";
10
11
  import { heldValues } from "./tool-name-readings.js";
@@ -24,7 +25,7 @@ function describeBehavior(v) {
24
25
  default: return v === null ? "null" : "an object";
25
26
  }
26
27
  }
27
- const DEFAULT_CAPS = {
28
+ export const DEFAULT_CAPS = {
28
29
  maxRules: 256,
29
30
  maxRuleLength: 512,
30
31
  maxPatternLength: 256,
@@ -50,6 +51,25 @@ function countStars(s) {
50
51
  n++;
51
52
  return n;
52
53
  }
54
+ function unreadableRuleIssue(text) {
55
+ const lenient = parsePermissionRule(text);
56
+ if (!lenient.toolName)
57
+ return { code: "invalid.empty_tool", message: "tool name cannot be empty" };
58
+ if (lenient.ruleContent === undefined && /[()\\]/.test(lenient.toolName)) {
59
+ return { code: "invalid.paren", message: "tool name still contains paren/escape characters — a mis-escaped rule would compile to a dead bare rule" };
60
+ }
61
+ const open = indexOfUnescaped(text, "(");
62
+ if (lenient.ruleContent === undefined && open !== -1) {
63
+ const close = lastIndexOfUnescaped(text, ")");
64
+ const legitimateBare = close === text.length - 1 && ["", "*"].includes(text.substring(open + 1, close));
65
+ if (!legitimateBare)
66
+ return { code: "invalid.paren", message: "malformed parentheses / trailing characters (would silently downgrade to a bare-tool rule)" };
67
+ }
68
+ return {
69
+ code: "invalid.tool_name",
70
+ message: `the tool name is a spelling no tool name can have — the rule syntax reads no rule in it (blanks around the rule, a character outside a tool name's spelling, or one before the "("), so the rule would name no tool; fix the entry`,
71
+ };
72
+ }
53
73
  function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
54
74
  const faceOf = (toolName) => {
55
75
  if (ruleFaces !== undefined) {
@@ -84,24 +104,16 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
84
104
  bad(text, "invalid.cap_exceeded", `rule longer than ${caps.maxRuleLength} chars`);
85
105
  continue;
86
106
  }
87
- const parsed = parsePermissionRule(text);
88
- if (!parsed.toolName) {
89
- bad(text, "invalid.empty_tool", "tool name cannot be empty");
107
+ const parsed = ruleSpellingOf(text);
108
+ if (parsed === undefined) {
109
+ const why = unreadableRuleIssue(text);
110
+ bad(text, why.code, why.message);
90
111
  continue;
91
112
  }
92
- if (parsed.ruleContent === undefined && /[()\\]/.test(parsed.toolName)) {
93
- bad(text, "invalid.paren", "tool name still contains paren/escape characters — a mis-escaped rule would compile to a dead bare rule");
113
+ if (parsed.toolName === "*") {
114
+ bad(text, "invalid.tool_name", `\`*\` names no tool — a rule reaches the tool it names, so this one would compile and never match; name the tool, or state the answer for every call no rule reaches with \`defaultAction\``);
94
115
  continue;
95
116
  }
96
- if (parsed.ruleContent === undefined && indexOfUnescaped(text, "(") !== -1) {
97
- const open = indexOfUnescaped(text, "(");
98
- const close = lastIndexOfUnescaped(text, ")");
99
- const legitimateBare = close === text.length - 1 && ["", "*"].includes(text.substring(open + 1, close));
100
- if (!legitimateBare) {
101
- bad(text, "invalid.paren", "malformed parentheses / trailing characters (would silently downgrade to a bare-tool rule)");
102
- continue;
103
- }
104
- }
105
117
  const toolName = parsed.toolName;
106
118
  const parenthesised = parsed.ruleContent !== undefined || indexOfUnescaped(text, "(") !== -1;
107
119
  if (toolName.startsWith(MCP_NAMESPACE.prefix) && parenthesised) {
@@ -153,7 +165,7 @@ function compile(rules, caps, primaryFieldGeneric, ruleFaces, pathBases = {}) {
153
165
  continue;
154
166
  }
155
167
  const face = resolved.face;
156
- if (ruleToolGrammarOf(toolName) === "name") {
168
+ if (nameGrammarReads(toolName, content)) {
157
169
  const parsedName = parseRuleText(text, verb);
158
170
  if ("reject" in parsedName) {
159
171
  bad(text, "invalid.command_rule", `${parsedName.reject.code}: ${parsedName.reject.message}`);
@@ -231,12 +243,16 @@ export function validatePermissionRules(rules, opts) {
231
243
  function isPlainObjectArgs(args) {
232
244
  return typeof args === "object" && args !== null && !Array.isArray(args);
233
245
  }
234
- function matchParamRules(rules, args, maxScalarValueChars) {
246
+ function matchParamRules(rules, req, maxScalarValueChars) {
247
+ const args = req.args;
235
248
  if (!isPlainObjectArgs(args))
236
249
  return undefined;
237
250
  for (const r of rules) {
238
- if (!Object.hasOwn(args, r.param))
251
+ if (!Object.hasOwn(args, r.param)) {
252
+ if (readingAbsorbs(req, r.param, r.pattern))
253
+ return r;
239
254
  continue;
255
+ }
240
256
  const raw = args[r.param];
241
257
  if (raw === undefined || raw === null)
242
258
  continue;
@@ -251,6 +267,17 @@ function matchParamRules(rules, args, maxScalarValueChars) {
251
267
  }
252
268
  return undefined;
253
269
  }
270
+ function readingAbsorbs(req, param, pattern) {
271
+ if (pattern.includes("*"))
272
+ return false;
273
+ try {
274
+ const read = canonicalize(argsAsTheToolReads(req, { ...req.args, [param]: pattern }));
275
+ return read !== UNCANONICALIZABLE && read === canonicalize(req.args);
276
+ }
277
+ catch {
278
+ return false;
279
+ }
280
+ }
254
281
  function ruleDenial(req, ruleText, source) {
255
282
  return ruleDenialSentence({ source: "permission", tool: req.toolName, rule: ruleText, ...(source ? { origin: source } : {}) });
256
283
  }
@@ -376,6 +403,16 @@ export function createPermissionRulePolicy(rules, opts) {
376
403
  }
377
404
  return unreadable;
378
405
  };
406
+ const keylessRefusal = (entry, req) => {
407
+ for (const r of [...entry.content.deny, ...entry.content.ask]) {
408
+ if (r.parsed.match !== "name" || nameRuleSubjectOf(r.parsed.tool, req.args) !== undefined)
409
+ continue;
410
+ const absent = keyedValueAbsentReason(r.parsed.tool);
411
+ if (absent !== undefined)
412
+ return ruleDenialSentence({ source: "permission", tool: req.toolName, rule: r.ruleText, ...(r.source ? { origin: r.source } : {}), detail: absent });
413
+ }
414
+ return undefined;
415
+ };
379
416
  const unreadableAsk = (hit, lane, req) => ({
380
417
  action: "ask",
381
418
  message: `tool "${req.toolName}" needs approval: the call could not be read against the permission rule ${hit.rule.ruleText} (${hit.unreadable}) — a person must decide`,
@@ -422,11 +459,14 @@ export function createPermissionRulePolicy(rules, opts) {
422
459
  return face !== undefined ? attest(denied, req, { pathDenial: { rule: contentDeny.rule.ruleText, view: contentDeny.view, face } }) : denied;
423
460
  }
424
461
  if (entry) {
425
- const paramDeny = matchParamRules(entry.param.deny, req.args, caps.maxScalarValueChars);
462
+ const paramDeny = matchParamRules(entry.param.deny, req, caps.maxScalarValueChars);
426
463
  if (paramDeny) {
427
464
  return { action: "deny", message: ruleDenial(req, paramDeny.ruleText, paramDeny.source) };
428
465
  }
429
466
  }
467
+ const keyless = entry !== undefined ? keylessRefusal(entry, req) : undefined;
468
+ if (keyless !== undefined)
469
+ return { action: "deny", message: keyless };
430
470
  if (contentDeny?.unreadable !== undefined)
431
471
  return unreadableAsk({ rule: contentDeny.rule, unreadable: contentDeny.unreadable }, "content_deny", req);
432
472
  if (entry) {
@@ -447,7 +487,7 @@ export function createPermissionRulePolicy(rules, opts) {
447
487
  return { action: "ask", message: ruleAskMessage(contentAsk.rule.ruleText, contentAsk.rule.source), matchedAskRule: contentAsk.rule.ruleText };
448
488
  }
449
489
  if (entry) {
450
- const paramAsk = matchParamRules(entry.param.ask, req.args, caps.maxScalarValueChars);
490
+ const paramAsk = matchParamRules(entry.param.ask, req, caps.maxScalarValueChars);
451
491
  if (paramAsk) {
452
492
  return { action: "ask", message: ruleAskMessage(paramAsk.ruleText, paramAsk.source), matchedAskRule: paramAsk.ruleText };
453
493
  }
@@ -1,8 +1,8 @@
1
- /** The named sections whose entries the host may dispose of — a closed set. */
1
+ import type { LegModBus } from "./mods/stations.js";
2
+ /** The named sections whose entries the host may dispose of — a closed set (the event's `name`). */
2
3
  export declare const DISPOSABLE_PROMPT_SECTIONS: readonly ["core/discovery.mcp-instructions"];
3
4
  export type DisposablePromptSection = (typeof DISPOSABLE_PROMPT_SECTIONS)[number];
4
- /** One entry of a named section, as the engine computed it, before it reaches the model. A frozen copy:
5
- * writing to it changes nothing. */
5
+ /** One entry of a named section, as the engine computed it, before it reaches the model. */
6
6
  export interface PromptSectionEntry {
7
7
  readonly section: DisposablePromptSection;
8
8
  /** The entry's key within the section: the MCP server's declared name. */
@@ -12,35 +12,16 @@ export interface PromptSectionEntry {
12
12
  /** The tools this leg mounted from that server, by their namespaced names. */
13
13
  readonly mountedTools: readonly string[];
14
14
  }
15
- /** The host's answer. `undefined` = include the entry as computed. */
16
- export type PromptSectionDisposition = {
17
- readonly op: "drop";
18
- } | {
19
- readonly op: "replace";
20
- readonly text: string;
21
- };
22
15
  /** Who wrote the text an entry carries into the model's view. */
23
16
  export type PromptSectionAuthor = "server" | "host";
24
- export interface PromptSectionSeat {
25
- /**
26
- * Answer the disposition of one entry of a named section ({@link DISPOSABLE_PROMPT_SECTIONS}): return
27
- * nothing to include it, `{ op: "drop" }` to leave it out of the model's view on every lane, or
28
- * `{ op: "replace", text }` to place the host's own non-blank text instead — host text, rendered
29
- * without the untrusted-data fence the server's text rides in, under the same per-entry bound and the same
30
- * disclosed cut. Called once each time the entry's text
31
- * enters the run (a re-dial asks again). Synchronous. A throw, a Promise, or any other value includes
32
- * the entry and raises a coded operator warning (`prompt.section_answer_invalid`).
33
- */
34
- section?(entry: PromptSectionEntry): PromptSectionDisposition | undefined;
35
- }
36
17
  /** One server's entry of the MCP instructions section as the run carries it, after the host's disposition. */
37
18
  export interface McpInstructionsEntry {
38
19
  readonly server: string;
39
20
  readonly text: string;
40
21
  readonly author: PromptSectionAuthor;
41
22
  }
42
- /** What one fold leaves in the run: the entry's text and author, absent when dropped, plus the defect
43
- * sentence when the answer could not be read. */
23
+ /** What one disposition leaves in the run: the entry's text and author, absent when dropped, plus the defect
24
+ * sentence when an answer could not be taken. */
44
25
  export interface DisposedSectionEntry {
45
26
  readonly kept?: {
46
27
  readonly text: string;
@@ -48,7 +29,14 @@ export interface DisposedSectionEntry {
48
29
  };
49
30
  readonly defect?: string;
50
31
  }
51
- /** Read the seat's answer for one entry. Each member of the answer is read once. */
52
- export declare function disposeSectionEntry(seat: PromptSectionSeat | undefined, entry: PromptSectionEntry): DisposedSectionEntry;
53
- /** The operator warning for an answer the fold could not read. */
32
+ /** The disposition the dial reads: one entry in, its disposition out. */
33
+ export type PromptSectionDisposer = (entry: PromptSectionEntry) => Promise<DisposedSectionEntry>;
34
+ /**
35
+ * The disposer over the leg's bus, or undefined when no handler hangs on `prompt.section` (the dial then keeps
36
+ * every entry as computed, with nothing raised).
37
+ */
38
+ export declare function sectionDisposerOf(bus: LegModBus | undefined, signal?: AbortSignal): PromptSectionDisposer | undefined;
39
+ /** One entry's disposition at its dial: the leg's disposer when one is wired, else the entry as the engine computed it. */
40
+ export declare function disposeSectionEntry(disposer: PromptSectionDisposer | undefined, entry: PromptSectionEntry): Promise<DisposedSectionEntry>;
41
+ /** The operator warning for an answer the station could not take. */
54
42
  export declare function sectionAnswerWarning(defect: string): Error;
@@ -1,48 +1,81 @@
1
- import { thrownText } from "./thrown-value.js";
1
+ import { bandOf } from "../prompt-assembly/bands.js";
2
+ import { lockedTextIn, receivePromptData } from "../prompt-assembly/overlay.js";
2
3
  import { inlineUntrusted } from "./untrusted-text.js";
3
- import { egressText } from "./untrusted-egress.js";
4
+ import { egressThrownText, extensionWords } from "./untrusted-egress.js";
4
5
  export const DISPOSABLE_PROMPT_SECTIONS = Object.freeze(["core/discovery.mcp-instructions"]);
5
- const ANSWER_KEYS = { drop: ["op"], replace: ["op", "text"] };
6
- const FOREIGN_VALUE_MAX = 200;
7
- const STRAY_KEYS_NAMED = 5;
8
6
  const DEFECT_MAX = 600;
9
- const foreign = (s, max) => inlineUntrusted(egressText("same-principal", s), max);
10
- export function disposeSectionEntry(seat, entry) {
11
- const computed = { text: entry.text, author: "server" };
12
- if (seat?.section === undefined)
13
- return { kept: computed };
14
- const offered = Object.freeze({ ...entry, mountedTools: Object.freeze([...entry.mountedTools]) });
15
- const where = `prompt section "${entry.section}" entry "${inlineUntrusted(entry.server, 160)}"`;
16
- const unread = (why) => ({ kept: computed, defect: inlineUntrusted(`${where}: ${why} — the entry is included as the engine computed it`, DEFECT_MAX) });
17
- try {
18
- const answer = seat.section(offered);
19
- if (answer === undefined)
20
- return { kept: computed };
21
- if (answer === null || typeof answer !== "object")
22
- return unread(`the answer is ${answer === null ? "null" : typeof answer}, not undefined, { op: "drop" } or { op: "replace", text }`);
23
- const record = answer;
24
- if (typeof record["then"] === "function") {
25
- void Promise.resolve(answer).catch(() => undefined);
26
- return unread("the section seat returned a Promise; it is synchronous");
7
+ function readAnswer(answer, seat) {
8
+ if (typeof answer !== "object" || answer === null || Array.isArray(answer))
9
+ return `answered ${answer === null ? "null" : Array.isArray(answer) ? "an array" : typeof answer}; prompt.section takes { text: string | null }`;
10
+ const received = receivePromptData(answer);
11
+ if ("notData" in received)
12
+ return `a prompt.section answer is data (plain objects, arrays, strings, booleans); it holds ${received.notData}`;
13
+ const data = received.value;
14
+ const keys = Object.keys(data);
15
+ const stray = keys.filter((k) => k !== "text");
16
+ if (stray.length > 0)
17
+ return `the answer carries ${stray.slice(0, 5).map((k) => JSON.stringify(extensionWords(k, 40))).join(", ")} (text only)`;
18
+ if (!keys.includes("text"))
19
+ return "the answer has no text (a string to place, null to leave the entry out)";
20
+ const text = data["text"];
21
+ const op = text === null ? "drop" : "replace";
22
+ if (text !== null && (typeof text !== "string" || text.trim() === ""))
23
+ return `text is ${typeof text === "string" ? "blank" : typeof text}; it is a non-blank string or null`;
24
+ const source = seat === "deployment" ? "deploy" : "task";
25
+ if (!bandOf("discovery").ops[source].includes(op))
26
+ return `a ${source} answer may not ${op} a discovery entry`;
27
+ if (typeof text === "string") {
28
+ const hits = lockedTextIn(text);
29
+ if (hits.length > 0)
30
+ return `the text contains, verbatim, the locked text of ${[...new Set(hits.map((h) => h.split("#")[0]))].join(", ")}`;
31
+ }
32
+ return { text };
33
+ }
34
+ export function sectionDisposerOf(bus, signal) {
35
+ if (bus === undefined || !bus.hasHandlers("prompt.section"))
36
+ return undefined;
37
+ return async (entry) => {
38
+ const computed = { text: entry.text, author: "server" };
39
+ const where = `prompt section "${entry.section}" entry "${inlineUntrusted(entry.server, 160)}"`;
40
+ const e = { name: entry.section, key: entry.server, mountedTools: Object.freeze([...entry.mountedTools]), text: entry.text };
41
+ const bottom = Object.freeze({ text: entry.text });
42
+ const taken = new WeakMap([[bottom, entry.text]]);
43
+ let outcome;
44
+ try {
45
+ outcome = await bus.dispatch("prompt.section", e, {
46
+ bottom: () => bottom,
47
+ ...(signal !== undefined ? { signal } : {}),
48
+ checkAnswer: (a, _e, by) => {
49
+ if (typeof a === "object" && a !== null && taken.has(a))
50
+ return undefined;
51
+ const read = readAnswer(a, by.seat);
52
+ if (typeof read === "string")
53
+ return read;
54
+ taken.set(a, read.text);
55
+ return undefined;
56
+ },
57
+ });
27
58
  }
28
- const op = record["op"];
29
- const text = record["text"];
30
- if (op !== "drop" && op !== "replace")
31
- return unread(`the answer's op is ${typeof op === "string" ? `"${foreign(op, 40)}"` : typeof op}, not "drop" or "replace"`);
32
- const stray = Object.keys(record).filter((k) => !ANSWER_KEYS[op].includes(k));
33
- if (stray.length > 0) {
34
- const named = stray.slice(0, STRAY_KEYS_NAMED).map((k) => foreign(k, 40)).join(", ");
35
- return unread(`a "${op}" answer carries ${named}${stray.length > STRAY_KEYS_NAMED ? ` and ${stray.length - STRAY_KEYS_NAMED} more` : ""}`);
59
+ catch (err) {
60
+ return { kept: computed, defect: inlineUntrusted(`${where}: the station could not be raised (${inlineUntrusted(egressThrownText("same-principal", err), 200)}) — the entry is included as the engine computed it`, DEFECT_MAX) };
36
61
  }
37
- if (op === "drop")
38
- return {};
39
- if (typeof text !== "string" || text.trim() === "")
40
- return unread(`a "replace" answer needs non-blank text`);
41
- return { kept: { text, author: "host" } };
42
- }
43
- catch (err) {
44
- return unread(`the section seat (or reading its answer) threw (${foreign(thrownText(err), FOREIGN_VALUE_MAX)})`);
45
- }
62
+ if (outcome.kind === "aborted")
63
+ return { kept: computed };
64
+ const skipped = outcome.skipped.map((s) => `extension "${extensionWords(s.registration, 80)}" ${s.cause === "violation" ? "gave an answer the station cannot take" : s.cause}: ${extensionWords(s.reason, 200)}`);
65
+ const defect = skipped.length > 0 ? inlineUntrusted(`${where}: ${skipped.join("; ")} — that answer is skipped; what is below it stands`, DEFECT_MAX) : undefined;
66
+ if (outcome.kind === "failed")
67
+ return { kept: computed, ...(defect !== undefined ? { defect } : {}) };
68
+ const answer = outcome.answer;
69
+ const text = typeof answer === "object" && answer !== null ? taken.get(answer) : undefined;
70
+ if (text === undefined) {
71
+ return { kept: computed, defect: inlineUntrusted(`${where}: the chain's answer is not one the station took — the entry is included as the engine computed it`, DEFECT_MAX) };
72
+ }
73
+ const disposed = text === null ? {} : typeof text === "string" && text !== entry.text ? { kept: { text, author: "host" } } : { kept: computed };
74
+ return { ...disposed, ...(defect !== undefined ? { defect } : {}) };
75
+ };
76
+ }
77
+ export function disposeSectionEntry(disposer, entry) {
78
+ return disposer === undefined ? Promise.resolve({ kept: { text: entry.text, author: "server" } }) : disposer(entry);
46
79
  }
47
80
  export function sectionAnswerWarning(defect) {
48
81
  return Object.assign(new Error(defect), { code: "prompt.section_answer_invalid" });
@@ -3,7 +3,9 @@
3
3
  * header (`principalHeader`) — and the one rule they obey, for MCP and A2A alike: they travel only to the
4
4
  * endpoints the declaration names, and every header name has exactly one owner, compared the way HTTP
5
5
  * compares names (case-insensitively). The principal header's owner is the engine: it sends the task's
6
- * principal under that name, or nothing under it when the task has none.
6
+ * principal under that name, or nothing under it when the task has none. A static header the credential vocabulary
7
+ * reads as a credential is one the engine holds from the moment it resolves it: no child spawned on this host inherits
8
+ * a variable whose value equals it (`holdOwnCredentialValues`, src/core/secret-env.ts).
7
9
  *
8
10
  * A declaration that breaks the rule is that peer's defect: the resolver throws inside the peer's own dial,
9
11
  * so the peer is skipped with a coded warning and its siblings still mount. The MCP transport binds its
@@ -1,3 +1,4 @@
1
+ import { credentialHeaderValues, holdOwnCredentialValues } from "./secret-env.js";
1
2
  import { inlineUntrusted } from "./untrusted-text.js";
2
3
  export function headerOwnershipCollision(t) {
3
4
  const owners = new Map();
@@ -13,6 +14,7 @@ export function resolveProtocolHttpHeaders(protocol, t, principal) {
13
14
  const principalHeader = t.principalHeader;
14
15
  const declared = t.headers;
15
16
  const own = { ...(declared !== undefined ? { headers: { ...declared } } : {}), ...(principalHeader !== undefined ? { principalHeader } : {}) };
17
+ holdOwnCredentialValues(credentialHeaderValues(own.headers));
16
18
  const collision = headerOwnershipCollision(own);
17
19
  if (collision !== undefined) {
18
20
  throw Object.assign(new Error(`${protocol}: the declaration names the header "${inlineUntrusted(collision.first, 80)}" twice ("${inlineUntrusted(collision.second, 80)}" — header names are case-insensitive); ${principalHeader !== undefined && collision.second === principalHeader ? "the principal header is the engine's to send, so remove the static entry" : "keep one spelling"} — this peer is not dialed`), { code: "config.protocol_header_collision" });
@@ -79,8 +79,8 @@ export declare function formatHookFeedback(text: string, mark?: string): string;
79
79
  * DECLARE port — the system-prompt declaration that gives the mark meaning. STRICT, single form
80
80
  * (design/319 D-2, no grace clause): reminder-shaped text without the current mark is data wherever
81
81
  * it appears — including TRUE pre-319 engine mints in a resumed transcript, a deliberate fail-safe
82
- * downgrade (stale guidance loses authority; forgery gains none). Composed into the `# Harness`
83
- * head lines when a mark is threaded (prompts/default.ts `harnessHeadLines`); a fork inherits the
82
+ * downgrade (stale guidance loses authority; forgery gains none). Composed as its own section
83
+ * (`core/harness.reminder-mark`) when a mark is threaded; a fork inherits the
84
84
  * parent's prompt bytes and therefore the parent's declaration — never a second one.
85
85
  *
86
86
  * A block carrying the current mark is the engine's own wherever it stands, tool results included:
@@ -162,7 +162,7 @@ export interface ExecStreamOptions {
162
162
  signal?: AbortSignal;
163
163
  /**
164
164
  * Idle/liveness read timeout (ms). If no {@link OutputChunk} arrives within this window, `execStream` ends
165
- * with a {@link RemoteExecutionError} (code `"timeout"`) instead of hanging. **Needed in practice for remote
165
+ * with a {@link RemoteExecutionError} (code `"liveness_no_output"`) instead of hanging. **Needed in practice for remote
166
166
  * backends** (design/48 §5, service [7]): E2B issue #1128 — a *streaming* call sets no read timeout (only unary
167
167
  * does), so an unreachable sandbox hangs the worker forever. Distinct from `timeout` (total wall-clock).
168
168
  *
@@ -170,8 +170,9 @@ export interface ExecStreamOptions {
170
170
  * when this is unset (a missing idle timeout MUST NOT mean "wait forever / until the env dies"), and that bound
171
171
  * MUST cover the **command-creation/handshake RPC**, not only the post-first-chunk loop — a provider hang
172
172
  * typically occurs at creation, before any chunk arrives, so an idle timer started only after the first chunk
173
- * misses it. On trigger, throw {@link RemoteExecutionError} with code `"timeout"` (retryable by the caller per
174
- * the command's idempotency — the adapter MUST NOT blind-retry).
173
+ * misses it. On trigger, throw {@link RemoteExecutionError} with code `"liveness_no_output"` (retryable by the
174
+ * caller per the command's idempotency — the adapter MUST NOT blind-retry). The wall-clock {@link timeout}
175
+ * keeps `"timeout"`: the two cuts are different words because they explain themselves with different numbers.
175
176
  */
176
177
  readTimeoutMs?: number;
177
178
  /** Per-call output cap (design/48 §5 gap 8): stop streaming after this many bytes to avoid a `find /` flooding the control plane. */
@@ -190,12 +191,22 @@ export type RemoteExecutionErrorCode =
190
191
  /** The command/stream was aborted via its `AbortSignal`. */
191
192
  | "aborted"
192
193
  /**
193
- * A command's wall-clock {@link ExecStreamOptions.timeout} or liveness {@link ExecStreamOptions.readTimeoutMs}
194
- * was exceeded — including a provider RPC hang at command creation (service [45]/[59]). **Retryable** by the
195
- * caller per the command's idempotency (the adapter MUST NOT blind-retry). Distinct from `"aborted"` (a
196
- * caller-driven `AbortSignal`) and `"connect_failed"` (workspace provisioning, not a per-command hang).
194
+ * A bound on elapsed time was exceeded: a command's wall-clock {@link ExecStreamOptions.timeout}, or the idle
195
+ * bound of a lifecycle / filesystem RPC (service [45]/[59]). **Retryable** by the caller per the op's
196
+ * idempotency (the adapter MUST NOT blind-retry). Distinct from `"aborted"` (a caller-driven `AbortSignal`),
197
+ * `"connect_failed"` (workspace provisioning, not a per-command hang) and `"liveness_no_output"` (an exec
198
+ * stream's silence window — below).
197
199
  */
198
200
  | "timeout"
201
+ /**
202
+ * An exec stream produced no {@link OutputChunk} for its liveness window ({@link ExecStreamOptions.readTimeoutMs},
203
+ * or the adapter's default bound) — including a provider RPC hang at command creation, before the first chunk
204
+ * (service [45]/[59]). A hang detector, not a budget: it is the word for the cut that used to share `"timeout"`
205
+ * with the wall-clock budget, and the two explain themselves with different numbers (the window versus the
206
+ * budget the caller asked for), so a consumer must be able to tell them apart by code. **Retryable** by the
207
+ * caller per the command's idempotency (the adapter MUST NOT blind-retry), exactly as `"timeout"` is.
208
+ */
209
+ | "liveness_no_output"
199
210
  /**
200
211
  * The op is not supported by this adapter's capabilities (design/61 §9 A) — e.g. `suspendVM`/`resumeVM` on a
201
212
  * non-suspendable SSH/ADB env. Permanent for this env; check {@link RemoteExecutionEnv.capabilities} first.
@@ -235,8 +246,8 @@ export type RemoteExecutionErrorCode =
235
246
  /**
236
247
  * The RETRYABLE half of {@link RemoteExecutionErrorCode} — the codes whose own contract above says a retry
237
248
  * can succeed (`auth_transient`: retry-exactly-once after the device is authorized; `connect_failed`: the
238
- * workspace could not be reached/provisioned this attempt; `timeout`: a liveness bound tripped;
239
- * `transport_lost`: re-establish the connection). Every OTHER code is permanent for this attempt
249
+ * workspace could not be reached/provisioned this attempt; `timeout` / `liveness_no_output`: a time bound
250
+ * tripped; `transport_lost`: re-establish the connection). Every OTHER code is permanent for this attempt
240
251
  * (`auth_failed`/`unsupported`), caller-driven (`aborted`), unclassifiable (`unknown`), or
241
252
  * outcome-unknowable (`outcome_unknown` — design/380 O12: the op may have ALREADY executed, so a retry
242
253
  * re-drives committed side effects) — retrying them burns budget or, worse, re-drives a rejected
@@ -284,8 +295,8 @@ export declare class RemoteExecutionError extends Error {
284
295
  * wall-clock would false-kill the (durable-checkpoint *命门*) path. So such ops bound on an **idle/no-heartbeat**
285
296
  * window (reset by observable progress), not total elapsed time. Cheap control RPCs (`isRunning`, a small
286
297
  * `connect` handshake) may use a short wall-clock. The adapter sizes the bound per op class.
287
- * 3. **A liveness breach surfaces as a typed, retryable error**: `RemoteExecutionError` code `"timeout"` for the
288
- * lifecycle/stream ops; for the inherited filesystem ops (which return the vendored `Result<_, FileError>`),
298
+ * 3. **A liveness breach surfaces as a typed, retryable error**: `RemoteExecutionError` code `"liveness_no_output"`
299
+ * for an exec stream's silence window and `"timeout"` for the lifecycle ops' idle bound; for the inherited filesystem ops (which return the vendored `Result<_, FileError>`),
289
300
  * a `FileError` — but still **bounded, never an unbounded wait**. Retry is the caller's decision per the op's
290
301
  * idempotency; the adapter MUST NOT blind-retry.
291
302
  */
@@ -418,7 +429,8 @@ export interface RemoteExecutionEnv extends ExecutionEnv {
418
429
  * per-command timeout is **independent of the env/sandbox lifetime** and an adapter MUST NOT fall back to the
419
430
  * lifetime when none is given (else a hung provider RPC pins the worker for the whole sandbox lifetime). An
420
431
  * adapter SHOULD enforce a bounded default liveness/idle timeout that also covers the command-creation RPC, and
421
- * surface a liveness/timeout breach as a typed, retryable {@link RemoteExecutionError} code `"timeout"`. See
432
+ * surface a silence breach as a typed, retryable {@link RemoteExecutionError} code `"liveness_no_output"` and a
433
+ * wall-clock breach as `"timeout"`. See
422
434
  * {@link ExecStreamOptions.timeout} / {@link ExecStreamOptions.readTimeoutMs}.
423
435
  */
424
436
  execStream(command: string, options?: ExecStreamOptions): AsyncIterable<OutputChunk>;
@@ -2,6 +2,7 @@ export const RETRYABLE_REMOTE_ERROR_CODES = [
2
2
  "auth_transient",
3
3
  "connect_failed",
4
4
  "timeout",
5
+ "liveness_no_output",
5
6
  "transport_lost",
6
7
  ];
7
8
  export function isRetryableRemoteErrorCode(code) {
@@ -9,6 +9,10 @@
9
9
  * · `environment` — the leg's infrastructure failed (the workspace restore, an abort): the decision is
10
10
  * untouched, and a retry replays it;
11
11
  * · `session_gone` — the resumed agent's transcript session is missing;
12
+ * · `transcript_corrupt` — the resumed agent's transcript session is THERE but cannot be read as a session: its log
13
+ * has no header its store wrote (`corrupt_session`), or its entry tree is structurally unusable — a leaf or parent
14
+ * entry that is not in the log (`invalid_session`). Distinct from `session_gone`: the bytes exist, so deleting or
15
+ * restoring the transcript is the remedy, not re-creating a session;
12
16
  * · `tool_unavailable` — the approved tool is not available to the resumed leg (gone, replaced by a
13
17
  * different contract, or an inherited tool the drive cannot hand over): this approval cannot run, and a
14
18
  * fresh decision resolves it;
@@ -18,6 +22,7 @@
18
22
  * · `decision_rejected` — the supplied decision does not fit the checkpoint (another gate's answer, an
19
23
  * unsafe payload, an input the constraints refuse): correct the decision and resubmit.
20
24
  */
25
+ import type { AssertAllKeysHandled } from "./ask-origin.js";
21
26
  /**
22
27
  * design/80 D-1: why a consumed checkpoint was {@link import("./checkpoint-store.js").CheckpointStore.reopen | reopened}
23
28
  * (resolved → pending). The reason drives re-resume validation (§3 invariant #1): an `env_failed` reopen is a SYSTEM
@@ -41,11 +46,20 @@
41
46
  */
42
47
  export declare const REOPEN_REASONS: readonly ["env_failed", "tool_unavailable", "constraint_rejected", "config_refused"];
43
48
  export type ReopenReason = (typeof REOPEN_REASONS)[number];
44
- export declare const RESUME_STARTUP_CAUSES: readonly ["environment", "session_gone", "tool_unavailable", "configuration", "decision_rejected"];
49
+ export declare const RESUME_STARTUP_CAUSES: readonly ["environment", "session_gone", "transcript_corrupt", "tool_unavailable", "configuration", "decision_rejected"];
45
50
  export type ResumeStartupCause = (typeof RESUME_STARTUP_CAUSES)[number];
46
51
  /** The cause a resume failure's code names; `undefined` when the code is absent or the table does not
47
52
  * name it. Every `config.*` code is a configuration door's refusal. */
48
53
  export declare function resumeStartupCauseOf(code: string | undefined): ResumeStartupCause | undefined;
54
+ declare const REOPEN_REASON_OF_CAUSE: {
55
+ readonly environment: "env_failed";
56
+ readonly session_gone: "env_failed";
57
+ readonly transcript_corrupt: "env_failed";
58
+ readonly tool_unavailable: "tool_unavailable";
59
+ readonly configuration: "config_refused";
60
+ readonly decision_rejected: "constraint_rejected";
61
+ };
62
+ export type ReopenReasonTableCoversEveryCause = AssertAllKeysHandled<Exclude<ResumeStartupCause, keyof typeof REOPEN_REASON_OF_CAUSE>>;
49
63
  /**
50
64
  * The reason a consumed checkpoint whose approved action never started returns to pending under. A failure
51
65
  * whose cause is not known reopens as `env_failed`: the leg went away before the action ran, the human's
@@ -54,3 +68,4 @@ export declare function resumeStartupCauseOf(code: string | undefined): ResumeSt
54
68
  export declare function reopenReasonOf(cause: ResumeStartupCause | undefined): ReopenReason;
55
69
  /** What the result of a returned resume leg says after its checkpoint was reopened, per reason. */
56
70
  export declare function reopenedUnstartedSentence(reason: ReopenReason): string;
71
+ export {};
@@ -1,9 +1,11 @@
1
1
  export const REOPEN_REASONS = Object.freeze(["env_failed", "tool_unavailable", "constraint_rejected", "config_refused"]);
2
- export const RESUME_STARTUP_CAUSES = Object.freeze(["environment", "session_gone", "tool_unavailable", "configuration", "decision_rejected"]);
2
+ export const RESUME_STARTUP_CAUSES = Object.freeze(["environment", "session_gone", "transcript_corrupt", "tool_unavailable", "configuration", "decision_rejected"]);
3
3
  const CAUSE_OF_CODE = new Map([
4
4
  ["resume.env_failed", "environment"],
5
5
  ["checkpoint.resume_aborted", "environment"],
6
6
  ["resume.session_not_found", "session_gone"],
7
+ ["corrupt_session", "transcript_corrupt"],
8
+ ["invalid_session", "transcript_corrupt"],
7
9
  ["resume.tool_unavailable", "tool_unavailable"],
8
10
  ["resume.tool_contract_mismatch", "tool_unavailable"],
9
11
  ["checkpoint.config_refused", "configuration"],
@@ -22,6 +24,7 @@ export function resumeStartupCauseOf(code) {
22
24
  const REOPEN_REASON_OF_CAUSE = {
23
25
  environment: "env_failed",
24
26
  session_gone: "env_failed",
27
+ transcript_corrupt: "env_failed",
25
28
  tool_unavailable: "tool_unavailable",
26
29
  configuration: "config_refused",
27
30
  decision_rejected: "constraint_rejected",
@@ -1,3 +1,4 @@
1
+ import { describeRejectedValue } from "./tool-search-setting.js";
1
2
  export const RETENTION_CASCADE_DOMAINS = Object.freeze(["checkpoints", "session-trees", "orphan-tool-results"]);
2
3
  export const RETENTION_CASCADE_EXEMPT = Object.freeze(["session-pollution", "session-capture-optout", "lineage.json"]);
3
4
  function codedError(code, message) {
@@ -7,8 +8,12 @@ function codedError(code, message) {
7
8
  }
8
9
  export function assertRetentionCapability(input) {
9
10
  const { policy, locked, stores } = input;
11
+ const declared = policy;
12
+ if (declared !== undefined && (typeof declared !== "object" || declared === null || Array.isArray(declared))) {
13
+ throw codedError("config.retention_policy", `retentionPolicy must be an object carrying maxAgeDays (got ${declared === null ? "null" : Array.isArray(declared) ? "an array" : typeof declared}).`);
14
+ }
10
15
  if (policy !== undefined && (!Number.isFinite(policy.maxAgeDays) || policy.maxAgeDays < 0)) {
11
- throw codedError("config.retention_policy", `retentionPolicy.maxAgeDays must be a finite non-negative number of days (got ${String(policy.maxAgeDays)}).`);
16
+ throw codedError("config.retention_policy", `retentionPolicy.maxAgeDays must be a finite non-negative number of days (got ${describeRejectedValue(policy.maxAgeDays)}).`);
12
17
  }
13
18
  const declaredRetention = (name, store) => {
14
19
  const r = store.retention;
@@ -19,7 +24,7 @@ export function assertRetentionCapability(input) {
19
24
  throw codedError("config.retention_capability", `store "${name}" declares an unparseable retention value ${JSON.stringify(r)} — expected "managed" or "none".`);
20
25
  };
21
26
  const declarations = stores
22
- .filter((s) => s.store !== undefined)
27
+ .filter((s) => s.store !== undefined && s.store !== null)
23
28
  .map(({ name, store }) => ({ name, retention: declaredRetention(name, store) }));
24
29
  if (!locked || policy === undefined)
25
30
  return;