@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
@@ -1,13 +1,15 @@
1
1
  import { posix } from "node:path";
2
2
  import { isWinFormPath } from "../tools/fs/safety.js";
3
- import { NAMESPACED_NAME_SHAPES, carriesNamespaceSeparator } from "./protocol-table.js";
4
- import { compileAllowList, compiledEntryName, inertEntryPhrase, readRuleEntry, renderListEntry } from "./allow-entry.js";
3
+ import { NAMESPACED_NAME_SHAPES } from "./protocol-table.js";
4
+ import { callerToolNameProblem } from "./caller-tool-name.js";
5
+ import { compileAllowList, compiledEntryName, inertEntryPhrase, readRuleEntry, renderListEntry, rootFacingToolNames } from "./allow-entry.js";
5
6
  import { valueTypeLabel } from "./tool-name-list.js";
7
+ import { noticeRuleText } from "./permission-rule-model.js";
6
8
  const SESSION_RULE_BUCKETS = { toolAllow: "allow", toolDeny: "deny", allowDirs: "dirs" };
7
9
  const BUCKETS = Object.keys(SESSION_RULE_BUCKETS);
8
10
  const ENTRY_FIELDS = BUCKETS.filter((f) => SESSION_RULE_BUCKETS[f] !== "dirs");
9
11
  const STORE_STAMPS = new Set(["rev", "gen", "grammar"]);
