@sema-agent/core 7.54.1 → 7.56.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 (621) hide show
  1. package/CHANGELOG.md +950 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cascade.js +1 -1
  5. package/dist/agents/cc-peer-directory.d.ts +36 -0
  6. package/dist/agents/cc-peer-directory.js +139 -0
  7. package/dist/agents/cc-peer-wire.d.ts +105 -0
  8. package/dist/agents/cc-peer-wire.js +98 -0
  9. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  10. package/dist/agents/cc-uds-peer-channel.js +457 -0
  11. package/dist/agents/child-model-seat.d.ts +0 -11
  12. package/dist/agents/child-model-seat.js +0 -3
  13. package/dist/agents/cross-session-envelope.d.ts +4 -1
  14. package/dist/agents/cross-session-envelope.js +8 -1
  15. package/dist/agents/cross-session-judge.d.ts +2 -2
  16. package/dist/agents/list-agents-tool.d.ts +3 -1
  17. package/dist/agents/list-agents-tool.js +9 -8
  18. package/dist/agents/observer.d.ts +4 -5
  19. package/dist/agents/observer.js +2 -1
  20. package/dist/agents/peer-admission.d.ts +6 -0
  21. package/dist/agents/peer-admission.js +4 -1
  22. package/dist/agents/peer-directory.d.ts +65 -13
  23. package/dist/agents/peer-directory.js +90 -25
  24. package/dist/agents/peer-notices.d.ts +1 -1
  25. package/dist/agents/peer-session-drain.d.ts +3 -1
  26. package/dist/agents/peer-session-drain.js +3 -2
  27. package/dist/agents/read-inbox-tool.js +2 -1
  28. package/dist/agents/repair-loop.js +2 -2
  29. package/dist/agents/retain-ledger.d.ts +1 -1
  30. package/dist/agents/roster-store.d.ts +1 -1
  31. package/dist/agents/send-message-tool.d.ts +10 -0
  32. package/dist/agents/send-message-tool.js +37 -8
  33. package/dist/agents/subagent.d.ts +39 -82
  34. package/dist/agents/subagent.js +109 -106
  35. package/dist/agents/tool-filter.d.ts +31 -46
  36. package/dist/agents/tool-filter.js +13 -33
  37. package/dist/agents/verify.d.ts +6 -5
  38. package/dist/agents/verify.js +3 -3
  39. package/dist/brain/anthropic.js +43 -81
  40. package/dist/brain/errors.d.ts +15 -0
  41. package/dist/brain/errors.js +10 -0
  42. package/dist/brain/media-degrade.d.ts +18 -7
  43. package/dist/brain/media-degrade.js +13 -2
  44. package/dist/brain/model-capability.d.ts +37 -0
  45. package/dist/brain/model-capability.js +34 -0
  46. package/dist/brain/model-presets.d.ts +6 -12
  47. package/dist/brain/model-presets.js +1 -6
  48. package/dist/brain/open-responses.js +27 -35
  49. package/dist/brain/openai.js +30 -98
  50. package/dist/brain/provider-dialect.d.ts +39 -3
  51. package/dist/brain/provider-dialect.js +28 -0
  52. package/dist/brain/reasoning-request.d.ts +96 -0
  53. package/dist/brain/reasoning-request.js +174 -0
  54. package/dist/brain/reasoning.d.ts +12 -12
  55. package/dist/brain/reasoning.js +4 -3
  56. package/dist/brain/request-params.d.ts +62 -9
  57. package/dist/brain/request-params.js +42 -7
  58. package/dist/brain/retry.d.ts +1 -1
  59. package/dist/brain/route-adjudicator.d.ts +15 -0
  60. package/dist/brain/route-adjudicator.js +15 -0
  61. package/dist/brain/status-sink.d.ts +20 -0
  62. package/dist/brain/status-sink.js +7 -0
  63. package/dist/brain/stream-engine.js +6 -5
  64. package/dist/brain/stream-shared.d.ts +1 -1
  65. package/dist/core/a2a.d.ts +2 -1
  66. package/dist/core/a2a.js +19 -13
  67. package/dist/core/advisor-verdict.d.ts +120 -0
  68. package/dist/core/advisor-verdict.js +92 -0
  69. package/dist/core/agent-definition.d.ts +17 -8
  70. package/dist/core/allow-entry.d.ts +69 -36
  71. package/dist/core/allow-entry.js +81 -52
  72. package/dist/core/allow-rule-shadow.d.ts +10 -3
  73. package/dist/core/approval-object.d.ts +2 -1
  74. package/dist/core/approval-object.js +6 -6
  75. package/dist/core/ask-origin.d.ts +127 -29
  76. package/dist/core/ask-origin.js +87 -25
  77. package/dist/core/ask-question.d.ts +51 -8
  78. package/dist/core/ask-question.js +12 -7
  79. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  80. package/dist/core/ask-unresolvable-notice.js +16 -2
  81. package/dist/core/auto-compaction.d.ts +11 -8
  82. package/dist/core/auto-compaction.js +4 -2
  83. package/dist/core/auto-mode-arming.d.ts +2 -2
  84. package/dist/core/auto-mode-defaults.d.ts +8 -8
  85. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  86. package/dist/core/auto-mode-prompt.d.ts +1 -1
  87. package/dist/core/auto-mode.d.ts +17 -9
  88. package/dist/core/auto-mode.js +9 -6
  89. package/dist/core/background-agent-store.d.ts +3 -3
  90. package/dist/core/canonical-json.d.ts +1 -1
  91. package/dist/core/canonical-json.js +2 -2
  92. package/dist/core/checkpoint-generation.d.ts +53 -0
  93. package/dist/core/checkpoint-generation.js +35 -0
  94. package/dist/core/checkpoint-queries.d.ts +180 -0
  95. package/dist/core/checkpoint-queries.js +272 -0
  96. package/dist/core/checkpoint-requirements.d.ts +19 -4
  97. package/dist/core/checkpoint-requirements.js +8 -14
  98. package/dist/core/checkpoint-store.d.ts +165 -72
  99. package/dist/core/checkpoint-store.js +79 -82
  100. package/dist/core/child-clamp-seats.d.ts +6 -0
  101. package/dist/core/child-clamp-seats.js +3 -16
  102. package/dist/core/compliance.d.ts +2 -2
  103. package/dist/core/context-edit.d.ts +6 -7
  104. package/dist/core/cross-boundary-taint.d.ts +11 -4
  105. package/dist/core/cross-boundary-taint.js +3 -3
  106. package/dist/core/decision-receipt.d.ts +37 -3
  107. package/dist/core/decision-receipt.js +19 -19
  108. package/dist/core/delegation-not-started.d.ts +6 -0
  109. package/dist/core/delegation-not-started.js +17 -0
  110. package/dist/core/effective-path-target.d.ts +1 -1
  111. package/dist/core/engine-attestation.d.ts +93 -0
  112. package/dist/core/engine-attestation.js +70 -0
  113. package/dist/core/engine-capabilities.d.ts +4 -1
  114. package/dist/core/engine-capabilities.js +1 -1
  115. package/dist/core/engine-notice.d.ts +45 -12
  116. package/dist/core/exec-output-tail.d.ts +1 -1
  117. package/dist/core/file-history-retention.d.ts +1 -1
  118. package/dist/core/file-history-store.d.ts +147 -21
  119. package/dist/core/file-history-store.js +58 -32
  120. package/dist/core/gate-fold.d.ts +1 -1
  121. package/dist/core/gate-fold.js +24 -11
  122. package/dist/core/gate-lanes.js +81 -68
  123. package/dist/core/gate-outcome.d.ts +40 -6
  124. package/dist/core/gate-outcome.js +56 -0
  125. package/dist/core/governance-codes.d.ts +17 -3
  126. package/dist/core/governance-codes.js +16 -0
  127. package/dist/core/hands-band.d.ts +1 -1
  128. package/dist/core/hooks.d.ts +21 -20
  129. package/dist/core/hooks.js +3 -1
  130. package/dist/core/host-floor.d.ts +128 -0
  131. package/dist/core/host-floor.js +206 -0
  132. package/dist/core/host-target.d.ts +84 -0
  133. package/dist/core/host-target.js +92 -0
  134. package/dist/core/image-downsample.d.ts +1 -1
  135. package/dist/core/lsp-diagnostics.d.ts +4 -4
  136. package/dist/core/lsp.d.ts +3 -3
  137. package/dist/core/mailbox-store.d.ts +4 -0
  138. package/dist/core/mcp-connection-pool.d.ts +18 -2
  139. package/dist/core/mcp-connection-pool.js +53 -6
  140. package/dist/core/mcp-failure.d.ts +23 -4
  141. package/dist/core/mcp-failure.js +26 -11
  142. package/dist/core/mcp-listing-drift.d.ts +10 -0
  143. package/dist/core/mcp-listing-drift.js +6 -0
  144. package/dist/core/mcp-server-link.d.ts +173 -0
  145. package/dist/core/mcp-server-link.js +127 -0
  146. package/dist/core/mcp-server-spec.d.ts +4 -2
  147. package/dist/core/mcp-session-end.d.ts +26 -0
  148. package/dist/core/mcp-session-end.js +29 -0
  149. package/dist/core/mcp-startup-request.d.ts +17 -0
  150. package/dist/core/mcp-startup-request.js +17 -0
  151. package/dist/core/mcp.d.ts +17 -13
  152. package/dist/core/mcp.js +240 -189
  153. package/dist/core/media-byte-cap.d.ts +1 -1
  154. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  155. package/dist/core/memory-engine/engine.d.ts +9 -9
  156. package/dist/core/memory-engine/engine.js +4 -4
  157. package/dist/core/memory-engine/layout.d.ts +60 -8
  158. package/dist/core/memory-engine/layout.js +65 -6
  159. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  160. package/dist/core/memory-engine/tools.js +4 -1
  161. package/dist/core/mode-policy.d.ts +1 -1
  162. package/dist/core/model-seat.d.ts +10 -3
  163. package/dist/core/mods/classic-events.d.ts +67 -0
  164. package/dist/core/mods/classic-events.js +1 -0
  165. package/dist/core/mods/dollar.d.ts +13 -0
  166. package/dist/core/mods/extension-call.d.ts +31 -0
  167. package/dist/core/mods/extension-call.js +43 -0
  168. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  169. package/dist/core/mods/kernel/dispatch.js +140 -69
  170. package/dist/core/mods/kernel/events.d.ts +47 -11
  171. package/dist/core/mods/kernel/events.js +66 -42
  172. package/dist/core/mods/kernel/index.d.ts +4 -4
  173. package/dist/core/mods/kernel/index.js +2 -2
  174. package/dist/core/mods/kernel/receive.d.ts +39 -5
  175. package/dist/core/mods/kernel/receive.js +290 -17
  176. package/dist/core/mods/kernel/registration.d.ts +33 -2
  177. package/dist/core/mods/kernel/registration.js +6 -7
  178. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  179. package/dist/core/mods/kernel/site-rules.js +24 -42
  180. package/dist/core/mods/spec-seats.d.ts +69 -0
  181. package/dist/core/mods/spec-seats.js +114 -0
  182. package/dist/core/mods/stations.d.ts +28 -8
  183. package/dist/core/mods/stations.js +29 -13
  184. package/dist/core/mods/tool-call.d.ts +79 -0
  185. package/dist/core/mods/tool-call.js +152 -0
  186. package/dist/core/namespaced-rule-name.d.ts +44 -24
  187. package/dist/core/namespaced-rule-name.js +50 -43
  188. package/dist/core/output-style.d.ts +1 -1
  189. package/dist/core/param-rule-reach.d.ts +15 -0
  190. package/dist/core/param-rule-reach.js +30 -0
  191. package/dist/core/parent-spec-seat.d.ts +13 -1
  192. package/dist/core/parent-spec-seat.js +6 -0
  193. package/dist/core/park-selfcheck.js +1 -0
  194. package/dist/core/pause-registry.d.ts +16 -5
  195. package/dist/core/pause-registry.js +6 -2
  196. package/dist/core/peer-channel.d.ts +70 -0
  197. package/dist/core/peer-channel.js +1 -0
  198. package/dist/core/permission-rule-consent.d.ts +30 -5
  199. package/dist/core/permission-rule-consent.js +147 -50
  200. package/dist/core/permission-rule-model.d.ts +245 -65
  201. package/dist/core/permission-rule-model.js +421 -107
  202. package/dist/core/permission-rule-org.d.ts +6 -2
  203. package/dist/core/permission-rule-org.js +7 -3
  204. package/dist/core/permission-rule-provider.d.ts +6 -2
  205. package/dist/core/permission-rule-provider.js +41 -11
  206. package/dist/core/permission-rule-store.d.ts +22 -26
  207. package/dist/core/permission-rule-store.js +12 -6
  208. package/dist/core/permission-rule-sync.d.ts +11 -2
  209. package/dist/core/permission-rule-sync.js +11 -3
  210. package/dist/core/permission-rule-syntax.d.ts +5 -4
  211. package/dist/core/permission-rule-syntax.js +2 -2
  212. package/dist/core/permission-rules.d.ts +53 -15
  213. package/dist/core/permission-rules.js +125 -100
  214. package/dist/core/persisted-rule-arms.d.ts +6 -4
  215. package/dist/core/persisted-rule-arms.js +10 -12
  216. package/dist/core/present-plan-tool.js +3 -1
  217. package/dist/core/principal-name.d.ts +20 -0
  218. package/dist/core/principal-name.js +22 -0
  219. package/dist/core/prompt-section-seat.js +4 -6
  220. package/dist/core/protocol-http-auth.d.ts +26 -5
  221. package/dist/core/protocol-http-auth.js +137 -4
  222. package/dist/core/protocol-naming.d.ts +2 -2
  223. package/dist/core/read-only-shell-table.d.ts +1 -1
  224. package/dist/core/read-only-shell.d.ts +1 -1
  225. package/dist/core/retired-keys.d.ts +16 -0
  226. package/dist/core/retired-keys.js +16 -4
  227. package/dist/core/rewrite-rejudge.d.ts +60 -0
  228. package/dist/core/rewrite-rejudge.js +36 -0
  229. package/dist/core/roles.d.ts +34 -3
  230. package/dist/core/roles.js +66 -53
  231. package/dist/core/rule-lane-reads.d.ts +20 -15
  232. package/dist/core/rule-lane-reads.js +45 -17
  233. package/dist/core/rule-offer-read.d.ts +53 -0
  234. package/dist/core/rule-offer-read.js +146 -0
  235. package/dist/core/rule-owner.d.ts +46 -0
  236. package/dist/core/rule-owner.js +29 -0
  237. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  238. package/dist/core/runner/advisor-instructions.js +61 -0
  239. package/dist/core/runner/advisor-tool.d.ts +33 -0
  240. package/dist/core/runner/advisor-tool.js +112 -0
  241. package/dist/core/runner/announce-once-ledger.d.ts +18 -26
  242. package/dist/core/runner/announce-once-ledger.js +19 -46
  243. package/dist/core/runner/approval-feedback.js +6 -3
  244. package/dist/core/runner/assemble-result.d.ts +2 -1
  245. package/dist/core/runner/assemble-result.js +1 -1
  246. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  247. package/dist/core/runner/caller-roster.d.ts +21 -2
  248. package/dist/core/runner/caller-roster.js +38 -0
  249. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  250. package/dist/core/runner/capability-withheld-seat.js +24 -0
  251. package/dist/core/runner/classifier-ladder.d.ts +33 -13
  252. package/dist/core/runner/classifier-ladder.js +15 -14
  253. package/dist/core/runner/compaction-restate.d.ts +10 -6
  254. package/dist/core/runner/compaction-restate.js +9 -3
  255. package/dist/core/runner/construction-doors.js +3 -0
  256. package/dist/core/runner/contracts.d.ts +40 -33
  257. package/dist/core/runner/conversation-segment.d.ts +28 -0
  258. package/dist/core/runner/conversation-segment.js +42 -0
  259. package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
  260. package/dist/core/runner/cross-boundary-lane.js +58 -34
  261. package/dist/core/runner/decide-continuation.d.ts +7 -4
  262. package/dist/core/runner/decide-continuation.js +2 -2
  263. package/dist/core/runner/denial-limit-arms.d.ts +4 -4
  264. package/dist/core/runner/denial-limit-arms.js +1 -1
  265. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  266. package/dist/core/runner/derived-route-fallback.js +9 -7
  267. package/dist/core/runner/file-history-request.d.ts +18 -0
  268. package/dist/core/runner/file-history-request.js +21 -13
  269. package/dist/core/runner/file-history-restore.d.ts +45 -0
  270. package/dist/core/runner/file-history-restore.js +46 -0
  271. package/dist/core/runner/gate-exit.d.ts +9 -3
  272. package/dist/core/runner/gate-exit.js +11 -5
  273. package/dist/core/runner/image.d.ts +7 -17
  274. package/dist/core/runner/image.js +9 -60
  275. package/dist/core/runner/initial-run-state.js +1 -1
  276. package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
  277. package/dist/core/runner/permission-rule-lanes.js +38 -15
  278. package/dist/core/runner/person-path-rows.d.ts +12 -9
  279. package/dist/core/runner/person-path-rows.js +19 -8
  280. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  281. package/dist/core/runner/prepare-advisor.js +77 -0
  282. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  283. package/dist/core/runner/prepare-ask-lane.js +5 -2
  284. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  285. package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
  286. package/dist/core/runner/prepare-config-doors.d.ts +31 -38
  287. package/dist/core/runner/prepare-config-doors.js +57 -34
  288. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  289. package/dist/core/runner/prepare-defer-classify.js +7 -8
  290. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  291. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  292. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  293. package/dist/core/runner/prepare-file-history.js +41 -73
  294. package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
  295. package/dist/core/runner/prepare-gate-stations.js +12 -8
  296. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  297. package/dist/core/runner/prepare-hands-readface.js +15 -14
  298. package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
  299. package/dist/core/runner/prepare-inherited-gate.js +8 -6
  300. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  301. package/dist/core/runner/prepare-park-ask.js +12 -12
  302. package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
  303. package/dist/core/runner/prepare-policy-chain.js +68 -81
  304. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  305. package/dist/core/runner/prepare-project-context.js +6 -3
  306. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  307. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  308. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  309. package/dist/core/runner/prepare-prompt-inputs.js +4 -6
  310. package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
  311. package/dist/core/runner/prepare-protocol-tools.js +5 -4
  312. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  313. package/dist/core/runner/prepare-safety-scan.js +8 -23
  314. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  315. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  316. package/dist/core/runner/prepare-task.d.ts +1 -1
  317. package/dist/core/runner/prepare-task.js +41 -35
  318. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  319. package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
  320. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  321. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  322. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
  323. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  324. package/dist/core/runner/resume-admission.js +1 -1
  325. package/dist/core/runner/resume-apply.js +11 -12
  326. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  327. package/dist/core/runner/resume-claim.d.ts +4 -2
  328. package/dist/core/runner/resume-claim.js +15 -8
  329. package/dist/core/runner/resume-policy-outcome.js +1 -1
  330. package/dist/core/runner/retired-runner-deps.js +2 -1
  331. package/dist/core/runner/rewind-files.d.ts +15 -0
  332. package/dist/core/runner/rewind-files.js +132 -0
  333. package/dist/core/runner/run-attachment-seats.js +2 -2
  334. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  335. package/dist/core/runner/run-brain-sinks.js +4 -2
  336. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  337. package/dist/core/runner/run-compaction-machinery.js +2 -12
  338. package/dist/core/runner/run-git-lane.d.ts +1 -0
  339. package/dist/core/runner/run-harness-handlers.js +14 -7
  340. package/dist/core/runner/run-leg.d.ts +1 -1
  341. package/dist/core/runner/run-leg.js +43 -18
  342. package/dist/core/runner/run-settle-and-teardown.js +3 -2
  343. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  344. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  345. package/dist/core/runner/run-turn-boundary.js +15 -22
  346. package/dist/core/runner/runtask.d.ts +3 -0
  347. package/dist/core/runner/runtask.js +8 -9
  348. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  349. package/dist/core/runner/session-read-file-states.js +28 -0
  350. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  351. package/dist/core/runner/session-rule-policy.js +17 -31
  352. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  353. package/dist/core/runner/shell-env-withheld.js +51 -0
  354. package/dist/core/runner/side-call-account.d.ts +32 -8
  355. package/dist/core/runner/side-call-account.js +23 -1
  356. package/dist/core/runner/skills-seat.js +6 -2
  357. package/dist/core/runner/stream-settle-backstop.js +1 -1
  358. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  359. package/dist/core/runner/sub-agent-deny-lists.js +4 -6
  360. package/dist/core/runner/synthetic-tools.d.ts +16 -13
  361. package/dist/core/runner/synthetic-tools.js +8 -3
  362. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  363. package/dist/core/runner/tool-disclosure.js +3 -4
  364. package/dist/core/runner/tool-end-body.d.ts +1 -1
  365. package/dist/core/runner/tool-end-body.js +10 -9
  366. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  367. package/dist/core/runner/tool-face-overlay.js +17 -1
  368. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  369. package/dist/core/runner/tool-not-executed.js +11 -0
  370. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  371. package/dist/core/runner/tool-occurrence.js +7 -0
  372. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  373. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  374. package/dist/core/runner/turn-attachments.d.ts +91 -80
  375. package/dist/core/runner/turn-attachments.js +62 -37
  376. package/dist/core/runner-deps.d.ts +42 -42
  377. package/dist/core/runtime-caps.d.ts +4 -4
  378. package/dist/core/safety-axis-vocab.d.ts +6 -4
  379. package/dist/core/safety-axis-vocab.js +6 -5
  380. package/dist/core/safety-merge-corpus.js +26 -2
  381. package/dist/core/same-plain-value.d.ts +40 -0
  382. package/dist/core/same-plain-value.js +49 -0
  383. package/dist/core/scheduler.d.ts +1 -1
  384. package/dist/core/secret-env.d.ts +26 -3
  385. package/dist/core/secret-env.js +44 -8
  386. package/dist/core/select-model.js +3 -3
  387. package/dist/core/sensitive-path-policy.d.ts +1 -1
  388. package/dist/core/sensitive-path-policy.js +1 -1
  389. package/dist/core/session-policy-store.d.ts +102 -35
  390. package/dist/core/session-policy-store.js +210 -48
  391. package/dist/core/session-reconcile.d.ts +2 -2
  392. package/dist/core/session-store.d.ts +106 -37
  393. package/dist/core/session-store.js +165 -91
  394. package/dist/core/session.d.ts +101 -57
  395. package/dist/core/session.js +53 -0
  396. package/dist/core/shared-memory/tools.js +3 -1
  397. package/dist/core/shared-memory/types.d.ts +1 -1
  398. package/dist/core/shell-read-silence.d.ts +11 -12
  399. package/dist/core/shell-read-silence.js +9 -5
  400. package/dist/core/shell-run-candidates.js +3 -1
  401. package/dist/core/shell-wrapper-projection.js +1 -1
  402. package/dist/core/shell-wrapper-table.d.ts +14 -7
  403. package/dist/core/shell-wrapper-table.js +5 -4
  404. package/dist/core/side-query.d.ts +10 -0
  405. package/dist/core/side-query.js +15 -1
  406. package/dist/core/skill-grant.d.ts +7 -2
  407. package/dist/core/skill-grant.js +5 -0
  408. package/dist/core/skills-directory.js +6 -2
  409. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  410. package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
  411. package/dist/core/store-contracts/file-history-store-contract.js +74 -4
  412. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  413. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  414. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  415. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  416. package/dist/core/store-contracts/session-repo-contract.js +176 -0
  417. package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
  418. package/dist/core/store-contracts/session-store-contract.js +361 -51
  419. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  420. package/dist/core/stub-env.d.ts +2 -0
  421. package/dist/core/stub-env.js +1 -0
  422. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  423. package/dist/core/synthetic-read-verdict.js +3 -3
  424. package/dist/core/task-event.d.ts +42 -8
  425. package/dist/core/task-notification.d.ts +19 -15
  426. package/dist/core/task-registry-agent.d.ts +4 -4
  427. package/dist/core/task-registry-shared.d.ts +4 -4
  428. package/dist/core/task-registry-shared.js +1 -0
  429. package/dist/core/task-registry.d.ts +13 -4
  430. package/dist/core/task-registry.js +14 -2
  431. package/dist/core/task-result.d.ts +21 -3
  432. package/dist/core/task-spec.d.ts +69 -64
  433. package/dist/core/task-stream.d.ts +6 -6
  434. package/dist/core/task-tool-shape.d.ts +4 -4
  435. package/dist/core/tighten-task-spec.d.ts +1 -1
  436. package/dist/core/tighten-task-spec.js +2 -1
  437. package/dist/core/tool-catalog-entries.d.ts +36 -2
  438. package/dist/core/tool-catalog-entries.js +69 -43
  439. package/dist/core/tool-check-reading.d.ts +11 -0
  440. package/dist/core/tool-check-reading.js +11 -6
  441. package/dist/core/tool-conformance.js +1 -0
  442. package/dist/core/tool-errors.d.ts +2 -2
  443. package/dist/core/tool-face-reader.js +5 -3
  444. package/dist/core/tool-face.d.ts +21 -2
  445. package/dist/core/tool-face.js +1 -1
  446. package/dist/core/tool-model-gate.d.ts +5 -5
  447. package/dist/core/tool-name-aliases.d.ts +29 -8
  448. package/dist/core/tool-name-aliases.js +22 -4
  449. package/dist/core/tool-name-readings.d.ts +10 -43
  450. package/dist/core/tool-name-readings.js +2 -11
  451. package/dist/core/tool-policy.d.ts +85 -196
  452. package/dist/core/tool-policy.js +150 -175
  453. package/dist/core/tool-registry.d.ts +14 -7
  454. package/dist/core/tool-registry.js +17 -7
  455. package/dist/core/tool-result-store.js +5 -1
  456. package/dist/core/tool-roster.d.ts +57 -33
  457. package/dist/core/tool-roster.js +56 -68
  458. package/dist/core/tool-spec-members.js +8 -3
  459. package/dist/core/tool-spec.d.ts +53 -31
  460. package/dist/core/tools.js +51 -10
  461. package/dist/core/trace.d.ts +6 -2
  462. package/dist/core/types.d.ts +1 -1
  463. package/dist/core/untrusted-egress.d.ts +1 -1
  464. package/dist/core/untrusted-text.d.ts +1 -1
  465. package/dist/core/user-attachment.d.ts +8 -1
  466. package/dist/core/user-attachment.js +64 -4
  467. package/dist/core/warm-resume.d.ts +1 -1
  468. package/dist/core/wiring-manifest.d.ts +58 -0
  469. package/dist/core/wiring-manifest.js +14 -5
  470. package/dist/core/workflow-journal-store.d.ts +62 -0
  471. package/dist/core/workflow-journal-store.js +78 -2
  472. package/dist/core/workflow-run-store.d.ts +6 -0
  473. package/dist/core/workflow-run-store.js +2 -0
  474. package/dist/engine/compaction/compaction.d.ts +9 -9
  475. package/dist/engine/compaction/compaction.js +3 -2
  476. package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
  477. package/dist/engine/execution-env/node-execution-env.js +54 -24
  478. package/dist/engine/harness/agent-harness.d.ts +39 -9
  479. package/dist/engine/harness/agent-harness.js +87 -33
  480. package/dist/engine/harness/types.d.ts +58 -9
  481. package/dist/engine/harness/types.js +12 -1
  482. package/dist/engine/llm/types.d.ts +36 -19
  483. package/dist/engine/llm/validation.d.ts +4 -1
  484. package/dist/engine/llm/validation.js +13 -1
  485. package/dist/engine/loop/agent-loop.d.ts +23 -1
  486. package/dist/engine/loop/agent-loop.js +26 -34
  487. package/dist/engine/loop/types.d.ts +31 -19
  488. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  489. package/dist/engine/session/memory-repo.d.ts +18 -12
  490. package/dist/engine/session/memory-repo.js +24 -9
  491. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  492. package/dist/engine/session/parent-chain-guard.js +1 -1
  493. package/dist/engine/session/repo-utils.d.ts +32 -3
  494. package/dist/engine/session/repo-utils.js +50 -5
  495. package/dist/index.d.ts +47 -23
  496. package/dist/index.js +35 -17
  497. package/dist/internal/harness-types.d.ts +1 -1
  498. package/dist/internal/harness.d.ts +3 -3
  499. package/dist/internal/harness.js +2 -2
  500. package/dist/internal/llm.d.ts +2 -2
  501. package/dist/internal/llm.js +1 -1
  502. package/dist/orchestration/goal.js +2 -2
  503. package/dist/orchestration/run-workflow-tool.d.ts +8 -6
  504. package/dist/orchestration/run-workflow-tool.js +10 -6
  505. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  506. package/dist/orchestration/workflow-types.d.ts +18 -0
  507. package/dist/orchestration/workflow-types.js +6 -0
  508. package/dist/orchestration/workflow.d.ts +5 -13
  509. package/dist/orchestration/workflow.js +57 -49
  510. package/dist/prompt-assembly/artifact.d.ts +2 -2
  511. package/dist/prompt-assembly/artifact.js +5 -3
  512. package/dist/prompt-assembly/assemble.d.ts +3 -2
  513. package/dist/prompt-assembly/assemble.js +1 -1
  514. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  515. package/dist/prompt-assembly/catalog/schema.js +34 -2
  516. package/dist/prompt-assembly/catalog/sections.js +0 -1
  517. package/dist/prompt-assembly/composer.d.ts +3 -1
  518. package/dist/prompt-assembly/composer.js +1 -1
  519. package/dist/prompt-assembly/event-registry.js +2 -0
  520. package/dist/prompt-assembly/overlay.js +3 -3
  521. package/dist/prompt-assembly/renderers.d.ts +1 -1
  522. package/dist/prompt-assembly/renderers.js +0 -3
  523. package/dist/prompt-assembly/role-base.d.ts +15 -0
  524. package/dist/prompt-assembly/role-base.js +9 -0
  525. package/dist/prompt-assembly/select.d.ts +39 -14
  526. package/dist/prompt-assembly/select.js +47 -16
  527. package/dist/prompt-assembly/sugar.d.ts +17 -11
  528. package/dist/prompt-assembly/sugar.js +8 -3
  529. package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
  530. package/dist/prompt-assembly/tool-catalog.js +117 -4
  531. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  532. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  533. package/dist/prompt-assembly/types.d.ts +0 -7
  534. package/dist/prompts/default.d.ts +14 -14
  535. package/dist/scenarios/full-body.d.ts +15 -15
  536. package/dist/scenarios/full-body.js +4 -3
  537. package/dist/shell/lex.js +10 -1
  538. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  539. package/dist/stores/file/adoption/adopt.js +27 -33
  540. package/dist/stores/file/adoption/marker.d.ts +6 -13
  541. package/dist/stores/file/adoption/marker.js +9 -17
  542. package/dist/stores/file/checkpoint-store.d.ts +24 -0
  543. package/dist/stores/file/checkpoint-store.js +45 -7
  544. package/dist/stores/file/file-history-store.d.ts +20 -19
  545. package/dist/stores/file/file-history-store.js +157 -141
  546. package/dist/stores/file/fs-atomic.d.ts +15 -0
  547. package/dist/stores/file/fs-atomic.js +89 -14
  548. package/dist/stores/file/index.d.ts +1 -1
  549. package/dist/stores/file/index.js +2 -1
  550. package/dist/stores/file/mailbox-store.d.ts +3 -0
  551. package/dist/stores/file/mailbox-store.js +3 -1
  552. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  553. package/dist/stores/file/permission-rule-adopt.js +18 -18
  554. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  555. package/dist/stores/file/permission-rule-store.js +31 -18
  556. package/dist/stores/file/session-policy-store.d.ts +3 -3
  557. package/dist/stores/file/session-store.d.ts +54 -16
  558. package/dist/stores/file/session-store.js +114 -85
  559. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  560. package/dist/stores/file/workflow-journal-store.js +28 -13
  561. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  562. package/dist/tools/artifact/artifact-tool.js +5 -3
  563. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  564. package/dist/tools/fs/bash-program-position.js +56 -9
  565. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  566. package/dist/tools/fs/fs-bash.d.ts +2 -2
  567. package/dist/tools/fs/fs-bash.js +8 -6
  568. package/dist/tools/fs/fs-glob.d.ts +86 -0
  569. package/dist/tools/fs/fs-glob.js +226 -0
  570. package/dist/tools/fs/fs-read.js +14 -14
  571. package/dist/tools/fs/fs-search-tools.js +7 -7
  572. package/dist/tools/fs/fs-shared.d.ts +8 -8
  573. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  574. package/dist/tools/fs/notebook.d.ts +2 -2
  575. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  576. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  577. package/dist/tools/fs/pdf.d.ts +9 -6
  578. package/dist/tools/fs/pdf.js +3 -3
  579. package/dist/tools/fs/program-read-model.d.ts +57 -7
  580. package/dist/tools/fs/program-read-model.js +11 -1
  581. package/dist/tools/fs/program-read-model.rows.js +78 -21
  582. package/dist/tools/fs/read-deny-home.js +3 -2
  583. package/dist/tools/fs/read-deny.d.ts +29 -7
  584. package/dist/tools/fs/read-deny.js +63 -22
  585. package/dist/tools/fs/removal-targets.d.ts +18 -8
  586. package/dist/tools/fs/removal-targets.js +47 -20
  587. package/dist/tools/fs/safety.d.ts +9 -9
  588. package/dist/tools/fs/search.d.ts +16 -6
  589. package/dist/tools/fs/search.js +20 -26
  590. package/dist/tools/fs/shell-read-argv.js +89 -12
  591. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  592. package/dist/tools/fs/shell-read-bindings.js +41 -0
  593. package/dist/tools/fs/shell-read-check.js +12 -20
  594. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  595. package/dist/tools/fs/shell-read-environment.js +3 -2
  596. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  597. package/dist/tools/fs/shell-read-establish.js +19 -20
  598. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  599. package/dist/tools/fs/shell-read-judge.js +5 -2
  600. package/dist/tools/fs/shell-read-plan.js +24 -16
  601. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  602. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  603. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  604. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  605. package/dist/tools/fs/shell-reentry-text.js +40 -2
  606. package/dist/tools/loop-tick.d.ts +2 -2
  607. package/dist/tools/scheduler-tools.js +5 -1
  608. package/dist/tools/task-list.d.ts +7 -7
  609. package/dist/tools/task-list.js +5 -1
  610. package/dist/tools/todo.js +65 -64
  611. package/dist/tools/web.d.ts +20 -15
  612. package/dist/tools/web.js +55 -69
  613. package/dist/tools/worktree.d.ts +3 -3
  614. package/dist/tools/worktree.js +3 -1
  615. package/package.json +1 -1
  616. package/test/export-surface.snapshot.json +5894 -5638
  617. package/wire-changes/core@7.55.0.json +3318 -0
  618. package/wire-changes/core@7.56.0.json +3891 -0
  619. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  620. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  621. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -22,6 +22,7 @@
