@sema-agent/core 7.54.0 → 7.55.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 (403) hide show
  1. package/CHANGELOG.md +451 -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/cc-peer-directory.d.ts +36 -0
  5. package/dist/agents/cc-peer-directory.js +138 -0
  6. package/dist/agents/cc-peer-wire.d.ts +105 -0
  7. package/dist/agents/cc-peer-wire.js +98 -0
  8. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  9. package/dist/agents/cc-uds-peer-channel.js +457 -0
  10. package/dist/agents/cross-session-envelope.d.ts +4 -1
  11. package/dist/agents/cross-session-envelope.js +8 -1
  12. package/dist/agents/cross-session-judge.d.ts +2 -2
  13. package/dist/agents/list-agents-tool.js +2 -1
  14. package/dist/agents/observer.d.ts +4 -5
  15. package/dist/agents/observer.js +2 -1
  16. package/dist/agents/peer-admission.d.ts +6 -0
  17. package/dist/agents/peer-admission.js +4 -1
  18. package/dist/agents/peer-directory.d.ts +43 -9
  19. package/dist/agents/peer-directory.js +66 -23
  20. package/dist/agents/peer-notices.d.ts +1 -1
  21. package/dist/agents/peer-session-drain.d.ts +3 -1
  22. package/dist/agents/peer-session-drain.js +1 -0
  23. package/dist/agents/read-inbox-tool.js +2 -1
  24. package/dist/agents/retain-ledger.d.ts +1 -1
  25. package/dist/agents/roster-store.d.ts +1 -1
  26. package/dist/agents/send-message-tool.d.ts +10 -0
  27. package/dist/agents/send-message-tool.js +34 -5
  28. package/dist/agents/subagent.d.ts +34 -79
  29. package/dist/agents/subagent.js +45 -46
  30. package/dist/agents/tool-filter.d.ts +29 -46
  31. package/dist/agents/tool-filter.js +8 -31
  32. package/dist/agents/verify.d.ts +3 -3
  33. package/dist/brain/anthropic.js +14 -9
  34. package/dist/brain/errors.d.ts +15 -0
  35. package/dist/brain/errors.js +10 -0
  36. package/dist/brain/model-presets.d.ts +4 -4
  37. package/dist/brain/open-responses.js +15 -10
  38. package/dist/brain/openai.js +17 -12
  39. package/dist/brain/provider-dialect.d.ts +39 -3
  40. package/dist/brain/provider-dialect.js +28 -0
  41. package/dist/brain/reasoning.d.ts +1 -1
  42. package/dist/brain/request-params.d.ts +55 -5
  43. package/dist/brain/request-params.js +35 -3
  44. package/dist/brain/retry.d.ts +1 -1
  45. package/dist/brain/route-adjudicator.d.ts +15 -0
  46. package/dist/brain/route-adjudicator.js +15 -0
  47. package/dist/brain/stream-engine.js +6 -5
  48. package/dist/brain/stream-shared.d.ts +1 -1
  49. package/dist/core/advisor-verdict.d.ts +120 -0
  50. package/dist/core/advisor-verdict.js +92 -0
  51. package/dist/core/agent-definition.d.ts +7 -8
  52. package/dist/core/allow-entry.d.ts +49 -23
  53. package/dist/core/allow-entry.js +57 -32
  54. package/dist/core/allow-rule-shadow.d.ts +7 -0
  55. package/dist/core/approval-object.d.ts +2 -1
  56. package/dist/core/approval-object.js +6 -6
  57. package/dist/core/ask-origin.d.ts +63 -11
  58. package/dist/core/ask-origin.js +27 -5
  59. package/dist/core/ask-question.js +10 -4
  60. package/dist/core/auto-compaction.d.ts +11 -8
  61. package/dist/core/auto-compaction.js +4 -2
  62. package/dist/core/auto-mode-arming.d.ts +2 -2
  63. package/dist/core/auto-mode-defaults.d.ts +8 -8
  64. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  65. package/dist/core/auto-mode-prompt.d.ts +1 -1
  66. package/dist/core/auto-mode.d.ts +17 -9
  67. package/dist/core/auto-mode.js +9 -6
  68. package/dist/core/background-agent-store.d.ts +3 -3
  69. package/dist/core/canonical-json.d.ts +1 -1
  70. package/dist/core/canonical-json.js +2 -2
  71. package/dist/core/checkpoint-requirements.d.ts +6 -3
  72. package/dist/core/checkpoint-requirements.js +4 -14
  73. package/dist/core/checkpoint-store.d.ts +80 -51
  74. package/dist/core/checkpoint-store.js +56 -74
  75. package/dist/core/child-clamp-seats.d.ts +6 -0
  76. package/dist/core/child-clamp-seats.js +3 -16
  77. package/dist/core/compliance.d.ts +2 -2
  78. package/dist/core/context-edit.d.ts +6 -7
  79. package/dist/core/cross-boundary-taint.d.ts +9 -3
  80. package/dist/core/cross-boundary-taint.js +5 -3
  81. package/dist/core/decision-receipt.js +2 -2
  82. package/dist/core/effective-path-target.d.ts +1 -1
  83. package/dist/core/engine-notice.d.ts +19 -5
  84. package/dist/core/exec-output-tail.d.ts +1 -1
  85. package/dist/core/file-history-retention.d.ts +1 -1
  86. package/dist/core/file-history-store.d.ts +59 -9
  87. package/dist/core/file-history-store.js +35 -17
  88. package/dist/core/gate-fold.js +3 -2
  89. package/dist/core/gate-lanes.js +12 -8
  90. package/dist/core/gate-outcome.d.ts +17 -4
  91. package/dist/core/gate-outcome.js +30 -0
  92. package/dist/core/governance-codes.d.ts +13 -3
  93. package/dist/core/governance-codes.js +10 -0
  94. package/dist/core/hands-band.d.ts +1 -1
  95. package/dist/core/hooks.d.ts +4 -4
  96. package/dist/core/host-target.d.ts +49 -0
  97. package/dist/core/host-target.js +59 -0
  98. package/dist/core/image-downsample.d.ts +1 -1
  99. package/dist/core/lsp-diagnostics.d.ts +4 -4
  100. package/dist/core/lsp.d.ts +3 -3
  101. package/dist/core/mailbox-store.d.ts +4 -0
  102. package/dist/core/mcp-connection-pool.d.ts +18 -2
  103. package/dist/core/mcp-connection-pool.js +53 -6
  104. package/dist/core/mcp-failure.d.ts +23 -4
  105. package/dist/core/mcp-failure.js +26 -11
  106. package/dist/core/mcp-listing-drift.d.ts +10 -0
  107. package/dist/core/mcp-listing-drift.js +6 -0
  108. package/dist/core/mcp-server-link.d.ts +173 -0
  109. package/dist/core/mcp-server-link.js +127 -0
  110. package/dist/core/mcp-server-spec.d.ts +4 -2
  111. package/dist/core/mcp-session-end.d.ts +26 -0
  112. package/dist/core/mcp-session-end.js +29 -0
  113. package/dist/core/mcp-startup-request.d.ts +17 -0
  114. package/dist/core/mcp-startup-request.js +17 -0
  115. package/dist/core/mcp.d.ts +13 -13
  116. package/dist/core/mcp.js +187 -162
  117. package/dist/core/media-byte-cap.d.ts +1 -1
  118. package/dist/core/memory-engine/engine.d.ts +9 -9
  119. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  120. package/dist/core/memory-engine/tools.js +4 -1
  121. package/dist/core/mode-policy.d.ts +1 -1
  122. package/dist/core/namespaced-rule-name.d.ts +33 -7
  123. package/dist/core/namespaced-rule-name.js +39 -25
  124. package/dist/core/output-style.d.ts +1 -1
  125. package/dist/core/param-rule-reach.d.ts +15 -0
  126. package/dist/core/param-rule-reach.js +30 -0
  127. package/dist/core/parent-spec-seat.d.ts +8 -1
  128. package/dist/core/parent-spec-seat.js +4 -0
  129. package/dist/core/pause-registry.d.ts +16 -5
  130. package/dist/core/pause-registry.js +6 -2
  131. package/dist/core/peer-channel.d.ts +70 -0
  132. package/dist/core/peer-channel.js +1 -0
  133. package/dist/core/permission-rule-consent.d.ts +11 -5
  134. package/dist/core/permission-rule-consent.js +37 -30
  135. package/dist/core/permission-rule-model.d.ts +233 -64
  136. package/dist/core/permission-rule-model.js +384 -85
  137. package/dist/core/permission-rule-provider.d.ts +2 -1
  138. package/dist/core/permission-rule-store.d.ts +20 -25
  139. package/dist/core/permission-rule-store.js +1 -4
  140. package/dist/core/permission-rule-sync.d.ts +11 -2
  141. package/dist/core/permission-rule-sync.js +8 -1
  142. package/dist/core/permission-rules.d.ts +49 -11
  143. package/dist/core/permission-rules.js +123 -89
  144. package/dist/core/persisted-rule-arms.d.ts +4 -2
  145. package/dist/core/present-plan-tool.js +3 -1
  146. package/dist/core/protocol-naming.d.ts +2 -2
  147. package/dist/core/read-only-shell-table.d.ts +1 -1
  148. package/dist/core/read-only-shell.d.ts +1 -1
  149. package/dist/core/roles.d.ts +6 -2
  150. package/dist/core/roles.js +45 -44
  151. package/dist/core/rule-offer-read.d.ts +53 -0
  152. package/dist/core/rule-offer-read.js +146 -0
  153. package/dist/core/rule-owner.d.ts +46 -0
  154. package/dist/core/rule-owner.js +28 -0
  155. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  156. package/dist/core/runner/advisor-instructions.js +61 -0
  157. package/dist/core/runner/advisor-tool.d.ts +33 -0
  158. package/dist/core/runner/advisor-tool.js +112 -0
  159. package/dist/core/runner/announce-once-ledger.d.ts +4 -26
  160. package/dist/core/runner/announce-once-ledger.js +14 -46
  161. package/dist/core/runner/approval-feedback.js +6 -3
  162. package/dist/core/runner/assemble-result.d.ts +1 -1
  163. package/dist/core/runner/caller-roster.d.ts +7 -0
  164. package/dist/core/runner/caller-roster.js +11 -0
  165. package/dist/core/runner/classifier-ladder.d.ts +27 -5
  166. package/dist/core/runner/classifier-ladder.js +12 -11
  167. package/dist/core/runner/compaction-restate.d.ts +10 -6
  168. package/dist/core/runner/compaction-restate.js +9 -3
  169. package/dist/core/runner/contracts.d.ts +13 -9
  170. package/dist/core/runner/conversation-segment.d.ts +28 -0
  171. package/dist/core/runner/conversation-segment.js +42 -0
  172. package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
  173. package/dist/core/runner/cross-boundary-lane.js +26 -15
  174. package/dist/core/runner/decide-continuation.d.ts +7 -4
  175. package/dist/core/runner/decide-continuation.js +2 -2
  176. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  177. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  178. package/dist/core/runner/derived-route-fallback.js +9 -7
  179. package/dist/core/runner/gate-exit.d.ts +6 -0
  180. package/dist/core/runner/gate-exit.js +7 -2
  181. package/dist/core/runner/initial-run-state.js +1 -1
  182. package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
  183. package/dist/core/runner/permission-rule-lanes.js +14 -7
  184. package/dist/core/runner/person-path-rows.js +1 -1
  185. package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -5
  186. package/dist/core/runner/prepare-acquire-reconcile.js +5 -3
  187. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  188. package/dist/core/runner/prepare-advisor.js +77 -0
  189. package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
  190. package/dist/core/runner/prepare-config-doors.d.ts +6 -4
  191. package/dist/core/runner/prepare-config-doors.js +18 -12
  192. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  193. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  194. package/dist/core/runner/prepare-file-history.js +39 -39
  195. package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
  196. package/dist/core/runner/prepare-gate-stations.js +2 -7
  197. package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
  198. package/dist/core/runner/prepare-inherited-gate.js +3 -3
  199. package/dist/core/runner/prepare-park-ask.js +7 -7
  200. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  201. package/dist/core/runner/prepare-policy-chain.js +4 -10
  202. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  203. package/dist/core/runner/prepare-project-context.js +6 -3
  204. package/dist/core/runner/prepare-prompt-inputs.js +1 -1
  205. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
  206. package/dist/core/runner/prepare-protocol-tools.js +3 -2
  207. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  208. package/dist/core/runner/prepare-safety-scan.js +8 -6
  209. package/dist/core/runner/prepare-task.js +15 -18
  210. package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
  211. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
  212. package/dist/core/runner/prepare-wiring-manifest.js +2 -2
  213. package/dist/core/runner/resume-policy-outcome.js +1 -1
  214. package/dist/core/runner/retired-runner-deps.js +1 -1
  215. package/dist/core/runner/run-attachment-seats.js +0 -1
  216. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  217. package/dist/core/runner/run-compaction-machinery.js +2 -12
  218. package/dist/core/runner/run-git-lane.d.ts +1 -0
  219. package/dist/core/runner/run-harness-handlers.js +2 -3
  220. package/dist/core/runner/run-leg.js +13 -0
  221. package/dist/core/runner/run-settle-and-teardown.js +1 -1
  222. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  223. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  224. package/dist/core/runner/run-turn-boundary.js +14 -12
  225. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  226. package/dist/core/runner/session-rule-policy.js +13 -28
  227. package/dist/core/runner/side-call-account.d.ts +32 -8
  228. package/dist/core/runner/side-call-account.js +23 -1
  229. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  230. package/dist/core/runner/sub-agent-deny-lists.js +4 -3
  231. package/dist/core/runner/synthetic-tools.d.ts +10 -13
  232. package/dist/core/runner/synthetic-tools.js +4 -2
  233. package/dist/core/runner/tool-disclosure.js +2 -1
  234. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  235. package/dist/core/runner/tool-face-overlay.js +17 -1
  236. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  237. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  238. package/dist/core/runner/turn-attachments.d.ts +60 -67
  239. package/dist/core/runner-deps.d.ts +37 -37
  240. package/dist/core/runtime-caps.d.ts +4 -4
  241. package/dist/core/safety-merge-corpus.js +17 -1
  242. package/dist/core/same-plain-value.d.ts +40 -0
  243. package/dist/core/same-plain-value.js +49 -0
  244. package/dist/core/scheduler.d.ts +1 -1
  245. package/dist/core/sensitive-path-policy.d.ts +1 -1
  246. package/dist/core/sensitive-path-policy.js +1 -1
  247. package/dist/core/session-policy-store.d.ts +77 -22
  248. package/dist/core/session-policy-store.js +56 -14
  249. package/dist/core/session-reconcile.d.ts +2 -2
  250. package/dist/core/session-store.d.ts +80 -30
  251. package/dist/core/session-store.js +118 -76
  252. package/dist/core/session.d.ts +24 -46
  253. package/dist/core/shared-memory/tools.js +3 -1
  254. package/dist/core/shared-memory/types.d.ts +1 -1
  255. package/dist/core/side-query.d.ts +10 -0
  256. package/dist/core/side-query.js +5 -0
  257. package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
  258. package/dist/core/store-contracts/file-history-store-contract.js +43 -3
  259. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  260. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  261. package/dist/core/store-contracts/session-repo-contract.js +125 -0
  262. package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
  263. package/dist/core/store-contracts/session-store-contract.js +259 -41
  264. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  265. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  266. package/dist/core/task-event.d.ts +10 -4
  267. package/dist/core/task-notification.d.ts +3 -3
  268. package/dist/core/task-registry-agent.d.ts +4 -4
  269. package/dist/core/task-registry-shared.d.ts +4 -4
  270. package/dist/core/task-registry-shared.js +1 -0
  271. package/dist/core/task-registry.d.ts +4 -4
  272. package/dist/core/task-registry.js +3 -1
  273. package/dist/core/task-result.d.ts +3 -3
  274. package/dist/core/task-spec.d.ts +52 -52
  275. package/dist/core/task-stream.d.ts +6 -6
  276. package/dist/core/task-tool-shape.d.ts +4 -4
  277. package/dist/core/tighten-task-spec.d.ts +1 -1
  278. package/dist/core/tool-catalog-entries.d.ts +19 -2
  279. package/dist/core/tool-catalog-entries.js +57 -42
  280. package/dist/core/tool-conformance.js +1 -0
  281. package/dist/core/tool-errors.d.ts +2 -2
  282. package/dist/core/tool-face-reader.js +5 -3
  283. package/dist/core/tool-face.d.ts +21 -2
  284. package/dist/core/tool-face.js +1 -1
  285. package/dist/core/tool-model-gate.d.ts +3 -3
  286. package/dist/core/tool-name-aliases.d.ts +29 -8
  287. package/dist/core/tool-name-aliases.js +27 -3
  288. package/dist/core/tool-name-readings.d.ts +5 -8
  289. package/dist/core/tool-name-readings.js +1 -2
  290. package/dist/core/tool-policy.d.ts +24 -5
  291. package/dist/core/tool-policy.js +34 -10
  292. package/dist/core/tool-registry.d.ts +14 -7
  293. package/dist/core/tool-registry.js +17 -7
  294. package/dist/core/tool-result-store.js +2 -1
  295. package/dist/core/tool-roster.d.ts +47 -18
  296. package/dist/core/tool-roster.js +53 -32
  297. package/dist/core/tool-spec-members.js +1 -1
  298. package/dist/core/tool-spec.d.ts +35 -21
  299. package/dist/core/tools.js +3 -2
  300. package/dist/core/trace.d.ts +4 -0
  301. package/dist/core/untrusted-egress.d.ts +1 -1
  302. package/dist/core/untrusted-text.d.ts +1 -1
  303. package/dist/core/warm-resume.d.ts +1 -1
  304. package/dist/core/wiring-manifest.d.ts +49 -0
  305. package/dist/core/wiring-manifest.js +13 -5
  306. package/dist/core/workflow-journal-store.d.ts +62 -0
  307. package/dist/core/workflow-journal-store.js +77 -1
  308. package/dist/core/workflow-run-store.d.ts +6 -0
  309. package/dist/core/workflow-run-store.js +2 -0
  310. package/dist/engine/compaction/compaction.d.ts +9 -9
  311. package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
  312. package/dist/engine/execution-env/node-execution-env.js +43 -22
  313. package/dist/engine/harness/agent-harness.d.ts +14 -8
  314. package/dist/engine/harness/agent-harness.js +33 -26
  315. package/dist/engine/harness/types.d.ts +29 -7
  316. package/dist/engine/harness/types.js +12 -1
  317. package/dist/engine/llm/types.d.ts +9 -9
  318. package/dist/engine/llm/validation.d.ts +4 -1
  319. package/dist/engine/llm/validation.js +13 -1
  320. package/dist/engine/loop/agent-loop.d.ts +1 -1
  321. package/dist/engine/loop/agent-loop.js +10 -8
  322. package/dist/engine/loop/types.d.ts +15 -13
  323. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  324. package/dist/engine/session/memory-repo.d.ts +10 -11
  325. package/dist/engine/session/memory-repo.js +13 -8
  326. package/dist/engine/session/parent-chain-guard.d.ts +11 -0
  327. package/dist/engine/session/parent-chain-guard.js +10 -0
  328. package/dist/engine/session/repo-utils.d.ts +31 -3
  329. package/dist/engine/session/repo-utils.js +42 -5
  330. package/dist/engine/session/storage-base.js +3 -0
  331. package/dist/index.d.ts +27 -15
  332. package/dist/index.js +21 -11
  333. package/dist/internal/harness-types.d.ts +1 -1
  334. package/dist/internal/harness.d.ts +4 -3
  335. package/dist/internal/harness.js +3 -2
  336. package/dist/internal/llm.d.ts +1 -1
  337. package/dist/internal/llm.js +1 -1
  338. package/dist/orchestration/goal.js +2 -2
  339. package/dist/orchestration/run-workflow-tool.d.ts +2 -2
  340. package/dist/orchestration/run-workflow-tool.js +5 -3
  341. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  342. package/dist/orchestration/workflow-types.d.ts +18 -0
  343. package/dist/orchestration/workflow-types.js +6 -0
  344. package/dist/orchestration/workflow.d.ts +2 -13
  345. package/dist/orchestration/workflow.js +21 -31
  346. package/dist/prompt-assembly/event-registry.js +1 -0
  347. package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
  348. package/dist/prompt-assembly/tool-catalog.js +3 -0
  349. package/dist/prompts/default.d.ts +14 -14
  350. package/dist/scenarios/full-body.d.ts +4 -4
  351. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  352. package/dist/stores/file/adoption/adopt.js +24 -31
  353. package/dist/stores/file/adoption/marker.d.ts +6 -13
  354. package/dist/stores/file/adoption/marker.js +6 -15
  355. package/dist/stores/file/checkpoint-store.d.ts +3 -0
  356. package/dist/stores/file/checkpoint-store.js +9 -3
  357. package/dist/stores/file/file-history-store.d.ts +20 -19
  358. package/dist/stores/file/file-history-store.js +152 -135
  359. package/dist/stores/file/fs-atomic.d.ts +15 -0
  360. package/dist/stores/file/fs-atomic.js +89 -14
  361. package/dist/stores/file/index.d.ts +1 -1
  362. package/dist/stores/file/mailbox-store.d.ts +3 -0
  363. package/dist/stores/file/mailbox-store.js +3 -1
  364. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  365. package/dist/stores/file/permission-rule-adopt.js +15 -16
  366. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  367. package/dist/stores/file/permission-rule-store.js +21 -14
  368. package/dist/stores/file/session-policy-store.d.ts +3 -3
  369. package/dist/stores/file/session-store.d.ts +26 -11
  370. package/dist/stores/file/session-store.js +77 -40
  371. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  372. package/dist/stores/file/workflow-journal-store.js +28 -13
  373. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  374. package/dist/tools/artifact/artifact-tool.js +2 -1
  375. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  376. package/dist/tools/fs/fs-bash.d.ts +2 -2
  377. package/dist/tools/fs/fs-bash.js +3 -1
  378. package/dist/tools/fs/fs-shared.d.ts +8 -8
  379. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  380. package/dist/tools/fs/notebook.d.ts +2 -2
  381. package/dist/tools/fs/read-deny.d.ts +29 -7
  382. package/dist/tools/fs/read-deny.js +63 -22
  383. package/dist/tools/fs/removal-targets.d.ts +1 -1
  384. package/dist/tools/fs/safety.d.ts +9 -9
  385. package/dist/tools/fs/search.d.ts +6 -6
  386. package/dist/tools/fs/shell-read-check.js +6 -1
  387. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  388. package/dist/tools/fs/shell-read-judge.js +5 -2
  389. package/dist/tools/loop-tick.d.ts +2 -2
  390. package/dist/tools/scheduler-tools.js +5 -1
  391. package/dist/tools/task-list.d.ts +7 -7
  392. package/dist/tools/task-list.js +5 -1
  393. package/dist/tools/todo.js +2 -1
  394. package/dist/tools/web.d.ts +1 -1
  395. package/dist/tools/web.js +40 -37
  396. package/dist/tools/worktree.d.ts +3 -3
  397. package/dist/tools/worktree.js +3 -1
  398. package/package.json +1 -1
  399. package/test/export-surface.snapshot.json +5756 -5638
  400. package/wire-changes/core@7.54.1.json +37 -0
  401. package/wire-changes/core@7.55.0.json +3318 -0
  402. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  403. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -1,7 +1,8 @@
