@sema-agent/core 7.48.0 → 7.49.1

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 (421) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +38 -31
  51. package/dist/core/arg-summary.d.ts +21 -28
  52. package/dist/core/arg-summary.js +235 -88
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +94 -65
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +43 -11
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +21 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp.d.ts +4 -0
  101. package/dist/core/mcp.js +70 -43
  102. package/dist/core/memory-engine/content-origin.js +2 -14
  103. package/dist/core/memory-engine/engine.d.ts +32 -22
  104. package/dist/core/memory-engine/engine.js +103 -55
  105. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  106. package/dist/core/memory-engine/file-backend.js +37 -252
  107. package/dist/core/memory-engine/index.d.ts +1 -1
  108. package/dist/core/memory-engine/index.js +1 -1
  109. package/dist/core/memory-engine/layout.d.ts +139 -9
  110. package/dist/core/memory-engine/layout.js +350 -7
  111. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  112. package/dist/core/memory-engine/scope-contract.js +8 -0
  113. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  114. package/dist/core/memory-engine/session-incarnation.js +5 -2
  115. package/dist/core/memory-engine/types.d.ts +10 -1
  116. package/dist/core/memory.js +5 -17
  117. package/dist/core/model-seat.d.ts +4 -4
  118. package/dist/core/model-seat.js +1 -1
  119. package/dist/core/mounted-mcp.d.ts +57 -0
  120. package/dist/core/mounted-mcp.js +19 -0
  121. package/dist/core/namespaced-rule-name.d.ts +29 -0
  122. package/dist/core/namespaced-rule-name.js +52 -0
  123. package/dist/core/park-selfcheck.d.ts +1 -1
  124. package/dist/core/park-selfcheck.js +16 -6
  125. package/dist/core/path-guard-rows.d.ts +99 -0
  126. package/dist/core/path-guard-rows.js +45 -0
  127. package/dist/core/path-identity.d.ts +22 -16
  128. package/dist/core/path-identity.js +10 -10
  129. package/dist/core/path-rule-binding.d.ts +2 -1
  130. package/dist/core/path-rule-binding.js +3 -1
  131. package/dist/core/pause-registry.d.ts +16 -2
  132. package/dist/core/pause-registry.js +6 -0
  133. package/dist/core/permission-rule-consent.js +0 -7
  134. package/dist/core/permission-rule-model.d.ts +68 -24
  135. package/dist/core/permission-rule-model.js +105 -24
  136. package/dist/core/permission-rule-store.js +2 -2
  137. package/dist/core/permission-rules.d.ts +3 -30
  138. package/dist/core/permission-rules.js +4 -54
  139. package/dist/core/read-root-candidate.d.ts +1 -3
  140. package/dist/core/read-root-candidate.js +4 -15
  141. package/dist/core/real-approval.d.ts +4 -3
  142. package/dist/core/retired-keys.d.ts +13 -0
  143. package/dist/core/retired-keys.js +14 -0
  144. package/dist/core/roles.d.ts +2 -3
  145. package/dist/core/roles.js +15 -6
  146. package/dist/core/runner/assemble-result.d.ts +0 -7
  147. package/dist/core/runner/assemble-result.js +19 -31
  148. package/dist/core/runner/caller-roster.d.ts +78 -0
  149. package/dist/core/runner/caller-roster.js +219 -0
  150. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  151. package/dist/core/runner/checkpoint-scope.js +2 -2
  152. package/dist/core/runner/child-tree.js +2 -2
  153. package/dist/core/runner/contracts.d.ts +68 -35
  154. package/dist/core/runner/decide-continuation.d.ts +51 -3
  155. package/dist/core/runner/decide-continuation.js +76 -21
  156. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  157. package/dist/core/runner/denial-limit-arms.js +11 -9
  158. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  159. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  160. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  161. package/dist/core/runner/finish-reason-seat.js +40 -0
  162. package/dist/core/runner/gate-exit.d.ts +44 -32
  163. package/dist/core/runner/gate-exit.js +112 -25
  164. package/dist/core/runner/inherited-ask-grants.js +6 -4
  165. package/dist/core/runner/mcp-redial.d.ts +3 -3
  166. package/dist/core/runner/mcp-redial.js +3 -4
  167. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  168. package/dist/core/runner/permission-rule-lanes.js +5 -4
  169. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  170. package/dist/core/runner/prepare-artifact.js +2 -1
  171. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  172. package/dist/core/runner/prepare-ask-lane.js +12 -6
  173. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  174. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  175. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  176. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  177. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  178. package/dist/core/runner/prepare-config-doors.js +10 -5
  179. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  180. package/dist/core/runner/prepare-defer-classify.js +5 -3
  181. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  182. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  183. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  184. package/dist/core/runner/prepare-gate-stations.js +9 -7
  185. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  186. package/dist/core/runner/prepare-hands-readface.js +7 -7
  187. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  188. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  189. package/dist/core/runner/prepare-listings.d.ts +7 -24
  190. package/dist/core/runner/prepare-listings.js +4 -5
  191. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  192. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  193. package/dist/core/runner/prepare-memory.d.ts +6 -0
  194. package/dist/core/runner/prepare-memory.js +13 -13
  195. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  196. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  198. package/dist/core/runner/prepare-park-ask.js +17 -10
  199. package/dist/core/runner/prepare-policy-chain.js +24 -44
  200. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  201. package/dist/core/runner/prepare-project-context.js +3 -4
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  204. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  205. package/dist/core/runner/prepare-run-refs.js +2 -1
  206. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  207. package/dist/core/runner/prepare-safety-scan.js +1 -2
  208. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  209. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  210. package/dist/core/runner/prepare-task.d.ts +1 -1
  211. package/dist/core/runner/prepare-task.js +67 -56
  212. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  213. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  214. package/dist/core/runner/resume-apply.js +7 -14
  215. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  216. package/dist/core/runner/resume-internals-and-config.js +2 -2
  217. package/dist/core/runner/resume-policy-outcome.js +5 -32
  218. package/dist/core/runner/resume-review-outcome.js +4 -1
  219. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  220. package/dist/core/runner/retired-runner-deps.js +10 -1
  221. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  222. package/dist/core/runner/run-brain-sinks.js +5 -2
  223. package/dist/core/runner/run-harness-handlers.js +29 -36
  224. package/dist/core/runner/run-leg.d.ts +0 -2
  225. package/dist/core/runner/run-leg.js +32 -33
  226. package/dist/core/runner/run-terminal-adoption.js +4 -3
  227. package/dist/core/runner/runtask.js +8 -8
  228. package/dist/core/runner/session-rule-policy.js +5 -5
  229. package/dist/core/runner/stream-settle-backstop.js +7 -4
  230. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  231. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  232. package/dist/core/runner/terminal-account.d.ts +48 -0
  233. package/dist/core/runner/terminal-account.js +186 -0
  234. package/dist/core/runner/tool-end-body.d.ts +54 -17
  235. package/dist/core/runner/tool-end-body.js +27 -2
  236. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  237. package/dist/core/runner/tool-face-overlay.js +6 -4
  238. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  239. package/dist/core/runner/tool-occurrence.js +123 -0
  240. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  241. package/dist/core/runner/tool-progress-lane.js +25 -34
  242. package/dist/core/runner/tool-turn-repair-seat.d.ts +28 -4
  243. package/dist/core/runner/tool-turn-repair-seat.js +36 -13
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/secret-env.d.ts +16 -5
  249. package/dist/core/secret-env.js +23 -63
  250. package/dist/core/sensitive-path-policy.d.ts +19 -18
  251. package/dist/core/sensitive-path-policy.js +73 -49
  252. package/dist/core/session-reconcile.d.ts +3 -0
  253. package/dist/core/session-reconcile.js +5 -4
  254. package/dist/core/session-store.d.ts +5 -0
  255. package/dist/core/session-store.js +12 -0
  256. package/dist/core/session.d.ts +13 -0
  257. package/dist/core/shared-memory/normalize.d.ts +17 -4
  258. package/dist/core/shared-memory/normalize.js +7 -7
  259. package/dist/core/shell-lexer.js +5 -4
  260. package/dist/core/shell-wrapper-projection.js +1 -1
  261. package/dist/core/skill-grant.js +1 -1
  262. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  263. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  264. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  265. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  266. package/dist/core/stub-env.d.ts +2 -0
  267. package/dist/core/stub-env.js +1 -0
  268. package/dist/core/synthetic-read-verdict.js +2 -2
  269. package/dist/core/task-event.d.ts +59 -5
  270. package/dist/core/task-result.d.ts +1 -1
  271. package/dist/core/task-spec.d.ts +42 -9
  272. package/dist/core/terminal-cause.d.ts +94 -11
  273. package/dist/core/tighten-task-spec.d.ts +5 -4
  274. package/dist/core/tighten-task-spec.js +20 -25
  275. package/dist/core/tool-catalog-entries.d.ts +5 -7
  276. package/dist/core/tool-catalog-entries.js +14 -15
  277. package/dist/core/tool-face.d.ts +47 -0
  278. package/dist/core/tool-face.js +5 -0
  279. package/dist/core/tool-model-gate.d.ts +5 -5
  280. package/dist/core/tool-name-aliases.d.ts +26 -2
  281. package/dist/core/tool-name-aliases.js +13 -0
  282. package/dist/core/tool-name-list.d.ts +30 -0
  283. package/dist/core/tool-name-list.js +55 -0
  284. package/dist/core/tool-name-readings.d.ts +1 -9
  285. package/dist/core/tool-name-readings.js +1 -3
  286. package/dist/core/tool-policy.d.ts +195 -85
  287. package/dist/core/tool-policy.js +165 -380
  288. package/dist/core/tool-registry.d.ts +44 -1
  289. package/dist/core/tool-registry.js +26 -0
  290. package/dist/core/tool-roster.d.ts +19 -1
  291. package/dist/core/tool-roster.js +21 -2
  292. package/dist/core/tool-spec-members.d.ts +45 -0
  293. package/dist/core/tool-spec-members.js +169 -0
  294. package/dist/core/tool-spec.d.ts +46 -8
  295. package/dist/core/tools.d.ts +6 -2
  296. package/dist/core/tools.js +8 -4
  297. package/dist/core/untrusted-egress.js +29 -26
  298. package/dist/core/untrusted-text.d.ts +13 -10
  299. package/dist/core/untrusted-text.js +6 -44
  300. package/dist/core/workflow-journal-store.d.ts +4 -1
  301. package/dist/core/write-protect.d.ts +65 -29
  302. package/dist/core/write-protect.js +235 -177
  303. package/dist/engine/compaction/compaction.d.ts +2 -2
  304. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  305. package/dist/engine/execution-env/node-execution-env.js +16 -38
  306. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  307. package/dist/engine/execution-env/symlink-chain.js +32 -0
  308. package/dist/engine/harness/types.d.ts +7 -0
  309. package/dist/engine/llm/tool-turns.d.ts +3 -0
  310. package/dist/engine/llm/tool-turns.js +1 -0
  311. package/dist/engine/llm/types.d.ts +59 -23
  312. package/dist/engine/loop/agent-loop.js +16 -2
  313. package/dist/engine/session/memory-repo.js +11 -3
  314. package/dist/engine/session/repo-utils.d.ts +8 -0
  315. package/dist/engine/session/repo-utils.js +13 -0
  316. package/dist/index.d.ts +20 -23
  317. package/dist/index.js +17 -20
  318. package/dist/internal/harness.d.ts +1 -1
  319. package/dist/internal/harness.js +1 -1
  320. package/dist/internal/llm.d.ts +2 -2
  321. package/dist/internal/llm.js +1 -1
  322. package/dist/orchestration/governance-baseline-validity.js +1 -1
  323. package/dist/orchestration/run-spec.js +3 -3
  324. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  325. package/dist/orchestration/run-workflow-tool.js +38 -78
  326. package/dist/orchestration/workflow-governance.d.ts +21 -25
  327. package/dist/orchestration/workflow-governance.js +38 -78
  328. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  329. package/dist/orchestration/workflow-primitives.js +5 -12
  330. package/dist/orchestration/workflow-types.d.ts +1 -1
  331. package/dist/orchestration/workflow.d.ts +61 -11
  332. package/dist/orchestration/workflow.js +189 -117
  333. package/dist/scenarios/full-body.d.ts +1 -1
  334. package/dist/shell/lex.d.ts +0 -21
  335. package/dist/shell/lex.js +250 -68
  336. package/dist/shell/shell-words.d.ts +35 -0
  337. package/dist/shell/shell-words.js +65 -0
  338. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  339. package/dist/stores/file/checkpoint-store.js +5 -2
  340. package/dist/stores/file/index.d.ts +0 -8
  341. package/dist/stores/file/index.js +0 -12
  342. package/dist/stores/file/session-store.d.ts +3 -0
  343. package/dist/stores/file/session-store.js +44 -19
  344. package/dist/tools/artifact/artifact-tool.js +2 -0
  345. package/dist/tools/fs/bash-program-position.d.ts +12 -4
  346. package/dist/tools/fs/bash-program-position.js +32 -9
  347. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  348. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  349. package/dist/tools/fs/containment-face.d.ts +4 -0
  350. package/dist/tools/fs/containment-face.js +3 -0
  351. package/dist/tools/fs/fs-shared.d.ts +10 -0
  352. package/dist/tools/fs/fs-shared.js +18 -0
  353. package/dist/tools/fs/fs-write.js +4 -2
  354. package/dist/tools/fs/index.d.ts +1 -1
  355. package/dist/tools/fs/program-read-model.d.ts +46 -20
  356. package/dist/tools/fs/program-read-model.js +50 -20
  357. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  358. package/dist/tools/fs/program-read-model.rows.js +16 -15
  359. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  360. package/dist/tools/fs/read-deny-home.js +35 -49
  361. package/dist/tools/fs/read-deny.d.ts +23 -22
  362. package/dist/tools/fs/read-deny.js +114 -89
  363. package/dist/tools/fs/removal-targets.d.ts +56 -23
  364. package/dist/tools/fs/removal-targets.js +65 -87
  365. package/dist/tools/fs/safety.d.ts +29 -22
  366. package/dist/tools/fs/safety.js +17 -11
  367. package/dist/tools/fs/search.js +10 -8
  368. package/dist/tools/fs/shell-read-argv.js +1 -1
  369. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  370. package/dist/tools/fs/shell-read-bindings.js +324 -86
  371. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  372. package/dist/tools/fs/shell-read-builtins.js +43 -0
  373. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  374. package/dist/tools/fs/shell-read-check.js +67 -43
  375. package/dist/tools/fs/shell-read-establish.js +6 -6
  376. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  377. package/dist/tools/fs/shell-read-functions.js +29 -0
  378. package/dist/tools/fs/shell-read-judge.d.ts +51 -18
  379. package/dist/tools/fs/shell-read-judge.js +40 -4
  380. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  381. package/dist/tools/fs/shell-read-plan.js +118 -113
  382. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  383. package/dist/tools/fs/shell-read-start.js +16 -9
  384. package/dist/tools/fs/shell-read-word.js +4 -0
  385. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  386. package/dist/tools/fs/shell-read-workdir.js +281 -0
  387. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  388. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  389. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  390. package/dist/tools/fs/shell-reentry-text.js +3 -11
  391. package/dist/tools/task-list.d.ts +1 -2
  392. package/dist/tools/web.js +1 -1
  393. package/package.json +4 -1
  394. package/test/export-surface.snapshot.json +107 -143
  395. package/wire-changes/core@7.49.0.json +4765 -0
  396. package/dist/agents/teacher.d.ts +0 -159
  397. package/dist/agents/teacher.js +0 -577
  398. package/dist/agents/team.d.ts +0 -226
  399. package/dist/agents/team.js +0 -257
  400. package/dist/core/strategy-store.d.ts +0 -238
  401. package/dist/core/strategy-store.js +0 -253
  402. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  403. package/dist/orchestration/builtin-workflows.js +0 -159
  404. package/dist/scenarios/env.d.ts +0 -40
  405. package/dist/scenarios/env.js +0 -39
  406. package/dist/scenarios/scenario-registry.d.ts +0 -110
  407. package/dist/scenarios/scenario-registry.js +0 -140
  408. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  409. package/dist/scenarios/teacher-quickstart.js +0 -12
  410. package/dist/stores/cc/lockfile.d.ts +0 -10
  411. package/dist/stores/cc/lockfile.js +0 -98
  412. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  413. package/dist/stores/cc/mailbox-store.js +0 -255
  414. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  415. package/dist/stores/cc/roster-adapter.js +0 -117
  416. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  417. package/dist/stores/cc/sidecar-transcript.js +0 -264
  418. package/dist/stores/cc/task-list-store.d.ts +0 -2
  419. package/dist/stores/cc/task-list-store.js +0 -125
  420. package/dist/stores/file/strategy-store.d.ts +0 -97
  421. package/dist/stores/file/strategy-store.js +0 -341