22
22
  * contract (`ToolGateInput`, `ToolGateResult`, the observer payload), which stays declared there.
23
23
  */
24
24
  import { type ClassifierDenyCause, type DeniedBy, type GateOutcome, type ModeRefusal, type ModeRelease, type Settlement } from "../gate-outcome.js";
25
+ import type { AllowRuleClearance } from "../allow-rule-shadow.js";
25
26
  import type { AutoModeClassifierRound } from "../auto-mode.js";
26
27
  import { type Arbitration, type AskClassification, type AskFace, type AskOrigin, type AskOriginFacts } from "../ask-origin.js";
27
28
  import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "../tool-policy.js";
@@ -49,6 +50,8 @@ export interface GateExitFacts {
49
50
  classifier?: AutoModeClassifierRound;
50
51
  /** The permission mode RELEASED the surviving ask (the allow exit's account of it); never beside `deniedBy`. */
51
52
  released?: ModeRelease;
53
+ /** An allow-layer member CLEARED the standing ask (the allow exit's account of it); never beside `deniedBy`, a settlement or a release. */
54
+ clearedBy?: AllowRuleClearance;
52
55
  /** The permission mode REFUSED the surviving ask — only beside `deniedBy: "mode"`. */
53
56
  modeRefusal?: ModeRefusal;
54
57
  }