1
1
  import { randomBytes } from "node:crypto";
2
- import { escapeForDisclosure, hasUnrenderableCharacters, parseRuleText, ruleAdmitsCommand, ruleBreadthWarningsOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForName, suggestRulesForCommand, EDITED_RULE_BREADTH_WARNING_CODES, UNCOVERED_SEGMENT_REASONS, RULE_BEHAVIORS, RULE_BEHAVIOR_PRECEDENCE, isRuleBehavior, } from "./permission-rule-model.js";
2
+ import { escapeForDisclosure, hasUnrenderableCharacters, parseRuleText, ruleAdmitsCommand, ruleBreadthWarningsOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForHost, suggestRuleForName, suggestRulesForCommand, EDITED_RULE_BREADTH_WARNING_CODES, RULE_OFFER_KINDS, UNCOVERED_SEGMENT_REASONS, RULE_BEHAVIORS, RULE_BEHAVIOR_PRECEDENCE, isRuleBehavior, } from "./permission-rule-model.js";
3
+ import { readRuleOwner, sameRuleOwner } from "./rule-owner.js";
3
4
  import { effectiveOrThrow } from "./permission-rule-provider.js";
4
- import { errText, isValidConsentScope, landRuleAdd, sameRuleOwner, sameScope, writerOf } from "./permission-rule-store.js";
5
+ import { errText, isValidConsentScope, landRuleAdd, sameScope, writerOf } from "./permission-rule-store.js";
5
6
  const isUncoveredSegmentReason = (v) => UNCOVERED_SEGMENT_REASONS.some((word) => v === word);
