@sema-agent/core 7.51.1 → 7.52.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 (372) hide show
  1. package/CHANGELOG.md +550 -2
  2. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  3. package/dist/agents/cascade.js +4 -0
  4. package/dist/agents/cumulative-stats.d.ts +3 -0
  5. package/dist/agents/cumulative-stats.js +3 -0
  6. package/dist/agents/list-agents-tool.d.ts +1 -1
  7. package/dist/agents/read-inbox-tool.d.ts +1 -1
  8. package/dist/agents/repair-loop.js +4 -0
  9. package/dist/agents/send-message-tool.d.ts +11 -16
  10. package/dist/agents/send-message-tool.js +11 -13
  11. package/dist/agents/subagent.d.ts +5 -0
  12. package/dist/agents/subagent.js +7 -4
  13. package/dist/agents/tool-filter.d.ts +40 -13
  14. package/dist/agents/tool-filter.js +28 -14
  15. package/dist/bench/metrics.d.ts +1 -0
  16. package/dist/brain/anthropic.js +16 -12
  17. package/dist/brain/model-presets.d.ts +4 -5
  18. package/dist/brain/model-presets.js +4 -4
  19. package/dist/brain/open-responses.js +16 -12
  20. package/dist/brain/openai.js +16 -12
  21. package/dist/brain/request-params.d.ts +12 -33
  22. package/dist/brain/request-params.js +5 -2
  23. package/dist/brain/request-route.d.ts +9 -8
  24. package/dist/brain/request-route.js +1 -0
  25. package/dist/brain/route-adjudicator.d.ts +117 -47
  26. package/dist/brain/route-adjudicator.js +171 -42
  27. package/dist/brain/route-conformance.js +2 -2
  28. package/dist/brain/status-sink.d.ts +18 -0
  29. package/dist/brain/status-sink.js +7 -0
  30. package/dist/core/allow-entry.d.ts +42 -8
  31. package/dist/core/allow-entry.js +24 -17
  32. package/dist/core/auto-compaction.d.ts +23 -20
  33. package/dist/core/auto-compaction.js +37 -16
  34. package/dist/core/auto-promote.d.ts +2 -1
  35. package/dist/core/auto-promote.js +2 -2
  36. package/dist/core/caller-tool-name.d.ts +9 -0
  37. package/dist/core/caller-tool-name.js +13 -0
  38. package/dist/core/checkpoint-requirements.d.ts +7 -1
  39. package/dist/core/checkpoint-requirements.js +2 -0
  40. package/dist/core/checkpoint-store.d.ts +36 -12
  41. package/dist/core/checkpoint-store.js +1 -1
  42. package/dist/core/child-clamp-seats.d.ts +6 -0
  43. package/dist/core/child-clamp-seats.js +2 -1
  44. package/dist/core/credential-vocabulary.d.ts +33 -8
  45. package/dist/core/credential-vocabulary.js +32 -7
  46. package/dist/core/decision-receipt.d.ts +2 -2
  47. package/dist/core/delegation-frames.d.ts +9 -2
  48. package/dist/core/delegation-name.d.ts +18 -0
  49. package/dist/core/delegation-name.js +47 -0
  50. package/dist/core/engine-capabilities.d.ts +8 -1
  51. package/dist/core/engine-capabilities.js +1 -1
  52. package/dist/core/engine-notice.d.ts +36 -19
  53. package/dist/core/frontmatter-fence.d.ts +10 -0
  54. package/dist/core/frontmatter-fence.js +6 -0
  55. package/dist/core/gate-fold.js +5 -23
  56. package/dist/core/gate-lanes.js +356 -270
  57. package/dist/core/governance-codes.d.ts +9 -4
  58. package/dist/core/governance-codes.js +9 -3
  59. package/dist/core/hooks.d.ts +276 -734
  60. package/dist/core/hooks.js +97 -192
  61. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  62. package/dist/{tools/fs → core}/image-admission.js +24 -6
  63. package/dist/core/locked-config.d.ts +26 -5
  64. package/dist/core/locked-config.js +31 -6
  65. package/dist/core/mcp-connection-pool.d.ts +4 -1
  66. package/dist/core/mcp-connection-pool.js +7 -2
  67. package/dist/core/mcp-probe.d.ts +12 -9
  68. package/dist/core/mcp-probe.js +2 -2
  69. package/dist/core/mcp-server-spec.d.ts +53 -7
  70. package/dist/core/mcp-server-spec.js +84 -1
  71. package/dist/core/mcp.d.ts +11 -7
  72. package/dist/core/mcp.js +27 -9
  73. package/dist/core/memory-engine/data-plane.js +5 -1
  74. package/dist/core/memory-engine/distiller.js +16 -2
  75. package/dist/core/memory-engine/engine.d.ts +8 -11
  76. package/dist/core/memory-engine/engine.js +9 -5
  77. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  78. package/dist/core/memory-engine/frontmatter.js +19 -16
  79. package/dist/core/memory.d.ts +2 -2
  80. package/dist/core/mode-policy.d.ts +4 -0
  81. package/dist/core/mode-policy.js +7 -5
  82. package/dist/core/model-seat.d.ts +4 -1
  83. package/dist/core/mods/dollar.d.ts +109 -0
  84. package/dist/core/mods/dollar.js +154 -0
  85. package/dist/core/mods/host.d.ts +23 -0
  86. package/dist/core/mods/host.js +21 -0
  87. package/dist/core/mods/kernel/budget.d.ts +43 -0
  88. package/dist/core/mods/kernel/budget.js +83 -0
  89. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  90. package/dist/core/mods/kernel/dispatch.js +701 -0
  91. package/dist/core/mods/kernel/events.d.ts +242 -0
  92. package/dist/core/mods/kernel/events.js +210 -0
  93. package/dist/core/mods/kernel/index.d.ts +6 -0
  94. package/dist/core/mods/kernel/index.js +5 -0
  95. package/dist/core/mods/kernel/receive.d.ts +65 -0
  96. package/dist/core/mods/kernel/receive.js +123 -0
  97. package/dist/core/mods/kernel/registration.d.ts +131 -0
  98. package/dist/core/mods/kernel/registration.js +102 -0
  99. package/dist/core/mods/kernel/site-rules.d.ts +84 -0
  100. package/dist/core/mods/kernel/site-rules.js +104 -0
  101. package/dist/core/mods/stations.d.ts +350 -0
  102. package/dist/core/mods/stations.js +444 -0
  103. package/dist/core/own-property-receipt.js +11 -23
  104. package/dist/core/parent-spec-seat.d.ts +18 -7
  105. package/dist/core/parent-spec-seat.js +6 -2
  106. package/dist/core/path-identity.js +2 -1
  107. package/dist/core/permission-rule-syntax.d.ts +15 -0
  108. package/dist/core/permission-rule-syntax.js +24 -16
  109. package/dist/core/permission-rules.d.ts +7 -1
  110. package/dist/core/permission-rules.js +26 -15
  111. package/dist/core/prompt-section-seat.d.ts +15 -27
  112. package/dist/core/prompt-section-seat.js +73 -40
  113. package/dist/core/protocol-http-auth.d.ts +3 -1
  114. package/dist/core/protocol-http-auth.js +2 -0
  115. package/dist/core/reminder-mint.d.ts +2 -2
  116. package/dist/core/remote-env.d.ts +24 -12
  117. package/dist/core/remote-env.js +1 -0
  118. package/dist/core/resume-startup-cause.d.ts +16 -1
  119. package/dist/core/resume-startup-cause.js +4 -1
  120. package/dist/core/retired-keys.d.ts +4 -0
  121. package/dist/core/retired-keys.js +3 -0
  122. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  123. package/dist/core/runner/announce-once-ledger.js +22 -0
  124. package/dist/core/runner/assemble-result.d.ts +9 -0
  125. package/dist/core/runner/assemble-result.js +3 -1
  126. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  127. package/dist/core/runner/call-hook-stations.js +58 -42
  128. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  129. package/dist/core/runner/caller-stop-gate.js +7 -0
  130. package/dist/core/runner/compaction-seams.d.ts +8 -22
  131. package/dist/core/runner/compaction-seams.js +28 -53
  132. package/dist/core/runner/construction-doors.js +11 -1
  133. package/dist/core/runner/contracts.d.ts +85 -83
  134. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  135. package/dist/core/runner/credential-origin-seat.js +19 -0
  136. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  137. package/dist/core/runner/gate-exit.d.ts +47 -36
  138. package/dist/core/runner/gate-exit.js +8 -2
  139. package/dist/core/runner/image.js +1 -2
  140. package/dist/core/runner/inline-image.js +1 -1
  141. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  142. package/dist/core/runner/notice-seat-input.js +1 -0
  143. package/dist/core/runner/person-path-rows.js +1 -0
  144. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  145. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  146. package/dist/core/runner/prepare-ask-lane.js +6 -15
  147. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  148. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  149. package/dist/core/runner/prepare-config-doors.d.ts +5 -0
  150. package/dist/core/runner/prepare-config-doors.js +9 -0
  151. package/dist/core/runner/prepare-defer-classify.js +3 -4
  152. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  153. package/dist/core/runner/prepare-gate-stations.js +11 -10
  154. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  155. package/dist/core/runner/prepare-inherited-gate.js +8 -21
  156. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  157. package/dist/core/runner/prepare-park-ask.js +10 -14
  158. package/dist/core/runner/prepare-policy-chain.d.ts +18 -16
  159. package/dist/core/runner/prepare-policy-chain.js +98 -101
  160. package/dist/core/runner/prepare-project-context.js +7 -10
  161. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  162. package/dist/core/runner/prepare-prompt-assembly.js +134 -101
  163. package/dist/core/runner/prepare-prompt-inputs.d.ts +18 -19
  164. package/dist/core/runner/prepare-prompt-inputs.js +5 -7
  165. package/dist/core/runner/prepare-protocol-tools.d.ts +6 -4
  166. package/dist/core/runner/prepare-protocol-tools.js +2 -2
  167. package/dist/core/runner/prepare-safety-scan.js +6 -10
  168. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  169. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  170. package/dist/core/runner/prepare-task.js +33 -15
  171. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  172. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  173. package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -6
  174. package/dist/core/runner/prepare-wiring-manifest.js +7 -7
  175. package/dist/core/runner/resume-apply.d.ts +5 -2
  176. package/dist/core/runner/resume-apply.js +24 -42
  177. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  178. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  179. package/dist/core/runner/resume-preflight.js +38 -16
  180. package/dist/core/runner/retired-runner-deps.js +3 -1
  181. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  182. package/dist/core/runner/run-brain-sinks.js +5 -1
  183. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  184. package/dist/core/runner/run-compaction-machinery.js +7 -33
  185. package/dist/core/runner/run-harness-handlers.js +4 -2
  186. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  187. package/dist/core/runner/run-identity-wiring.js +3 -2
  188. package/dist/core/runner/run-leg.js +62 -84
  189. package/dist/core/runner/run-notification-lane.js +1 -0
  190. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  191. package/dist/core/runner/run-recovery-lanes.js +11 -10
  192. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  193. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  194. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  195. package/dist/core/runner/run-terminal-adoption.js +33 -22
  196. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  197. package/dist/core/runner/run-turn-boundary.js +23 -34
  198. package/dist/core/runner/runtask.d.ts +6 -7
  199. package/dist/core/runner/runtask.js +14 -72
  200. package/dist/core/runner/session-rule-policy.d.ts +6 -4
  201. package/dist/core/runner/session-rule-policy.js +17 -10
  202. package/dist/core/runner/side-call-account.d.ts +68 -0
  203. package/dist/core/runner/side-call-account.js +61 -0
  204. package/dist/core/runner/stream-halt-verbs.js +12 -17
  205. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  206. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  207. package/dist/core/runner/stream-steer-verb.js +20 -38
  208. package/dist/core/runner/sub-agent-deny-lists.d.ts +121 -22
  209. package/dist/core/runner/sub-agent-deny-lists.js +228 -71
  210. package/dist/core/runner/tool-end-body.d.ts +5 -6
  211. package/dist/core/runner/tool-end-body.js +6 -4
  212. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  213. package/dist/core/runner/tool-not-executed.js +30 -0
  214. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  215. package/dist/core/runner/tool-occurrence.js +5 -5
  216. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  217. package/dist/core/runner-deps.d.ts +20 -28
  218. package/dist/core/safety-merge-corpus.js +18 -2
  219. package/dist/core/secret-env.d.ts +93 -20
  220. package/dist/core/secret-env.js +192 -38
  221. package/dist/core/session-policy-store.d.ts +93 -17
  222. package/dist/core/session-policy-store.js +178 -25
  223. package/dist/core/session-reconcile.d.ts +4 -0
  224. package/dist/core/session-reconcile.js +2 -1
  225. package/dist/core/shell-read-silence.js +3 -32
  226. package/dist/core/side-query.d.ts +5 -3
  227. package/dist/core/skill-grant.d.ts +3 -2
  228. package/dist/core/skill-grant.js +17 -9
  229. package/dist/core/skills-directory.d.ts +31 -11
  230. package/dist/core/skills-directory.js +655 -104
  231. package/dist/core/task-event.d.ts +13 -3
  232. package/dist/core/task-result.d.ts +8 -0
  233. package/dist/core/task-spec.d.ts +20 -19
  234. package/dist/core/task-stream.d.ts +14 -4
  235. package/dist/core/tighten-task-spec.d.ts +4 -3
  236. package/dist/core/tighten-task-spec.js +2 -4
  237. package/dist/core/tool-check-reading.d.ts +74 -0
  238. package/dist/core/tool-check-reading.js +80 -0
  239. package/dist/core/tool-policy.d.ts +59 -18
  240. package/dist/core/tool-policy.js +77 -12
  241. package/dist/core/tool-registry.d.ts +20 -0
  242. package/dist/core/tool-registry.js +4 -0
  243. package/dist/core/tool-spec.d.ts +10 -6
  244. package/dist/core/tools.js +2 -0
  245. package/dist/core/trace.d.ts +51 -32
  246. package/dist/core/types.d.ts +2 -1
  247. package/dist/core/types.js +1 -0
  248. package/dist/core/unc-spelling.d.ts +10 -0
  249. package/dist/core/unc-spelling.js +3 -0
  250. package/dist/core/untrusted-egress.d.ts +8 -0
  251. package/dist/core/untrusted-egress.js +4 -1
  252. package/dist/core/user-attachment.d.ts +12 -2
  253. package/dist/core/user-attachment.js +17 -2
  254. package/dist/core/wiring-manifest.d.ts +14 -13
  255. package/dist/core/wiring-manifest.js +2 -2
  256. package/dist/engine/compaction/utils.js +1 -2
  257. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  258. package/dist/engine/execution-env/symlink-chain.js +1 -1
  259. package/dist/engine/harness/agent-harness.d.ts +1 -1
  260. package/dist/engine/harness/agent-harness.js +3 -3
  261. package/dist/engine/harness/types.d.ts +17 -16
  262. package/dist/engine/harness/types.js +7 -1
  263. package/dist/engine/llm/types.d.ts +12 -7
  264. package/dist/engine/loop/agent-loop.js +1 -1
  265. package/dist/engine/loop/types.d.ts +1 -1
  266. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  267. package/dist/engine/session/import-validate.js +3 -10
  268. package/dist/engine/session/session.d.ts +4 -4
  269. package/dist/engine/session/session.js +4 -4
  270. package/dist/index.d.ts +24 -17
  271. package/dist/index.js +15 -12
  272. package/dist/internal/harness.d.ts +1 -1
  273. package/dist/internal/harness.js +1 -1
  274. package/dist/orchestration/run-spec.d.ts +4 -6
  275. package/dist/orchestration/run-spec.js +39 -63
  276. package/dist/orchestration/run-workflow-tool.js +1 -2
  277. package/dist/orchestration/workflow.d.ts +11 -3
  278. package/dist/orchestration/workflow.js +11 -2
  279. package/dist/prompt-assembly/artifact-store.d.ts +37 -56
  280. package/dist/prompt-assembly/artifact-store.js +31 -49
  281. package/dist/prompt-assembly/artifact.d.ts +89 -76
  282. package/dist/prompt-assembly/artifact.js +167 -146
  283. package/dist/prompt-assembly/assemble.d.ts +34 -29
  284. package/dist/prompt-assembly/assemble.js +33 -220
  285. package/dist/prompt-assembly/bands.d.ts +20 -0
  286. package/dist/prompt-assembly/bands.js +18 -0
  287. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  288. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  289. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  290. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  291. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  292. package/dist/prompt-assembly/catalog/index.js +59 -0
  293. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  294. package/dist/prompt-assembly/catalog/modes.js +137 -0
  295. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  296. package/dist/prompt-assembly/catalog/role.js +157 -0
  297. package/dist/prompt-assembly/catalog/schema.d.ts +124 -0
  298. package/dist/prompt-assembly/catalog/schema.js +25 -0
  299. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  300. package/dist/prompt-assembly/catalog/sections.js +98 -0
  301. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  302. package/dist/prompt-assembly/catalog/team.js +258 -0
  303. package/dist/prompt-assembly/composer.d.ts +24 -28
  304. package/dist/prompt-assembly/composer.js +124 -46
  305. package/dist/prompt-assembly/epoch.d.ts +89 -79
  306. package/dist/prompt-assembly/epoch.js +115 -142
  307. package/dist/prompt-assembly/explain.d.ts +58 -34
  308. package/dist/prompt-assembly/explain.js +21 -24
  309. package/dist/prompt-assembly/overlay.d.ts +127 -0
  310. package/dist/prompt-assembly/overlay.js +301 -0
  311. package/dist/prompt-assembly/renderers.d.ts +21 -0
  312. package/dist/prompt-assembly/renderers.js +39 -0
  313. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  314. package/dist/prompt-assembly/section-usage.js +1 -1
  315. package/dist/prompt-assembly/select.d.ts +56 -0
  316. package/dist/prompt-assembly/select.js +69 -0
  317. package/dist/prompt-assembly/sugar.d.ts +31 -0
  318. package/dist/prompt-assembly/sugar.js +20 -0
  319. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  320. package/dist/prompt-assembly/types.d.ts +45 -148
  321. package/dist/prompts/coordinator.d.ts +2 -21
  322. package/dist/prompts/coordinator.js +3 -255
  323. package/dist/prompts/cowork.d.ts +27 -16
  324. package/dist/prompts/cowork.js +2 -23
  325. package/dist/prompts/default.d.ts +38 -500
  326. package/dist/prompts/default.js +20 -285
  327. package/dist/prompts/supervisor.d.ts +6 -71
  328. package/dist/prompts/supervisor.js +6 -117
  329. package/dist/stores/file/session-policy-store.d.ts +3 -3
  330. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  331. package/dist/tools/fs/dir-entries.d.ts +4 -2
  332. package/dist/tools/fs/dir-entries.js +16 -4
  333. package/dist/tools/fs/fs-bash.d.ts +1 -1
  334. package/dist/tools/fs/fs-bash.js +22 -11
  335. package/dist/tools/fs/fs-pdf.js +17 -13
  336. package/dist/tools/fs/fs-read.js +4 -3
  337. package/dist/tools/fs/fs-shared.d.ts +1 -10
  338. package/dist/tools/fs/fs-shared.js +3 -4
  339. package/dist/tools/fs/fs-write.js +2 -1
  340. package/dist/tools/fs/notebook.js +1 -1
  341. package/dist/tools/fs/pdf.d.ts +20 -10
  342. package/dist/tools/fs/pdf.js +19 -10
  343. package/dist/tools/fs/program-read-model.d.ts +68 -8
  344. package/dist/tools/fs/program-read-model.js +112 -33
  345. package/dist/tools/fs/program-read-model.rows.js +30 -10
  346. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  347. package/dist/tools/fs/read-deny-home.js +28 -27
  348. package/dist/tools/fs/read-deny.d.ts +41 -11
  349. package/dist/tools/fs/read-deny.js +51 -5
  350. package/dist/tools/fs/safety.d.ts +4 -26
  351. package/dist/tools/fs/safety.js +10 -32
  352. package/dist/tools/fs/search.js +15 -10
  353. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  354. package/dist/tools/fs/shell-read-argv.js +118 -38
  355. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  356. package/dist/tools/fs/shell-read-establish.js +11 -61
  357. package/dist/tools/fs/shell-read-identity.js +6 -3
  358. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  359. package/dist/tools/fs/shell-read-judge.js +18 -4
  360. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  361. package/dist/tools/web.js +1 -1
  362. package/package.json +13 -1
  363. package/test/export-surface.snapshot.json +256 -99
  364. package/wire-changes/core@7.51.1.json +5 -5
  365. package/wire-changes/core@7.51.2.json +293 -0
  366. package/wire-changes/core@7.52.0.json +5859 -0
  367. package/dist/core/hook-seats.d.ts +0 -66
  368. package/dist/core/hook-seats.js +0 -37
  369. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  370. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  371. package/dist/prompts/simple-sections.d.ts +0 -58
  372. package/dist/prompts/simple-sections.js +0 -43