@@ -235,9 +238,9 @@ export interface GatePass {
235
238
  hookAsk: Extract<PermissionResult, {
236
239
  action: "ask";
237
240
  }> | undefined;
238
- /** borrowed-mutable — the phase-1 screen answered its own `allow` (the exact word), naming the registration that answered
239
- * it: the allow layer's hook member (its `entries`), which speaks only while no policy rewrote the arguments after the
240
- * screen saw them. Writer: the dispatch (phase 1). Reader: the lanes' allow layer (its one reader). */
241
+ /** borrowed-mutable — the screen answered its own `allow` (the exact word) for the bytes that run, naming the registration
242
+ * that answered it: the allow layer's hook member (its `entries`). Writers: the dispatch (phase 1) and the fold's second
243
+ * look after a policy rewrite (rewrite-rejudge.ts), whose answer replaces the first. Reader: the lanes' allow layer. */
241
244
  hookAllowedBy?: readonly string[];
242
245
  /** borrowed-mutable — `tool.check` was raised in this pass's first adjudication, which raises it once: set by the
243
246
  * raise in front of the ask branch, read by the raise behind the read-only arm (it then raises nothing). Writer and
@@ -333,6 +336,9 @@ export interface GatePass {
333
336
  arbitration?: Exclude<Arbitration, {
334
337
  kind: "ask";
335
338
  }>;
339
+ /** borrowed-mutable — the allow-layer member that CLEARED the standing ask and the entries it stood on (the allow exit projects
340
+ * it onto the disposition when nobody answered an ask on this pass). Writer: the lanes' allow layer. */
341
+ clearedBy?: AllowRuleClearance;
336
342
  }