6
7
  export const RULE_APPROVAL_KINDS = Object.freeze(["card", "import", "starter"]);
7
8
  export const RULE_APPROVAL_STATES = Object.freeze(["pending", "approved", "redeemed"]);
@@ -47,41 +48,46 @@ function mintId(deps, prefix) {
47
48
  return `${prefix}_${Date.now().toString(36)}_${randomBytes(9).toString("base64url")}`;
48
49
  }
49
50
  function requirePrincipal(principal, entry) {
50
- if (typeof principal !== "string" || principal === "") {
51
+ const owner = readRuleOwner({ kind: "principal", principal });
52
+ if (owner?.kind !== "principal") {
51
53
  throw new Error(`${entry} requires a verified principal — refusing to create an approval record without one`);
52
54
  }
53
- return principal;
55
+ return owner.principal;
54
56
  }
55
57
  function resolveCallerOwner(principal, owner, entry) {
56
58
  if (owner !== undefined) {
57
- if (owner.kind === "principal") {
58
- const p = requirePrincipal(owner.principal, entry);
59
- if (typeof principal === "string" && principal !== "" && principal !== p) {
60
- throw new Error(`${entry}: contradictory identity — principal "${principal}" and owner principal "${p}" disagree`);
59
+ const given = readRuleOwner(owner);
60
+ if (given === undefined) {
61
+ throw new Error(`${entry} requires a verified principal or the local owner — the owner given is neither (a principal owner names a non-blank principal)`);
62
+ }
63
+ if (given.kind === "principal") {
64
+ if (typeof principal === "string" && principal !== "" && principal !== given.principal) {
65
+ throw new Error(`${entry}: contradictory identity — principal "${principal}" and owner principal "${given.principal}" disagree`);
61
66
  }
62
- return { kind: "principal", principal: p };
67
+ return given;
63
68
  }
64
69
  if (typeof principal === "string" && principal !== "") {
65
70
  throw new Error(`${entry}: contradictory identity — a principal and a local-owner were both given; a bucket has one owner`);
66
71
  }
67
- return { kind: "local-owner" };
72
+ return given;
68
73
  }
69
74
  return { kind: "principal", principal: requirePrincipal(principal, entry) };
70
75
  }
71
76
  function ownerOfRecord(rec) {
72
- if (rec.owner !== undefined) {
73
- if (rec.owner.kind === "principal") {
74
- if (typeof rec.owner.principal !== "string" || rec.owner.principal === "")
75
- return undefined;
76
- if (typeof rec.principal === "string" && rec.principal !== "" && rec.principal !== rec.owner.principal)
77
- return undefined;
78
- return rec.owner;
79
- }
80
- if (typeof rec.principal === "string" && rec.principal !== "")
81
- return undefined;
82
- return { kind: "local-owner" };
83
- }
84
- return typeof rec.principal === "string" && rec.principal !== "" ? { kind: "principal", principal: rec.principal } : undefined;
77
+ const stated = rec.owner;
78
+ const owner = stated === undefined ? undefined : readRuleOwner(stated);
79
+ if (stated !== undefined && owner === undefined)
80
+ return undefined;
81
+ const principal = rec.principal;
82
+ const given = typeof principal === "string" && principal !== "";
83
+ const named = given ? readRuleOwner({ kind: "principal", principal }) : undefined;
84
+ if (given && named === undefined)
85
+ return undefined;
86
+ if (owner === undefined)
87
+ return named;
88
+ if (named !== undefined && !sameRuleOwner(owner, named))
89
+ return undefined;
90
+ return owner;
85
91
  }
86
92
  function recordIdentityOf(owner) {
87
93
  return owner.kind === "principal" ? { principal: owner.principal } : { owner: { kind: "local-owner" } };
@@ -111,7 +117,7 @@ function approvalRecordDamageOf(rec) {
111
117
  for (const [at, offer] of rec.offers.entries()) {
112
118
  if (typeof offer !== "object" || offer === null)
113
119
  return `offer ${at} is not an offer object`;
114
- if (offer.kind !== "single" && offer.kind !== "batch")
120
+ if (!RULE_OFFER_KINDS.some((word) => offer.kind === word))
115
121
  return `offer ${at} has an unknown kind`;
116
122
  if (offer.kind === "batch" && (!Array.isArray(offer.candidates) || offer.candidates.length === 0)) {
117
123
  return `batch offer ${at} has no members`;
@@ -283,8 +289,9 @@ export async function prepareCardApproval(opts) {
283
289
  e.code = "config.invalid_argument";
284
290
  throw e;
285
291
  }
286
- const nameCard = ruleToolGrammarOf(opts.toolName) === "name";
287
- if (opts.toolName !== CARD_RULE_TOOL && !nameCard)
292
+ const grammar = ruleToolGrammarOf(opts.toolName);
293
+ const oneRuleCard = grammar === "name" || grammar === "domain" ? grammar : undefined;
294
+ if (opts.toolName !== CARD_RULE_TOOL && oneRuleCard === undefined)
288
295
  return undefined;
289
296
  const scope = (() => {
290
297
  if (opts.scope !== undefined) {
@@ -308,7 +315,7 @@ export async function prepareCardApproval(opts) {
308
315
  throw e;
309
316
  })();
310
317
  let coverage;
311
- if (!nameCard) {
318
+ if (oneRuleCard === undefined) {
312
319
  try {
313
320
  const view = await effectiveOrThrow(storeForOwner(opts.deps.provider, owner), opts.sessionId !== undefined ? { sessionId: opts.sessionId } : undefined);
314
321
  const table = view.rules;
@@ -318,8 +325,8 @@ export async function prepareCardApproval(opts) {
318
325
  coverage = undefined;
319
326
  }
320
327
  }
321
- const suggested = nameCard
322
- ? [suggestRuleForName(opts.toolName, opts.command)].filter((o) => o !== undefined)
328
+ const suggested = oneRuleCard !== undefined
329
+ ? [oneRuleCard === "name" ? suggestRuleForName(opts.toolName, opts.command) : suggestRuleForHost(opts.toolName, opts.command)].filter((o) => o !== undefined)
323
330
  : suggestRulesForCommand(opts.command, {
324
331
  ...(coverage !== undefined ? { coverage } : {}),
325
332
  scope,
@@ -358,7 +365,7 @@ export async function prepareCardApproval(opts) {
358
365
  rev: 0,
359
366
  candidates,
360
367
  offers,
361
- ...(nameCard ? {} : { command: opts.command }),
368
+ ...(oneRuleCard !== undefined ? {} : { command: opts.command }),
362
369
  createdAt: nowIso(opts.deps),
363
370
  ...(opts.toolCallId !== undefined ? { toolCallId: opts.toolCallId } : {}),
364
371
  ...(opts.boundInputHash !== undefined ? { boundInputHash: opts.boundInputHash } : {}),
@@ -72,9 +72,11 @@
72
72
  * here) and no leading-env-assignment stripping (`FOO=1 git status` simply does not match
73
73
  * `Bash(git status:*)`) — the last two are strict-side divergences from upstream, registered as such.
74
74
  */
75
+ import { type ParsedPermissionRule } from "./permission-rule-syntax.js";
75
76
  import { type DenyFace } from "../tools/fs/read-deny.js";
76
77
  import type { AssertAllKeysHandled, RuleOffersAbsence } from "./ask-origin.js";
77
78
  import { type ToolCallLike } from "./tool-registry.js";
79
+ import { type HostReading } from "./host-target.js";
78
80
  import { type PathDenialEvidence, type PathFamily, type PathIdentity } from "../tools/fs/safety.js";
79
81
  import { type TargetViews } from "./path-rule-binding.js";
80
82
  /**
@@ -160,73 +162,148 @@ export declare function callPathFaceOf(call: ToolCallLike): DenyFace | undefined
160
162
  /** Does some {@link PATH_RULE_FACES} tightening column (deny or ask) hold `face` — may a face-keyed row speak for a call on
161
163
  * it, whatever the call's tool is called (a caller's tool declaring a read path target is on the read face too)? */
162
164
  export declare function faceRowsSpeakFor(face: DenyFace | undefined): boolean;
165
+ /** One row of {@link NAME_RULE_FACES}. */
166
+ export interface NameRuleFace {
167
+ /** The argument a rule's content is read against. */
168
+ readonly param: string;
169
+ /** The arguments whose `<param>:` spelling the row CLAIMS: on a bare row that spelling is refused (the bare one is the rule's),
170
+ * on a keyed row it is the rule. An argument the tool carries that the row does not claim keeps the generic parameter lane. */
171
+ readonly params: readonly string[];
172
+ /** KEYED: the closed set of values the tool itself declares for `param` (the tool's own set, never a copy). */
173
+ readonly words?: readonly string[];
174
+ /** `mounted`: the values a rule names are the MOUNTED tool's own — its `ToolRuleFace.nameValues`, riding the call's face — and a
175
+ * rule's value and the call's are each resolved to one of them by the one resolver ({@link canonicalNameValue}). */
176
+ readonly values?: "mounted";
177
+ }
163
178
  /**
164
179
  * The tools whose rule content NAMES THE VALUE of one parameter instead of a command or a path — ONE grammar (the name grammar,
165
180
  * match `name`), one row per tool, the row declaring the tool's SPELLING of it:
166
- * · BARE — the reference's `Skill(<name>)` / `Skill(<prefix>:*)`: `param` is the argument the rule's content is read against,
167
- * `params` every scalar argument the tool carries (the parameter spelling `Tool(<param>:<pattern>)` those names used to reach
168
- * is retired for such a tool, see {@link parseNameRuleContent}). The Skill tool's real schema keys are pinned equal to
169
- * `params` (test/backlog1318).
181
+ * · BARE — the reference's `Skill(<name>)` / `Skill(<prefix>:*)`: `params` is every scalar argument the tool carries, read off
182
+ * its catalog row (the parameter spelling `Tool(<param>:<pattern>)` those names used to reach is retired for such a tool,
183
+ * see {@link parseNameRuleContent}). The Skill tool's real schema keys are pinned equal to `params` (test/backlog1318).
170
184
  * · KEYED — `words` present: the reference's `Artifact(action:<word>)`, the content carrying the argument's own key. `params`
171
- * is that one key; `words` is the closed set of values the tool itself declares for it (the row points at the tool's own
172
- * set, never a copy), and a rule names exactly one of them — no prefix form, no `*`.
185
+ * is that one key, and a rule names exactly one of the words — no prefix form, no `*`.
186
+ * · MOUNTED — `values: "mounted"`: the reference's `Agent(<subagent_type>)`, bare, naming one value of the set the mounted tool
187
+ * declares (which agent types this leg offers) — no prefix form, no `*`, no leading-slash reading. `params` is the one
188
+ * argument it claims; the tool's other arguments keep the generic parameter lane (`Agent(model:…)`).
173
189
  * Whatever the spelling, a rule of this grammar says "the call's value of `param` is this value", read by the one subject
174
- * reader ({@link nameRuleSubjectOf}), the one predicate ({@link nameRuleAdmits}), the one precedence walk
190
+ * reader ({@link nameRuleSubjectOf}), the one predicate ({@link nameRuleReach}), the one precedence walk
175
191
  * ({@link adjudicatePersistedNameRules}) and the one offer ({@link suggestRuleForName}).
176
192
  */
177
- export declare const NAME_RULE_FACES: Readonly<Record<string, {
178
- readonly param: string;
179
- readonly params: readonly string[];
180
- readonly words?: readonly string[];
181
- }>>;
193
+ export declare const NAME_RULE_FACES: Readonly<Record<string, NameRuleFace>>;
182
194
  /**
183
- * Why a call of a KEYED value tool that names no value for the key cannot be read against that key's deny / ask rules, or
184
- * undefined (a bare-spelling tool, or no value tool). Every judge reads a call's arguments as the tool reads them
185
- * (`argsAsTheToolReads`: its argument preparation, then the schema's coercions); a call that STILL names no value for the key
186
- * runs a value no argument shows — a default filled in inside the tool's execution (a caller's tool mounted under the keyed
187
- * name, or answering to it, with no argument preparation of its own). Whether a rule by the key reaches such a call is
188
- * unknown, so every reader REFUSES it on the key's deny or ask rule — a refusal, never an ask a person could approve past a
189
- * deny, and no allow by the key reaches it. A tool whose reading always names the key (the built-in `Artifact`: an absent
190
- * action reads as `publish`) never meets this. A bare-spelling tool's call that names nothing is reached by nothing: no
191
- * default stands behind it.
195
+ * The reference's fold of a delegated agent type (`lhe`, cli296.js:246723):
196
+ * `e.normalize("NFKC").toLowerCase().replace(/[\p{White_Space}\p{Pd}_]+/gu, "")`.
197
+ *
198
+ * Deliberately lossy and deliberately NOT a resolver: it decides whether two spellings denote the same entry of a value set AFTER
199
+ * an exact match has already failed ({@link canonicalNameValue} is the resolver). `\p{Pd}` is the dash punctuation class (an
200
+ * en-dash paste folds like a hyphen), `\p{White_Space}` covers NBSP and friends, and NFKC folds fullwidth/compatibility forms —
201
+ * the three ways a name gets mangled between a listing line and a tool call. It can map DISTINCT entries onto one key
202
+ * ("code-review" / "code_review"), which is why a fold that lands on several is ambiguous, never a pick.
192
203
  */
193
- export declare function keyedValueAbsentReason(tool: string): string | undefined;
204
+ export declare function normalizeSubagentType(value: string): string;
205
+ /** What a spelling names in a value set ({@link canonicalNameValue}): one entry, several (the fold lands on each), or none. */
206
+ export type NameValueResolution = {
207
+ readonly kind: "entry";
208
+ readonly entry: string;
209
+ } | {
210
+ readonly kind: "ambiguous";
211
+ readonly entries: readonly string[];
212
+ } | {
213
+ readonly kind: "unknown";
214
+ };
215
+ /**
216
+ * THE resolver of a spelling against a value set — the one identity a delegated agent type has, read alike by the tool that runs
217
+ * the call and by every rule judged on it: an EXACT member first (a correct spelling never moves); else the members the
218
+ * reference's fold ({@link normalizeSubagentType}) maps onto the same key — exactly one ⇒ that member, several ⇒ `ambiguous`
219
+ * (listed, never one picked), none (or a spelling that folds to nothing) ⇒ `unknown`.
220
+ */
221
+ export declare function canonicalNameValue(value: string, values: readonly string[]): NameValueResolution;
222
+ /**
223
+ * Why a call of a name tool whose rules name one value of a CLOSED set (a keyed tool's `words`, a mounted tool's values) cannot
224
+ * be read against the tool's deny / ask rules when it names no value, or undefined (an open-set tool, or no value tool). Every
225
+ * judge reads a call's arguments as the tool reads them (`argsAsTheToolReads`: its argument preparation, then the schema's
226
+ * coercions); a call that STILL names no value runs one no argument shows — a default filled in inside the tool's execution (a
227
+ * caller's tool mounted under the name with no argument preparation of its own; the delegation tool's plain lane while a
228
+ * definition shadows its default type's name). Whether a rule by the value reaches such a call is unknown, so every reader
229
+ * REFUSES it on the tool's deny or ask rule — a refusal, never an ask a person could approve past a deny, and no allow by the
230
+ * value reaches it. A tool whose reading always names its value (the built-in `Artifact`: an absent action reads as
231
+ * `publish`) never meets this. An open-set tool's call that names nothing is reached by nothing: no default stands behind it.
232
+ */
233
+ export declare function nameValueAbsentReason(tool: string): string | undefined;
194
234
  /**
195
- * Does the name grammar read this content of this tool? Every content of a bare-spelling tool; on a keyed tool only content
196
- * keyed by its own parameter (`action:…` on `Artifact`) — another key (`Artifact(url:…)`) is a rule on another argument,
197
- * which the persisted grammar has no form for and the caller policy reads with its generic parameter lane. Undefined grammar
198
- * ⇒ false.
235
+ * Does the name grammar read this content of this tool ALONE? On a keyed tool only content keyed by its own parameter
236
+ * (`action:…` on `Artifact`); on a bare tool every content but one keyed by an argument the catalog's tool carries and the row
237
+ * does not claim ({@link NameRuleFace.params}) — that is a rule on that argument (`Agent(model:…)`, `Artifact(url:…)`), which the
238
+ * caller policy reads with its generic parameter lane; a MOUNTED row's such content is read as its value too where it tightens
239
+ * ({@link mountedValueArmOf}). The arguments are the catalog's, whatever face a leg mounts the tool with: one text reads one way
240
+ * on every compile. Undefined grammar ⇒ false.
199
241
  */
200
242
  export declare function nameGrammarReads(tool: string, content: string): boolean;
201
243
  /**
202
- * The tools whose rule content names the HOST of the URL one parameter carries — the reference's `WebFetch(domain:<host>)`
203
- * form, one row per tool: `param` is the URL argument the host is read from ({@link domainRuleSubjectOf}). Read by
204
- * {@link parseDomainRuleContent}; an allow only (see there).
244
+ * The VALUE arm of a mounted row's (`Agent`) `<key>:<rest>` deny / ask that the parameter lane reads as a rule on the argument
245
+ * `key` — or undefined (any other tool, or an allow). One rule for every reader of such a content: a TIGHTENING reaches the call
246
+ * under every reading of its text — the rule on the argument, and the whole text as one of the tool's values (an agent type may
247
+ * carry a colon), either reaching ⇒ it applies (the reference reads the content as an agent type for its deny filter and as a
248
+ * `key:value` for its generic parameter check alike); a GRANT reads exactly one way — the argument rule where `key` is an
249
+ * argument the tool carries — so an allow never widens through a second reading. The value arm is the name grammar's own rule
250
+ * over the whole content, judged like every value rule ({@link nameRuleReach}).
251
+ */
252
+ export declare function mountedValueArmOf(text: string, tool: string, behavior: RuleBehavior): ParsedRule | undefined;
253
+ /**
254
+ * The argument a mounted row's (`Agent`) `<key>:<rest>` content is keyed by when the leg's own tool declares it (`mountedParams`,
255
+ * the leg's face) and the catalog's does not — or undefined. A rule's grammar reads the catalog's arguments only, so such a
256
+ * content would read as one of the tool's values and never reach a call setting that argument: a compile that holds the leg's
257
+ * face knows this and refuses it; one without the face cannot tell, and reads the value.
258
+ */
259
+ export declare function mountedOnlyArgumentOf(tool: string, content: string, mountedParams: readonly string[] | undefined): string | undefined;
260
+ /**
261
+ * The ARGUMENT arm of a mounted row's value rule — the other half of {@link mountedValueArmOf}'s law, read where the rule is a
262
+ * stored row (a list entry, a session bucket's entry, the person's persisted row): a deny or an ask whose value is
263
+ * `<argument>:<pattern>`, `argument` one the catalog's tool carries and the row does not claim, is ALSO the rule on that
264
+ * argument, judged by the one argument predicate (`paramRuleReaches`) — so a stored `Agent(model:opus)` deny refuses a call
265
+ * running `model: opus` as the rule policy does. Undefined for an allow (a grant reads one way), another tool, or another value.
205
266
  */
206
- export declare const DOMAIN_RULE_FACES: Readonly<Record<string, {
267
+ export declare function mountedArgumentArmOf(rule: Pick<PersistedRule, "tool" | "behavior" | "match" | "command">): {
207
268
  readonly param: string;
208
- }>>;
269
+ readonly pattern: string;
270
+ } | undefined;
271
+ /** The marker a DOMAIN-grammar rule's content starts with: `<Tool>(domain:<host>)` (the reference's spelling). */
272
+ export declare const DOMAIN_RULE_MARKER = "domain:";
209
273
  /**
210
- * Which tools a rule may name — the model's tool set is DERIVED, never a hand-kept list: the command rule word
211
- * ({@link COMMAND_RULE_TOOL}) takes the COMMAND grammar — the other shell-face tools take none of their own, their command is
212
- * judged by the `Bash(…)` rules ({@link laneToolNamesOf}); every tool the catalog declares a path target for (Read / Edit / Write /
213
- * Glob / NotebookEdit / …, `pathTargetOf`) takes the PATH grammar; the tools of {@link NAME_RULE_FACES} take the NAME grammar
214
- * (each in its row's spelling: bare `Skill(<name>)`, keyed `Artifact(action:<word>)`); the tools of {@link DOMAIN_RULE_FACES} the
215
- * DOMAIN grammar.
216
- * A rule on any other tool has no content this model can judge and is refused (`unsupported.tool`). The tool set therefore
217
- * moves with the catalog's declarations, exactly as the protective fences' covered set does.
274
+ * THE grammar a rule on a tool takes — the one reading every rule reader shares (the persisted model's {@link parseRuleText}, the
275
+ * rule policy's compiler through {@link ruleLaneOf}, the entry lists, the approval card), and a property of the rule's tool NAME
276
+ * as the catalog declares it, never of the tool a leg mounts under that name. The model's tool set is DERIVED, never a hand-kept
277
+ * list: the command rule word ({@link COMMAND_RULE_TOOL}) takes the COMMAND grammar — the other shell-face tools take none of
278
+ * their own, their command is judged by the `Bash(…)` rules ({@link laneToolNamesOf}); the tools of {@link NAME_RULE_FACES} the
279
+ * NAME grammar (each in its row's spelling: bare `Skill(<name>)`, keyed `Artifact(action:<word>)`); every name the catalog
280
+ * declares a host target for (`hostTargetOf`: WebFetch) the DOMAIN grammar; every name it declares a path target for
281
+ * (`pathTargetOf`: Read / Edit / Write / Glob / NotebookEdit / …) the PATH grammar. A rule on any other tool has no content
282
+ * this model can judge and is refused (`unsupported.tool`). The tool set therefore moves with the catalog's declarations,
283
+ * exactly as the protective fences' covered set does.
218
284
  */
219
285
  export type RuleGrammar = "command" | "path" | "name" | "domain";
220
286
  export declare function ruleToolGrammarOf(toolName: string): RuleGrammar | undefined;
287
+ /** The parameter a shell-face tool's rule content names as one of the tool's own scalar arguments (`Monitor(description:*)`,
288
+ * `Bash(timeout:5)`), or undefined — the content is then a command spelling. */
289
+ export declare function shellRuleParamOf(tool: string, content: string): string | undefined;
290
+ /** A lane of the rule policy's compiler: one of the content grammars, or the generic `param:pattern` lane. */
291
+ export type RuleLane = RuleGrammar | "param";
221
292
  /**
222
- * The HOST a domain-grammar tool's call fetches — the string every DOMAIN rule is read against — or undefined: not a domain
223
- * tool; no URL argument, or one that is not a string; a URL that does not parse, is not http(s), or carries credentials (the
224
- * fetch tool refuses those itself). The host is the URL parser's (lower case, IDN in its ASCII form, an IPv4 shorthand
225
- * expanded — the host the fetch connects to), its trailing dots read off.
293
+ * THE dispatch of a `<tool>(<content>)` rule in the rule policy's compiler — which lane reads it. A shell-face tool's content
294
+ * is a COMMAND spelling unless it names one of that tool's own scalar arguments (the command word's `<param>:*` keeps the
295
+ * command-prefix reading); otherwise the tool's grammar ({@link ruleToolGrammarOf}, the rule model's own reading) reads the
296
+ * content it claims — a name tool every content (a keyed one only content keyed by its own parameter, {@link nameGrammarReads}),
297
+ * a path tool a content with no `:` past its first character, a host tool a content that starts with {@link DOMAIN_RULE_MARKER}
298
+ * — and every other content is a rule on a parameter. The lane is a function of the rule's name and content alone: it is decided
299
+ * before any lane's own check runs, a content a grammar claims is never judged as a parameter rule, and the same rule text takes
300
+ * the same lane whether the policy is compiled with no leg resolver or with a leg's roster (whose faces say only which
301
+ * parameters a tool carries).
226
302
  */
227
- export declare function domainRuleSubjectOf(toolName: string, args: unknown): string | undefined;
303
+ export declare function ruleLaneOf(tool: string, content: string): RuleLane;
228
304
  /** The value a name-grammar tool's call carries in its name argument — the string every NAME rule is read against, the one a
229
- * `Skill` call is resolved by — or undefined (not a name-grammar tool; no such argument; not a string). */
305
+ * `Skill` call is resolved by — or undefined (not a name-grammar tool; no such argument; not a string; the empty string, which
306
+ * names no value: an empty and an omitted argument are one call to every reader, as they are to the tool that runs it). */
230
307
  export declare function nameRuleSubjectOf(toolName: string, args: unknown): string | undefined;
231
308
  /** The rule WORDS a call is judged under, once each: for every name the call answers to (the model's spelling, the wire
232
309
  * name, the other aliases that resolve to it), the word its rules are written in — a shell-face name's is the command
@@ -238,7 +315,7 @@ export declare function laneToolNamesOf(req: Pick<import("./tool-policy.js").Too
238
315
  /** The match words a persisted rule is stored with, spelled once: {@link PersistedRuleMatch} is derived from this
239
316
  * tuple (each form is documented there). A store backend that checks a stored row's `match` reads this value
240
317
  * rather than keeping its own list. */
241
- export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
318
+ export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "pattern", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
242
319
  /**
243
320
  * Match forms, one family per grammar (`prefix` and `wildcard` are one predicate):
244
321
  * · `exact` — admits the one string the rule spells.
@@ -252,6 +329,12 @@ export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildc
252
329
  * (`Bash(cd /tmp && adb pull:*)`): the trailing-star form deliberately has no compound reading
253
330
  * (see {@link parseRuleText}), because upstream's own trailing-star pattern is inert on a
254
331
  * compound and importing/minting one as a chain licence would grant what nobody approved.
332
+ * · `pattern` — the PATTERN spelling (`Bash(git * main)`): any other unescaped `*` in the content, the reference's
333
+ * wildcard. `command` is the folded pattern as written (stars and `\*` escapes kept); `*` is any text, newlines
334
+ * included, `\*` a literal star, a `/` then `**` then `/` also matches one `/`. It reaches ONE simple command, matched whole:
335
+ * an allow against the command's spelling, a deny / ask against each program run's words
336
+ * ({@link programRunReachOf}); never a chain — its body is one command, and a compound is covered segment
337
+ * by segment. No allow leaves the program open (a `*` in the first word) or opens an interpreter's arguments.
255
338
  * · `subpath` — the directory form (design/382 §2.2): `Tool(//abs-dir/**)`, reaching every path under
256
339
  * one absolute directory. Never admits any command; its one predicate is {@link directoryRuleAdmits}.
257
340
  * As an ALLOW it exists on the two face tools ({@link PATH_RULE_FACES}); as a deny/ask on every
@@ -270,7 +353,7 @@ export type PersistedRuleMatch = (typeof PERSISTED_RULE_MATCHES)[number];
270
353
  * Where a rule applies — design/382 §4.1, the THREE consent dimensions.
271
354
  *
272
355
  * · `global` — the personal-global dimension: this OWNER's rules, everywhere (the bucket is already
273
- * per-owner, {@link import("./permission-rule-store.js").RuleOwner}). The member keeps its historical
356
+ * per-owner, {@link import("./rule-owner.js").RuleOwner}). The member keeps its historical
274
357
  * spelling on purpose: renaming it `personal-global` would be a no-benefit migration of every stored
275
358
  * row; the "personal" half lives in documentation and card wording, not in the wire byte.
276
359
  * · `project` — applies ONLY inside `root`. `root` is expected to be already canonicalized (realpath)
@@ -527,6 +610,19 @@ export declare const SHELL_RESERVED_WORDS: ReadonlySet<string>;
527
610
  * misled.
528
611
  */
529
612
  export declare const SUGGESTION_LEXICON: readonly string[];
613
+ /**
614
+ * THE spelling of a content rule on a call's tool under one behavior — its rule word and grammar with a placeholder for the
615
+ * content, never a rule minted for the call — or undefined: the tool takes no content rule (the catalog gives it no grammar,
616
+ * whatever face a leg mounts it with), and the whole-tool entry is the only rule it has. The command grammar's `Bash(<command>)`
617
+ * for a tool on the shell face (`Monitor` too: a command rule is written on the command word); a name tool's own spelling
618
+ * ({@link nameRuleFormOf}); a host tool's `<Tool>(domain:<host>)`; a path tool's — a TIGHTENING on the tool's own word
619
+ * (`Write(<path>)` reaches the tool it is written on), a GRANT on the face tool whose allow column holds the call's face
620
+ * (`Read(<path>)` for a read, `Edit(<path>)` for a write: a path allow exists on the two face tools of {@link PATH_RULE_FACES}
621
+ * only). Read off the dispatch every reader shares ({@link ruleToolGrammarOf}, {@link callPathFaceOf}) and spelled by
622
+ * {@link formatRuleText}; every sentence that offers a rule's shape (a compile refusal's way out, the dontAsk refusal's remedy)
623
+ * reads it.
624
+ */
625
+ export declare function ruleShapeOf(call: ToolCallLike, behavior: RuleBehavior): string | undefined;
530
626
  /**
531
627
  * Render a peer- or file-controlled value for a DISCLOSURE line (a warning, a refusal message, an
532
628
  * operator log). Takes `unknown` on purpose: most of these values are typed but arrive off a wire or a
@@ -600,6 +696,13 @@ export declare function renderUntrustedCommandText(text: unknown, maxLen?: numbe
600
696
  * Not part of the package's public surface — an internal screen for lane entry points.
601
697
  */
602
698
  export declare function hasUnrenderableCharacters(text: string): boolean;
699
+ /**
700
+ * A rule spelling's content as a content rule, or undefined when the spelling names its WHOLE tool: no content (`Bash`,
701
+ * `Bash()`, `Bash(*)` — the syntax's reading), or a command content that folds to the lone `*` (`Bash( * )`): the command
702
+ * grammar folds its spacing, so that spelling is `Bash(*)` and never a pattern. The one reading every lane asks — the
703
+ * store, the entry lists, the rule policy — so a spelling of the whole tool is answered as the whole tool wherever it is written.
704
+ */
705
+ export declare function ruleContentOf(parsed: ParsedPermissionRule): string | undefined;
603
706
  /**
604
707
  * Parse one rule text into its canonical shape, or refuse it with a reason.
605
708
  *
@@ -624,10 +727,25 @@ export declare function parseRuleText(text: string, behavior: RuleBehavior): {
624
727
  * `subpath` the command is the lexical-normal absolute directory (one leading slash), re-spelled in the
625
728
  * double-slash directory form; for `path` it is the pattern as spelled. */
626
729
  export declare function formatRuleText(command: string, match: PersistedRuleMatch, tool: PersistedRuleTool): string;
627
- /** Does a name rule reach this name? `name`: equal; `name_prefix`: begins with it (no boundary — the reference's `startsWith`).
628
- * A rule of any other family reaches no name. */
730
+ /** Does a name rule reach this name, spelling against spelling? `name`: equal; `name_prefix`: begins with it (no boundary — the
731
+ * reference's `startsWith`). A rule of any other family reaches no name. The comparison {@link nameRuleReach} makes for a row
732
+ * whose values are not resolved against a set. */
629
733
  export declare function nameRuleAdmits(rule: Pick<PersistedRule, "match" | "command">, name: string): boolean;
630
- /** Does a domain rule reach this host (as {@link domainRuleSubjectOf} reads it)? `host`: equal; `subdomain`: a name ending in
734
+ /** How a name rule meets a call ({@link nameRuleReach}). `unread`: the call's face carries no value set for a row that needs one. */
735
+ export type NameRuleReach = "reached" | "not_reached" | "unread";
736
+ /**
737
+ * THE predicate of a name rule over one call's value — every reader of a name rule (the rule policy, the lists, the person's
738
+ * stored rows) asks it. An open or keyed row compares spellings ({@link nameRuleAdmits}). A MOUNTED row (`Agent`) resolves the
739
+ * rule's value and the call's through the one resolver ({@link canonicalNameValue}) against the set the call's face carries
740
+ * (`values`, the mounted tool's `nameValues`): both one entry ⇒ reached iff the same one; a rule value the fold lands on several
741
+ * entries with ⇒ a deny or an ask reaches every one of them and an allow none (an operand is never resolved to one of several);
742
+ * a side that resolves to none ⇒ the two spellings compared exactly (an unknown rule value never reaches a resolved call); no
743
+ * set ⇒ `unread` — which type the call runs cannot be read, so a deny refuses, an ask asks a person, and an allow grants nothing.
744
+ */
745
+ export declare function nameRuleReach(rule: Pick<PersistedRule, "tool" | "behavior" | "match" | "command">, name: string, values: readonly string[] | undefined): NameRuleReach;
746
+ /** Why a call is unread against a mounted row's rule ({@link nameRuleReach} `unread`) — the sentence every reader carries. */
747
+ export declare function nameValuesUnreadReason(tool: string): string;
748
+ /** Does a domain rule reach this host (as `hostOfUrl` reads it)? `host`: equal; `subdomain`: a name ending in
631
749
  * `.<domain>` with at least one label before it and no empty label. A rule of any other family reaches no host. */
632
750
  export declare function domainRuleAdmits(rule: Pick<PersistedRule, "match" | "command">, host: string): boolean;
633
751
  /**
@@ -696,7 +814,7 @@ export declare function pathRuleReachOf(rule: Pick<PersistedRule, "match" | "com
696
814
  * reaches lies at or below the head, so a spelling of the head that the environment resolves elsewhere (a link, a
697
815
  * firmlink, `/var` → `/private/var`) is a second spelling of everything the rule reaches — the deny tables judge the
698
816
  * rule at both ({@link import("../tools/fs/read-deny.js").withRuleRowsWhereTheyLead}; the reference's "physical twin"
699
- * of a rule prefix, cli280.js 9766583). The head may be the bare anchor (`/`, a drive or share root — `Read(/**)` at a
817
+ * of a rule prefix). The head may be the bare anchor (`/`, a drive or share root — `Read(/**)` at a
700
818
  * drive root): an environment can resolve a drive or share root elsewhere. `undefined`: the pattern needs a base the
701
819
  * call does not supply (the rule then reads `unreadable`, a reach, everywhere), or a directory rule names the bare
702
820
  * anchor (it admits nothing).
@@ -787,6 +905,15 @@ export declare function programRunReachOf(rule: Pick<PersistedRule, "match" | "c
787
905
  /** The boolean face of {@link programRunReachOf}: `reached` only. The shadow view and the pins that
788
906
  * assert a reach read this; a lane that must fail closed on `unreadable` reads the outcome. */
789
907
  export declare function ruleReachesProgramRun(rule: Pick<PersistedRule, "match" | "command">, command: string): boolean;
908
+ /**
909
+ * Could the run this pattern names be one of `programs` (each its word or words, then anything)? The program is read as the
910
+ * read station reads it — past the launchers and wrappers in front of it (`nice`, `timeout 5`, `command`, `doas`, `env`,
911
+ * …: {@link readProgramPosition}) and by basename (`/usr/bin/python` runs `python`) — and the words from it on are read as
912
+ * the run receives them (quotes off), in lower case as the auto-mode strip reads every rule
913
+ * ({@link import("./allow-entry.js").autoStripped}). A program word the pattern leaves open (a star in it), or a run whose
914
+ * program cannot be read, could be any of them.
915
+ */
916
+ export declare function commandPatternMayRun(body: string, programs: readonly string[]): boolean;
790
917
  /** The breadth-warning codes, spelled once: {@link EditedRuleBreadthWarning}'s `code` is derived from this tuple,
791
918
  * and a consent record's `edited.warnings` stores exactly these words (its readback refuses any other). */
792
919
  export declare const EDITED_RULE_BREADTH_WARNING_CODES: readonly ["broad_prefix", "compound_prefix"];
@@ -820,7 +947,8 @@ export interface EditedRuleBreadthWarning {
820
947
  * and a SUBPATH rule is not this classifier's subject (no command reach at all). The two
821
948
  * reach-bearing forms take the same two questions: `prefix` (colon-star) and `wildcard`
822
949
  * (trailing space-star, #510 — match-equivalent reach on a single-command body; its grammar has no
823
- * chain reading, so only the single-token question can fire for it).
950
+ * chain reading, so only the single-token question can fire for it), and `pattern` (the pattern form: one command, its
951
+ * first word star-free in an allow, so neither question fires for an allow pattern today).
824
952
  * MAINTENANCE DUTY, stated where it binds: every match form with PREFIX REACH belongs here — a
825
953
  * new reach-bearing member added to {@link PersistedRuleMatch} owes this classifier its arm, judged
826
954
  * by the same "single token / chain body" questions (an exact-only form never warns).
@@ -1083,36 +1211,68 @@ export declare function adjudicatePersistedPathRules(rules: readonly PersistedRu
1083
1211
  readonly tighten?: TargetViews;
1084
1212
  readonly allow?: TargetViews;
1085
1213
  }, anchorsOf: (rule: PersistedRule) => PathRuleBases, leads: ReadonlyMap<string, string | undefined>): PersistedRuleVerdict | undefined;
1214
+ /** The call a persisted name rule is judged on — the request itself: its arguments (the one string it names is read off them,
1215
+ * `nameRuleSubjectOf`; a mounted row's argument arm reads them too) and its face (a mounted tool's values, the tool's reading). */
1216
+ export interface PersistedNameCall {
1217
+ readonly args: unknown;
1218
+ readonly face?: {
1219
+ readonly nameValues?: readonly string[];
1220
+ } | undefined;
1221
+ }
1086
1222
  /**
1087
1223
  * The name-family sibling of {@link adjudicatePersistedRules}: the same precedence walk over the rules of one name tool
1088
- * ({@link NAME_RULE_FACES}), judged on the one string the call names (`nameRuleSubjectOf`). A rule of the tool speaks for the call
1089
- * when it is live, of this behavior, in scope ({@link eligiblePersisted}, the one predicate) and {@link nameRuleAdmits} the name; the
1090
- * first behavior in {@link RULE_BEHAVIORS_BY_PRECEDENCE} whose rules speak decides, the first table-order rule of it is the answer.
1091
- * Every behavior is judged with the one predicate — a name has no "program run" the tightening direction could read wider.
1092
- * A call that names nothing (read as the tool reads it): on a bare-spelling tool it is reached by no rule; on a KEYED tool it
1093
- * cannot be read against the key's rules ({@link keyedValueAbsentReason}) and is REFUSED — a deny verdict standing on the
1094
- * first eligible deny row of the key, else its first ask row (an ask a person could approve would let a deny be approved
1224
+ * ({@link NAME_RULE_FACES}), judged on the call itself (`request`): the one string it names (`nameRuleSubjectOf`) and, for a
1225
+ * mounted row, the value set its face carries. A rule of the tool speaks for the call when it is live, of this behavior, in scope
1226
+ * ({@link eligiblePersisted}, the one predicate) and reaches the call — a tightening of a mounted row by its argument arm
1227
+ * ({@link mountedArgumentArmOf}, judged by `paramRuleReaches`) or by its value ({@link nameRuleReach}); the first behavior in
1228
+ * {@link RULE_BEHAVIORS_BY_PRECEDENCE} whose rules speak decides, the first table-order rule of it is the answer. A call a
1229
+ * mounted row cannot be read against (`unread`: no value set on the face) is REFUSED by the first such deny row and asked in the
1230
+ * fail-closed form (`unreadable`) by the first such ask row; no allow row reaches it.
1231
+ * A call that names nothing (read as the tool reads it): on an open-set tool it is reached by no rule; on a closed-set tool it
1232
+ * cannot be read against the tool's rules ({@link nameValueAbsentReason}) and is REFUSED — a deny verdict standing on the
1233
+ * first eligible deny row of the tool, else its first ask row (an ask a person could approve would let a deny be approved
1095
1234
  * past) — and no allow row reaches it.
1096
1235
  */
1097
1236
  export declare function adjudicatePersistedNameRules(rules: readonly PersistedRule[], call: {
1098
1237
  tool: string;
1099
- name: string | undefined;
1238
+ request: PersistedNameCall;
1100
1239
  cwd: string | undefined;
1101
1240
  sessionId?: string;
1102
1241
  scopeIdentity?: ScopeRootIdentity;
1103
1242
  }): PersistedRuleVerdict | undefined;
1104
1243
  /**
1105
- * The domain-family sibling of {@link adjudicatePersistedNameRules}: the rules of one domain tool ({@link DOMAIN_RULE_FACES})
1106
- * judged on the host the call fetches ({@link domainRuleSubjectOf}) by {@link domainRuleAdmits}; the first table-order rule
1107
- * that is eligible and admits the host is the answer. The grammar has an allow form only, so only an allow can speak.
1244
+ * The host the domain rules of one call are judged on, per direction (`callHostTargetOf`): `tighten` for a deny and an ask
1245
+ * (the protective reading), `grant` for an allow (the declared reading). Absent ⇒ the call has no URL slot in that direction.
1246
+ */
1247
+ export interface CallHosts {
1248
+ readonly tighten: HostReading | undefined;
1249
+ readonly grant: HostReading | undefined;
1250
+ }
1251
+ /**
1252
+ * The domain-family sibling of {@link adjudicatePersistedNameRules}: the same precedence walk (deny > ask > allow) over the rules of
1253
+ * one host tool, each behavior judged on its direction's host ({@link CallHosts}) by {@link domainRuleAdmits}; the first behavior
1254
+ * whose eligible rules speak decides, the first table-order rule of it is the answer. A call whose host cannot be read (a URL
1255
+ * that does not parse, is not http(s), carries credentials, or names a host that does not read back as itself) is REFUSED by the
1256
+ * tool's first eligible deny row, whatever host that row names, and otherwise ASKED by its first eligible ask row in the
1257
+ * fail-closed form (`unreadable`, never a matched ask); no allow row reaches it, and with no deny or ask row it is reached by
1258
+ * nothing.
1108
1259
  */
1109
1260
  export declare function adjudicatePersistedDomainRules(rules: readonly PersistedRule[], call: {
1110
1261
  tool: string;
1111
- host: string | undefined;
1262
+ hosts: CallHosts;
1112
1263
  cwd: string | undefined;
1113
1264
  sessionId?: string;
1114
1265
  scopeIdentity?: ScopeRootIdentity;
1115
1266
  }): PersistedRuleVerdict | undefined;
1267
+ /**
1268
+ * The ONE offer a host tool's approval card carries: the exact rule for the host the call reaches (`WebFetch(domain:<host>)`, the
1269
+ * reference's "don't ask again for <host>" row), or undefined when no rule spells exactly that host (the round-trip law: the
1270
+ * canonical text, parsed back as an allow, must be the exact host rule over the very host). Never a `*.` rule: it would widen past
1271
+ * the host shown.
1272
+ */
1273
+ export declare function suggestRuleForHost(tool: string, host: string): Extract<RuleOffer, {
1274
+ kind: "single";
1275
+ }> | undefined;
1116
1276
  /**
1117
1277
  * The ONE offer a name tool's approval card carries: the exact rule for the name the call carries (`Skill(<name>)`, the reference's
1118
1278
  * "don't ask again for <skill>" row), or undefined when no rule spells exactly that name (the round-trip law: the canonical text,
@@ -1297,6 +1457,15 @@ export type RuleOffer = {
1297
1457
  */
1298
1458
  readonly uncoveredDetail?: readonly UncoveredSegmentDetail[];
1299
1459
  };
1460
+ /** The offer discriminants as a value: the `kind` words of {@link RuleOffer} and of the consent record's own option form
1461
+ * (`RuleOffer2`, which stores the same choice by candidate index), each union fenced to the tuple in both directions
1462
+ * ({@link RuleOfferKindsCoverEveryArm} / {@link RuleOfferArmsCoverEveryKind} here, their twins beside `RuleOffer2`).
1463
+ * The engine's offer reader and record check read it; a backend's offer or record shape reads it too. */
1464
+ export declare const RULE_OFFER_KINDS: readonly ["single", "batch"];
1465
+ /** Compile fence: an arm whose `kind` is not in {@link RULE_OFFER_KINDS} turns the argument into that word. */
1466
+ export type RuleOfferKindsCoverEveryArm = AssertAllKeysHandled<Exclude<RuleOffer["kind"], (typeof RULE_OFFER_KINDS)[number]>>;
1467
+ /** Compile fence, the other direction: a word in {@link RULE_OFFER_KINDS} that no arm carries. */
1468
+ export type RuleOfferArmsCoverEveryKind = AssertAllKeysHandled<Exclude<(typeof RULE_OFFER_KINDS)[number], RuleOffer["kind"]>>;
1300
1469
  /** The uncovered-segment reason words, spelled once: {@link UncoveredSegmentDetail}'s `reason` is derived from this
1301
1470
  * tuple, {@link UNCOVERED_SEGMENT_REASON_BASELINE} is keyed by it, and a consent record's reason rows are read
1302
1471
  * against it. */