@@ -1,8 +1,9 @@
1
1
  import { userInfo } from "node:os";
2
- import { canonicalizeTarget, isAbsolutePathForm, joinForFamily, normalizeAbsPathLexically, pathFamilyOf } from "./safety.js";
2
+ import { canonicalizeTarget, isAbsoluteForFamily, joinForFamily, normalizeAbsPathLexically, pathFamilyOf } from "./safety.js";
3
3
  import { DEFAULT_GATE_AWAIT_TIMEOUT_MS, withGateTimeout } from "../../core/gate-bounded-await.js";
4
4
  import { thrownText } from "../../core/thrown-value.js";
5
5
  import { agentConfigDirTail } from "../../core/agent-config-dir.js";
6
+ import { validatePath } from "../../core/effective-path-target.js";
6
7
  import { isRootedReadDenyPattern, readDenyPatternRun, readDenyRunHead } from "./read-deny.js";
7
8
  export const AUXILIARY_HOME_PROBE_MS = 2_000;
8
9
  const said = new Set();
@@ -36,8 +37,9 @@ function valueText(v) {
36
37
  function accountHomeOf() {
37
38
  try {
38
39
  const home = userInfo().homedir;
39
- if (typeof home === "string" && isAbsolutePathForm(home))
40
- return { state: "home", home };
40
+ const valid = validatePath(home, { intent: "validate-coordinate" });
41
+ if (valid !== undefined)
42
+ return { state: "home", home: valid };
41
43
  sayOnce("bad_value", `read-deny homes: the account home lookup answered ${valueText(home)}, not an absolute path — home-anchored read-deny rows are placed under the environment's declared home only.`);
42
44
  return { state: "none" };
43
45
  }
@@ -49,8 +51,7 @@ function accountHomeOf() {
49
51
  }
50
52
  }
51
53
  function declaredHomeOf(env) {
52
- const home = env.homeDir;
53
- return home !== undefined && isAbsolutePathForm(home) ? home : undefined;
54
+ return validatePath(env.homeDir, { intent: "validate-coordinate" });
54
55
  }
55
56
  function declaredReadDenyHomesAnswered(env) {
56
57
  const home = declaredHomeOf(env);
@@ -105,56 +106,43 @@ function sayAuxiliary(what, subject = "auxiliary") {
105
106
  }
106
107
  sayOnce("auxiliary", `read-deny homes: a home beside the environment's declared home did not answer its probes within ${AUXILIARY_HOME_PROBE_MS} ms (${what}) — its home-anchored read-deny rows sit at its spelling only, and a path through an alias of it is judged as spelled, until the next placement.`);
107
108
  }
108
- export async function readDenyHomeLinksOf(env, entries, homes, signal, deadline) {
109
- const rows = [];
110
- for (const { pattern, caseSensitive } of entries) {
111
- const { homeAnchored, run } = readDenyPatternRun(pattern);
112
- if (!homeAnchored)
113
- continue;
114
- const head = literalHeadOf(run);
115
- if (head.length === 0)
116
- continue;
117
- const spelled = homes.map((home) => normalizeAbsPathLexically(joinForFamily(pathFamilyOf({ root: home }), home, head)));
118
- rows.push({ pattern, caseSensitive: caseSensitive === true, spelled, anchored: spelled });
119
- }
120
- return await linkedLocationsOf(env, rows, signal, deadline);
109
+ export async function readDenyLinksOf(env, entries, anchor, signal, deadline) {
110
+ return await linkedLocationsOf(env, anchoredRowsOf(entries, anchor), signal, deadline);
121
111
  }
122
112
  const ROOT = "/";
123
- export async function readDenyRootLinksOf(env, entries, signal, deadline) {
124
- const rows = [];
125
- for (const { pattern, caseSensitive } of entries) {
126
- if (!isRootedReadDenyPattern(pattern))
127
- continue;
128
- const head = literalHeadOf(pattern);
129
- if (head.length === 0)
130
- continue;
131
- const spelled = [normalizeAbsPathLexically(joinForFamily(pathFamilyOf({ root: ROOT }), ROOT, head))];
132
- rows.push({ pattern, caseSensitive: caseSensitive === true, spelled, anchored: spelled });
133
- }
134
- return await linkedLocationsOf(env, rows, signal, deadline);
135
- }
136
113
  function literalHeadOf(run) {
137
114
  return run.split("/").filter(Boolean).slice(0, readDenyRunHead(run)).join("/");
138
115
  }
139
- export async function readDenyConfigRootLinksOf(env, entries, roots, signal, deadline) {
140
- return await linkedLocationsOf(env, configRootRowsOf(entries, roots), signal, deadline);
141
- }
142
- function configRootRowsOf(entries, roots) {
116
+ function anchoredRowsOf(entries, anchor) {
117
+ const places = anchor.at === "home" ? anchor.homes : anchor.at === "root" ? [ROOT] : anchor.roots;
143
118
  const rows = [];
144
119
  for (const { pattern, caseSensitive } of entries) {
145
- const { homeAnchored, run } = readDenyPatternRun(pattern);
146
- const tail = homeAnchored ? agentConfigDirTail(run, caseSensitive === true) : undefined;
147
- if (tail === undefined)
120
+ const head = rowHeadOf(pattern, caseSensitive === true, anchor);
121
+ if (head === undefined)
148
122
  continue;
149
- const head = literalHeadOf(tail);
150
- const spelled = roots.map((root) => normalizeAbsPathLexically(head.length === 0 ? root : joinForFamily(pathFamilyOf({ root }), root, head)));
151
- rows.push({ pattern, caseSensitive: caseSensitive === true, spelled, anchored: [] });
123
+ const spelled = places.map((place) => normalizeAbsPathLexically(head.length === 0 ? place : joinForFamily(pathFamilyOf({ root: place }), place, head)));
124
+ rows.push({ pattern, caseSensitive: caseSensitive === true, spelled, anchored: anchor.at === "unanchored" ? [] : spelled });
152
125
  }
153
126
  return rows;
154
127
  }
128
+ function rowHeadOf(pattern, caseSensitive, anchor) {
129
+ if (anchor.at === "root") {
130
+ const head = isRootedReadDenyPattern(pattern) ? literalHeadOf(pattern) : "";
131
+ return head.length > 0 ? head : undefined;
132
+ }
133
+ const { homeAnchored, run } = readDenyPatternRun(pattern);
134
+ if (!homeAnchored)
135
+ return undefined;
136
+ if (anchor.at === "unanchored") {
137
+ const tail = agentConfigDirTail(run, caseSensitive);
138
+ return tail === undefined ? undefined : literalHeadOf(tail);
139
+ }
140
+ const head = literalHeadOf(run);
141
+ return head.length > 0 ? head : undefined;
142
+ }
155
143
  function configRootSpelledLinks(entries, roots) {
156
144
  const out = new Map();
157
- for (const { pattern, spelled } of configRootRowsOf(entries, roots))
145
+ for (const { pattern, spelled } of anchoredRowsOf(entries, { at: "unanchored", roots }))
158
146
  out.set(pattern, [...new Set(spelled)]);
159
147
  return out;
160
148
  }
@@ -259,9 +247,7 @@ async function readAuxiliaryHome(env, home, opts, signal) {
259
247
  typeof identity === "function" ? chainAbove(env, identity, spelled.canonical, signal, deadline) : Promise.resolve({ ancestors: [], whole: true }),
260
248
  opts.entries === undefined
261
249
  ? Promise.resolve({ linked: new Map(), whole: true })
262
- : opts.configRoot === true
263
- ? readDenyConfigRootLinksOf(env, opts.entries, place, signal, deadline)
264
- : readDenyHomeLinksOf(env, opts.entries, place, signal, deadline),
250
+ : readDenyLinksOf(env, opts.entries, opts.configRoot === true ? { at: "unanchored", roots: place } : { at: "home", homes: place }, signal, deadline),
265
251
  ]);
266
252
  reading = { place, chain, linked: heads.linked, answered: chain.whole && heads.whole };
267
253
  }
@@ -337,7 +323,7 @@ function homeViewSourceOver(env, auxiliary) {
337
323
  };
338
324
  return {
339
325
  async of(path, opts) {
340
- if (typeof identity !== "function" || (declared === undefined && auxiliary.length === 0) || !isAbsolutePathForm(path))
326
+ if (typeof identity !== "function" || (declared === undefined && auxiliary.length === 0) || !isAbsoluteForFamily("own", path))
341
327
  return undefined;
342
328
  const spelled = normalizeAbsPathLexically(path);
343
329
  const view = await viewOf(spelled, opts?.leaf === "file");
@@ -365,7 +351,7 @@ export function sayPlacementLost() {
365
351
  }
366
352
  function readAuxiliaryHomes(env, homes, opts, signal) {
367
353
  const declared = declaredHomeOf(env);
368
- return [...new Set(homes.filter((h) => isAbsolutePathForm(h) && !isDeclared(declared, h)))].map((home) => readAuxiliaryHome(env, home, opts, signal));
354
+ return [...new Set(homes.filter((h) => isAbsoluteForFamily("own", h) && !isDeclared(declared, h)))].map((home) => readAuxiliaryHome(env, home, opts, signal));
369
355
  }
370
356
  export function homeViewsAt(env, homes) {
371
357
  return homeViewSourceOver(env, readAuxiliaryHomes(env, homes, {}));
@@ -380,7 +366,7 @@ export async function placeReadDenyAtHome(env, compile, homes, signal, configRoo
380
366
  const entries = compile([]).entries;
381
367
  const declared = declaredHomeOf(env);
382
368
  const relocated = configRoot === undefined ? undefined : readAuxiliaryHome(env, configRoot, { entries, configRoot: true }, signal);
383
- const rooted = readDenyRootLinksOf(env, entries, signal);
369
+ const rooted = readDenyLinksOf(env, entries, { at: "root" }, signal);
384
370
  const heldAnywhere = async (whole) => {
385
371
  const linked = new Map();
386
372
  for (const map of [(await relocated)?.linked, (await rooted).linked])
@@ -400,7 +386,7 @@ export async function placeReadDenyAtHome(env, compile, homes, signal, configRoo
400
386
  declaredAt = [...new Set([...own, ...ownSpellings.spellings])];
401
387
  }
402
388
  const auxiliary = readAuxiliaryHomes(env, listed.homes, { entries }, signal);
403
- const [heads, readings, root, rootedHeads] = await Promise.all([readDenyHomeLinksOf(env, entries, declaredAt, signal), Promise.all(auxiliary), relocated, rooted]);
389
+ const [heads, readings, root, rootedHeads] = await Promise.all([readDenyLinksOf(env, entries, { at: "home", homes: declaredAt }, signal), Promise.all(auxiliary), relocated, rooted]);
404
390
  const at = [...new Set([...declaredAt, ...readings.flatMap((r) => r.place)])];
405
391
  const linked = new Map();
406
392
  for (const map of [heads.linked, ...readings.map((r) => r.linked), ...(root === undefined ? [] : [root.linked]), rootedHeads.linked]) {
@@ -1,3 +1,4 @@
1
+ import { type PathGuardFold, type PathGuardRow, type PathRowsHit, type TargetViews } from "../../core/path-guard-rows.js";
1
2
  /**
2
3
  * One deny entry: a `/`-separated run of path SEGMENTS. `*` matches any run of non-separator
3
4
  * characters within one segment and is the ONLY metacharacter (everything else is literal). The run
@@ -86,28 +87,12 @@ export type PathRowReach = {
86
87
  export interface JudgedPathRow extends PathRuleDenyRow {
87
88
  readonly reach?: (absolutePath: string) => PathRowReach;
88
89
  }
89
- /** A call's target as a judgment reads it: the absolute spellings of its views (lexical, canonical, the leaf chain's hops —
90
- * any order the caller holds), or `unreadable` when the call names a target this reading cannot locate. */
91
- export interface TargetViews {
92
- readonly spellings: readonly string[];
93
- readonly unreadable?: string;
94
- }
95
- /** What {@link pathRowsReach} found: the row, the view it met there (absent on an unreadable hold), and — when nothing was
96
- * reached and some row could not be judged — the reason of the first such row. */
97
- export interface PathRowsHit<R> {
98
- readonly row: R;
99
- readonly view?: string;
100
- readonly unreadable?: string;
101
- }
102
90
  /**
103
- * THE one judgment of path rule rows over a call's target, for the gate's rule lanes and the tool's deny table alike: rows
104
- * outer, views inner — the first row (in the caller's order) that some view reaches is the answer, so the rule a refusal
105
- * names does not depend on which view happened to meet it. `tighten` (deny / ask): any view reaching the row reaches it; a
106
- * row that cannot be judged (or a target that cannot be read) is held and answered only when no row reaches. `allow`: a
107
- * row admits the call only when it admits EVERY view (a link out of an allowed directory is not admitted through its
108
- * spelling); an unreadable target is admitted by nothing.
91
+ * Rule rows judged by THE one judgment ({@link judgePathRows}): each rule row read as a guarded row whose reach over a view
92
+ * is the rule's own reach over the view's spelling (never exemptible — a rule says exactly where it reaches). Same rows
93
+ * outer, views inner, same tighten / allow law as every other row; the hit names the rule row itself.
109
94
  */
110
- export declare function pathRowsReach<R extends JudgedPathRow>(rows: readonly R[], views: TargetViews, direction: "tighten" | "allow"): PathRowsHit<R> | undefined;
95
+ export declare function judgeRuleRows<R extends JudgedPathRow>(rows: readonly R[], views: TargetViews, direction: "tighten" | "allow"): PathRowsHit<R> | undefined;
111
96
  /** The locations a row is also judged at (each leading part of its HEAD: the anchor's children down to the head itself,
112
97
  * a share's root for a UNC head) — what a leg resolves once, for every row whose head it holds. */
113
98
  export declare function ruleHeadParts(rows: readonly Pick<PathRuleDenyRow, "head">[]): string[];
@@ -129,10 +114,23 @@ export declare function rowsWhereTheyLead<R extends JudgedPathRow>(rows: readonl
129
114
  export declare function locationLeadsTo(path: string, leads: ReadonlyMap<string, string | undefined>): string | undefined;
130
115
  /** {@link rowsWhereTheyLead} with each part resolved by `leadsTo` (the leg's resolution; each part once). */
131
116
  export declare function withRuleRowsWhereTheyLead<R extends JudgedPathRow>(rows: readonly R[], leadsTo: (head: string) => Promise<string | undefined>): Promise<R[]>;
117
+ /** A rule row as a row of the one table: its name is the rule text, its reach the rule's own over a view's spelling. */
118
+ export declare function ruleGuardRow<R extends JudgedPathRow>(rule: R): PathGuardRow & {
119
+ readonly rule: R;
120
+ };
121
+ /** A compiled segment-glob row as a row of the one table (`faces`, `polarity`, `exemptible` and `origin` are the table's). */
122
+ export declare function segmentGuardRow(pat: CompiledSegmentPattern, columns: {
123
+ readonly faces: readonly DenyFace[];
124
+ readonly polarity: "deny" | "ask";
125
+ readonly exemptible: boolean;
126
+ readonly fold: PathGuardFold;
127
+ readonly origin: PathGuardRow["origin"];
128
+ readonly tier?: string;
129
+ }): PathGuardRow;
132
130
  /**
133
131
  * The WRITE face of the deny table: the rule rows whose faces include `write` — the judge the shell station reads for a
134
132
  * command's write targets (a redirection, `tee`, `sed -i`, `cp` / `mv` / `touch` / `mkdir` / `rm` operands). Same row
135
- * type, same judgment ({@link pathRowsReach}) as the read face's rule rows; a hit names the row by its rule text.
133
+ * type, same judgment ({@link judgePathRows}) as the read face's rows; a hit names the row by its rule text.
136
134
  */
137
135
  export interface WriteDenyMatcher {
138
136
  /** Which face this judge is — the write tools' path resolution reads it to word and code the refusal as a write. */
@@ -412,6 +410,9 @@ export declare function compileSegmentPattern(raw: string, fold: "none" | "ascii
412
410
  export declare function matchSegmentPatterns(path: string, compiled: readonly CompiledSegmentPattern[], opts?: {
413
411
  readonly aliasResolved?: boolean;
414
412
  }): string | null;
413
+ /** One entry's refusal under the deny list's entry law ({@link normalizeEntry}, the compiler's own), or `undefined` when the
414
+ * entry is lawful — the law read without compiling, for a door that judges a list before anything folds it. */
415
+ export declare function readDenyEntryProblem(entry: unknown, layer: string): string | undefined;
415
416
  /** Is a canonical pattern ROOTED — placed at the filesystem root ({@link ReadDenyEntry})? Only {@link canonicalReadDenyPattern}
416
417
  * puts a leading `/` on a canonical pattern, so the text is the whole answer. */
417
418
  export declare function isRootedReadDenyPattern(canonical: string): boolean;
@@ -445,7 +446,7 @@ export declare function checkedReadDenyHomes(homes: unknown, seat?: string): rea
445
446
  * home: a home-anchored entry then matches its run anywhere — a row that cannot be placed holds wider, never narrower.
446
447
  *
447
448
  * `linked` — where a home-anchored or a rooted row's LITERAL HEAD ({@link readDenyRunHead}) really leads, keyed by the row's
448
- * pattern: the canonical locations a mount resolved (`readDenyHomeLinksOf` / `readDenyRootLinksOf`, read-deny-home.ts) where
449
+ * pattern: the canonical locations a mount resolved (`readDenyLinksOf`, read-deny-home.ts) where
449
450
  * one of the head's segments is a link (`~/.sema` linked into a dotfiles directory; `/app` a link to `/data/app`). The row is placed at each location too —
450
451
  * the same row, the same name in every refusal — with the rest of its run matched below it. The read faces judge
451
452
  * canonical keys, so every spelling that reaches the linked file meets the row there. Absolute locations only.
@@ -1,6 +1,8 @@
1
1
  import { sliceHeadSafe, sliceTailSafe } from "../../core/surrogate-safe-slice.js";
2
- import { isAbsolutePathForm, normalizeAbsPathLexically, pathFamilyOf, pathIdentityOf, spellingOfIdentity } from "./safety.js";
2
+ import { isAbsoluteForFamily, normalizeAbsPathLexically, pathFamilyOf, pathIdentityOf, spellingOfIdentity } from "./safety.js";
3
3
  import { PROBE_REASON_MAX } from "../../core/untrusted-text.js";
4
+ import { validatePath } from "../../core/effective-path-target.js";
5
+ import { judgePathRows } from "../../core/path-guard-rows.js";
4
6
  export const READ_DENY_HOME_WORD = "~";
5
7
  export function readDenyPatternRun(pattern) {
6
8
  const segments = pattern.split("/").filter(Boolean);
@@ -15,28 +17,12 @@ export const DENY_FACES = Object.freeze(["read", "write"]);
15
17
  const REACHED = { reach: "reached" };
16
18
  const NOT_REACHED = { reach: "not_reached" };
17
19
  const reachOf = (row, spelled) => row.reach?.(spelled) ?? (row.reaches(spelled) ? REACHED : NOT_REACHED);
18
- export function pathRowsReach(rows, views, direction) {
19
- if (direction === "allow") {
20
- if (views.unreadable !== undefined || views.spellings.length === 0)
21
- return undefined;
22
- for (const row of rows)
23
- if (views.spellings.every((v) => reachOf(row, v).reach === "reached"))
24
- return { row };
25
- return undefined;
26
- }
27
- let held;
28
- for (const row of rows) {
29
- if (views.unreadable !== undefined)
30
- held ??= { row, unreadable: views.unreadable };
31
- for (const view of views.spellings) {
32
- const r = reachOf(row, view);
33
- if (r.reach === "reached")
34
- return { row, view };
35
- if (r.reach === "unreadable")
36
- held ??= { row, unreadable: r.reason };
37
- }
38
- }
39
- return held;
20
+ export function judgeRuleRows(rows, views, direction) {
21
+ const hit = judgePathRows(rows.map(ruleGuard), views, direction);
22
+ return hit === undefined ? undefined : { ...hit, row: hit.row.rule };
23
+ }
24
+ function ruleGuard(rule) {
25
+ return { rule, reach: (view) => reachOf(rule, view.path) };
40
26
  }
41
27
  export function ruleHeadParts(rows) {
42
28
  const out = new Set();
@@ -130,34 +116,42 @@ function rowLedTo(row, head, at) {
130
116
  : {}),
131
117
  };
132
118
  }
133
- function ruleRowsHit(rows, face, spellings) {
134
- const onFace = rows.filter((r) => r.faces.includes(face));
135
- return onFace.length === 0 ? undefined : pathRowsReach(onFace, { spellings }, "tighten");
119
+ export function ruleGuardRow(rule) {
120
+ return { rule, name: rule.rule, grammar: { kind: "rule", rule: rule.rule }, polarity: "deny", faces: rule.faces, placement: "anywhere", fold: "exact", exemptible: false, origin: "rule", reach: (view) => reachOf(rule, view.path) };
121
+ }
122
+ export function segmentGuardRow(pat, columns) {
123
+ const placement = pat.anchors === undefined ? "anywhere" : pat.rootedOnly !== true ? "home" : pat.anchors.length === 1 && pat.anchors[0].length === 0 ? "rooted" : { below: `/${(pat.anchors[0] ?? []).join("/")}` };
124
+ return {
125
+ name: pat.raw,
126
+ grammar: { kind: "segment-glob", run: pat.raw },
127
+ placement,
128
+ ...columns,
129
+ reach: (view) => (segmentRowMeets(pat, segmentReadingsOf(view.path, view.aliasResolved === true)) ? REACHED : NOT_REACHED),
130
+ };
131
+ }
132
+ function denyTableHit(rows, views) {
133
+ const hit = judgePathRows(rows, views, "tighten");
134
+ if (hit === undefined)
135
+ return null;
136
+ const view = hit.view ?? views.views[0]?.path;
137
+ return { pattern: hit.row.name, ...(view !== undefined ? { matchedView: view } : {}) };
138
+ }
139
+ function denyTargetViews(canonicalKey, lexicalView, opts) {
140
+ const views = [{ path: canonicalKey, kind: "canonical", ...(opts?.aliasResolved === true ? { aliasResolved: true } : {}) }];
141
+ if (lexicalView !== undefined)
142
+ views.push({ path: lexicalView, kind: "lexical" });
143
+ for (const hop of opts?.hops ?? [])
144
+ views.push({ path: hop, kind: "hop" });
145
+ return { views };
136
146
  }
137
147
  export function compileWriteDeny(rules = []) {
138
148
  const ruleRows = rules.filter((r) => r.faces.includes("write"));
149
+ const rows = ruleRows.map(ruleGuardRow);
139
150
  const matchPath = (path) => {
140
- const hit = ruleRowsHit(ruleRows, "write", [path]);
141
- return hit === undefined ? null : { pattern: hit.row.rule };
151
+ const hit = denyTableHit(rows, { views: [{ path, kind: "lexical" }] });
152
+ return hit === null ? null : { pattern: hit.pattern };
142
153
  };
143
- return { face: "write", ruleRows, matchPath, matchTarget: (canonicalKey, lexicalView, opts) => matchTargetOver(() => null, ruleRows, "write", canonicalKey, lexicalView, opts) };
144
- }
145
- function matchTargetOver(segmentPath, ruleRows, face, canonicalKey, lexicalView, opts) {
146
- const canonical = segmentPath(canonicalKey, opts);
147
- if (canonical !== null)
148
- return { ...canonical, matchedView: canonicalKey };
149
- if (lexicalView !== undefined) {
150
- const lexical = segmentPath(lexicalView);
151
- if (lexical !== null)
152
- return { ...lexical, matchedView: lexicalView };
153
- }
154
- for (const hop of opts?.hops ?? []) {
155
- const viaHop = segmentPath(hop);
156
- if (viaHop !== null)
157
- return { ...viaHop, matchedView: hop };
158
- }
159
- const hit = ruleRowsHit(ruleRows, face, [canonicalKey, ...(lexicalView !== undefined ? [lexicalView] : []), ...(opts?.hops ?? [])]);
160
- return hit === undefined ? null : { pattern: hit.row.rule, matchedView: hit.view ?? canonicalKey };
154
+ return { face: "write", ruleRows, matchPath, matchTarget: (canonicalKey, lexicalView, opts) => denyTableHit(rows, denyTargetViews(canonicalKey, lexicalView, opts)) };
161
155
  }
162
156
  export function readDenySeat(matcher) {
163
157
  const entries = [...(matcher?.entries ?? []).map((e) => e.pattern), ...(matcher?.ruleRows ?? []).map((r) => r.rule)];
@@ -320,28 +314,43 @@ export function compileSegmentPattern(raw, fold) {
320
314
  return { raw, segments, foldAscii: fold === "ascii" };
321
315
  }
322
316
  export function matchSegmentPatterns(path, compiled, opts) {
323
- const views = segmentViewsOf(path, opts);
324
- const rooted = isAbsolutePathForm(path);
325
- const lowered = new Map();
326
- for (const pat of compiled) {
327
- for (const view of views) {
328
- const segs = pat.foldAscii ? (lowered.get(view) ?? lowered.set(view, view.map(asciiLower)).get(view)) : view;
329
- const n = pat.segments.length;
330
- const runAt = (i) => i + n <= segs.length && pat.segments.every((re, j) => re.test(segs[i + j] ?? ""));
331
- if (pat.anchors !== undefined && rooted) {
332
- for (const anchor of pat.anchors)
333
- if (anchor.every((a, j) => segs[j] === a) && runAt(anchor.length))
334
- return pat.raw;
335
- continue;
336
- }
337
- if (pat.rootedOnly === true)
338
- continue;
339
- for (let i = 0; i + n <= segs.length; i++)
340
- if (runAt(i))
341
- return pat.raw;
317
+ const readings = segmentReadingsOf(path, opts?.aliasResolved === true);
318
+ for (const pat of compiled)
319
+ if (segmentRowMeets(pat, readings))
320
+ return pat.raw;
321
+ return null;
322
+ }
323
+ const SEGMENT_READINGS = new Map();
324
+ function segmentReadingsOf(path, aliasResolved) {
325
+ const key = `${aliasResolved ? "1" : "0"}${path}`;
326
+ const known = SEGMENT_READINGS.get(key);
327
+ if (known !== undefined)
328
+ return known;
329
+ const views = segmentViewsOf(path, aliasResolved ? { aliasResolved } : undefined);
330
+ const readings = { views, lowered: views.map((v) => v.map(asciiLower)), rooted: isAbsoluteForFamily("own", path) };
331
+ if (SEGMENT_READINGS.size >= 512)
332
+ SEGMENT_READINGS.clear();
333
+ SEGMENT_READINGS.set(key, readings);
334
+ return readings;
335
+ }
336
+ function segmentRowMeets(pat, readings) {
337
+ const n = pat.segments.length;
338
+ const views = pat.foldAscii ? readings.lowered : readings.views;
339
+ for (const segs of views) {
340
+ const runAt = (i) => i + n <= segs.length && pat.segments.every((re, j) => re.test(segs[i + j] ?? ""));
341
+ if (pat.anchors !== undefined && readings.rooted) {
342
+ for (const anchor of pat.anchors)
343
+ if (anchor.every((a, j) => segs[j] === a) && runAt(anchor.length))
344
+ return true;
345
+ continue;
342
346
  }
347
+ if (pat.rootedOnly === true)
348
+ continue;
349
+ for (let i = 0; i + n <= segs.length; i++)
350
+ if (runAt(i))
351
+ return true;
343
352
  }
344
- return null;
353
+ return false;
345
354
  }
346
355
  function segmentViewsOf(path, opts) {
347
356
  const literalSegs = path.split(/[\\/]/).filter(Boolean);
@@ -386,7 +395,7 @@ function rowMeetsPath(pat, segs, rooted) {
386
395
  return false;
387
396
  }
388
397
  function rowAtOrBelowOf(rows, path) {
389
- const rooted = isAbsolutePathForm(path);
398
+ const rooted = isAbsoluteForFamily("own", path);
390
399
  const views = segmentViewsOf(path);
391
400
  for (const pat of rows) {
392
401
  for (const view of views)
@@ -401,6 +410,15 @@ function homeAnchorSegments(home) {
401
410
  function rgGlobEscape(pattern) {
402
411
  return pattern.replace(/[?[\]{}]/g, (c) => `[${c}]`);
403
412
  }
413
+ export function readDenyEntryProblem(entry, layer) {
414
+ try {
415
+ normalizeEntry(entry, layer);
416
+ return undefined;
417
+ }
418
+ catch (e) {
419
+ return e.message;
420
+ }
421
+ }
404
422
  function normalizeEntry(entry, layer) {
405
423
  const shape = typeof entry === "string" ? { pattern: entry, caseSensitive: false } : entry;
406
424
  if (typeof shape !== "object" || shape === null || typeof shape.pattern !== "string") {
@@ -446,7 +464,7 @@ export function persistedReadDenyEntryProblem(e) {
446
464
  return null;
447
465
  }
448
466
  export function checkedReadDenyHomes(homes, seat = "readDenyHomes") {
449
- if (!Array.isArray(homes) || !homes.every((h) => typeof h === "string" && isAbsolutePathForm(h))) {
467
+ if (!Array.isArray(homes) || !homes.every((h) => validatePath(h, { intent: "validate-coordinate" }) !== undefined)) {
450
468
  let shown;
451
469
  try {
452
470
  shown = JSON.stringify(homes) ?? String(homes);
@@ -469,10 +487,19 @@ export function compileReadDeny(additions = [], layer = "additions", builtin, ru
469
487
  seen.add(key);
470
488
  normalized.push(e);
471
489
  };
472
- for (const row of resolveReadDenyBuiltins(builtin))
473
- push(normalizeEntry(row.pattern, "built-in"));
474
- for (const entry of additions)
475
- push(normalizeEntry(entry, layer));
490
+ const columns = new Map();
491
+ for (const row of resolveReadDenyBuiltins(builtin)) {
492
+ const e = normalizeEntry(row.pattern, "built-in");
493
+ push(e);
494
+ if (!columns.has(e.pattern))
495
+ columns.set(e.pattern, { origin: "builtin", tier: row.tier });
496
+ }
497
+ for (const entry of additions) {
498
+ const e = normalizeEntry(entry, layer);
499
+ push(e);
500
+ if (!columns.has(e.pattern))
501
+ columns.set(e.pattern, { origin: "addition" });
502
+ }
476
503
  const homeSegments = [...new Set(checkedReadDenyHomes(homes))].map(homeAnchorSegments);
477
504
  const compiled = normalized.map((e) => {
478
505
  const { homeAnchored, run } = readDenyPatternRun(e.pattern);
@@ -502,40 +529,38 @@ export function compileReadDeny(additions = [], layer = "additions", builtin, ru
502
529
  }
503
530
  });
504
531
  const judged = linkedPlacements.length === 0 ? compiled : [...compiled, ...linkedPlacements];
532
+ const segmentRows = judged.map((c) => {
533
+ const col = columns.get(c.raw);
534
+ return segmentGuardRow(c, { faces: ["read"], polarity: "deny", exemptible: false, fold: c.foldAscii ? "ascii" : "exact", origin: col?.origin ?? "addition", ...(col?.tier !== undefined ? { tier: col.tier } : {}) });
535
+ });
536
+ const tableRows = [...segmentRows, ...ruleRows.map(ruleGuardRow)];
505
537
  const rgExclusionGlobs = [];
506
538
  const rgProbeGlobs = [];
507
- normalized.forEach((e, i) => {
508
- if (compiled[i].anchors !== undefined)
509
- return;
510
- const flag = e.caseSensitive ? "--glob" : "--iglob";
511
- const g = rgGlobEscape(readDenyPatternRun(e.pattern).run);
539
+ for (const row of segmentRows) {
540
+ if (row.placement !== "anywhere" || !row.faces.includes("read") || row.grammar.kind !== "segment-glob")
541
+ continue;
542
+ const flag = row.fold === "exact" ? "--glob" : "--iglob";
543
+ const g = rgGlobEscape(readDenyPatternRun(row.grammar.run).run);
512
544
  rgExclusionGlobs.push({ flag, glob: `!**/${g}` }, { flag, glob: `!**/${g}/**` });
513
545
  rgProbeGlobs.push({ flag, glob: `**/${g}` }, { flag, glob: `**/${g}/**` });
514
- });
546
+ }
515
547
  const placed = judged.filter((c) => c.anchors !== undefined);
516
- const unexcludableUnder = (scope) => placed.length > 0 && (!isAbsolutePathForm(scope) || rowAtOrBelowOf(placed, normalizeAbsPathLexically(scope)) !== null);
548
+ const unexcludableUnder = (scope) => placed.length > 0 && (!isAbsoluteForFamily("own", scope) || rowAtOrBelowOf(placed, normalizeAbsPathLexically(scope)) !== null);
517
549
  const rowAtOrBelow = (path) => {
518
550
  const hit = rowAtOrBelowOf(judged, path);
519
551
  if (hit !== null)
520
552
  return { pattern: hit };
521
553
  return ruleRows.length === 0 ? null : { pattern: ruleRows[0].rule };
522
554
  };
523
- const segmentPath = (path, opts) => {
524
- const hit = matchSegmentPatterns(path, judged, opts);
525
- return hit === null ? null : { pattern: hit };
526
- };
527
555
  const matchPath = (path, opts) => {
528
- const hit = segmentPath(path, opts);
529
- if (hit !== null)
530
- return hit;
531
- const rule = ruleRows.length === 0 || opts?.walked === true ? undefined : ruleRowsHit(ruleRows, "read", [path]);
532
- return rule === undefined ? null : { pattern: rule.row.rule };
556
+ const hit = denyTableHit(opts?.walked === true ? segmentRows : tableRows, { views: [{ path, kind: "lexical", ...(opts?.aliasResolved === true ? { aliasResolved: true } : {}) }] });
557
+ return hit === null ? null : { pattern: hit.pattern };
533
558
  };
534
559
  return {
535
560
  entries: normalized,
536
561
  ...(ruleRows.length > 0 ? { ruleRows } : {}),
537
562
  matchPath,
538
- matchTarget: (canonicalKey, lexicalView, opts) => matchTargetOver(segmentPath, ruleRows, "read", canonicalKey, lexicalView, opts),
563
+ matchTarget: (canonicalKey, lexicalView, opts) => denyTableHit(tableRows, denyTargetViews(canonicalKey, lexicalView, opts)),
539
564
  rgExclusionGlobs,
540
565
  rgProbeGlobs,
541
566
  unexcludableUnder,