337
343
  /**
338
344
  * The engine's fail-closed block of phase 1 — the PreToolUse face THREW or never ANSWERED, so the engine
@@ -23,7 +23,12 @@ export function mintGateOutcome(facts) {
23
23
  ...(attribution !== undefined ? { classifier: attribution } : {}),
24
24
  ...(facts.modeRefusal !== undefined ? { mode: facts.modeRefusal.mode, askClass: facts.modeRefusal.askClass, classes: Object.freeze([...facts.modeRefusal.classes]) } : {}),
25
25
  }
26
- : { kind: "allowed", ...(attribution !== undefined ? { classifier: attribution } : {}), ...(facts.released !== undefined ? { released: Object.freeze({ ...facts.released, classes: Object.freeze([...facts.released.classes]) }) } : {}) }),
26
+ : {
27
+ kind: "allowed",
28
+ ...(attribution !== undefined ? { classifier: attribution } : {}),
29
+ ...(facts.released !== undefined ? { released: Object.freeze({ ...facts.released, classes: Object.freeze([...facts.released.classes]) }) } : {}),
30
+ ...(facts.clearedBy !== undefined ? { clearedBy: Object.freeze({ ...facts.clearedBy, entries: Object.freeze([...facts.clearedBy.entries]), ...(facts.clearedBy.positions !== undefined ? { positions: Object.freeze([...facts.clearedBy.positions]) } : {}) }) } : {}),
31
+ }),
27
32
  ...(facts.settled !== undefined ? { settlement: settlement, origin: facts.settled.origin } : {}),
28
33
  });
29
34
  const defects = screenGateOutcome(outcome, { reading: "producer" });
@@ -239,7 +244,7 @@ export function hookDenyExit(pass, deniedReason) {
239
244
  preToolContext: pass.preToolContext,
240
245
  };
241
246
  }
242
- const ANCESTOR_UNRESOLVED_CLASSIFICATION = classifyAsk({ action: "ask", message: "" }, { contentQuestion: false, markedUnresolvable: true, org: undefined, tightened: undefined, mandateMarks: {} });
247
+ const ancestorUnresolvedClassification = (call) => classifyAsk({ action: "ask", message: "" }, { call, contentQuestion: false, markedUnresolvable: true, org: undefined, tightened: undefined, mandateMarks: {} });
243
248
  function unresolvableCauseOfSettlement(gate) {
244
249
  if (gate.disposition.kind !== "denied" || gate.disposition.deniedBy !== "ask_resolution" || gate.settlement === undefined)
245
250
  return undefined;
@@ -269,12 +274,13 @@ export async function exitGate(pass) {
269
274
  const tableSeat = unresolvable !== undefined ? askUnresolvableRemedySeat(unresolvable) : undefined;
270
275
  const remedySeat = tableSeat === "absent" && input.askSeatForm === "declared_none" && pass.askClassification?.classes.has("content_question") !== true ? "declared_none" : tableSeat;
271
276
  const bindingRefusal = attestationOf(pass.decision, { toolCallId, toolName })?.bindingRefusal;
272
- const remedy = bindingRefusal !== undefined ? undefined : remedySeat !== undefined ? headlessApprovalRemedy({ mode: input.permissionMode?.(), classification: foldCause !== undefined ? ANCESTOR_UNRESOLVED_CLASSIFICATION : pass.askClassification, approverSeat: remedySeat, coveredWrite: isProtectedWrite(pass.req), ...(pass.shellUnplacedOptions !== undefined ? { unplacedOptions: pass.shellUnplacedOptions } : {}) }) : undefined;
277
+ const headless = bindingRefusal !== undefined ? undefined : remedySeat !== undefined ? headlessApprovalRemedy({ mode: input.permissionMode?.(), classification: foldCause !== undefined ? ancestorUnresolvedClassification(pass.req) : pass.askClassification, approverSeat: remedySeat, coveredWrite: isProtectedWrite(pass.req), ...(pass.shellUnplacedOptions !== undefined ? { unplacedOptions: pass.shellUnplacedOptions } : {}) }) : undefined;
278
+ const remedy = headless?.sentence;
273
279
  const denyReason = withParkFailureCause(`${decisionText(pass.decision) ?? `tool "${toolName}" denied by policy`}${remedy !== undefined ? ` — ${remedy}` : ""}`, pass.parkFailed, unresolvable !== undefined);
274
280
  if (unresolvable !== undefined) {
275
281
  const cause = unresolvable;
276
282
  const noticeRemedy = bindingRefusal ?? remedy;
277
- pass.notifier.notify(() => input.onAskUnresolvable?.({ toolName, toolCallId, cause, parkLaneExisted: pass.suspendAsk !== undefined, ...(noticeRemedy !== undefined ? { remedy: noticeRemedy } : {}) }), "toolGate.onAskUnresolvable");
283
+ pass.notifier.notify(() => input.onAskUnresolvable?.({ toolName, toolCallId, cause, parkLaneExisted: pass.suspendAsk !== undefined, ...(noticeRemedy !== undefined ? { remedy: noticeRemedy } : {}), ...(headless !== undefined ? { remedies: headless.remedies } : {}) }), "toolGate.onAskUnresolvable");
278
284
  }
279
285
  const finalInput = frozenInputSnapshot(pass.currentInput);
280
286
  await notifyPermissionDenied({
@@ -315,7 +321,7 @@ export async function exitGate(pass) {
315
321
  return undefined; const a = pass.arbitration === undefined ? input.ancestorArbitrationOf?.(toolCallId) : undefined; return a?.kind === "released" ? a : undefined; })();
316
322
  return {
317
323
  updatedInput: pass.currentInput,
318
- gate: mintGateOutcome({ ...(ledger.settled !== undefined ? { settled: ledger.settled } : {}), ...(pass.classifierRound !== undefined ? { classifier: pass.classifierRound } : {}), ...(release !== undefined ? { released: releaseRecordOf(release) } : {}) }),
324
+ gate: mintGateOutcome({ ...(ledger.settled !== undefined ? { settled: ledger.settled } : {}), ...(pass.classifierRound !== undefined ? { classifier: pass.classifierRound } : {}), ...(release !== undefined ? { released: releaseRecordOf(release) } : {}), ...(pass.clearedBy !== undefined && ledger.settled === undefined && release === undefined ? { clearedBy: pass.clearedBy } : {}) }),
319
325
  finalInput: frozenInputSnapshot(pass.currentInput),
320
326
  preToolContext: pass.preToolContext,
321
327
  };
@@ -1,22 +1,12 @@
1
1
  import type { ImageContent } from "../../internal/llm.js";
2
+ import { type HostFloor } from "../host-floor.js";
2
3
  import type { ImageInput } from "../types.js";
3
4
  /**
4
- * Block obviously-internal hosts (loopback / private ranges / link-local incl. cloud metadata / CGNAT / IPv6
5
- * ULA, site-local, unspecified, IPv4-mapped, NAT64). Classifies with `net.isIP` rather than a string-prefix
6
- * regex — the old regex both UNDER-matched (IPv4-mapped `::ffff:`, NAT64, CGNAT 100.64/10, `::`) and
7
- * OVER-matched (any DNS name starting `fc`/`fd`, e.g. `fdpartners.com`). Numeric IPv4 forms (decimal/octal/hex)
8
- * are normalized to dotted-decimal by `URL` before this is called, so they're already covered.
9
- * Note: this checks the LITERAL host; it does NOT resolve DNS, so a hostname resolving to a private IP is not
10
- * caught here (documented limitation — a deployment needing that supplies its own resolve-and-pin guard).
5
+ * The guard of a remote image URL: https only, then the one egress hop judge with the private-network floor (`hopRefusal`,
6
+ * host-floor.ts) — the deployment's host floor (`RunnerDeps.hostFloor`, `floor`) must admit the host, and a private host is
7
+ * reachable only when the floor's `only` list names it — so an end-user-supplied `images[].url` can't make the server fetch
8
+ * `169.254.169.254` or a private box. The host is read literally (no DNS resolution). Throws on a refused URL.
11
9
  */