@@ -19,7 +19,8 @@ import { egressText, egressThrownText } from "./untrusted-egress.js";
19
19
  import { assertNoRetiredToolPolicyKeys, RETIRED_DECISION_MEMBERS } from "./retired-keys.js";
20
20
  import { isEngineRefusal, nestedRecordsOf, receiveContract, receiveNestedRecords, refusedOutOfContract, screenContractValues } from "./decision-receipt.js";
21
21
  export { isEngineRefusal } from "./decision-receipt.js";
22
- import { isNamespacedCoveringRuleName, namespacedRuleNameCovers, parsePermissionRule } from "./permission-rules.js";
22
+ import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "./permission-rules.js";
23
+ import { ruleSpellingOf } from "./permission-rule-syntax.js";
23
24
  import { protocolOf } from "./protocol-table.js";
24
25
  import { anchorSpelling, isAbsoluteForFamily, normalizeAbsPathLexically, pathFamilyOf, writeTargetPath } from "../tools/fs/safety.js";
25
26
  import { KNOWN_SAFE_ROOTS, removalReadingOf } from "../tools/fs/removal-targets.js";
@@ -176,6 +177,9 @@ export function namespacedCoveringEntries(entries) {
176
177
  export function namespacedCoveringHit(covering, call) {
177
178
  return covering.length > 0 && nameListHolds({ has: (name) => covering.some((e) => namespacedRuleNameCovers(e, name)) }, call);
178
179
  }
180
+ export function projectionToolNames(c) {
181
+ return c.kind === "shell_command" ? { member: "tools", list: c.tools } : { member: "names", list: c.names };
182
+ }
179
183
  export function checkToolPolicyProjection(projection, req) {
180
184
  const listed = (list) => heldBy("policy.projectionReplay", { has: (n) => list.includes(n) }, req);
181
185
  for (const c of projection.components) {
@@ -305,6 +309,12 @@ export function refuseOutOfContractDecision(d, opts) {
305
309
  return refusedOutOfContract(`a permission decision's members could not be detached from the layer that returned them (${detached.reason}) — ` +
306
310
  `the engine keeps its own copy of what it read; denied fail-closed`);
307
311
  }
312
+ const rewrite = detached.value.updatedInput;
313
+ const ownedRewrite = rewrite !== undefined ? ownedCopy(rewrite, "updatedInput") : undefined;
314
+ if (ownedRewrite !== undefined && !ownedRewrite.ok) {
315
+ return refusedOutOfContract(`a permission decision's members could not be detached from the layer that returned them (${ownedRewrite.reason}) — ` +
316
+ `the engine keeps its own copy of what it read; denied fail-closed`);
317
+ }
308
318
  const receipt = Object.freeze(attestation !== undefined ? { ...detached.value, attestation } : detached.value);
309
319
  for (const v of Object.values(receipt))
310
320
  if (Array.isArray(v))
@@ -318,9 +328,6 @@ export function refuseOutOfContractDecision(d, opts) {
318
328
  (hookSeam ? HOOK_RECEIPTS : ENGINE_RECEIPTS).add(receipt);
319
329
  return receipt;
320
330
  }
321
- export function receiveHookResult(result) {
322
- return refuseOutOfContractDecision(result, { reasonIsNonInput: true });
323
- }
324
331
  const DEADLINE_ELAPSED = Symbol("approval.deadline_elapsed");
325
332
  function withTimeout(p, ms, onTimeout) {
326
333
  if (ms === undefined) {
@@ -353,6 +360,7 @@ export function createAllowDenyPolicy(opts) {
353
360
  if (entries === undefined)
354
361
  return undefined;
355
362
  const kept = [];
363
+ const seen = new Set();
356
364
  for (const entry of entries) {
357
365
  const ns = protocolOf(entry);
358
366
  if (ns !== undefined) {
@@ -367,8 +375,23 @@ export function createAllowDenyPolicy(opts) {
367
375
  continue;
368
376
  }
369
377
  }
370
- if (parsePermissionRule(entry).ruleContent === undefined) {
371
- kept.push(entry);
378
+ const spelled = ruleSpellingOf(entry);
379
+ if (spelled === undefined) {
380
+ const lesson = `a spelling no tool name can have — the rule syntax reads no tool name in it, so a name set never names a tool by it. Fix the entry.`;
381
+ invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
382
+ continue;
383
+ }
384
+ if (spelled.ruleContent === undefined) {
385
+ if (spelled.toolName === "*" && list === "deny") {
386
+ const lesson = `the wildcard — \`*\` names no tool, and a deny entry reaches the tool it names, so this one would be kept and never match ` +
387
+ `(a deny that reads protective and denies nothing). Name the tools to deny; to leave a run no tools, write an empty allow list.`;
388
+ invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
389
+ continue;
390
+ }
391
+ if (!seen.has(spelled.toolName)) {
392
+ seen.add(spelled.toolName);
393
+ kept.push(spelled.toolName);
394
+ }
372
395
  continue;
373
396
  }
374
397
  const lesson = `a rule CONTENT form, not a tool name — a name set matches raw tool names, so this entry ` +
@@ -562,7 +585,7 @@ export function combinePolicies(...policies) {
562
585
  ...carriedMembersOf(folded),
563
586
  async check(req, signal) {
564
587
  let asked;
565
- let current = req;
588
+ let current = Object.freeze({ ...req });
566
589
  let rewrite;
567
590
  let stated;
568
591
  let records;
@@ -574,7 +597,7 @@ export function combinePolicies(...policies) {
574
597
  let authoredBySeen = false;
575
598
  const contributors = [];
576
599
  const settleDeny = (d) => {
577
- const out = rewrite?.updatedInput !== undefined ? { ...d, updatedInput: rewrite.updatedInput } : d;
600
+ const out = rewrite !== undefined ? refusalOf(d, current.args) : d;
578
601
  if (records === undefined)
579
602
  return out;
580
603
  return { ...out, attestation: mergeAttestation(req, records, d.attestation) };
@@ -590,7 +613,7 @@ export function combinePolicies(...policies) {
590
613
  }
591
614
  if (d.updatedInput !== undefined) {
592
615
  const reread = withArgsReading(current, d.updatedInput, signal);
593
- current = reread !== undefined ? await reread : { ...current, args: d.updatedInput };
616
+ current = Object.freeze(reread !== undefined ? await reread : { ...current, args: d.updatedInput });
594
617
  rewrite = d;
595
618
  stated = d.action === "allow" ? d.decisionReason : undefined;
596
619
  }
@@ -871,6 +894,48 @@ export function tryCloneArgs(v) {
871
894
  return { ok: false, reason: describeThrown(err), cause: err };
872
895
  }
873
896
  }
897
+ export function refusalOf(deny, judged) {
898
+ return deny.action !== "deny" || deny.updatedInput !== undefined ? deny : { ...deny, updatedInput: judged };
899
+ }
900
+ export function foldHookAsk(verdict, hookAsk) {
901
+ if (verdict.action === "deny")
902
+ return verdict;
903
+ const mandate = hookAsk.requiresRealApproval === true ? { requiresRealApproval: true } : {};
904
+ if (verdict.action === "allow") {
905
+ return { action: "ask", ...(hookAsk.message !== undefined ? { message: hookAsk.message } : {}), decisionReason: "hook", ...mandate, ...(hookAsk.updatedInput !== undefined ? { updatedInput: hookAsk.updatedInput } : {}) };
906
+ }
907
+ const hookMessage = hookAsk.message;
908
+ const message = hookMessage !== undefined && hookMessage !== verdict.message ? `${verdict.message !== undefined ? `${verdict.message} ` : ""}(a PreToolUse hook also asks: ${hookMessage})` : verdict.message;
909
+ return { ...verdict, decisionReason: "hook", ...(message !== undefined ? { message } : {}), ...mandate };
910
+ }
911
+ const OWNED_ARGS = new WeakSet();
912
+ export function ownArgs(v, root = "args") {
913
+ if (v === null || (typeof v !== "object" && typeof v !== "function") || OWNED_ARGS.has(v))
914
+ return { ok: true, value: v };
915
+ const copy = tryCloneArgs(v);
916
+ return copy.ok ? ownedCopy(copy.value, root) : { ...copy, reason: `unclonable value: ${copy.reason}` };
917
+ }
918
+ function ownedCopy(fresh, root) {
919
+ const pending = [[fresh, root]];
920
+ for (let next = pending.pop(); next !== undefined; next = pending.pop()) {
921
+ const [x, at] = next;
922
+ if (typeof x !== "object" || x === null || Object.isFrozen(x))
923
+ continue;
924
+ const proto = Object.getPrototypeOf(x);
925
+ if (proto !== Object.prototype && proto !== Array.prototype && proto !== null) {
926
+ return { ok: false, reason: `${inlineUntrusted(at, 200)} is a ${Object.prototype.toString.call(x).slice(8, -1)}, whose contents cannot be made immutable — args are plain data` };
927
+ }
928
+ Object.freeze(x);
929
+ for (const key of Reflect.ownKeys(x)) {
930
+ const d = Object.getOwnPropertyDescriptor(x, key);
931
+ if (d !== undefined && "value" in d)
932
+ pending.push([d.value, Array.isArray(x) ? `${at}[${String(key)}]` : `${at}.${String(key)}`]);
933
+ }
934
+ }
935
+ if (typeof fresh === "object" && fresh !== null)
936
+ OWNED_ARGS.add(fresh);
937
+ return { ok: true, value: fresh };
938
+ }
874
939
  export function describeThrown(err) {
875
940
  const contained = containThrownText(egressThrownText("same-principal", err));
876
941
  if (contained !== "")
@@ -1127,7 +1192,7 @@ function readApproverOutcomeObject(ok, toolName, editLane) {
1127
1192
  `re-adjudication an approver's edit gets; denied fail-closed (approve or refuse what was shown, and route edits ` +
1128
1193
  `through the run's approver seat)`, settledByNobody("approver_contract"));
1129
1194
  }
1130
- const edit = tryCloneArgs(suppliedEdit);
1195
+ const edit = ownArgs(suppliedEdit);
1131
1196
  if (!edit.ok) {
1132
1197
  return refused(`the approved edit for "${toolName}" is not safely clonable (${edit.reason}) — denied fail-closed`, settledByNobody("presentation_failed"));
1133
1198
  }
@@ -1150,11 +1215,11 @@ async function resolveAskArms(req, onAsk, signal, onLateSettlement) {
1150
1215
  if (signal?.aborted) {
1151
1216
  return { action: "deny", message: `approval aborted for "${req.toolName}" (run or turn interrupted)`, decisionReason: "mode", settlement: settledByNobody("task_aborted") };
1152
1217
  }
1153
- const presented = tryCloneArgs(req.args);
1218
+ const presented = ownArgs(req.args);
1154
1219
  if (!presented.ok) {
1155
1220
  return {
1156
1221
  action: "deny",
1157
- message: `approval for "${req.toolName}" could not present the args safely (unclonable value: ${presented.reason}) — denied fail-closed`,
1222
+ message: `approval for "${req.toolName}" could not present the args safely (${presented.reason}) — denied fail-closed`,
1158
1223
  decisionReason: "mode",
1159
1224
  settlement: settledByNobody("presentation_failed"),
1160
1225
  };
@@ -88,6 +88,26 @@ export declare function pathTargetValue(args: unknown, pt: {
88
88
  param: string;
89
89
  aliases?: readonly string[];
90
90
  }): string | undefined;
91
+ /**
92
+ * CC parity: Read/Edit/Write take the file path as `file_path`. Read the target the same way
93
+ * EVERYWHERE the path is consumed from a tool-call's args — not just the tool body but ALSO every gate that
94
+ * extracts the write target to confine it (sensitive-path, session allowDirs, the fs-write gate). A gate that only
95
+ * read `args.path` would see `undefined` for a `file_path` call and either fail-OPEN (circumvent the guard — a real
96
+ * hole) or fail-closed (deny a legitimate write). Single source.
97
+ *
98
+ * The `path` arm is deliberately BROADER than what Read/Edit/Write accept: their schema requires
99
+ * `file_path` (fs-shared.ts FILE_PATH_PARAMS; Write alone repairs the `path` spelling onto it BEFORE validation,
100
+ * `coerceWriteArguments`, so a gate never sees the alias there), but this reader is
101
+ * shared with gates that judge OTHER tool vocabularies — Glob's real `path` parameter, deployment-authored tools —
102
+ * and a gate must never see LESS than the tool it is confining might act on. So the asymmetry is the design: the
103
+ * schema decides what a caller may send, this decides what gets judged, and this side over-reads on purpose.
104
+ *
105
+ * `file_path` wins; an empty/non-string `file_path` falls back to `path` (NOT an alias for Read/Edit/Write, whose
106
+ * schema requires `file_path`). Empty string ⇒ undefined (treated as "no path") so every caller's `=== undefined`
107
+ * check is sufficient — no separate length-0 guard needed. It lives beside {@link pathTargetValue} and is that
108
+ * reader over the one slot above: the engine's compaction metadata reads it too, and the engine never imports tools/.
109
+ */
110
+ export declare function fileArgPath(args: unknown): string | undefined;
91
111
  /** The path target of a wire name — the FIRST definition's (every definition under one name declares
92
112
  * the same target; the conformance test pins that). */
93
113
  /** A gated call as every fence sees it: the wire name, the args, and the OBJECT face a prepared leg stamped on the
@@ -85,6 +85,10 @@ export function pathTargetValue(args, pt) {
85
85
  }
86
86
  return undefined;
87
87
  }
88
+ const FILE_ARG_PATH_TARGET = { param: "file_path", aliases: ["path"] };
89
+ export function fileArgPath(args) {
90
+ return pathTargetValue(args, FILE_ARG_PATH_TARGET);
91
+ }
88
92
  export function protectivePathTargetOf(call) {
89
93
  if (call.face?.pathTarget !== undefined)
90
94
  return call.face.pathTarget;
@@ -121,10 +121,14 @@ export interface ReadRootGrantCandidate {
121
121
  }
122
122
  export interface ToolSpec<TParams extends TSchema = TSchema> {
123
123
  /**
124
- * Model-facing tool name. MUST NOT contain `__` — that separator is reserved by the PROTOCOL TABLE
125
- * (`protocol-table.ts`), the umbrella over every namespaced family the engine speaks: `mcp__<server>__<tool>`,
126
- * `a2a__<peer>__<skill>`, and whatever a third protocol appends. A caller tool name carrying it is rejected
127
- * at prepare-time (`config.tool_name_invalid`).
124
+ * Model-facing tool name. It keeps the caller tool name contract (`caller-tool-name.ts`), judged at prepare-time — a
125
+ * name that breaks it is refused there (`config.tool_name_invalid`) and the run does not start:
126
+ * - it is a name a rule can name: ASCII letters, digits and `_ - . : *`, starting with a letter, a digit or `_`, not
127
+ * ending with `.` or `:`, and not the lone wildcard `*` — so every allow / deny list can name the tool (a leading `-`,
128
+ * a character outside ASCII, a blank or an empty name is refused);
129
+ * - it does not contain `__` — that separator is reserved by the PROTOCOL TABLE (`protocol-table.ts`), the umbrella over
130
+ * every namespaced family the engine speaks: `mcp__<server>__<tool>`, `a2a__<peer>__<skill>`, and whatever a third
131
+ * protocol appends.
128
132
  *
129
133
  * The live reason (not the retired durable-resume name shim, RB-476-A): every table-driven site — the
130
134
  * namespace `parse`, the grouped display key, the permission-rule lanes, the tool-manifest origin
@@ -136,7 +140,7 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
136
140
  /**
137
141
  * Backward-compatible model-facing names that should dispatch to this tool. New transcripts and tool rosters
138
142
  * should use {@link name}; aliases exist only so old model calls / SDK payloads / resumed sessions don't strand
139
- * across a canonical rename.
143
+ * across a canonical rename. Each alias keeps the same contract as {@link name} (a rule naming an alias reaches the tool).
140
144
  */
141
145
  aliases?: string[];
142
146
  description: string;
@@ -711,7 +715,7 @@ export interface ToolExecuteContext {
711
715
  * PreToolUse SCREENING entry (issue #33), whose policy the engine mints. Rebuild it with the
712
716
  * exported `createPreToolUseConstraintPolicy(hook, env)` — same callback, same installed env —
713
717
  * or the chain handed back here will be short and rejected on the count check. A face that only
714
- * observes should carry `Hooks.preToolUseObservational` instead, and then never enters the chain
718
+ * observes should be declared `{ observe: true }` instead, and then never enters the chain
715
719
  * at all; a park under a screening entry announces the requirement on `onError`
716
720
  * (classification `screening-constraint-in-durable-chain`) at park time.
717
721
  */
@@ -2,6 +2,7 @@ import { Value } from "typebox/value";
2
2
  import { formatToolError, formatZodValidationError } from "./tool-errors.js";
3
3
  import { readMember } from "./thrown-value.js";
4
4
  import { frozenToolSpec } from "./tool-spec-members.js";
5
+ import { carryDelegationName } from "./delegation-name.js";
5
6
  import { attachToolContract } from "../prompt-assembly/tool-catalog.js";
6
7
  function normalizeContent(ret) {
7
8
  if (typeof ret === "string") {
@@ -135,6 +136,7 @@ function buildProduct(spec, owner, options) {
135
136
  }
136
137
  },
137
138
  };
139
+ carryDelegationName(spec.execute, tool.execute);
138
140
  if (spec.contract) {
139
141
  attachToolContract(tool, {
140
142
  contractId: spec.contract.contractId,
@@ -19,6 +19,44 @@
19
19
  import type { BrainRetryErrClass, TaskStatus, ToolEffect } from "./types.js";
20
20
  import type { ThinkingLevel } from "../internal/harness-types.js";
21
21
  import type { ToolManifestRow } from "../prompt-assembly/tool-catalog.js";
22
+ import type { PromptEpochActivation, PromptIdentityLayers } from "../prompt-assembly/epoch.js";
23
+ import type { ChainLink, SupersededOverlay } from "../prompt-assembly/overlay.js";
24
+ import type { HostForm, HostRole, RendererId } from "../prompt-assembly/catalog/schema.js";
25
+ /** The run's prompt identity as the manifest reports it: the identity digest, its inputs, and the session record that
26
+ * names it (the record's counter and how it came to be). */
27
+ export interface PromptManifestIdentity {
28
+ artifact: string;
29
+ layers: PromptIdentityLayers;
30
+ epoch: number;
31
+ activatedBy: PromptEpochActivation;
32
+ }
33
+ /** The run's selector values — the plain form of the identity's `binding` element. */
34
+ export interface PromptManifestSelectors {
35
+ binding?: string;
36
+ traits: string[];
37
+ host: {
38
+ role: HostRole;
39
+ form: HostForm;
40
+ };
41
+ facts: Record<string, boolean>;
42
+ }
43
+ /** One rendered section: where it sits, which variant and renderer made it, whose text it carries (`locale`: the
44
+ * catalog's canonical text, or text an overlay author wrote), its content digest (`sha256:` unsalted for published
45
+ * text, `salted:` for text carrying the task's or the run's own inputs) and its history (`chain`). */
46
+ export interface PromptManifestSection {
47
+ id: string;
48
+ band: string;
49
+ rank: number;
50
+ variant?: string;
51
+ renderer?: {
52
+ id: RendererId;
53
+ version: number;
54
+ };
55
+ chars: number;
56
+ locale: "canonical" | "overlay";
57
+ contentHash: string;
58
+ chain: ChainLink[];
59
+ }
22
60
  /**
23
61
  * R4 (1.285): the scalar face of `TaskResult.stats.mechanisms`, echoed on `task.end` so "did the
24
62
  * engine machinery fire" is answerable from the trace alone. Counters/flags only —
@@ -82,46 +120,27 @@ export type TraceEvent = {
82
120
  ts: number;
83
121
  } | {
84
122
  /**
85
- * 提示词主权批 — the labelled composition of the assembled system prompt, emitted once right after
86
- * `task.start`. Kills the "which blocks were actually in the prompt" black box: a deployment can
87
- * assert the constitution/safety blocks are present (or that their absence was a deliberate
88
- * `replaceAll`) instead of diagnosing missing-prompt incidents by archaeology. Metadata-only
89
- * (block ids + sizes + short content hashes — never prompt text, per the file-header privacy rule).
123
+ * The labelled composition of the assembled system prompt (manifest v3), emitted once right after `task.start`:
124
+ * which prompt this is (the identity and its selector values), which blocks and sections composed it, and where
125
+ * each section's text came from (its chain of overlays, the superseded ones marked). Metadata-only — ids, sizes
126
+ * and digests, never prompt text (the file-header privacy rule).
90
127
  */
91
128
  kind: "prompt.assembled";
92
- version: 1;
129
+ version: 3;
93
130
  taskId: string;
94
- /** Who owned the constitution layer: "core" (structural default) / "replaced" (provider
95
- * `replaceAll` opt-out) / "provider-assembled" (migration guard pass-through). */
96
- constitution: "core" | "replaced" | "provider-assembled";
97
- /** Ordered blocks: stable id (e.g. `role.base`, `harness.context`, `memory.safety`,
98
- * `env.context`, `memory.tail`), size in chars, sha256-prefix content hash. [c209-C]:
99
- * `skills.block` is GONE — the skills listing left the stable prefix for the skills_listing
100
- * reminder frame (observable via `steering_injected` source "skills_listing"). */
131
+ identity: PromptManifestIdentity;
132
+ selectors: PromptManifestSelectors;
133
+ /** Ordered blocks: stable id (e.g. `role.base`, `harness.context`, `memory.safety`, `env.context`,
134
+ * `memory.tail`), size in chars, salted short content hash — the block-view id wordlist is a downstream contract. */
101
135
  blocks: Array<{
102
136
  id: string;
103
137
  chars: number;
104
138
  hash: string;
105
139
  }>;
106
- /**
107
- * Manifest v2 (stage S1, ADDITIVE — the v1 `blocks` id wordlist above is a downstream
108
- * contract and stays as-is): the compiled-IR view, one entry per pack section, carrying the
109
- * assembly protocol's semantic/lifecycle dimensions (slot/carrier/cadence/cacheClass).
110
- * Absent on the legacy free-form provider path (single opaque block, no section structure).
111
- * `contentHash` (digest tiering): UNSALTED full sha256, present ONLY on
112
- * operator-declared sections (typed `stableBlocks` lane) — the center-publish ↔ manifest
113
- * reconciliation anchor. Core-native sections stay salted-only (`hash`).
114
- */
115
- sections?: Array<{
116
- id: string;
117
- slot: string;
118
- carrier: string;
119
- cadence: string;
120
- cacheClass: string;
121
- chars: number;
122
- hash: string;
123
- contentHash?: string;
124
- }>;
140
+ sections: PromptManifestSection[];
141
+ /** Every overlay the composition superseded (a later one on the same target won, or it changed nothing this
142
+ * run); absent when none was. */
143
+ superseded?: SupersededOverlay[];
125
144
  /**
126
145
  * S2 (additive): the mounted tools plane — per-tool contract identity, durable-replay
127
146
  * aliases, presentation-invariant shape digest and full wire-schema digest (initial mount face;
@@ -18,7 +18,8 @@ export type { PermissionMode } from "./ask-origin.js";
18
18
  export type { ToolEffect, ToolContentOrigin, ReversibilityVerdict, ReadRootGrantCandidate, ToolSpec, ToolReturn, NestedUsage, NestedUsageAccum, ToolExecuteContext } from "./tool-spec.js";
19
19
  export type { BeforeWriteRequest, BeforeWriteResult, BeforeWriteHook, TrackEditRequest, TrackEditResult, TrackFileEditHook, FileEditedNotice, FileEditedHook, HandsBandOptions } from "./hands-band.js";
20
20
  export type { AgentDefinition, SkillSpec } from "./agent-definition.js";
21
- export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit, McpRevocationLedger, McpMountIdentity } from "./mcp-server-spec.js";
21
+ export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit, McpRevocationLedger, McpMountIdentity, McpToolAxesRead } from "./mcp-server-spec.js";
22
+ export { readMcpToolAxes } from "./mcp-server-spec.js";
22
23
  export type { TaskLimits } from "./task-limits.js";
23
24
  export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
24
25
  export type { TerminalCause, PausedCause } from "./terminal-cause.js";
@@ -1,4 +1,5 @@
1
1
  export { MODEL_ROLES } from "./model-seat.js";
2
+ export { readMcpToolAxes } from "./mcp-server-spec.js";
2
3
  export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
3
4
  export { __resetMalformedDelegationSeatAnnouncement, backgroundChildTerminal, deliverDelegationLifecycle, emitsChildRowFrames, taskStartedFrame } from "./delegation-frames.js";
4
5
  export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, parentLegIds, settleOwedUserInput, undrainedUserInputNotices, USER_INPUT_UNDRAINED_CAUSES, USER_INPUT_UNDRAINED_FAMILIES } from "./engine-notice.js";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * UNC under the win family: two leading separators, a host, a share — either separator, as `path.win32`
3
+ * reads it. The ONE UNC recognizer behind `isAbsoluteForFamily`, `pathIdentityOf` and `joinForFamily`
4
+ * (tools/fs/safety.ts), the symlink-chain reader (core/path-identity.ts) and the engine's own chain walk
5
+ * (engine/execution-env/symlink-chain.ts).
6
+ *
7
+ * A pure spelling test with no dependency, so the engine layer and the tools layer both read it from here:
8
+ * the engine never imports tools/, and tools reach the engine only through the `internal/harness` facade.
9
+ */
10
+ export declare function isUncSpelling(p: string): boolean;
@@ -0,0 +1,3 @@
1
+ export function isUncSpelling(p) {
2
+ return /^[\\/]{2}[^\\/]+[\\/]+[^\\/]/.test(p);
3
+ }
@@ -34,6 +34,14 @@ export declare function egressText<T extends EgressTier>(tier: T, text: string,
34
34
  export declare function egressThrownText<T extends EgressTier>(tier: T, err: unknown): Egress<T>;
35
35
  /** The `same-principal` tier's pass, under the name hosts call it by (the engine calls {@link egressText}). */
36
36
  export declare function redactSecrets(s: string, report?: RedactionReport): Egress<"same-principal">;
37
+ /**
38
+ * An extension's own words — its registration name, a bus reason, a key it wrote — made fit for an operator line: the
39
+ * `same-principal` egress pass first, then one line and bounded. The pass runs before the cut, so a cut never leaves part
40
+ * of a credential the pass would have recognised whole. Every station sentence that carries such words reads them here.
41
+ * It lives beside the pass, not in the stations module: a value import of the stations graph from a station's consumer
42
+ * closed a load-order cycle through the fs tools' barrel (an export the barrel copied before it existed).
43
+ */
44
+ export declare function extensionWords(s: string, max: number): string;
37
45
  /** The `human` tier's pass, under the name hosts call it by (the engine calls {@link egressText}). */
38
46
  export declare function redactHostLeaks(s: string, report?: RedactionReport): Egress<"human">;
39
47
  /**
@@ -1,4 +1,4 @@
1
- import { delimitUntrusted, neutralizeForFence } from "./untrusted-text.js";
1
+ import { delimitUntrusted, inlineUntrusted, neutralizeForFence } from "./untrusted-text.js";
2
2
  import { egressPasses, runRedactionPasses } from "./redaction-passes.js";
3
3
  import { CREDENTIAL_VOCABULARY, egressPassGroups, isSensitiveRecordKey, URI_SCHEME_SOURCE } from "./credential-vocabulary.js";
4
4
  import { isErrorLike, readMember, thrownText } from "./thrown-value.js";
@@ -34,6 +34,9 @@ export function egressThrownText(tier, err) {
34
34
  export function redactSecrets(s, report) {
35
35
  return egressText("same-principal", s, report);
36
36
  }
37
+ export function extensionWords(s, max) {
38
+ return inlineUntrusted(egressText("same-principal", s), max);
39
+ }
37
40
  export function redactHostLeaks(s, report) {
38
41
  return egressText("human", s, report);
39
42
  }
@@ -27,6 +27,7 @@ import type { HumanInputAttachment } from "./task-event.js";
27
27
  import { type ModelFileReader } from "../tools/fs/fs-read.js";
28
28
  import type { SyntheticReadJudge } from "./synthetic-read-verdict.js";
29
29
  import { type ReminderDisclosureCounts } from "./reminder-disclosure.js";
30
+ import type { ContextWindowOverlay } from "./context-settings.js";
30
31
  /** At most this many attachments on one objective. */
31
32
  export declare const USER_ATTACHMENTS_MAX = 20;
32
33
  /** The longest path or name an entry may carry (the platform path limit). */
@@ -133,9 +134,18 @@ export interface ReadUserAttachmentsInput {
133
134
  * frame carries the commit its delivery owes, run only when the frame is in the transcript.
134
135
  */
135
136
  export declare function readUserAttachments(input: ReadUserAttachmentsInput): Promise<MintedAttachmentFrame[]>;
137
+ /** The objective as the window check sees it: a reader of the live overlay over the model's window declarations (the
138
+ * same seat the request guard reads) and the objective text's length — it rides the first request ahead of the
139
+ * frames. The overlay is a GETTER because it is read when the frames exist, not when the call is made: the reads are
140
+ * asynchronous and a deployment may swap its window declarations meanwhile, as it may before any request. */
141
+ export interface AttachmentWindowInput {
142
+ readonly overlay: () => ContextWindowOverlay | undefined;
143
+ readonly objectiveChars: number;
144
+ }
136
145
  /** The objective lane's read: once the UserPromptSubmit hook let the objective through (a blocked objective reads
137
- * nothing), and before the pre-call gate, which prices the frames (`chars`). Commits nothing. */
138
- export declare function readObjectiveAttachments(prepared: Pick<import("./runner/contracts.js").Prepared, "userAttachments" | "modelFileReader" | "syntheticReadVerdict" | "cwdRef" | "reminderMark" | "reminderDisclosureCounts" | "abortController">, inputId: string, blocked: boolean): Promise<{
146
+ * nothing), and before the pre-call gate, which prices the frames (`chars`). Refuses the whole objective when the frames
147
+ * and the objective cannot ride one request ({@link refuseFramesOverWindow}). Commits nothing. */
148
+ export declare function readObjectiveAttachments(prepared: Pick<import("./runner/contracts.js").Prepared, "userAttachments" | "modelFileReader" | "syntheticReadVerdict" | "cwdRef" | "reminderMark" | "reminderDisclosureCounts" | "abortController" | "harness">, inputId: string, blocked: boolean, window: AttachmentWindowInput): Promise<{
139
149
  frames: MintedAttachmentFrame[];
140
150
  chars: number;
141
151
  }>;
@@ -3,10 +3,12 @@ import { READ_OUTCOMES } from "../tools/fs/fs-read.js";
3
3
  import { renderDirectoryListing } from "../tools/fs/dir-entries.js";
4
4
  import { MAX_READ_OUTPUT_CHARS } from "../tools/fs/fs-shared.js";
5
5
  import { normalizeFileText } from "../tools/fs/encoding.js";
6
- import { ADMITTED_IMAGE_MIME_TYPES, admitImageBytes } from "../tools/fs/image-admission.js";
6
+ import { ADMITTED_IMAGE_MIME_TYPES, admitImageBytes } from "./image-admission.js";
7
7
  import { PDF_MAX_PAGES_PER_READ } from "../tools/fs/pdf.js";
8
8
  import { MARKED_BLOCK_AFTER_DATA, mintSystemReminder } from "./reminder-mint.js";
9
9
  import { commitReminderDisclosureEffects, planReminderDisclosure } from "./reminder-disclosure.js";
10
+ import { DEFAULT_CHARS_PER_TOKEN, estimateTokens } from "../internal/harness.js";
11
+ import { guardBudget } from "./context-guard.js";
10
12
  export const USER_ATTACHMENTS_MAX = 20;
11
13
  export const USER_ATTACHMENT_LABEL_MAX = 4096;
12
14
  export const USER_ATTACHMENT_KINDS = Object.freeze(["text", "notebook", "image", "pdf", "directory", "client_text", "client_image"]);
@@ -383,7 +385,19 @@ function mintFrame(r, at, seat) {
383
385
  const commit = result !== undefined || extra.length > 0 ? () => seat.commit(result, extra) : undefined;
384
386
  return { seed: { content, attachment }, ...(commit !== undefined ? { commit } : {}) };
385
387
  }
386
- export async function readObjectiveAttachments(prepared, inputId, blocked) {
388
+ function refuseFramesOverWindow(frames, model, window) {
389
+ const budget = guardBudget(model, window.overlay());
390
+ if (!Number.isFinite(budget))
391
+ return;
392
+ const cpt = model.charsPerToken ?? DEFAULT_CHARS_PER_TOKEN;
393
+ const asMessage = (f) => ({ role: "user", content: [...f.seed.content], timestamp: 0 });
394
+ const tokens = frames.reduce((n, f) => n + estimateTokens(asMessage(f), cpt), 0) + Math.ceil(window.objectiveChars / cpt);
395
+ if (tokens <= budget)
396
+ return;
397
+ const n = frames.length;
398
+ throw userAttachmentRefusal(SEAT_FIELD, `the ${n} ${n === 1 ? "attachment" : "attachments"} and the objective come to about ${tokens} tokens, over the ${budget} tokens one request can hold on this model — to send it the engine would have to drop the objective or some of the attachments. Nothing was sent; attach fewer or smaller parts.`);
399
+ }
400
+ export async function readObjectiveAttachments(prepared, inputId, blocked, window) {
387
401
  if (blocked || prepared.userAttachments === undefined)
388
402
  return { frames: [], chars: 0 };
389
403
  const frames = await readUserAttachments({
@@ -397,6 +411,7 @@ export async function readObjectiveAttachments(prepared, inputId, blocked) {
397
411
  counts: prepared.reminderDisclosureCounts,
398
412
  signal: prepared.abortController.signal,
399
413
  });
414
+ refuseFramesOverWindow(frames, prepared.harness.getModel(), window);
400
415
  return { frames, chars: frames.reduce((n, f) => n + f.seed.content.reduce((m, b) => m + (b.type === "text" ? b.text.length : 0), 0), 0) };
401
416
  }
402
417
  export function lastAttachmentFrameOf(entries, id) {
@@ -23,7 +23,7 @@
23
23
  import { type PermissionMode } from "./ask-origin.js";
24
24
  import type { RunnerDeps, TaskSpec } from "./types.js";
25
25
  import { type StoreDurability } from "./checkpoint-store.js";
26
- import type { WiringManifestHookEntry } from "./hook-seats.js";
26
+ import type { ModAdmissionRecord } from "./mods/kernel/index.js";
27
27
  import type { McpDelivered, McpFailureKind, McpServerLiveness } from "./mcp-failure.js";
28
28
  import type { WriteProtectionTargetView } from "./write-protect.js";
29
29
  import type { OnAsk } from "./tool-policy.js";
@@ -180,7 +180,6 @@ export declare function deriveLspSeam(mounted: boolean, diagnosticsLive: boolean
180
180
  * (`schemaVersion` bumps only on a semantic break of an EXISTING field). The TaskEvent face is the
181
181
  * host/operator plane — the manifest never enters model context.
182
182
  */
183
- export type { WiringManifestHookEntry };
184
183
  export interface WiringManifest {
185
184
  schemaVersion: 1;
186
185
  /** Present on EFFECTIVE (per-leg) manifests only; the static half has no leg. */
@@ -356,14 +355,16 @@ export interface WiringManifest {
356
355
  */
357
356
  tools?: import("./tool-roster.js").ToolRoster;
358
357
  /**
359
- * EFFECTIVE half only: the hook seats this leg wired, one entry per family, in {@link import("./hook-seats.js").HOOK_FAMILIES} order. PRESENT IFF at least one
360
- * seat is wired — a deployment that wires none reports nothing here and its manifest (and {@link configFingerprint}) is byte-for-byte what it was; an empty
361
- * array is never emitted, so absence reads as "this leg wired no hook RECORD of its own" — NOT as "no hook runs": a delegated child with no local record can
362
- * still be screened (and refused) by an ancestor's `preToolUse` through the gate's constraint fold, which this face deliberately does not call a hook of
363
- * this leg. Every entry is deployment code the engine awaits on the critical path, fail-closed on the two decision seats. EXCLUDED from
364
- * {@link configFingerprint}: the record is a per-task seat, so one assembly's legs legitimately differ on it.
358
+ * EFFECTIVE half only: the leg's mods admission — one record per registration of the two seats, in run order: a
359
+ * mounted one with the patterns it actually hung (`events`), the ones it declared observe-only (`observe`) and the
360
+ * judges skipped while it was judged (`skipped`), or a refused one with who refused it and why (`refusedBy`,
361
+ * `reason`). PRESENT IFF the leg has a registration — a deployment that wires none reports nothing here and its
362
+ * manifest (and {@link configFingerprint}) is byte-for-byte what it was. Absence reads as "this leg carries no
363
+ * registration", NOT as "no extension judges this leg's calls": a delegated child can still be screened by an
364
+ * ancestor's chain through the gate's constraint fold. EXCLUDED from {@link configFingerprint}: the task seat is a
365
+ * per-task seat, so one assembly's legs legitimately differ on it.
365
366
  */
366
- hooks?: readonly WiringManifestHookEntry[];
367
+ mods?: readonly ModAdmissionRecord[];
367
368
  /**
368
369
  * EFFECTIVE half only: the LSP code-intelligence seam. PRESENT IFF a manager seat resolved
369
370
  * (`spec.lspManager ?? deps.lspManager`); a deployment that wires none reports nothing (byte-for-byte
@@ -412,7 +413,7 @@ export interface WiringManifest {
412
413
  * the engine's seats — the same fact `config.write_protection_target_view_absent` announces once per run
413
414
  * when a covered write tool is mounted beside a `"spelling-only"` judge.
414
415
  *
415
- * IN the fingerprint below (unlike `tools`/`lsp`/`hooks`): which view the judge got is an ASSEMBLY fact
416
+ * IN the fingerprint below (unlike `tools`/`lsp`/`mods`): which view the judge got is an ASSEMBLY fact
416
417
  * — it follows the table seat and whether the deployment wired hands at all — so legs of one assembly
417
418
  * agree on it, which is exactly the equality the fingerprint advertises.
418
419
  *
@@ -466,7 +467,7 @@ export interface WiringManifest {
466
467
  * `"on"` — it records (store wired, neither layer declared it off, a filesystem env mounted). `"disabled"` — it does
467
468
  * not, whichever layer or missing half made it so (`TaskSpec.fileHistory`, `RunnerDeps.fileHistoryStore: "disabled"`, `RunnerDeps.fileHistoryCapture: "off"`,
468
469
  * no store, no filesystem env); the host knows its own deployment seat. ABSENT = an older mint or an external
469
- * derivation, never a state. Out of {@link configFingerprint}: the request word is a per-task seat (`hooks` reasoning).
470
+ * derivation, never a state. Out of {@link configFingerprint}: the request word is a per-task seat (`mods` reasoning).
470
471
  */
471
472
  fileHistory?: "on" | "disabled";
472
473
  /** EFFECTIVE half only — a short, non-sensitive fingerprint (sha256 prefix over the canonical
@@ -544,8 +545,8 @@ export interface WiringFacts {
544
545
  mcp?: readonly WiringManifestMcpEntry[];
545
546
  /** Effective half only — the leg's minted tool roster (see {@link WiringManifest.tools}). */
546
547
  tools?: import("./tool-roster.js").ToolRoster;
547
- /** Effective half only — the wired hook seats ({@link WiringManifest.hooks}); an empty array and an absent value derive the same thing (no section). */
548
- hooks?: readonly WiringManifestHookEntry[];
548
+ /** Effective half only — the leg's mods admission records ({@link WiringManifest.mods}); an empty array and an absent value derive the same thing (no section). */
549
+ mods?: readonly ModAdmissionRecord[];
549
550
  /** Effective half only — the LSP seam ({@link WiringManifest.lsp}); absent ⇒ no manager wired. */
550
551
  lsp?: {
551
552
  mounted: boolean;
@@ -210,7 +210,7 @@ export function deriveWiringManifest(facts) {
210
210
  ...(facts.half === "effective" && facts.autoMode !== undefined ? { autoMode: readAutoModeFact(facts.autoMode) } : {}),
211
211
  ...(facts.half === "effective" && facts.mcp !== undefined ? { mcp: facts.mcp.map((e) => ({ ...e })) } : {}),
212
212
  ...(facts.half === "effective" && facts.tools !== undefined ? { tools: facts.tools } : {}),
213
- ...(facts.half === "effective" && facts.hooks !== undefined && facts.hooks.length > 0 ? { hooks: facts.hooks.map((h) => ({ ...h })) } : {}),
213
+ ...(facts.half === "effective" && facts.mods !== undefined && facts.mods.length > 0 ? { mods: [...facts.mods] } : {}),
214
214
  ...(facts.half === "effective" && facts.lsp !== undefined ? { lsp: { ...facts.lsp } } : {}),
215
215
  ...(facts.half === "effective" && facts.hands !== undefined ? { hands: readHandsFact(facts.hands) } : {}),
216
216
  ...(facts.half === "effective" && facts.permissionMode !== undefined ? { permissionMode: readPermissionModeFact(facts.permissionMode) } : {}),
@@ -226,7 +226,7 @@ export function deriveWiringManifest(facts) {
226
226
  : {}),
227
227
  };
228
228
  if (facts.half === "effective") {
229
- const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, hooks: _hooks, teamRole: _teamRole, peerPresence: _peerPresence, fileHistory: _fileHistory, permissionMode: _permissionMode, ...assembly } = manifest;
229
+ const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, mods: _mods, teamRole: _teamRole, peerPresence: _peerPresence, fileHistory: _fileHistory, permissionMode: _permissionMode, ...assembly } = manifest;
230
230
  const { provenance: _askSeat, ...askForHash } = assembly.ask;
231
231
  const { provenance: _questionSeat, ...questionForHash } = assembly.question;
232
232
  manifest.configFingerprint = createHash("sha256")
@@ -2,8 +2,7 @@ import { renderUserAttachmentView, userAttachmentOf } from "../llm/index.js";
2
2
  import { normalizeLlmMessageContent } from "../harness/messages.js";
3
3
  import { sliceHeadSafe } from "../../core/surrogate-safe-slice.js";
4
4
  import { cutEnginePrefix, cutEngineSegments, flattenableUserText } from "../../core/untrusted-text.js";
5
- import { fileArgPath } from "../../tools/fs/safety.js";
6
- import { fileOpAccessOf } from "../../core/tool-registry.js";
5
+ import { fileArgPath, fileOpAccessOf } from "../../core/tool-registry.js";
7
6
  export const DURABLE_HISTORY_NAMES = new Map([
8
7
  ["read", "read"],
9
8
  ["write", "create"],