10
- export const SESSION_RULES_GRAMMAR = 1;
12
+ export const SESSION_RULES_GRAMMAR = 2;
11
13
  export class SessionPolicyError extends Error {
12
14
  code;
13
15
  detail;
@@ -29,10 +31,11 @@ export function readMountedToolNames(value) {
29
31
  refuse("must be an iterable of tool names (an array or a Set), not a single value");
30
32
  const names = new Set();
31
33
  for (const n of value) {
32
- if (typeof n !== "string" || n.length === 0)
33
- refuse(`holds ${JSON.stringify(n) ?? String(n)}, which is not a non-empty tool name`);
34
- if (carriesNamespaceSeparator(n))
35
- refuse(`holds ${JSON.stringify(n)}: "__" is reserved for protocol tool names and no deployment tool may carry it`);
34
+ if (typeof n !== "string")
35
+ refuse(`holds ${JSON.stringify(n) ?? String(n)}, which is not a tool name`);
36
+ const problem = callerToolNameProblem(n);
37
+ if (problem !== undefined)
38
+ refuse(`holds ${JSON.stringify(n)}: ${problem}`);
36
39
  names.add(n);
37
40
  }
38
41
  return names;
@@ -116,34 +119,122 @@ function canonicalRules(read) {
116
119
  }
117
120
  return out;
118
121
  }
119
- function readsAsNothingIn(grammar, field, entry, compiled) {
120
- return grammar === 0 && SESSION_RULE_BUCKETS[field] === "allow" && compiledEntryName(compiled) !== entry;
122
+ function earlierGrammarReads(grammar, field, entry, reading) {
123
+ if (grammar >= SESSION_RULES_GRAMMAR)
124
+ return false;
125
+ if (reading.kind === "inert" && reading.reason === "grammar")
126
+ return true;
127
+ if (grammar !== 0 || SESSION_RULE_BUCKETS[field] !== "allow")
128
+ return false;
129
+ return reading.kind === "row" ? compiledEntryName(reading.compiled) !== entry : reading.reason === "wildcard_all";
130
+ }
131
+ function readsAsNoRule(entry, field) {
132
+ const reading = readRuleEntry(entry, SESSION_RULE_BUCKETS[field]);
133
+ return reading.kind === "inert" && reading.reason === "grammar";
134
+ }
135
+ const NO_RULE_REASONS = new Set(["grammar", "earlier_grammar"]);
136
+ export function unreadableDenyEntries(rules, roster) {
137
+ return compileSessionRuleBucket(rules, "toolDeny", roster).inert.filter((i) => NO_RULE_REASONS.has(i.reason));
138
+ }
139
+ function readsAsWildcard(entry) {
140
+ return compileAllowList([entry], "allow").inert.some((i) => i.reason === "wildcard_all");
141
+ }
142
+ const STAR_IS_NO_ALLOW_RULE = "it is no allow rule in any grammar and a write holding it is refused";
143
+ function starWayOut(onlyStars, others, left) {
144
+ return onlyStars
145
+ ? `"*" is no allow rule in any grammar (a write holding it is refused); to drop it, write the session's rules afresh without it ${REWRITE_THROUGH}; ${left}`
146
+ : `${others}, leaving "*" out — ${STAR_IS_NO_ALLOW_RULE}; ${left}`;
121
147
  }
122
148
  export function compileSessionRuleBucket(rules, field, roster) {
123
- const list = compileAllowList(rules[field] ?? [], SESSION_RULE_BUCKETS[field], roster);
124
- const rows = list.rows.filter((r) => !readsAsNothingIn(rules.grammar, field, r.entry, r.compiled));
125
- if (rows.length === list.rows.length)
126
- return list;
127
- const earlier = list.rows.filter((r) => readsAsNothingIn(rules.grammar, field, r.entry, r.compiled)).map((r) => ({ entry: r.entry, reason: "earlier_grammar" }));
128
- return { rows, inert: [...list.inert, ...earlier] };
149
+ const direction = SESSION_RULE_BUCKETS[field];
150
+ const entries = rules[field] ?? [];
151
+ const earlier = new Set(entries.filter((e) => earlierGrammarReads(rules.grammar, field, e, readRuleEntry(e, direction, roster))));
152
+ const whole = compileAllowList(entries, direction, roster);
153
+ const voided = direction === "allow" && whole.inert.some((i) => i.reason === "wildcard_all");
154
+ if (earlier.size === 0 || (voided && rules.grammar > 0))
155
+ return whole;
156
+ const list = compileAllowList(entries.filter((e) => !earlier.has(e)), direction, roster);
157
+ return { rows: list.rows, inert: [...list.inert, ...entries.filter((e) => earlier.has(e)).map((entry) => ({ entry, reason: "earlier_grammar" }))] };
129
158
  }
130
159
  const ADVISORY_ENTRIES_SHOWN = 5;
131
- export function earlierGrammarAdvisory(sessionId, entries) {
132
- const one = entries.length === 1;
133
- const shown = entries.slice(0, ADVISORY_ENTRIES_SHOWN).map(renderListEntry).join(", ");
160
+ function shownEntries(entries, render) {
134
161
  const rest = entries.length > ADVISORY_ENTRIES_SHOWN ? ` and ${entries.length - ADVISORY_ENTRIES_SHOWN} more` : "";
135
- return (`session permission rules of session ${JSON.stringify(sessionId)}: toolAllow ${shown}${rest} ${one ? "was" : "were"} stored before the rule grammar stamp, when session rules compared an entry as a tool name as written, so a parenthesized entry named no tool — ` +
136
- `${one ? "it admits" : "they admit"} nothing, as when written. To make ${one ? "it an allow rule" : "them allow rules"}, write the session's rules afresh through this engine (an operator write of a value without the stored row's rev; the write stamps grammar ${SESSION_RULES_GRAMMAR}); left as stored, ${one ? "it keeps" : "they keep"} admitting nothing.`);
162
+ return `${entries.slice(0, ADVISORY_ENTRIES_SHOWN).map(render).join(", ")}${rest}`;
163
+ }
164
+ const REWRITE_THROUGH = `through this engine (an operator write of a new value without the stored row's rev; the write stamps grammar ${SESSION_RULES_GRAMMAR})`;
165
+ export function earlierGrammarAdvisory(sessionId, entries, field, grammar) {
166
+ const read = earlierGrammarReadings(entries, field);
167
+ const noRule = read.filter((r) => r.reader === "no_rule").map((r) => r.entry);
168
+ const namedNoTool = read.filter((r) => r.reader === "named_no_tool").map((r) => r.entry);
169
+ const sentences = [...(namedNoTool.length > 0 ? [namedNoToolInGrammar0(namedNoTool)] : []), ...(noRule.length > 0 ? [noRuleInThisGrammar(noRule, field, grammar)] : [])];
170
+ return `session permission rules of session ${JSON.stringify(sessionId)}: ${sentences.join(" ")}`;
171
+ }
172
+ function earlierGrammarReadings(entries, field) {
173
+ return entries.map((entry) => ({ entry, reader: readsAsNoRule(entry, field) ? "no_rule" : "named_no_tool" }));
174
+ }
175
+ export function earlierGrammarNotice(input) {
176
+ const { rulesSessionId, sessionId, entries, field, grammar } = input;
177
+ return {
178
+ code: "config.session_rules_earlier_grammar",
179
+ message: earlierGrammarAdvisory(rulesSessionId, entries, field, grammar),
180
+ detail: {
181
+ bucket: field,
182
+ storedGrammar: grammar,
183
+ entries: earlierGrammarReadings(entries, field).map((r) => ({ entry: noticeRuleText(r.entry), reader: r.reader })),
184
+ rewrite: { by: "operator_write_without_rev", stampsGrammar: SESSION_RULES_GRAMMAR },
185
+ rulesSessionId,
186
+ sessionId,
187
+ },
188
+ };
189
+ }
190
+ function namedNoToolInGrammar0(entries) {
191
+ const one = entries.length === 1;
192
+ const wildcard = entries.some(readsAsWildcard);
193
+ const rules = entries.some((e) => !readsAsWildcard(e));
194
+ const left = `left as stored, ${one ? "it keeps" : "they keep"} admitting nothing.`;
195
+ const way = !wildcard
196
+ ? `To make ${one ? "it an allow rule" : "them allow rules"}, write the session's rules afresh ${REWRITE_THROUGH}; ${left}`
197
+ : starWayOut(!rules, `To make the parenthesized ones allow rules, write the session's rules afresh ${REWRITE_THROUGH}`, left);
198
+ return (`toolAllow ${shownEntries(entries, renderListEntry)} ${one ? "was" : "were"} stored before the rule grammar stamp, when session rules compared an entry as a tool name as written, so ${wildcard ? 'an entry that is no bare tool name (a parenthesized rule, or "*")' : "a parenthesized entry"} named no tool — ` +
199
+ `${one ? "it admits" : "they admit"} nothing, as when written${wildcard ? "; the rest of the list is read as written, not voided" : ""}. ${way}`);
200
+ }
201
+ function noRuleInThisGrammar(entries, field, grammar) {
202
+ const one = entries.length === 1;
203
+ const stored = `${field} ${shownEntries(entries, (entry) => inertEntryPhrase({ entry, reason: "grammar" }))} ${one ? "was" : "were"} stored in rule grammar ${grammar}${grammar === 0 ? ", before the rule grammar stamp" : ""}, and this engine's rule grammar (${SESSION_RULES_GRAMMAR}) reads ${one ? "it" : "them"} as no rule`;
204
+ const way = `write the session's rules afresh ${REWRITE_THROUGH}, leaving ${one ? "it" : "them"} out or spelling the tool's name as a rule spells one — the write judge refuses an entry it cannot read`;
205
+ if (SESSION_RULE_BUCKETS[field] === "deny") {
206
+ return `${stored}: rules whose toolDeny holds an entry no grammar reads cannot be read, so every call is refused until they are rewritten. To lift that, ${way}, and a non-operator write cannot loosen rules that refuse every call.`;
207
+ }
208
+ const stars = entries.filter(readsAsWildcard).length;
209
+ const left = `left as stored, ${one ? "it keeps" : "they keep"} admitting nothing.`;
210
+ const wayOut = stars === 0
211
+ ? `To allow what ${one ? "it" : "they"} meant, ${way}; ${left}`
212
+ : starWayOut(stars === entries.length, `To allow what the others meant, write the session's rules afresh ${REWRITE_THROUGH}, spelling each tool's name as a rule spells one`, left);
213
+ return `${stored} — ${one ? "it admits" : "they admit"} nothing, and the rest of the list is read as written. ${wayOut}`;
214
+ }
215
+ export function earlierGrammarRefusalClause(entries, grammar) {
216
+ if (entries.length === 0)
217
+ return "";
218
+ const noRule = entries.filter((e) => readsAsNoRule(e, "toolAllow")).length;
219
+ const namedNoTool = entries.filter((e) => !readsAsNoRule(e, "toolAllow"));
220
+ const stars = namedNoTool.filter(readsAsWildcard).length;
221
+ const others = namedNoTool.length - stars;
222
+ const named = [...(stars > 0 ? ['"*"'] : []), ...(others > 0 ? [`${others} parenthesized ${others === 1 ? "entry" : "entries"}`] : [])];
223
+ const clauses = [
224
+ ...(namedNoTool.length > 0 ? [`where ${named.join(" and ")} ${namedNoTool.length === 1 ? "names no tool and admits" : "name no tool and admit"} nothing`] : []),
225
+ ...(noRule > 0 ? [`${namedNoTool.length > 0 ? "and " : "where "}${noRule} ${noRule === 1 ? "entry is" : "entries are"} no rule in this engine's rule grammar (${SESSION_RULES_GRAMMAR}) and ${noRule === 1 ? "admits" : "admit"} nothing`] : []),
226
+ ];
227
+ return `; the session's rules are stored in rule grammar ${grammar}, ${clauses.join(" ")}`;
137
228
  }
138
229
  export function earlierGrammarAnnouncer(sink) {
139
230
  const announced = new Set();
140
- return (entries) => {
141
- const key = JSON.stringify(entries);
231
+ return (entries, field, grammar) => {
232
+ const key = JSON.stringify([field, grammar, entries]);
142
233
  if (sink === undefined || entries.length === 0 || announced.has(key))
143
234
  return;
144
235
  announced.add(key);
145
236
  try {
146
- sink(entries);
237
+ sink(entries, field, grammar);
147
238
  }
148
239
  catch {
149
240
  }
@@ -153,23 +244,36 @@ function effectiveEntries(rules, field, mountedToolNames) {
153
244
  return compileSessionRuleBucket(rules, field, mountedToolNames).rows.map((r) => r.entry);
154
245
  }
155
246
  function assertEntriesRead(rules, mountedToolNames) {
247
+ const known = rootFacingToolNames(mountedToolNames);
156
248
  for (const field of ENTRY_FIELDS) {
157
249
  for (const entry of rules[field] ?? []) {
158
- const reading = readRuleEntry(entry, SESSION_RULE_BUCKETS[field], mountedToolNames);
159
- const read = reading.kind === "row" && readsAsNothingIn(rules.grammar, field, entry, reading.compiled) ? { kind: "inert", reason: "earlier_grammar" } : reading;
250
+ const reading = readRuleEntry(entry, SESSION_RULE_BUCKETS[field], known);
251
+ const read = earlierGrammarReads(rules.grammar, field, entry, reading) ? { kind: "inert", reason: "earlier_grammar" } : reading;
160
252
  if (read.kind === "row")
161
253
  continue;
162
254
  const { kind: _kind, ...why } = read;
163
255
  void _kind;
164
256
  const way = why.reason === "earlier_grammar"
165
- ? ` These rules are written in grammar ${rules.grammar} (a stored row from before the grammar stamp), in which this entry names no tool. To make it an allow rule, write the rules afresh — a value without the stored row's rev; the write stamps grammar ${SESSION_RULES_GRAMMAR} — or leave the entry out.`
166
- : why.verdict === "retired"
257
+ ? readsAsNoRule(entry, field)
258
+ ? ` These rules are written in grammar ${rules.grammar} (a stored row), and this engine's grammar (${SESSION_RULES_GRAMMAR}) reads this entry as no rule (grammar) — ` +
259
+ (field === "toolAllow" && readsAsWildcard(entry) ? `leave the entry out: it spells "*", and ${STAR_IS_NO_ALLOW_RULE}.` : "leave the entry out, or spell the tool's name as a rule spells one.")
260
+ : ` These rules are written in grammar ${rules.grammar} (a stored row from before the grammar stamp), in which this entry names no tool.` +
261
+ (readsAsWildcard(entry)
262
+ ? ` It is no allow rule in grammar ${SESSION_RULES_GRAMMAR} either (a write holding it is refused) — leave the entry out.`
263
+ : ` To make it an allow rule, write the rules afresh — a value without the stored row's rev; the write stamps grammar ${SESSION_RULES_GRAMMAR} — or leave the entry out.`)
264
+ : why.verdict === "retired" || why.reason === "near_miss"
167
265
  ? ` If this deployment mounts its own tool under ${renderListEntry(entry)}, declare it in the store's mountedToolNames.`
168
266
  : why.currentName === undefined
169
267
  ? ` An entry is a tool name (Read; a protocol tool is named ${NAMESPACED_NAME_SHAPES}), a protocol namespace (mcp__<server>), or a rule in its tool's own grammar (Bash(<command>), Edit(<path>), Skill(<name>), WebFetch(domain:<host>)).`
170
268
  : "";
171
269
  const sentence = why.guidance !== undefined ? ` — ${why.guidance}` : "";
172
- throw new SessionPolicyError("inert_entry", `session rules ${field} holds ${inertEntryPhrase({ entry, ...why })}, which ${SESSION_RULE_BUCKETS[field] === "deny" ? "refuses" : "admits"} nothing as written${sentence}; nothing was written.${way}`, { field, entry, ...why });
270
+ const does = SESSION_RULE_BUCKETS[field] === "allow"
271
+ ? "admits nothing as written"
272
+ : NO_RULE_REASONS.has(why.reason)
273
+ ? "refuses every call as stored (rules whose toolDeny holds an entry no grammar reads cannot be read) — a write holding it is refused"
274
+ : "refuses nothing as written";
275
+ const carriedBy = why.reason === "near_miss" && why.currentName !== undefined && !mountedToolNames.has(why.currentName) ? { carriedBy: "catalog" } : {};
276
+ throw new SessionPolicyError("inert_entry", `session rules ${field} holds ${inertEntryPhrase({ entry, ...why, ...carriedBy })}, which ${does}${sentence}; nothing was written.${way}`, { field, entry, ...why });
173
277
  }
174
278
  }
175
279
  }
@@ -201,6 +305,12 @@ export function loosenReasons(priorValue, nextValue, mountedToolNames = NO_DECLA
201
305
  };
202
306
  const prior = shapeOf("prior", priorValue);
203
307
  const next = shapeOf("next", nextValue);
308
+ if (unreadableDenyEntries(next, mountedToolNames).length > 0)
309
+ return [];
310
+ const unreadPrior = unreadableDenyEntries(prior, mountedToolNames);
311
+ if (unreadPrior.length > 0) {
312
+ return [`the prior rules refuse every call — their toolDeny holds ${shownEntries(unreadPrior.map((i) => i.entry), (entry) => inertEntryPhrase({ entry, reason: "grammar" }))}, which no grammar reads`];
313
+ }
204
314
  const reasons = [];
205
315
  const keptDeny = new Set(effectiveEntries(next, "toolDeny", mountedToolNames));
206
316
  for (const x of effectiveEntries(prior, "toolDeny", mountedToolNames))
@@ -51,6 +51,9 @@ export interface OrphanToolCall {
51
51
  * message and `errorCode` on the synthetic `tool_end` frame, so a consumer never parses the text. Two-valued
52
52
  * (a third value needs a cross-repo slip, see {@link reconcileInterruptedSession}). */
53
53
  export type ReconciledErrorKind = "interrupted_never_started" | "interrupted_outcome_unknown";
54
+ /** The class that is positive evidence the call never ran: closed with no start observed. The synthetic `tool_end` frame's
55
+ * `notExecuted` (`reconciledEnd`) and the persisted close's `details.notExecuted` both read it — one table, two faces. */
56
+ export declare const closeNeverExecuted: (errorKind: ReconciledErrorKind) => boolean;
54
57
  /** One orphan closed by {@link reconcileInterruptedSession}, with everything the caller needs to mint the
55
58
  * matching stream frame WITHOUT re-reading the session. */
56
59
  export type RecoveredOrphan = OrphanToolCall & {
@@ -153,6 +156,7 @@ export declare function isInterruptedClose(message: {
153
156
  /** The `toolResult` message for one {@link InterruptedResult} — the persisted and the request-view closes are this one shape. */
154
157
  export declare function interruptedResultMessage(result: InterruptedResult, timestamp: number): ToolResultMessage<{
155
158
  errorKind: ReconciledErrorKind;
159
+ notExecuted?: true;
156
160
  }>;
157
161
  /**
158
162
  * Reconcile a resumed session's active branch: close any orphan tool calls with a synthetic
@@ -1,4 +1,5 @@
1
1
  import { readMember } from "./thrown-value.js";
2
+ export const closeNeverExecuted = (errorKind) => errorKind === "interrupted_never_started";
2
3
  const INTERRUPTED_UNKNOWN = "[INTERRUPTED] The previous run ended before this tool call's result was recorded. Its outcome " +
3
4
  "is UNKNOWN — the action may have completed, partially completed, or never run. Do not assume " +
4
5
  "success or failure. Before relying on it: if it is safe to read, query the current state to " +
@@ -119,7 +120,7 @@ export function interruptedResultMessage(result, timestamp) {
119
120
  toolCallId: result.toolCallId,
120
121
  toolName: result.toolName,
121
122
  content: [{ type: "text", text: result.text }],
122
- details: { errorKind: result.errorKind },
123
+ details: { errorKind: result.errorKind, ...(closeNeverExecuted(result.errorKind) ? { notExecuted: true } : {}) },
123
124
  isError: true,
124
125
  timestamp,
125
126
  };
@@ -2,6 +2,7 @@ import { types } from "node:util";
2
2
  import { dispositionsOfRow, SHELL_READ_FINDINGS } from "../tools/fs/shell-read-judge.js";
3
3
  import { receiveContract } from "./decision-receipt.js";
4
4
  import { egressThrownText } from "./untrusted-egress.js";
5
+ import { receive } from "./mods/kernel/receive.js";
5
6
  const DISPOSITIONS = ["refuse", "mandated", "ordinary", "vouch"];
6
7
  const MEMBER_KINDS = {
7
8
  disposition: "word",
@@ -20,37 +21,7 @@ const MEMBER_KINDS = {
20
21
  admit: "admission",
21
22
  };
22
23
  const VERDICT_MEMBERS = Object.keys(MEMBER_KINDS);
23
- const DATA_DEPTH = 8;
24
- function ownedData(value, depth, path) {
25
- if (value === null || value === undefined || typeof value === "string" || typeof value === "number" || typeof value === "boolean")
26
- return { ok: true, value };
27
- if (typeof value !== "object" || depth >= DATA_DEPTH || types.isProxy(value) || path.has(value))
28
- return { ok: false };
29
- const list = Array.isArray(value);
30
- const proto = Object.getPrototypeOf(value);
31
- if (list ? proto !== Array.prototype : proto !== Object.prototype && proto !== null)
32
- return { ok: false };
33
- const own = Object.getOwnPropertyDescriptors(value);
34
- path.add(value);
35
- try {
36
- const out = list ? [] : {};
37
- for (const key of Object.keys(own)) {
38
- if (list && key === "length")
39
- continue;
40
- const d = own[key];
41
- if (!Object.hasOwn(d, "value") || d.enumerable !== true)
42
- return { ok: false };
43
- const inner = ownedData(d.value, depth + 1, path);
44
- if (!inner.ok)
45
- return { ok: false };
46
- Object.defineProperty(out, key, { value: inner.value, enumerable: true, writable: true, configurable: true });
47
- }
48
- return { ok: true, value: out };
49
- }
50
- finally {
51
- path.delete(value);
52
- }
53
- }
24
+ const OWNED_DATA_MODE = Object.freeze({ accessors: "refuse", depth: 8, others: "refuse", isProxy: (v) => types.isProxy(v) });
54
25
  function receivedAnswer(answer, call) {
55
26
  if (typeof answer !== "object" || answer === null)
56
27
  return undefined;
@@ -65,7 +36,7 @@ function receivedAnswer(answer, call) {
65
36
  if (kind === "word" ? typeof v !== "string" : kind === "mark" ? v !== true : kind === "face" ? v !== "write" : kind === "admission" ? typeof v !== "function" || types.isProxy(v) : false)
66
37
  return undefined;
67
38
  if (kind === "record") {
68
- const data = ownedData(v, 0, new Set());
39
+ const data = receive(v, OWNED_DATA_MODE);
69
40
  if (!data.ok || typeof data.value !== "object" || data.value === null || Array.isArray(data.value))
70
41
  return undefined;
71
42
  v = data.value;
@@ -63,9 +63,11 @@ export interface SideQuerySpec {
63
63
  * Per-model auth — MIRRORS {@link TaskSpec.getApiKeyAndHeaders} (same signature, resolved per
64
64
  * call against the RESOLVED model, exactly like the task path's per-call hook). The brain
65
65
  * contract is the route pairing law (route-adjudicator.ts): a per-model credential (this hook,
66
- * or an auth header on `Model.headers`) always rides; the deployment credential rides only to the
67
- * deployment's own root — a model carrying a root of its own is refused
68
- * (`route.credential_mismatch` / `route.credential_missing`), never silently followed.
66
+ * or a credential header on `Model.headers`) rides to the origin it first went out to and is
67
+ * refused anywhere else (`route.credential_origin_mismatch`); an answer handing the key beside
68
+ * the lane's own key header is refused as one verdict (`route.credential_answer_conflict`); the
69
+ * deployment credential rides only to the deployment's own root — a model carrying a root of its
70
+ * own is refused (`route.credential_mismatch` / `route.credential_missing`), never silently followed.
69
71
  * Historically the fallback was unconditional (`options.apiKey ?? config.apiKey`, with a model's
70
72
  * own `baseUrl` outranking the brain's), so a side query routed to a model carrying its own
71
73
  * `baseUrl` + per-model key sent the GATEWAY key to the per-model (possibly external) URL — the
@@ -69,8 +69,9 @@ export declare function skillGrantBindingMembers(call: {
69
69
  * bytes — the row stays pending: deny it, then activate again) and the resumed execution boundary (`site: "execution"`, the
70
70
  * bytes that will run, after every station that can rewrite them — the approval is spent: the call does not run). The
71
71
  * sentence says which side of the digest differs, read off the row's own arguments: the arguments name another skill than
72
- * the card's (`row.args`), or the card's skill no longer declares the lists the card showed (or is not served). Names the
73
- * skills, never a path; says the way out.
72
+ * the card's (`row.args`), or the card's skill's lists no longer bind to the card's digest (or it is not served) — its
73
+ * definition changed, or this engine reads an entry of it differently than the engine that parked the row (an entry that
74
+ * reads as nothing: the digest is the list reader's reading, not the text). Names the skills, never a path; says the way out.
74
75
  */
75
76
  export declare function parkedSkillApprovalRefusal(row: {
76
77
  readonly toolName: string;
@@ -1,25 +1,33 @@
1
1
  import { wireOf } from "./tool-name-readings.js";
2
- import { parsePermissionRule } from "./permission-rules.js";
2
+ import { ruleSpellingOf } from "./permission-rule-syntax.js";
3
3
  import { mountedToolPermissionSeat } from "./mode-policy.js";
4
4
  import { inlineUntrusted } from "./untrusted-text.js";
5
5
  import { boundInputHashOf } from "./canonical-json.js";
6
6
  import { NOT_BINDABLE } from "./skill-grant-binding.js";
7
7
  import { readToolNameList } from "./tool-name-list.js";
8
- import { allowingRows, autoStripped, compileAllowList, readRuleEntry, inertEntryPhrase, judgeAllowEntries, nonListValueLabel, nonStringMemberLabel, renderListEntry } from "./allow-entry.js";
8
+ import { allowingRows, autoStripped, compileAllowList, readRuleEntry, inertEntryPhrase, judgeAllowEntries, nonListValueLabel, renderListEntry, spelledListEntry } from "./allow-entry.js";
9
9
  export const SKILL_GRANT_ORIGINS = Object.freeze(["model", "user", "inherited"]);
10
10
  const FROZEN_SKILL_GRANT_ORIGINS = new Set(["model", "inherited"]);
11
11
  export function skillNamedBy(args, skills) {
12
12
  const named = args?.skill;
13
13
  return typeof named === "string" ? skills.find((s) => s.name === named) : undefined;
14
14
  }
15
+ function readsAsNothingLabel(inert) {
16
+ return `<reads as nothing (${inert.reason}): ${spelledListEntry(inert.entry)}>`;
17
+ }
15
18
  function skillGrantBinding(skill) {
16
- const canonical = (entries) => [...new Set((entries ?? []).map((e) => {
17
- if (typeof e !== "string")
18
- return nonStringMemberLabel(e);
19
- const p = parsePermissionRule(e);
19
+ const canonical = (entries, behavior) => {
20
+ const read = compileAllowList((entries ?? []), behavior);
21
+ const spelled = read.rows.map((r) => {
22
+ const p = ruleSpellingOf(r.entry);
23
+ if (p === undefined)
24
+ return readsAsNothingLabel({ entry: r.entry, reason: "grammar" });
20
25
  return p.ruleContent === undefined ? p.toolName : `${p.toolName}(${p.ruleContent})`;
21
- }))].sort();
22
- const boundGrants = { skill: skill?.name ?? null, allowedTools: canonical(skill?.allowedTools), disallowedTools: canonical(skill?.disallowedTools) };
26
+ });
27
+ const unread = read.inert.map((i) => (i.valueType !== undefined ? i.entry : readsAsNothingLabel(i)));
28
+ return [...new Set([...spelled, ...unread])].sort();
29
+ };
30
+ const boundGrants = { skill: skill?.name ?? null, allowedTools: canonical(skill?.allowedTools, "allow"), disallowedTools: canonical(skill?.disallowedTools, "deny") };
23
31
  return { boundGrantDigest: boundInputHashOf(boundGrants), boundGrants };
24
32
  }
25
33
  export function skillGrantDigest(skill) {
@@ -43,7 +51,7 @@ export function parkedSkillApprovalRefusal(row, args, skills, skillToolName, sit
43
51
  ? `this parked Skill activation of "${chosen}" carries no digest of the allowed-tools / disallowed-tools it was asked under (it was parked before Skill approvals bound them), so it cannot cover what the activation grants or refuses`
44
52
  : nameIn(args) !== nameIn(row.args)
45
53
  ? `this Skill approval was given on the card for "${shown(nameIn(row.args))}", and ${site === "claim" ? "this decision selects" : "the call would now activate"} "${chosen}" — not the Skill that card asked about, so the approval does not cover activating it`
46
- : `"${chosen}" no longer declares the allowed-tools / disallowed-tools this Skill approval was asked under — as this resume serves it (one it does not load counts as absent), it changed after the approval was given, so the approval does not cover what activating it would now grant or refuse`;
54
+ : `the allowed-tools / disallowed-tools of "${chosen}", as this resume serves it (one it does not load counts as absent), no longer bind to the digest this Skill approval was asked under — its definition changed, or this engine reads one of its entries differently than the engine that approved it (an entry that reads as nothing) — so the approval does not cover what activating it would now grant or refuse`;
47
55
  return site === "claim"
48
56
  ? `${why} — refusing pre-CAS (nothing ran; the checkpoint stays pending). Decide this checkpoint as deny and re-activate it: the new card shows the current lists.`
49
57
  : `The approved Skill call was not executed: ${why}. This approval is spent — to use "${chosen}", have the model activate it again: the new card shows its lists.`;
@@ -18,25 +18,45 @@
18
18
  * directory third parties can write to is the same as pasting their text into the system prompt. The
19
19
  * loader validates SHAPE (spec conformance), never intent.
20
20
  *
21
- * **`allowed-tools` / `disallowed-tools` are COPIED, never judged.** Each frontmatter list reaches
21
+ * **`allowed-tools` / `disallowed-tools` are COPIED, never judged for what they mean.** Each frontmatter list reaches
22
22
  * {@link SkillSpec.allowedTools} / {@link SkillSpec.disallowedTools} entry by entry as the author wrote it — no
23
- * intersection with a roster, no projection onto a tool name, no refusal, no de-duplication. What an entry means
24
- * (a tool, a namespace, a command rule, a path, a wildcard that grants nothing) is read in ONE place, the run's
25
- * grant table, which announces what it cannot read; a loader that also judged would be a second reader of the grammar.
23
+ * intersection with a roster, no projection onto a tool name, no de-duplication. Each entry must be a rule SPELLING — the
24
+ * rule syntax's own test, `ruleSpellingOf` (a tool name, then at most one parenthesized rule) — or the skill is refused;
25
+ * what a spelled entry means (a tool, a namespace, a command rule, a path, a wildcard that grants nothing) is read in ONE
26
+ * place, the run's grant table, which announces what it cannot read. The deny list has a second spelling,
27
+ * `disallowedTools`, read where `disallowed-tools` is absent or null (YAML's null is the key's absence); a hyphen key with
28
+ * a value is the list and the alias is not looked at. The allow list has none. **Each list is read whole by ONE scanner,
29
+ * {@link scanValue} (its JSDoc states the rules), or the skill is refused by name (`no_frontmatter`)** — never installed
30
+ * shorter: a `disallowed-tools` that lost entries is a looser skill than the one its author wrote. The scanner reads YAML's
31
+ * structure as YAML does — a comment, a flow's `,` / `]` and a mapping's `: ` are YAML's inside a rule's parentheses too —
32
+ * and departs from what YAML and the reference's reader give only where the list is cut into entries, on purpose: the cut
33
+ * counts a rule's parentheses by depth and refuses an entry whose parentheses are not one group closing it — unmatched
34
+ * either way, or followed by more text (the reference's zone is boolean and installs such an entry); a `*` entry is
35
+ * copied, the list not collapsed to `*` alone; tab-indented block items are read (the reference's retry reads them too);
36
+ * and a block scalar's text is cut line by line — each line of a literal one (`|`) as written, a folded one (`>`) after
37
+ * YAML's folding, so `>` lines that hold one rule read as that rule (YAML keeps the line breaks of `|` in one string, which
38
+ * the reference installs as one entry no rule reads).
26
39
  *
27
- * Frontmatter is parsed by a deliberately closed subset reader (no YAML dependency — the runtime
28
- * dependency budget is a standing constraint): top-level `key: value` scalars, optional surrounding
29
- * quotes, `#` comment lines, block scalars (`|` / `>` with their indentation + chomping indicators),
30
- * flow sequences (`[a, b]`, including the multi-line form), and indented mapping bodies skipped
31
- * wholesale. That covers every field the spec defines, and the same posture the memory-engine
32
- * frontmatter reader already takes.
40
+ * Frontmatter is read by a deliberately closed subset reader (no YAML dependency — the runtime dependency budget is a
41
+ * standing constraint): top-level key lines ({@link yamlKeyLineOf}), `#` comment lines, block scalars (`|` / `>` with their
42
+ * indentation and chomping indicators), the tool lists, and nested blocks (a mapping or a sequence under a key with nothing
43
+ * on its line) skipped wholesale but for a line that opens a tool-list key (below). A key other than the tool lists keeps its
44
+ * value as written on its line (a value that is one quoted scalar, the scanner's own judgment, is that scalar decoded, over
45
+ * every line it runs); a value of it that opens a quote, a `[` or a `{` and does not
46
+ * close it refuses the skill too — the same scanner, over the same lines, says so. Every value takes its own lines and no
47
+ * more, and every line no value takes is judged in one place: an indented `key:` line under a value that is not a nested
48
+ * block — plain, quoted, a flow, a block scalar — refuses the skill naming both keys (YAML reads no key there), and a
49
+ * flush-left line that is no key line refuses it naming the line (YAML reads no key there either). A tool list is read only
50
+ * as a key of the frontmatter, written flush left: a tool-list key written in another key's nested block (at any depth), or
51
+ * after another key's closing quote or `]` on its line, or as a key of a flow mapping (or a pair in a flow sequence) that
52
+ * value holds, refuses the skill naming both keys — its list would be lost.
33
53
  */
34
54
  import type { SkillSpec } from "./types.js";
35
55
  /** Why one skill directory (or one of its parts) was not taken as-declared. */
36
56
  export type SkillsDirectoryWarningCode =
37
57
  /** The directory holds no `SKILL.md`. */
38
58
  "no_skill_file"
39
- /** `SKILL.md` has no well-formed `---` fenced frontmatter block. */
59
+ /** `SKILL.md` has no well-formed `---` fenced frontmatter block: no opening fence, an opening fence never closed by a whole-line `---`, a tool list (`allowed-tools` / `disallowed-tools`) whose value the reader cannot read as a list, a key whose value opens a quote, a `[` or a `{` it does not close, a value that is not a nested block followed by an indented `key:` line, a tool-list key written anywhere but flush left (in a nested block, or after a closing quote or `]` on a key's line), or a flush-left line that is no key line. */
40
60
  | "no_frontmatter"
41
61
  /** Required `name` absent. */
42
62
  | "missing_name"