12
- export declare function isPrivateHost(host: string): boolean;
13
- /**
14
- * Default SSRF guard for a remote image URL: https only, and no internal/reserved hosts (so an
15
- * end-user-supplied `images[].url` can't make the server fetch `169.254.169.254` or a private box).
16
- * Note: this checks the URL host literally — it does not resolve DNS, so a hostname that resolves to
17
- * a private IP is not caught here; a deployment needing that should supply `RunnerDeps.allowImageUrl`
18
- * (e.g. a CDN allowlist or a resolve-and-pin check). Throws on a disallowed URL.
19
- */
20
- export declare function defaultImageUrlGuard(raw: string): void;
10
+ export declare function defaultImageUrlGuard(raw: string, floor?: HostFloor): void;
21
11
  /** Resolve an {@link ImageInput} (inline base64 or a URL to fetch) into a vendored `ImageContent` block. */
22
- export declare function toImageContent(img: ImageInput, allowUrl?: (url: string) => boolean): Promise<ImageContent>;
12
+ export declare function toImageContent(img: ImageInput, floor: HostFloor | undefined): Promise<ImageContent>;
@@ -1,55 +1,10 @@
1
- import { isIP } from "node:net";
1
+ import { hopRefusal } from "../host-floor.js";
2
2
  import { ADMITTED_IMAGE_MIME_TYPES, imageMagicMatches } from "../image-admission.js";
3
3
  import { admitInlineImage } from "./inline-image.js";
4
4
  function sniffImageMime(bytes) {
5
5
  return ADMITTED_IMAGE_MIME_TYPES.find((mime) => imageMagicMatches(bytes, mime));
6
6
  }
7
- function isPrivateV4(ip) {
8
- const o = ip.split(".").map(Number);
9
- if (o.length !== 4 || o.some((n) => !Number.isInteger(n) || n < 0 || n > 255))
10
- return true;
11
- const [a, b] = o;
12
- return (a === 127 ||
13
- a === 10 ||
14
- a === 0 ||
15
- (a === 172 && b >= 16 && b <= 31) ||
16
- (a === 192 && b === 168) ||
17
- (a === 169 && b === 254) ||
18
- (a === 100 && b >= 64 && b <= 127));
19
- }
20
- function embeddedV4(h) {
21
- const fromHex = (hi, lo) => {
22
- const a = parseInt(hi, 16), c = parseInt(lo, 16);
23
- return `${(a >> 8) & 255}.${a & 255}.${(c >> 8) & 255}.${c & 255}`;
24
- };
25
- let m = /^(?:::ffff:|64:ff9b::)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.exec(h);
26
- if (m)
27
- return m[1];
28
- m = /^(?:::ffff:|64:ff9b::)([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(h);
29
- if (m)
30
- return fromHex(m[1], m[2]);
31
- return undefined;
32
- }
33
- export function isPrivateHost(host) {
34
- const h = host
35
- .replace(/^\[|\]$/g, "")
36
- .replace(/\.+$/, "")
37
- .toLowerCase();
38
- if (h === "localhost")
39
- return true;
40
- const fam = isIP(h);
41
- if (fam === 0)
42
- return false;
43
- if (fam === 4)
44
- return isPrivateV4(h);
45
- const v4 = embeddedV4(h);
46
- if (v4)
47
- return isPrivateV4(v4);
48
- if (h === "::1" || h === "::")
49
- return true;
50
- return /^fe[89ab]/.test(h) || /^f[cd]/.test(h) || /^fe[c-f]/.test(h);
51
- }
52
- export function defaultImageUrlGuard(raw) {
7
+ export function defaultImageUrlGuard(raw, floor) {
53
8
  let u;
54
9
  try {
55
10
  u = new URL(raw);
@@ -60,9 +15,9 @@ export function defaultImageUrlGuard(raw) {
60
15
  if (u.protocol !== "https:") {
61
16
  throw new Error(`image url must be https (got "${u.protocol}")`);
62
17
  }
63
- if (isPrivateHost(u.hostname)) {
64
- throw new Error(`image url host not allowed (private/reserved): ${u.hostname}`);
65
- }
18
+ const refused = hopRefusal(u, floor, true);
19
+ if (refused !== undefined)
20
+ throw new Error(`image url not fetched — ${refused}`);
66
21
  }
67
22
  const IMAGE_FETCH_TIMEOUT_MS = 30_000;
68
23
  const IMAGE_MAX_BYTES = 20 * 1024 * 1024;
@@ -112,17 +67,11 @@ async function fetchImageCapped(url) {
112
67
  }
113
68
  return { buf, mimeType: sniffed };
114
69
  }
115
- export async function toImageContent(img, allowUrl) {
70
+ export async function toImageContent(img, floor) {
116
71
  if ("url" in img) {
117
- if (allowUrl) {
118
- if (!allowUrl(img.url)) {
119
- throw new Error(`image url rejected by policy: ${img.url}`);
120
- }
121
- }
122
- else {
123
- defaultImageUrlGuard(img.url);
124
- }
125
- const { buf, mimeType } = await fetchImageCapped(img.url);
72
+ const url = img.url;
73
+ defaultImageUrlGuard(url, floor);
74
+ const { buf, mimeType } = await fetchImageCapped(url);
126
75
  return { type: "image", data: buf.toString("base64"), mimeType };
127
76
  }
128
77
  return admitInlineImage(img);
@@ -4,7 +4,7 @@ export function createRunState() {
4
4
  degrade: { degradeToModel: undefined, degraded: undefined, outputErrorStreak: 0, outputInvalid: false, recordDegraded: () => { } },
5
5
  limits: { turnsExceeded: false, budgetHit: undefined, budgetAxis: undefined, platformTerminal: undefined, outputRetryCap: 0, effectiveMaxTurns: undefined },
6
6
  budget: { remainingMicroUsd: undefined, maxCostMicroUsd: undefined, remainingTokens: undefined, maxTokensWindow: undefined, overBudget: () => undefined, streamCancel: false, callOutputChars: 0, lastStreamBudgetCheck: 0, projectedOverBudget: () => undefined },
7
- turn: { callStartAt: undefined, firstTokenAt: undefined, turnUsage: undefined, turnUsageMissing: false, turnStopReason: undefined, turnResponseModel: undefined, lastTurnHadToolCalls: false, toolBatch: [] },
7
+ turn: { callStartAt: undefined, firstTokenAt: undefined, turnUsage: undefined, turnUsageMissing: false, turnStopReason: undefined, turnResponseModel: undefined, toolBatch: [] },
8
8
  counters: { approachNoticesSent: 0, walltimeSyncBackstopFired: false, compactionFloor: 0, trimForceBackoff: false, compactionPasses: 0, repetitionCuts: 0, repetitionSpared: 0, repetitionEvents: [], REPETITION_EVENTS_CAP: 0, preemptIgnoredReported: false, wroteThisRun: false, finalVerifyInjections: 0, groundingSignalPreR9: false, groundingSignalPostR9: false, cadenceTurns: 0 },
9
9
  attach: { attachmentsCfg: undefined, agentListingOn: false, skillsListingOn: false, attachState: undefined, dateState: undefined, instrProbe: undefined, instrState: undefined, sizeGuidelineState: undefined, attachmentsInjected: 0 },
10
10
  };
@@ -32,7 +32,7 @@ import { type HeadLeads } from "../path-rule-binding.js";
32
32
  import type { ToolCallLike } from "../tool-registry.js";
33
33
  import { type OrgRuleResolution } from "../permission-rule-org.js";
34
34
  import { type EffectivePermissionRules, type PermissionRuleStoreProvider, type PersonRowsRead } from "../permission-rule-provider.js";
35
- /** The one SHELL tool the persisted-rule lane's COMMAND grammar speaks for (the rule-offer face mints for it and the name tools); the other grammars' tools are derived (`ruleToolGrammarOf`). */
35
+ /** The one SHELL tool the persisted-rule lane's COMMAND grammar speaks for (the rule-offer face mints for it, the name tools and the host tools); the other grammars' tools are derived (`ruleToolGrammarOf`). */
36
36
  export declare const PERSISTED_RULE_TOOL = "Bash";
37
37
  /**
38
38
  * The evidence an INHERITED-lane ask carries.
@@ -121,7 +121,7 @@ export interface PermissionRuleLanes {
121
121
  * `onDegraded` receives the snapshot's degraded line ({@link describeUnreadableOrgRows}) on every adjudication over a
122
122
  * snapshot carrying a row this layer cannot read. */
123
123
  export declare function orgRuleLane(cfg: {
124
- read: (toolCallId: string) => Promise<Pick<EffectivePermissionRules, "org">>;
124
+ read: (toolCallId: string, judged: unknown) => Promise<Pick<EffectivePermissionRules, "org">>;
125
125
  questionToolMounted: boolean;
126
126
  questionToolName: string;
127
127
  onRevisionDefect: (message: string) => void;
@@ -177,10 +177,10 @@ export declare function createPermissionRuleLanes(cfg: {
177
177
  onRevisionDefect: (message: string) => void;
178
178
  /** Sink for a judgment against the rows that threw, and for the org lane's degraded-snapshot line. */
179
179
  onDisclosure: (message: string) => void;
180
- /** The run's one reader of the person's rules: the call's ONE read, pinned, that the read station, the org lane and the
181
- * personal lane all take (the lanes consume a reader; they do not make one). */
180
+ /** The run's one reader of the person's rules: the call's ONE read of the bytes judged, pinned, that the read station, the
181
+ * org lane and the personal lane all take (the lanes consume a reader; they do not make one). */
182
182
  rows: {
183
- pin(toolCallId: string): Promise<PersonRowsRead>;
183
+ pin(toolCallId: string, judged?: unknown): Promise<PersonRowsRead>;
184
184
  };
185
185
  /** The allow layer's auto strip over a stored ALLOW row (true ⇒ out of this call's table BEFORE the coverage is chosen). */
186
186
  stripsAllow?: (rule: PersistedRule, req: ToolCallRequest) => boolean;
@@ -225,7 +225,7 @@ interface RuleOffersAskFacts extends RuleClearanceFacts {
225
225
  * "stop asking me this" on a card that will keep asking lets a person mint a rule that never
226
226
  * takes effect where they minted it.
227
227
  *
228
- * (CC 2.1.245 toolPolicy 对表, F11: "wildcard `ask` … keeps every matching tool behind a
228
+ * (toolPolicy 对表, F11: "wildcard `ask` … keeps every matching tool behind a
229
229
  * per-call prompt (no persistent always-allow)") — `matchedAskRule` was the one conjunct of the
230
230
  * lane's own clearing predicate this door did not mirror, and the asymmetry was live: the
231
231
  * persisted-rule lane refuses to clear ANY ask carrying it (`hooks.ts`, the
@@ -1,12 +1,14 @@
1
1
  import { persistedRuleMandateOf, ruleClearanceOf } from "../ask-origin.js";
2
2
  import {} from "../hooks.js";
3
- import { adjudicatePersistedDomainRules, adjudicatePersistedNameRules, adjudicatePersistedPathRules, adjudicatePersistedRules, callPathFaceOf, domainRuleSubjectOf, escapeForDisclosure, faceRowsSpeakFor, laneToolNamesOf, nameRuleSubjectOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForName, suggestRulesForCommand } from "../permission-rule-model.js";
3
+ import { adjudicatePersistedDomainRules, adjudicatePersistedNameRules, adjudicatePersistedPathRules, adjudicatePersistedRules, callPathFaceOf, eligiblePersisted, escapeForDisclosure, faceRowsSpeakFor, parseRuleText, laneToolNamesOf, nameRuleSubjectOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForHost, suggestRuleForName, suggestRulesForCommand } from "../permission-rule-model.js";
4
+ import { callHostTargetOf } from "../host-target.js";
4
5
  import { callTargetViewsOf, validatePath } from "../effective-path-target.js";
5
6
  import { bindPathRules, persistedRowAnchors, projectScopeIdentity } from "../path-rule-binding.js";
6
7
  import { heldBy, seatOf, wireOf } from "../tool-name-readings.js";
7
8
  import { describeUnreadableOrgRows, readOrgRules, settleOrgVerdictWithin } from "../permission-rule-org.js";
8
9
  import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
9
10
  import { ownerStoreOf } from "../permission-rule-provider.js";
11
+ import { readPrincipal } from "../principal-name.js";
10
12
  import { thrownText } from "../thrown-value.js";
11
13
  import { strongestAnswer } from "../persisted-rule-arms.js";
12
14
  import { ORG_ADJUDICATION_TIMEOUT_MS } from "../permission-rule-org.js";
@@ -58,7 +60,7 @@ export function orgRuleLane(cfg) {
58
60
  return { status: "available" };
59
61
  let resolution;
60
62
  try {
61
- resolution = (await cfg.read(req.toolCallId)).org;
63
+ resolution = (await cfg.read(req.toolCallId, req.args)).org;
62
64
  }
63
65
  catch (err) {
64
66
  return { status: "unavailable", disclosures: [`the permission-rule store threw while resolving the org partition: ${thrownText(err)}`] };
@@ -105,10 +107,10 @@ export function createPermissionRuleLanes(cfg) {
105
107
  }
106
108
  if (provider === undefined)
107
109
  return { personal: undefined, org: undefined };
108
- const anonymous = cfg.principal === undefined || cfg.principal === "";
110
+ const anonymous = readPrincipal(cfg.principal).kind === "absent";
109
111
  const reader = cfg.rows;
110
- const orgViewOf = async (toolCallId) => {
111
- const read = await reader.pin(toolCallId);
112
+ const orgViewOf = async (toolCallId, judged) => {
113
+ const read = await reader.pin(toolCallId, judged);
112
114
  if (read.org === undefined)
113
115
  throw new Error(read.unreadable ?? "the store did not answer");
114
116
  return { org: read.org };
@@ -120,14 +122,24 @@ export function createPermissionRuleLanes(cfg) {
120
122
  const judged = laneToolNamesOf(req).map((n) => [n, ruleToolGrammarOf(n)]);
121
123
  if (!judged.some(([, g]) => g === "path") && faceRowsSpeakFor(callPathFaceOf(req)))
122
124
  judged.push([req.toolName, "path"]);
125
+ const view = await reader.pin(req.toolCallId, req.args);
123
126
  if (judged.length === 0)
124
- return undefined;
125
- const view = await reader.pin(req.toolCallId);
127
+ return view.unreadable !== undefined ? { unreadable: true } : undefined;
126
128
  try {
127
- const table = view.rules.filter((r) => r.behavior !== "allow" || cfg.stripsAllow?.(r, req) !== true);
128
- const leads = judged.some(([, g]) => g === "path") ? await cfg.leads.resolve(bindPathRules(table.filter((r) => r.match === "path" || r.match === "subpath").map((r) => ({ parsed: r, ruleText: r.rule, rule: r })), (spec) => anchorsOf(spec.rule))) : NO_LEADS;
129
+ const stripped = view.rules.filter((r) => r.behavior !== "allow" || cfg.stripsAllow?.(r, req) !== true);
130
+ const judgesPath = judged.some(([, g]) => g === "path");
131
+ const noRule = [];
132
+ const table = stripped.filter((r) => {
133
+ const read = judged.some(([n]) => n === r.tool) || (judgesPath && (r.match === "path" || r.match === "subpath")) ? parseRuleText(r.rule, r.behavior) : undefined;
134
+ if (read !== undefined && "reject" in read)
135
+ noRule.push({ row: r, why: read.reject.message });
136
+ return read === undefined || !("reject" in read) || r.behavior !== "allow";
137
+ });
138
+ const leads = judgesPath ? await cfg.leads.resolve(bindPathRules(table.filter((r) => r.match === "path" || r.match === "subpath").map((r) => ({ parsed: r, ruleText: r.rule, rule: r })), (spec) => anchorsOf(spec.rule))) : NO_LEADS;
129
139
  const scopeIdentity = await projectScopeIdentity(table, cfg.rootCanonical, cfg.leads);
130
- const answer = strongestAnswer(judged.map(([n, grammar]) => judgeAgainst(table, { ...req, toolName: n }, grammar, leads, scopeIdentity)));
140
+ const judgedAnswer = strongestAnswer(judged.map(([n, grammar]) => judgeAgainst(table, { ...req, toolName: n }, grammar, leads, scopeIdentity)));
141
+ const unjudged = noRule.find(({ row }) => (row.behavior === "deny" || row.behavior === "ask") && eligiblePersisted(row, { tool: row.tool, cwd: cfg.root, sessionId: cfg.sessionId, ...(scopeIdentity !== undefined ? { scopeIdentity } : {}) }, row.behavior));
142
+ const answer = unjudged !== undefined && !(judgedAnswer !== undefined && "behavior" in judgedAnswer && judgedAnswer.behavior === "deny") ? unjudgedRowAnswer(unjudged.row, unjudged.why, req.toolName) : judgedAnswer;
131
143
  const stands = answer !== undefined && (("behavior" in answer && answer.behavior === "deny") || "unreadable" in answer);
132
144
  return view.unreadable !== undefined && !stands ? { unreadable: true } : answer;
133
145
  }
@@ -137,6 +149,11 @@ export function createPermissionRuleLanes(cfg) {
137
149
  return { unreadable: true, reason: why };
138
150
  }
139
151
  };
152
+ const unjudgedRowAnswer = (row, refusal, tool) => {
153
+ const why = `the stored ${row.behavior} rule ${escapeForDisclosure(row.rule)} is no rule this engine reads (${refusal})`;
154
+ cfg.onDisclosure(`the persisted rule lane could not judge a ${tool} call against the rows it read — ${why}`);
155
+ return { unreadable: true, reason: why };
156
+ };
140
157
  const anchorsOf = (rule) => persistedRowAnchors(rule.scope, cfg.chainTop);
141
158
  const judgeAgainst = (table, req, grammar, leads, scopeIdentity) => {
142
159
  const liveCwd = cfg.liveCwd();
@@ -144,9 +161,9 @@ export function createPermissionRuleLanes(cfg) {
144
161
  if (grammar === "path")
145
162
  return pathRuleLaneAnswer(table, req, { root: cfg.root, sessionId: cfg.sessionId, anchorsOf, leads, ...scope });
146
163
  if (grammar === "name")
147
- return persistedRuleAnswerOf(adjudicatePersistedNameRules(table, { tool: req.toolName, name: nameRuleSubjectOf(req.toolName, req.args), cwd: cfg.root, sessionId: cfg.sessionId, ...scope }));
164
+ return persistedRuleAnswerOf(adjudicatePersistedNameRules(table, { tool: req.toolName, request: req, cwd: cfg.root, sessionId: cfg.sessionId, ...scope }));
148
165
  if (grammar === "domain")
149
- return persistedRuleAnswerOf(adjudicatePersistedDomainRules(table, { tool: req.toolName, host: domainRuleSubjectOf(req.toolName, req.args), cwd: cfg.root, sessionId: cfg.sessionId, ...scope }));
166
+ return persistedRuleAnswerOf(adjudicatePersistedDomainRules(table, { tool: req.toolName, hosts: { tighten: callHostTargetOf(req, "tighten"), grant: callHostTargetOf(req, "grant") }, cwd: cfg.root, sessionId: cfg.sessionId, ...scope }));
150
167
  const command = req.args?.command;
151
168
  if (typeof command !== "string")
152
169
  return undefined;
@@ -163,9 +180,10 @@ export function createPermissionRuleLanes(cfg) {
163
180
  export function createRuleOffersOf(cfg) {
164
181
  return (call, args, ask) => {
165
182
  const toolName = wireOf("offer.laneTool", call);
166
- if (!cfg.laneArmed || (toolName !== PERSISTED_RULE_TOOL && ruleToolGrammarOf(toolName) !== "name"))
183
+ const grammar = ruleToolGrammarOf(toolName);
184
+ if (!cfg.laneArmed || (toolName !== PERSISTED_RULE_TOOL && grammar !== "name" && grammar !== "domain"))
167
185
  return {};
168
- if ((cfg.principal === undefined || cfg.principal === "") && !cfg.localOwnerDeclared)
186
+ if (readPrincipal(cfg.principal).kind === "absent" && !cfg.localOwnerDeclared)
169
187
  return {};
170
188
  const tierSeat = seatOf("offer.marks", cfg.irreversibilityTier, call);
171
189
  const closedDoor = ruleClearanceOf(ask, {
@@ -175,10 +193,15 @@ export function createRuleOffersOf(cfg) {
175
193
  }).word;
176
194
  if (closedDoor !== undefined)
177
195
  return { ruleOffersAbsence: closedDoor };
178
- if (ruleToolGrammarOf(toolName) === "name") {
196
+ if (grammar === "name") {
179
197
  const offer = suggestRuleForName(toolName, nameRuleSubjectOf(toolName, args) ?? "");
180
198
  return offer !== undefined ? { ruleOffers: [offer] } : { ruleOffersAbsence: "lane_cannot_speak" };
181
199
  }
200
+ if (grammar === "domain") {
201
+ const host = callHostTargetOf({ toolName: call.toolName, args, face: call.face }, "grant");
202
+ const offer = host !== undefined && "host" in host ? suggestRuleForHost(toolName, host.host) : undefined;
203
+ return offer !== undefined ? { ruleOffers: [offer] } : { ruleOffersAbsence: "lane_cannot_speak" };
204
+ }
182
205
  const command = args?.command;
183
206
  if (typeof command !== "string")
184
207
  return { ruleOffersAbsence: "lane_cannot_speak" };
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * The person's persisted rules as ONE run reads them.
3
3
  *
4
- * ## One read per adjudicated call
4
+ * ## One read per judgment of a call's bytes
5
5
  *
6
- * A call is judged against ONE read of the store, pinned to its `toolCallId` ({@link PersonPathRows.pin}): whichever of the
7
- * call's consumers asks first — the read station's judgment, the org layer, the personal rule lane — takes the read, the
8
- * others are handed the same answer, and the tables the call's tool judges with when it executes are compiled from it
9
- * ({@link PathTablesFacade.forCall}). A call is an attempt the leg's occurrence table holds; the pin is released when the
6
+ * A call's bytes are judged against ONE read of the store, pinned to its `toolCallId` ({@link PersonPathRows.pin}): whichever
7
+ * of the consumers judging those bytes asks first — the read station's judgment, the org layer, the personal rule lane —
8
+ * takes the read, the others are handed the same answer, and the tables the call's tool judges with when it executes are
9
+ * compiled from it ({@link PathTablesFacade.forCall}). Judging other bytes of the same call (an approved edit) is another
10
+ * judgment: it takes a new read, which the call then holds — a rule written while a person decided binds their edit. A call is an attempt the leg's occurrence table holds; the pin is released when the
10
11
  * table no longer holds that attempt. A judgment that is no call of the leg (a visibility probe's fixed id, a gate with no
11
12
  * leg) keeps nothing: its rule lanes take a read of their own, its read station the run's latest tables.
12
13
  *
@@ -106,10 +107,12 @@ export interface PersonPathRows {
106
107
  readonly holdsPersonRows: boolean;
107
108
  /** The prepare read — the unit's first write. `undefined`, synchronously, when there is no person's rows to read. */
108
109
  prime(): Promise<void> | undefined;
109
- /** The rows of a call's one read — a call the leg's occurrence table holds: taken by its first consumer, handed to every
110
- * other until the table no longer holds that attempt; any other judgment (no leg, or an id the table does not hold — a
111
- * visibility probe) takes a read of its own, kept by nobody. Bounded ({@link PERSON_READ_BOUND_MS}); never rejects. */
112
- pin(toolCallId: string): Promise<PersonRowsRead>;
110
+ /** The rows of a call's one read of the bytes it judges (`judged`) — a call the leg's occurrence table holds: taken by its
111
+ * first consumer, handed to every other that judges the same bytes (or names none) until the table no longer holds that
112
+ * attempt; a judgment of OTHER bytes of the call (an approved edit, its outlet form) takes a new read, which the call then
113
+ * holds — a judgment reads the store, as the session rules' does. Any other judgment (no leg, or an id the table does not
114
+ * hold — a visibility probe) takes a read of its own, kept by nobody. Bounded ({@link PERSON_READ_BOUND_MS}); never rejects. */
115
+ pin(toolCallId: string, judged?: unknown): Promise<PersonRowsRead>;
113
116
  /** Settles once the tables a reader takes are compiled: a pinned call's own; any other reader's (no id, or a call holding
114
117
  * no pin), the unit's newest — through every change that lands meanwhile, within {@link PATH_TABLES_READY_BOUND_MS} —
115
118
  * or at `signal` or the run's cut ({@link PersonPathRowsConfig.signal}). Never rejects: a reader whose wait was cut
@@ -1,5 +1,7 @@
1
1
  import { ownerStoreOf } from "../permission-rule-provider.js";
2
+ import { readPrincipal } from "../principal-name.js";
2
3
  import { ORG_ADJUDICATION_TIMEOUT_MS } from "../permission-rule-org.js";
4
+ import { canonicalize } from "../canonical-json.js";
3
5
  import { PATH_RULE_FACES, READ_RULE_TOOL, eligiblePersisted, noticeRuleText } from "../permission-rule-model.js";
4
6
  import { bindPathRules, persistedRowAnchors, projectScopeIdentity } from "../path-rule-binding.js";
5
7
  import { DEFAULT_GATE_AWAIT_TIMEOUT_MS, gateWaitFailureOf, withGateTimeout } from "../gate-bounded-await.js";
@@ -21,7 +23,7 @@ const COMPILED_TABLES_KEPT = 8;
21
23
  export const EMPTY_READ_ROOTS = Object.assign(() => [], { forCall: () => () => [], ready: () => Promise.resolve() });
22
24
  export function createPersonPathRows(cfg) {
23
25
  const provider = cfg.provider;
24
- const anonymous = cfg.principal === undefined || cfg.principal === "";
26
+ const anonymous = readPrincipal(cfg.principal).kind === "absent";
25
27
  const holdsPersonRows = provider !== undefined && provider.partitions.durable && (!anonymous || cfg.localOwnerDeclared);
26
28
  const partitions = PARTITIONS.filter((p) => (p === "durable" ? provider?.partitions.durable === true : provider?.partitions.session === true));
27
29
  const unit = { durable: { failedSeq: 0 }, session: { failedSeq: 0 } };
@@ -186,20 +188,29 @@ export function createPersonPathRows(cfg) {
186
188
  pins.delete(toolCallId);
187
189
  return undefined;
188
190
  };
189
- const enter = (toolCallId, attempt) => {
191
+ const enter = (toolCallId, attempt, judged) => {
190
192
  const rows = readOnce("call").then((read) => (entry.read = read));
191
- const entry = { attempt, rows, tables: holdsPersonRows ? rows.then((read) => settleTables(entry, read)) : Promise.resolve(), ...(holdsPersonRows ? {} : { settled: {} }) };
193
+ const entry = { attempt, rows, tables: holdsPersonRows ? rows.then((read) => settleTables(entry, read)) : Promise.resolve(), ...(holdsPersonRows ? {} : { settled: {} }), ...(judged !== undefined ? { judged: { value: judged } } : {}) };
192
194
  pins.set(toolCallId, entry);
193
195
  return entry;
194
196
  };
195
- const pin = (toolCallId) => {
197
+ const serves = (p, judged) => {
198
+ if (judged === undefined || p.judged === undefined || p.judged.value === judged)
199
+ return true;
200
+ p.judged.canonical ??= canonicalize(p.judged.value);
201
+ return p.judged.canonical === canonicalize(judged);
202
+ };
203
+ const pin = (toolCallId, judged) => {
196
204
  for (const id of [...pins.keys()])
197
205
  pinOf(id);
198
206
  const known = pinOf(toolCallId);
199
- if (known !== undefined)
207
+ if (known !== undefined && serves(known, judged)) {
208
+ if (judged !== undefined)
209
+ known.judged ??= { value: judged };
200
210
  return known.rows;
211
+ }
201
212
  const attempt = cfg.occurrences?.get(toolCallId);
202
- return attempt === undefined ? readOnce("call") : enter(toolCallId, attempt).rows;
213
+ return attempt === undefined ? readOnce("call") : enter(toolCallId, attempt, judged).rows;
203
214
  };
204
215
  const settleTables = async (entry, read) => {
205
216
  try {
@@ -317,7 +328,7 @@ export function onPinnedRead(rows, stations) {
317
328
  const id = callOpts.toolCallId;
318
329
  if (readStationMemberOf(call, members) === undefined)
319
330
  return check.judge(call, args, cwd, signal, callOpts);
320
- const ready = id !== undefined && rows.holds(id) ? rows.pin(id).then(() => rows.tablesReady(id)) : rows.tablesReady(undefined, signal);
331
+ const ready = id !== undefined && rows.holds(id) ? rows.pin(id, args).then(() => rows.tablesReady(id)) : rows.tablesReady(undefined, signal);
321
332
  return ready.then(() => check.judge(call, args, cwd, signal, callOpts) ?? VOUCHED);
322
333
  },
323
334
  unanswered: (call, cause) => check.unanswered(call, cause),
@@ -367,7 +378,7 @@ export function ruleStoreUnreadableNotice(onNotice, ids) {
367
378
  const which = sources !== undefined && sources.length > 0 ? `your persisted permission rules from the ${sourcesWord(sources)} sources` : "your persisted permission rules";
368
379
  deliverEngineNotice(onNotice, {
369
380
  code: "permission.rule_store_unavailable",
370
- message: `${which} could not be read ${at === "prepare" ? "when this run started" : "for a call on this run"}. Until a read of them succeeds, none of their allow rows (Read directory rows included) applies, while the deny and ask rows most recently read from them this run still apply — a deny row you removed since that read keeps refusing until then. While they cannot be read, every call your rules judge (a file read, a write, a command) is asked about rather than allowed, until a read of them succeeds. Every later check reads them again.`,
381
+ message: `${which} could not be read ${at === "prepare" ? "when this run started" : "for a call on this run"}. Until a read of them succeeds, none of their allow rows (Read directory rows included) applies, while the deny and ask rows most recently read from them this run still apply — a deny row you removed since that read keeps refusing until then. While they cannot be read, every call is asked about rather than allowed, whatever its tool (rules nobody can read may name any), until a read of them succeeds. Every later check reads them again.`,
371
382
  detail: { at, sessionId: ids.sessionId, runId: ids.runId },
372
383
  });
373
384
  };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * PrepareTask's ADVISOR phase: whether this leg mounts the `advisor` tool, and what it owes the model about it. In order —
3
+ * the deployment switch (`RunnerDeps.advisorTool: "disabled"` ignores the spec's advisor model unread); the static verdict
4
+ * (`advisorAttachVerdict`, the one answer a host's advisor query reads too); then the mount chain — the reserved name, the
5
+ * leg's tool selector (its valve's own predicate, asked of the tool's name), the conversation's hold (the transcript), the
6
+ * advisor route (the shared derived-seat pre-flight, posture `detach`) — and the mount. Its answer is the manifest fact,
7
+ * the person's notice for a reason they are told (root legs only, once per conversation per pair), and the leg's
8
+ * instruction seat (what the model is owed, against what it was told in the conversation's current segment).
9
+ *
10
+ * Runs after the scaffold mounts and before the tool-face fold, so the deferred classification, the prompt and the
11
+ * manifest see the roster the leg runs with. A leg whose spec names no advisor model and whose conversation never told
12
+ * the model about one does nothing here and reads nothing.
13
+ */
14
+ import type { SessionTreeEntry } from "../../internal/harness-types.js";
15
+ import type { Model } from "../../internal/llm.js";
16
+ import type { CompactionForkContext } from "../auto-compaction.js";
17
+ import type { ToolSelector } from "../tool-face.js";
18
+ import type { RosterBuilder } from "../tool-roster.js";
19
+ import { type RunnerDeps, type TaskSpec } from "../types.js";
20
+ import type { WiringAdvisorFact } from "../wiring-manifest.js";
21
+ import { type AdvisorInstructionSeat } from "./advisor-instructions.js";
22
+ import { type AnnounceOnceLedger } from "./announce-once-ledger.js";
23
+ import type { Prepared } from "./contracts.js";
24
+ export interface PrepareAdvisorInput {
25
+ /** borrowed-readonly — the REBOUND spec: the advisor model, the caller's tools (the reserved name), the whole-face switch, the auth hook. */
26
+ spec: Pick<TaskSpec, "advisorModel" | "tools" | "excludeAllTools" | "getApiKeyAndHeaders">;
27
+ /** borrowed-readonly — the deployment switch as the value door screened it. */
28
+ advisorTool: "disabled" | undefined;
29
+ /** borrowed-readonly — the catalog and tiers the verdict reads, the brain the advisor lane books, the notice sink. */
30
+ deps: Pick<RunnerDeps, "models" | "tiers" | "brain" | "onNotice">;
31
+ /** borrowed-readonly — the leg's resolved main model. */
32
+ model: Model;
33
+ /** borrowed-mutable — the mount array (the advisor tool is mounted on it). */
34
+ roster: RosterBuilder;
35
+ /** borrowed-readonly — the leg's frozen tool selector (the valve's predicate). */
36
+ selector: ToolSelector;
37
+ /** borrowed-readonly — the acquired session: its branch (the hold, the segment). */
38
+ session: {
39
+ getBranch(): Promise<ReadonlyArray<SessionTreeEntry>>;
40
+ };
41
+ /** borrowed-readonly — the once-per-session ledger: what the model was told (`arms().advisor`), and the notice's dedupe. */
42
+ onceLedger: Pick<AnnounceOnceLedger, "arms" | "oncePerSession">;
43
+ /** borrowed-readonly — a leg the person reads (not a delegated child): only such a leg tells them. */
44
+ rootLeg: boolean;
45
+ /** borrowed-readonly — the acquired session's id (the notice's routing key). */
46
+ sessionId: string;
47
+ /** borrowed-readonly — this invocation's id (the notices' correlation key). */
48
+ runId: string | undefined;
49
+ /** borrowed-readonly — the leg's usage-account door (the run body binds it before any tool call). */
50
+ sideCallBookRef: Prepared["sideCallBookRef"];
51
+ /** borrowed-readonly — the request the main lane last sent (read at each call). */
52
+ lastSentRequest: () => CompactionForkContext | undefined;
53
+ /** borrowed-readonly — the leg's resolved brain-call guardrail (the value doors' answer; `undefined` = off). */
54
+ brainCallGuardrailMs: number | undefined;
55
+ }
56
+ export interface PrepareAdvisorResult {
57
+ /** The manifest's `advisor` fact; absent ⇔ the spec names no advisor model. */
58
+ manifest: WiringAdvisorFact | undefined;
59
+ /** The leg's instruction seat; absent when there is nothing to tell and nothing told. */
60
+ instruction: AdvisorInstructionSeat | undefined;
61
+ }
62
+ /** The phase body — see the module header. Throws only `config.reserved_tool_name` (a caller tool named `advisor` on a leg that mounts it). */
63
+ export declare function prepareAdvisor(input: PrepareAdvisorInput): Promise<PrepareAdvisorResult>;