@sema-agent/core 7.15.0 → 7.17.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 (287) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/dist/agents/builtin-agents.d.ts +3 -3
  3. package/dist/agents/cross-session-envelope.d.ts +0 -1
  4. package/dist/agents/cross-session-envelope.js +0 -1
  5. package/dist/agents/peer-notices.d.ts +0 -9
  6. package/dist/agents/peer-notices.js +0 -63
  7. package/dist/agents/subagent.js +7 -15
  8. package/dist/brain/request-params.d.ts +2 -2
  9. package/dist/config/defaults.d.ts +0 -7
  10. package/dist/config/defaults.js +0 -2
  11. package/dist/core/artifact-host.d.ts +218 -0
  12. package/dist/core/artifact-host.js +92 -0
  13. package/dist/core/ask-origin.d.ts +29 -3
  14. package/dist/core/ask-origin.js +17 -9
  15. package/dist/core/ask-question.d.ts +25 -0
  16. package/dist/core/ask-question.js +4 -0
  17. package/dist/core/ask-unresolvable-notice.d.ts +30 -21
  18. package/dist/core/ask-unresolvable-notice.js +16 -8
  19. package/dist/core/auto-compaction.d.ts +10 -10
  20. package/dist/core/auto-mode-arming.d.ts +2 -2
  21. package/dist/core/background-agent-store.d.ts +5 -5
  22. package/dist/core/background-shell.d.ts +1 -1
  23. package/dist/core/checkpoint-execution-record.d.ts +0 -3
  24. package/dist/core/checkpoint-execution-record.js +0 -4
  25. package/dist/core/checkpoint-store.d.ts +71 -99
  26. package/dist/core/checkpoint-store.js +9 -16
  27. package/dist/core/context-edit.d.ts +36 -104
  28. package/dist/core/context-edit.js +37 -60
  29. package/dist/core/effective-path-target.d.ts +68 -8
  30. package/dist/core/effective-path-target.js +42 -30
  31. package/dist/core/engine-notice.d.ts +46 -32
  32. package/dist/core/env-budget.d.ts +31 -0
  33. package/dist/core/env-budget.js +39 -0
  34. package/dist/core/exec-output-tail.d.ts +5 -5
  35. package/dist/core/file-history-store.js +3 -6
  36. package/dist/core/fs-write-gate-policy.d.ts +1 -1
  37. package/dist/core/fs-write-gate-policy.js +3 -3
  38. package/dist/core/gate-lanes.js +9 -15
  39. package/dist/core/governance-codes.d.ts +1 -1
  40. package/dist/core/governance-codes.js +4 -0
  41. package/dist/core/hands-band.d.ts +1 -1
  42. package/dist/core/hooks.d.ts +18 -17
  43. package/dist/core/lsp-session.d.ts +1 -1
  44. package/dist/core/lsp.d.ts +1 -1
  45. package/dist/core/lsp.js +5 -4
  46. package/dist/core/mcp.d.ts +5 -5
  47. package/dist/core/mcp.js +4 -48
  48. package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
  49. package/dist/core/memory-engine/delegation-settlement.js +128 -39
  50. package/dist/core/memory-engine/engine.d.ts +9 -8
  51. package/dist/core/memory-engine/engine.js +115 -120
  52. package/dist/core/memory-engine/file-backend.d.ts +17 -5
  53. package/dist/core/memory-engine/file-backend.js +78 -34
  54. package/dist/core/memory-engine/index.d.ts +2 -2
  55. package/dist/core/memory-engine/index.js +2 -2
  56. package/dist/core/memory-engine/layout.d.ts +152 -54
  57. package/dist/core/memory-engine/layout.js +441 -104
  58. package/dist/core/memory-engine/types.d.ts +8 -3
  59. package/dist/core/memory-engine/types.js +5 -0
  60. package/dist/core/memory-recall.d.ts +0 -8
  61. package/dist/core/memory.d.ts +1 -1
  62. package/dist/core/oracle-isolation.js +2 -2
  63. package/dist/core/parent-spec-seat.d.ts +66 -0
  64. package/dist/core/parent-spec-seat.js +47 -0
  65. package/dist/core/permission-rule-model.d.ts +11 -6
  66. package/dist/core/permission-rule-model.js +53 -37
  67. package/dist/core/permission-rules.js +8 -3
  68. package/dist/core/protocol-naming.d.ts +2 -2
  69. package/dist/core/remote-env.d.ts +1 -1
  70. package/dist/core/retired-keys.d.ts +19 -0
  71. package/dist/core/retired-keys.js +15 -0
  72. package/dist/core/runner/abort-race.d.ts +3 -3
  73. package/dist/core/runner/active-skill-scope.d.ts +2 -2
  74. package/dist/core/runner/active-skill-scope.js +3 -3
  75. package/dist/core/runner/assemble-result.d.ts +42 -40
  76. package/dist/core/runner/assemble-result.js +5 -4
  77. package/dist/core/runner/checkpoint-scope.d.ts +4 -4
  78. package/dist/core/runner/clock-and-limits.d.ts +3 -3
  79. package/dist/core/runner/compaction-call-options.d.ts +35 -99
  80. package/dist/core/runner/compaction-knobs.d.ts +4 -4
  81. package/dist/core/runner/compaction-seams.d.ts +5 -5
  82. package/dist/core/runner/contracts.d.ts +232 -233
  83. package/dist/core/runner/decide-continuation.d.ts +6 -6
  84. package/dist/core/runner/denial-limit-arms.d.ts +8 -8
  85. package/dist/core/runner/derived-route-fallback.d.ts +2 -2
  86. package/dist/core/runner/gate-exit.d.ts +6 -6
  87. package/dist/core/runner/gate-exit.js +15 -1
  88. package/dist/core/runner/git-status-frame.d.ts +7 -7
  89. package/dist/core/runner/halt-attribution.d.ts +35 -0
  90. package/dist/core/runner/halt-attribution.js +16 -0
  91. package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
  92. package/dist/core/runner/memory-capture-optout.d.ts +1 -1
  93. package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
  94. package/dist/core/runner/memory-consolidation.d.ts +6 -8
  95. package/dist/core/runner/memory-consolidation.js +0 -1
  96. package/dist/core/runner/park-commit.d.ts +6 -6
  97. package/dist/core/runner/permission-rule-lanes.d.ts +19 -19
  98. package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
  99. package/dist/core/runner/prepare-artifact.d.ts +53 -0
  100. package/dist/core/runner/prepare-artifact.js +77 -0
  101. package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
  102. package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
  103. package/dist/core/runner/prepare-caps-and-workflow.d.ts +9 -7
  104. package/dist/core/runner/prepare-caps-and-workflow.js +2 -3
  105. package/dist/core/runner/prepare-config-doors.d.ts +24 -24
  106. package/dist/core/runner/prepare-config-doors.js +5 -2
  107. package/dist/core/runner/prepare-context-lane.d.ts +8 -8
  108. package/dist/core/runner/prepare-context-lane.js +2 -13
  109. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  110. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  111. package/dist/core/runner/prepare-file-history.d.ts +3 -3
  112. package/dist/core/runner/prepare-file-history.js +3 -52
  113. package/dist/core/runner/prepare-gate-stations.d.ts +5 -5
  114. package/dist/core/runner/prepare-hands-readface.d.ts +35 -38
  115. package/dist/core/runner/prepare-hands-readface.js +3 -2
  116. package/dist/core/runner/prepare-inherited-gate.d.ts +9 -6
  117. package/dist/core/runner/prepare-inherited-gate.js +7 -8
  118. package/dist/core/runner/prepare-listings.d.ts +3 -3
  119. package/dist/core/runner/prepare-lsp.d.ts +3 -3
  120. package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
  121. package/dist/core/runner/prepare-memory.d.ts +4 -6
  122. package/dist/core/runner/prepare-memory.js +10 -9
  123. package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
  124. package/dist/core/runner/prepare-park-ask.d.ts +6 -6
  125. package/dist/core/runner/prepare-policy-chain.d.ts +7 -7
  126. package/dist/core/runner/prepare-policy-chain.js +15 -30
  127. package/dist/core/runner/prepare-prompt-assembly.js +1 -1
  128. package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
  129. package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
  130. package/dist/core/runner/prepare-question-face.d.ts +4 -4
  131. package/dist/core/runner/prepare-run-refs.d.ts +11 -11
  132. package/dist/core/runner/prepare-safety-scan.d.ts +2 -2
  133. package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
  134. package/dist/core/runner/prepare-suspend-saga.js +0 -2
  135. package/dist/core/runner/prepare-task.d.ts +12 -12
  136. package/dist/core/runner/prepare-task.js +10 -9
  137. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
  138. package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
  139. package/dist/core/runner/prepare-wiring-manifest.js +9 -7
  140. package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
  141. package/dist/core/runner/remote-env-retry.d.ts +3 -3
  142. package/dist/core/runner/resume-admission.d.ts +1 -1
  143. package/dist/core/runner/resume-admission.js +2 -1
  144. package/dist/core/runner/resume-claim.d.ts +1 -1
  145. package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
  146. package/dist/core/runner/resume-internals-and-config.js +4 -0
  147. package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
  148. package/dist/core/runner/resume-preflight.d.ts +1 -1
  149. package/dist/core/runner/resume-review-outcome.d.ts +1 -1
  150. package/dist/core/runner/retired-runner-deps.d.ts +3 -0
  151. package/dist/core/runner/retired-runner-deps.js +7 -0
  152. package/dist/core/runner/run-brain-sinks.d.ts +1 -1
  153. package/dist/core/runner/run-clock-and-content.d.ts +4 -4
  154. package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
  155. package/dist/core/runner/run-git-lane.d.ts +1 -1
  156. package/dist/core/runner/run-harness-handlers.d.ts +2 -2
  157. package/dist/core/runner/run-harness-handlers.js +2 -3
  158. package/dist/core/runner/run-identity-wiring.d.ts +4 -4
  159. package/dist/core/runner/run-leg.d.ts +3 -3
  160. package/dist/core/runner/run-notification-lane.d.ts +2 -2
  161. package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
  162. package/dist/core/runner/run-settle-and-teardown.d.ts +5 -5
  163. package/dist/core/runner/run-settle-and-teardown.js +3 -1
  164. package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
  165. package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
  166. package/dist/core/runner/runtask.d.ts +14 -14
  167. package/dist/core/runner/session-file-state-replay.d.ts +3 -3
  168. package/dist/core/runner/session-file-state-replay.js +3 -3
  169. package/dist/core/runner/session-rule-policy.d.ts +2 -2
  170. package/dist/core/runner/session-rule-policy.js +3 -4
  171. package/dist/core/runner/steer-admission.d.ts +2 -2
  172. package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
  173. package/dist/core/runner/stream-halt-verbs.js +1 -1
  174. package/dist/core/runner/stream-reap.d.ts +1 -1
  175. package/dist/core/runner/stream-steer-verb.js +1 -4
  176. package/dist/core/runner/synthetic-tools.d.ts +8 -8
  177. package/dist/core/runner/teardown-bounded.d.ts +2 -2
  178. package/dist/core/runner/tool-defer-gate.d.ts +1 -1
  179. package/dist/core/runner/tool-disclosure.d.ts +33 -33
  180. package/dist/core/runner/tool-end-body.d.ts +3 -3
  181. package/dist/core/runner/tool-face-overlay.d.ts +2 -2
  182. package/dist/core/runner/tool-output-projection.d.ts +2 -2
  183. package/dist/core/runner/turn-attachments.d.ts +53 -53
  184. package/dist/core/runner/usage-accounting.d.ts +4 -4
  185. package/dist/core/runner/workspace-path.d.ts +1 -1
  186. package/dist/core/runner/workspace-path.js +3 -0
  187. package/dist/core/runner-deps.d.ts +30 -49
  188. package/dist/core/safe-notify.d.ts +1 -1
  189. package/dist/core/sensitive-path-policy.d.ts +1 -1
  190. package/dist/core/sensitive-path-policy.js +4 -4
  191. package/dist/core/session.d.ts +2 -2
  192. package/dist/core/skill-tool-specifier.d.ts +1 -1
  193. package/dist/core/skills-directory.d.ts +1 -1
  194. package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
  195. package/dist/core/strategy-store.d.ts +8 -11
  196. package/dist/core/task-event.d.ts +20 -17
  197. package/dist/core/task-limits.d.ts +1 -1
  198. package/dist/core/task-notification.d.ts +5 -5
  199. package/dist/core/task-registry-agent.d.ts +5 -5
  200. package/dist/core/task-registry-monitor.d.ts +2 -2
  201. package/dist/core/task-registry-shared.d.ts +27 -27
  202. package/dist/core/task-registry-shared.js +3 -13
  203. package/dist/core/task-registry.d.ts +8 -8
  204. package/dist/core/task-result.d.ts +37 -37
  205. package/dist/core/task-spec.d.ts +5 -5
  206. package/dist/core/task-stream.d.ts +16 -11
  207. package/dist/core/tool-catalog-entries.d.ts +1 -0
  208. package/dist/core/tool-catalog-entries.js +5 -0
  209. package/dist/core/tool-conformance.d.ts +0 -2
  210. package/dist/core/tool-conformance.js +1 -3
  211. package/dist/core/tool-errors.d.ts +5 -0
  212. package/dist/core/tool-errors.js +1 -0
  213. package/dist/core/tool-policy.d.ts +51 -22
  214. package/dist/core/tool-policy.js +28 -5
  215. package/dist/core/tool-result-budget.d.ts +1 -1
  216. package/dist/core/tool-result-store.d.ts +11 -11
  217. package/dist/core/tool-spec.d.ts +34 -38
  218. package/dist/core/tools.d.ts +2 -2
  219. package/dist/core/trace.d.ts +12 -15
  220. package/dist/core/untrusted-text.d.ts +1 -1
  221. package/dist/core/wiring-manifest.d.ts +4 -3
  222. package/dist/core/workflow-journal-store.d.ts +11 -11
  223. package/dist/engine/execution-env/node-execution-env.d.ts +3 -2
  224. package/dist/engine/execution-env/node-execution-env.js +4 -2
  225. package/dist/engine/harness/agent-harness.d.ts +47 -4
  226. package/dist/engine/harness/agent-harness.js +52 -9
  227. package/dist/engine/llm/types.d.ts +1 -1
  228. package/dist/engine/loop/agent-loop.js +15 -8
  229. package/dist/engine/loop/types.d.ts +5 -0
  230. package/dist/index.d.ts +21 -16
  231. package/dist/index.js +17 -12
  232. package/dist/internal/harness.d.ts +1 -0
  233. package/dist/orchestration/run-spec.d.ts +3 -0
  234. package/dist/orchestration/run-spec.js +3 -3
  235. package/dist/orchestration/run-workflow-tool.d.ts +12 -6
  236. package/dist/orchestration/run-workflow-tool.js +23 -5
  237. package/dist/orchestration/workflow-primitives.d.ts +4 -2
  238. package/dist/orchestration/workflow-primitives.js +1 -4
  239. package/dist/orchestration/workflow-types.d.ts +34 -4
  240. package/dist/orchestration/workflow-types.js +2 -0
  241. package/dist/orchestration/workflow.d.ts +39 -7
  242. package/dist/orchestration/workflow.js +234 -113
  243. package/dist/prompt-assembly/assemble.d.ts +2 -2
  244. package/dist/prompt-assembly/assemble.js +9 -9
  245. package/dist/prompt-assembly/composer.d.ts +6 -7
  246. package/dist/prompt-assembly/composer.js +10 -10
  247. package/dist/prompt-assembly/epoch.js +1 -1
  248. package/dist/prompt-assembly/event-registry.d.ts +0 -21
  249. package/dist/prompt-assembly/packs/sema-default.js +30 -30
  250. package/dist/prompt-assembly/types.d.ts +14 -14
  251. package/dist/prompts/coordinator.d.ts +0 -13
  252. package/dist/prompts/coordinator.js +0 -3
  253. package/dist/stores/file/checkpoint-store.js +1 -5
  254. package/dist/stores/file/file-history-store.js +2 -2
  255. package/dist/stores/file/permission-rule-store.d.ts +4 -35
  256. package/dist/stores/file/permission-rule-store.js +4 -148
  257. package/dist/tools/artifact/artifact-text.d.ts +62 -0
  258. package/dist/tools/artifact/artifact-text.js +68 -0
  259. package/dist/tools/artifact/artifact-tool.d.ts +52 -0
  260. package/dist/tools/artifact/artifact-tool.js +351 -0
  261. package/dist/tools/artifact/local-stub.d.ts +26 -0
  262. package/dist/tools/artifact/local-stub.js +296 -0
  263. package/dist/tools/fs/bash-readonly-classifier.d.ts +114 -48
  264. package/dist/tools/fs/bash-readonly-classifier.js +171 -60
  265. package/dist/tools/fs/encoding.d.ts +31 -40
  266. package/dist/tools/fs/fs-bash.d.ts +49 -45
  267. package/dist/tools/fs/fs-bash.js +19 -27
  268. package/dist/tools/fs/fs-pdf.d.ts +8 -8
  269. package/dist/tools/fs/fs-search-tools.d.ts +4 -4
  270. package/dist/tools/fs/fs-search-tools.js +5 -2
  271. package/dist/tools/fs/fs-shared.d.ts +146 -158
  272. package/dist/tools/fs/fs-shared.js +3 -11
  273. package/dist/tools/fs/fs-write.d.ts +8 -8
  274. package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
  275. package/dist/tools/fs/index.d.ts +78 -78
  276. package/dist/tools/fs/index.js +4 -1
  277. package/dist/tools/fs/notebook.d.ts +24 -25
  278. package/dist/tools/fs/pdf.d.ts +3 -3
  279. package/dist/tools/fs/read-deny.d.ts +22 -22
  280. package/dist/tools/fs/read-face.d.ts +21 -24
  281. package/dist/tools/fs/repo-map.d.ts +8 -8
  282. package/dist/tools/fs/safety.d.ts +233 -130
  283. package/dist/tools/fs/safety.js +131 -31
  284. package/dist/tools/fs/search.d.ts +63 -71
  285. package/dist/tools/fs/search.js +8 -6
  286. package/package.json +6 -2
  287. package/test/export-surface.snapshot.json +119 -39
@@ -4,11 +4,11 @@ import { type CwdRef } from "./fs-shared.js";
4
4
  import type { ReversibilityVerdict } from "../../core/types.js";
5
5
  import { type BashReadonlyRootBoundary } from "./bash-readonly-classifier.js";
6
6
  /**
7
- * design/80 D-2 (part-1): a parsed-command classifier for the `bash` tool, exposed as a
7
+ * A parsed-command classifier for the `bash` tool, exposed as a
8
8
  * `ToolSpec.reversibilityProbe`. A full shell is treated as egress+irreversible by DEFAULT; this probe is the
9
- * "real parsed classifier" that lets a deployment safely auto-allow the provably-benign subset (the §4-OQ4
10
- * doctrine: shell⇒always-gate UNLESS a parsed classifier is wired). design/154 upgraded it from
11
- * single-command to {@link classifyCompoundReadonly}: a command is reversible ONLY if every `;`/`&&`/`||`/`|`
9
+ * "real parsed classifier" that lets a deployment safely auto-allow the provably-benign subset (the
10
+ * doctrine: shell⇒always-gate UNLESS a parsed classifier is wired). It is COMPOUND-aware
11
+ * ({@link classifyCompoundReadonly}): a command is reversible ONLY if every `;`/`&&`/`||`/`|`
12
12
  * connected segment is a bare command (no redirects/substitution/subshells/escapes/`&` anywhere — those
13
13
  * whole-string reject, so it can't chain to `curl`/`git push`/`rm` or background past TaskStop) whose
14
14
  * `argv[0]` is in the reversible allowlist (default
@@ -23,7 +23,7 @@ import { type BashReadonlyRootBoundary } from "./bash-readonly-classifier.js";
23
23
  * Wire it on the `bash` tool with `irreversibility: "maybe"` (or via `TaskSpec.shellGate: "classify"`); without
24
24
  * a classifier a deployment should mark `bash` `irreversibility: "always"` (`shellGate: "always"`) — fail-closed.
25
25
  *
26
- * RB-412 closed the DATA-side residual named above for the read direction: pass `boundary` and a listed
26
+ * The DATA-side residual named above is closed for the read direction: pass `boundary` and a listed
27
27
  * reader whose path arguments leave the allowed directories stops being reversible, so the gate asks
28
28
  * instead of auto-allowing. Pass it as a FUNCTION wherever the working directory is observable (an
29
29
  * in-task `cd` moves the base a relative operand resolves against, and the probe is called per command).
@@ -38,7 +38,7 @@ import { type BashReadonlyRootBoundary } from "./bash-readonly-classifier.js";
38
38
  * safety argument lives on that function). Additive by construction: the plain verdict is tried
39
39
  * first and is never overridden.
40
40
  *
41
- * backlog #239 — the RECURSIVE-READ demotion returns a STRUCTURED cause alongside the verdict. That
41
+ * The RECURSIVE-READ demotion returns a STRUCTURED cause alongside the verdict. That
42
42
  * demotion is the one arm whose reason is genuinely unrecoverable downstream: a recursive read is
43
43
  * refused for what the traversal REACHES, and the reached set is by definition not in the command text
44
44
  * an approval card shows. The cause is minted from the SAME classification pass that produced the
@@ -73,24 +73,28 @@ export declare function bashReversibilityProbe(allow?: readonly string[], bounda
73
73
  * · the boundary DECLARED an objection — a deny-listed operand, a recursive walk under the deny judge, an
74
74
  * operand outside the roots — ⇒ `{ reversible: false, mandated: true }` (+ the recursive-reach `cause`);
75
75
  * · the boundary could NOT READ where the command reads — an unexpanded glob operand (the compound face
76
- * reports it as undecided), a `~`-rooted operand with no home declared, a working-directory move the walk
77
- * cannot model — ⇒ `{ reversible: false }` (fail-closed; a plain ask, which a stored allow rule may retire —
78
- * the seat did not declare anything, it declined to guess);
76
+ * reports it as undecided), a `~`-rooted operand under an adapter that declares no home, a working-directory
77
+ * move the walk cannot model — ⇒ `{ reversible: false }` (fail-closed; a plain ask, which a stored allow rule
78
+ * may retire — the seat did not declare anything, it declined to guess). The engine wires the environment's
79
+ * declared home, so `~/x`, `$HOME/x` and `${HOME}/x` RESOLVE and are judged like the absolute spelling;
79
80
  * · otherwise ⇒ `{ reversible: true }`. This includes every command whose SHAPE the read faces refuse whole
80
81
  * (an unlisted program, a redirection, a substitution, a segment that is not a reader): those shapes carry
81
82
  * no read-face verdict, so this seat has no question to ask — the residual is the doctrine's, and under
82
- * `"off"` the doctrine asks nothing. `run_in_background` is likewise not this seat's question (it changes
83
- * WHEN the command runs, never WHERE it reads).
83
+ * `"off"` the doctrine asks nothing. A listed reader refused for a PER-SEGMENT shape (follow mode, a device,
84
+ * a blocking stdin read) is different: the compound face still walks its operands and carries the boundary's
85
+ * structural findings beside the sentence, so `tail -f <denied>` is the declared ask `cat <denied>` is.
86
+ * `run_in_background` is likewise not this seat's question (it changes WHEN the command runs, never WHERE it
87
+ * reads).
84
88
  *
85
89
  * Reach = the read faces' reach, and nothing wider: the compound face walks the operands of a command whose
86
90
  * every segment is a listed reader, and the bounded poll-loop face walks a loop body of listed readers. A
87
- * read hidden in a shape the faces refuse whole (`cat x | <unlisted>`, `$(cat x)`, `cat $DIR/x`, a launcher
88
- * `env cat x`, a path-prefixed `/bin/cat x`) is not seen here — deny-listed or out-of-root alike — exactly
91
+ * read hidden in a shape the faces refuse whole (`cat x | <unlisted>`, `$(cat x)`, `cat $DIR/x` a variable other
92
+ * than the home's own deterministic spellings — a launcher `env cat x`, a path-prefixed `/bin/cat x`) is not
93
+ * seen here — deny-listed or out-of-root alike — exactly
89
94
  * the shapes the `"classify"` doctrine exists to ask about. The text-level containment gate the classify
90
95
  * seat consults on its demotion arms is deliberately not consulted here ({@link boundaryDeclared}: it may
91
- * add a mandate to an ask, never originate one). The poll-loop face reports its refusal as one sentence,
92
- * so the boundary's share of it is read by removing the boundary's judging seats
93
- * ({@link pollLoopBoundaryVerdict}).
96
+ * add a mandate to an ask, never originate one). The poll-loop face's structured verdict
97
+ * ({@link classifyBoundedReadonlyPollLoopDetailed}) is read the same three ways as the compound face's.
94
98
  *
95
99
  * The reader set is the engine's classify set ({@link BASH_CLASSIFY_DEFAULT_ALLOW}) — here it is NOT an
96
100
  * auto-allow list but the set of programs whose operands the faces read; a wider set means more reads are
@@ -98,7 +102,7 @@ export declare function bashReversibilityProbe(allow?: readonly string[], bounda
98
102
  */
99
103
  export declare function bashReadBoundaryProbe(boundary: BashReadonlyRootBoundary | (() => BashReadonlyRootBoundary | undefined)): (args: unknown) => ReversibilityVerdict;
100
104
  /**
101
- * design/199 D-6 — the FULL shell's contract id, single-sourced: both shell faces share the wire
105
+ * The FULL shell's contract id, single-sourced: both shell faces share the wire
102
106
  * name "Bash", so this id is the ONE structural discriminator between the write-capable shell and
103
107
  * the read-only allowlist face (`core.bash_readonly@1`). Consumed by prepare-task's
104
108
  * fullShellReachable roster assertion (its first load-bearing consumer).
@@ -107,36 +111,36 @@ export { FULL_SHELL_CONTRACT_ID } from "../../core/tool-catalog-entries.js";
107
111
  /** The CC-verbatim exit-1 interpretation for `command`, or undefined when exit 1 means a real error.
108
112
  * Conservative parse: last `;`/`&&`/`||`/newline statement → last `|` pipeline segment → leading
109
113
  * command name (env-assignments skipped, path prefix stripped); `git grep`/`git diff` special-cased
110
- * (CC cLp). Exported for the 批④ unit tests. */
114
+ * (CC `cLp`). Exported for its unit tests. */
111
115
  export declare function bashExitOneInterpretation(command: string): string | undefined;
112
116
  export declare function canAutoBackground(command: string, depth?: number): boolean;
113
117
  /**
114
118
  * `bash` (effect:write) — a full shell. ⚠️ It runs with `rootCanonical` as the initial cwd but is NOT
115
119
  * sandboxed: a command can `cd` out, read/write/delete any path the process can reach, and use the
116
- * network. `rootPath` is a file-tool guard rail, NOT a bash sandbox (design/44 §5, DESIGN#6) real
117
- * isolation is the deployment's job (inject a chroot/container `ExecutionEnv`). Every call still goes
118
- * through the design/37 policy gate, which a multi-tenant deployment MUST wire to constrain it. The cwd
119
- * persists across calls (design/64 §8.1A): a per-task `cwdRef` starts at `rootCanonical` and is updated
120
+ * network. `rootPath` is a file-tool guard rail, NOT a bash sandbox real isolation is the
121
+ * deployment's job (inject a chroot/container `ExecutionEnv`). Every call still goes through the
122
+ * tool-policy gate, which a multi-tenant deployment MUST wire to constrain it. The cwd
123
+ * persists across calls: a per-task `cwdRef` starts at `rootCanonical` and is updated
120
124
  * from the shell's final pwd after each command.
121
125
  */
122
126
  export declare function createBashTool(env: ExecutionEnv, rootCanonical: string, coAuthor?: string | false, cwdRef?: CwdRef, taskOpts?: {
123
127
  taskRegistry?: TaskRegistry;
124
128
  taskOwner?: string;
125
129
  taskScope?: string;
126
- /** (design/129, mirrors MonitorToolOptions.sessionId): when the task runs INSIDE a session,
130
+ /** (mirrors MonitorToolOptions.sessionId): when the task runs INSIDE a session,
127
131
  * a background command registers session-resident (owner = sessionId, sessionScoped flag) — it
128
132
  * survives the run teardown like CC's bg shells and is reaped at the session terminal. Absent ⇒
129
133
  * run-scoped registration exactly as before (killed-with-receipt at teardown). */
130
134
  sessionId?: string;
131
- /** design/116 §7 G2b: completion-notification sink — a finished background command fires ONE
135
+ /** Completion-notification sink — a finished background command fires ONE
132
136
  * task-notification (priority "next": boundary interrupt, CC LocalShellTask posture). */
133
137
  onTaskNotification?: (n: import("../../core/task-notification.js").TaskNotificationPayload, opts?: {
134
138
  priority?: "now" | "next" | "later";
135
139
  }) => void;
136
- /** design/116 detach: per-tool-call detach hub — a fired signal adopts the running command as background. */
140
+ /** Per-tool-call detach hub — a fired signal adopts the running command as background. */
137
141
  detachHub?: import("../../core/tool-detach.js").ToolDetachHub;
138
142
  /**
139
- * RB-198 F1 (CC 220 `Zry`/`WZi.#m` parity) — EXPLICIT deployment opt-in: on this command's own
143
+ * EXPLICIT deployment opt-in: on this command's own
140
144
  * timeout, an eligible foreground command (see `canAutoBackground`'s own docstring — a
141
145
  * DELIBERATELY simplified, narrower-than-CC classifier) is adopted as a background task instead
142
146
  * of being killed. Defaults to `false` (the pre-existing, unconditional kill-on-timeout behavior)
@@ -151,7 +155,7 @@ export declare function createBashTool(env: ExecutionEnv, rootCanonical: string,
151
155
  */
152
156
  autoBackgroundOnTimeout?: boolean;
153
157
  /**
154
- * RB-220 — mirrors {@link import("../../core/types.js").TaskSpec.oneShot}: this run has no later
158
+ * Mirrors {@link import("../../core/types.js").TaskSpec.oneShot}: this run has no later
155
159
  * turn for an async background notification to land in (a headless `-p` process exits once the
156
160
  * turn ends). Branches the background-launch receipt's guidance toward an active block-wait
157
161
  * instruction instead of "you will be notified — do not poll", the same failure form
@@ -160,18 +164,18 @@ export declare function createBashTool(env: ExecutionEnv, rootCanonical: string,
160
164
  */
161
165
  oneShot?: boolean;
162
166
  /**
163
- * RB-371 ②: the EXTRA containment roots of the structured file tools (additionalDirectories,
167
+ * The EXTRA containment roots of the structured file tools (additionalDirectories,
164
168
  * canonical) — combined with `rootCanonical` and consulted ONLY for the post-`cd` disclosure
165
169
  * note (a committed cwd outside every root gets one trailer line saying the structured tools'
166
170
  * relative paths now resolve there and may be refused). Bash itself stays deliberately
167
171
  * unconfined; passing this never gates anything.
168
172
  */
169
173
  additionalRoots?: readonly string[];
170
- /** RB-370 ② (cli): override of the `timeout` parameter's DEFAULT budget, in ms — see
174
+ /** Override of the `timeout` parameter's DEFAULT budget, in ms — see
171
175
  * {@link import("./index.js").HandsToolkitOptions.bashDefaultTimeoutMs} for the resolution
172
176
  * contract (options over env over constant; invalid values discarded). */
173
177
  bashDefaultTimeoutMs?: number;
174
- /** RB-370 ② (cli): override of the `timeout` parameter's engine CEILING, in ms — only-widen
178
+ /** Override of the `timeout` parameter's engine CEILING, in ms — only-widen
175
179
  * vs the resolved default; see {@link import("./index.js").HandsToolkitOptions.bashMaxTimeoutMs}. */
176
180
  bashMaxTimeoutMs?: number;
177
181
  /** Structured sink for this leg's timeout-cap discard announcements — consumed by
@@ -179,36 +183,36 @@ export declare function createBashTool(env: ExecutionEnv, rootCanonical: string,
179
183
  * {@link import("./index.js").HandsToolkitOptions.onNotice} for the replace-vs-warn contract). */
180
184
  onNotice?: (n: import("../../core/types.js").EngineNotice) => void;
181
185
  /**
182
- * #181-F6 — whether the Monitor tool is on THIS run's roster (the Runner's own mount predicate is
186
+ * Whether the Monitor tool is on THIS run's roster (the Runner's own mount predicate is
183
187
  * `backgroundTaskToolsActive`; it, not this tool, mounts Monitor). Read by the SR-2 gh rate-limit
184
188
  * hint, whose closing clause teaches the Monitor tool: `false` ⇒ the clause is dropped (the sleep
185
189
  * advice stays), absent/`true` ⇒ historic full wording (a standalone toolkit consumer may well have
186
190
  * mounted Monitor itself — the omitted default must not silently rewrite its hint).
187
191
  */
188
192
  monitorToolActive?: boolean;
189
- /** design/319 (A ticket) — the session's reminder provenance mark: stamped on the gh rate-limit
193
+ /** The session's reminder provenance mark: stamped on the gh rate-limit
190
194
  * hint's open tag by the mint home (see {@link import("./index.js").HandsToolkitOptions.reminderMark}).
191
195
  * Absent ⇒ historic bare tag. */
192
196
  reminderMark?: string;
193
197
  }): AgentTool;
194
198
  /**
195
- * `bash_readonly` (effect:read) — a restricted shell for the verifier read-only boundary (design/44 M2):
196
- * a single allowlisted, bare command with no shell operators. effect:read lets it survive the verifier's
197
- * read-only filter, but it is NOT a policy circumvention — it still goes through the design/37 gate (council #7:
198
- * a read can still be a side channel, e.g. dumping a secret file). The allowlist is a coarse pre-filter;
199
+ * `bash_readonly` (effect:read) — a restricted shell for the verifier read-only boundary: a single
200
+ * allowlisted, bare command with no shell operators. effect:read lets it survive the verifier's
201
+ * read-only filter, but it is NOT a policy circumvention — it still goes through the tool-policy gate,
202
+ * because a read can still be a side channel (dumping a secret file). The allowlist is a coarse pre-filter;
199
203
  * the policy gate is the authoritative control.
200
204
  *
201
- * RB-413 (安全面, adjudicated: hard refusal) that allowlist vets argv[0] and nothing else, so until this
202
- * leg carried a path boundary an allowlisted reader could name ANY file on the host and get it: `cat
203
- * /etc/passwd` went straight through. RB-412 gave the full `bash` leg the same boundary as a DEMOTION —
204
- * that leg's verdict feeds an approval gate, so "outside the roots" can become a prompt. This face has no
205
+ * Hard refusal, not a demotion: the allowlist vets argv[0] and nothing else, so without a path
206
+ * boundary an allowlisted reader could name ANY file on the host and get it (`cat /etc/passwd` would go
207
+ * straight through). The full `bash` leg carries the same boundary as a DEMOTION — that leg's verdict
208
+ * feeds an approval gate, so "outside the roots" can become a prompt. This face has no
205
209
  * such channel: `effect:"read"` is precisely what lets it run where the write shell may not (the verifier's
206
210
  * read-only band), so an out-of-root read here is not something to escalate, it is outside what the tool
207
211
  * is. It is refused, fail-closed, before anything executes — including the conservative direction, where
208
212
  * the operand cannot be resolved statically (there is nothing to degrade to).
209
213
  */
210
214
  export declare function createBashReadonlyTool(env: ExecutionEnv, rootCanonical: string, allow: ReadonlySet<string>, opts?: {
211
- /** RB-370 ② (cli): same timeout-cap overrides the full `bash` leg takes — see
215
+ /** Same timeout-cap overrides the full `bash` leg takes — see
212
216
  * {@link import("./index.js").HandsToolkitOptions.bashDefaultTimeoutMs} /
213
217
  * {@link import("./index.js").HandsToolkitOptions.bashMaxTimeoutMs} (类修完整域: both foreground
214
218
  * legs share runShell's clamp, so both must share the configurable resolution). */
@@ -217,21 +221,21 @@ export declare function createBashReadonlyTool(env: ExecutionEnv, rootCanonical:
217
221
  /** Structured sink for the timeout-cap discard announcements — same seat the full `bash` leg
218
222
  * takes (both foreground legs share the resolver, so both must share the sink). */
219
223
  onNotice?: (n: import("../../core/types.js").EngineNotice) => void;
220
- /** RB-413: the extra containment roots the structured file tools got (design/119 `--add-dir`,
224
+ /** The extra containment roots the structured file tools got (the CC `--add-dir` family,
221
225
  * canonical). A read this deployment already sanctions for Read/Grep/Glob is equally sanctioned
222
226
  * here — the two faces must not disagree about which directories exist for this session. */
223
227
  additionalRoots?: readonly string[];
224
228
  }): AgentTool;
225
229
  /**
226
- * design/115 P0 `TaskOutput` (legacy aliases: BashOutput/AgentOutput*) — read a background shell's NEW output
230
+ * `TaskOutput` — read a background shell's NEW output
227
231
  * since the last call (cursor), by task_id. Optional legacy `filter` regex is applied BEFORE the per-poll truncation so a watched line survives even when it
228
232
  * falls in a high-throughput middle window. Untrusted process output is fenced (delimitUntrusted) — observe-only,
229
233
  * never re-fed as instructions.
230
234
  */
231
235
  export declare function createEnvTaskOutputTool(env: ExecutionEnv): AgentTool;
232
- /** design/115 P0 `TaskStop` (RB-476-A: legacy aliases cleared) — terminate a background shell by task_id.
236
+ /** `TaskStop` — terminate a background shell by task_id.
233
237
  *
234
- * design/134 KNOWN-ISSUES close-out: this band kills ENV-DIRECT (it mounts precisely when the toolkit has
238
+ * This band kills ENV-DIRECT (it mounts precisely when the toolkit has
235
239
  * no registry — the createHandsToolkit ternary routes registry deployments to createTaskStopTool), so a
236
240
  * row for the SAME shell in the process-local {@link defaultTaskRegistry} (a Runner-mounted run sharing
237
241
  * this env) used to settle via the watcher's no-claimant floor as stoppedBy:"system". The tool now marks
@@ -11,7 +11,7 @@ import { isRemoteExecutionEnv, hasDestroy, isIsolated } from "../../core/remote-
11
11
  import { ghRateLimitHint } from "./gh-rate-limit.js";
12
12
  import { resolveBashTimeoutCaps, bashTimeoutCapsSec, bashTimeoutArgRefusal, bashTimeoutParamDescription, envErrorDetail, bashMaxOutputChars, clipShellOutput, writeShellOverflowFile, createShellOverflowSpoolFence, shellRecoveryHint, CWD_SENTINEL, BASH_READONLY_CONFINEMENT_NOTE, } from "./fs-shared.js";
13
13
  import { PROBE_CAUSE_PATH_MAX, inlineUntrusted } from "../../core/untrusted-text.js";
14
- import { BASH_CLASSIFY_DEFAULT_ALLOW, BASH_READONLY_DEFAULT_ALLOW, coarseReadonlyCheck, classifyBoundedReadonlyPollLoop, classifyCompoundReadonlyDetailed, classifyOutOfRootReadGate, classifySimpleCommandReadBoundary, NOT_AUTO_ALLOWED, } from "./bash-readonly-classifier.js";
14
+ import { BASH_CLASSIFY_DEFAULT_ALLOW, BASH_READONLY_DEFAULT_ALLOW, coarseReadonlyCheck, classifyBoundedReadonlyPollLoopDetailed, classifyCompoundReadonlyDetailed, classifyOutOfRootReadGate, classifySimpleCommandReadBoundary, NOT_AUTO_ALLOWED, } from "./bash-readonly-classifier.js";
15
15
  import { toolFace } from "../../core/tool-catalog-entries.js";
16
16
  const RECURSIVE_CAUSE_MAX_PATHS = 3;
17
17
  const RECURSIVE_READ_CAUSE_CODE = "shell.recursive_read_unbounded";
@@ -36,7 +36,7 @@ export function bashReversibilityProbe(allow, boundary) {
36
36
  if (backgrounded)
37
37
  return { reversible: false, ...boundaryGate(detailed) };
38
38
  if (detailed.reason === undefined) {
39
- if (detailed.undecidedPaths !== undefined && detailed.undecidedPaths.length > 0) {
39
+ if (boundaryUnread(detailed)) {
40
40
  const cause = recursiveReadCause(detailed);
41
41
  if (cause !== undefined)
42
42
  return { reversible: false, ...boundaryGate(detailed), cause };
@@ -44,23 +44,16 @@ export function bashReversibilityProbe(allow, boundary) {
44
44
  }
45
45
  return { reversible: true };
46
46
  }
47
- const loopRefusal = classifyBoundedReadonlyPollLoop(command, allowSet, resolved);
48
- if (loopRefusal === undefined)
47
+ const loop = classifyBoundedReadonlyPollLoopDetailed(command, allowSet, resolved);
48
+ if (loop.reason === undefined)
49
49
  return { reversible: true };
50
- return { reversible: false, ...(pollLoopBoundaryVerdict(command, allowSet, resolved, loopRefusal) === "declared" ? { mandated: true } : boundaryGate(detailed)) };
50
+ if (boundaryDeclared(loop))
51
+ return { reversible: false, mandated: true };
52
+ return { reversible: false, ...boundaryGate(detailed) };
51
53
  };
52
54
  }
53
- function attributeRefusal(face, resolved, fullRefusal) {
54
- if (resolved === undefined)
55
- return "shape";
56
- const { denyMatch: _deny, ...withoutDenyJudge } = resolved;
57
- const opened = face({ ...withoutDenyJudge, face: "open" });
58
- if (opened === undefined || opened !== fullRefusal)
59
- return "declared";
60
- return face(undefined) === opened ? "shape" : "unread";
61
- }
62
- function pollLoopBoundaryVerdict(command, allowSet, resolved, fullRefusal) {
63
- return attributeRefusal((b) => classifyBoundedReadonlyPollLoop(command, allowSet, b), resolved, fullRefusal);
55
+ function boundaryUnread(verdict) {
56
+ return (verdict.undecidedPaths !== undefined && verdict.undecidedPaths.length > 0) || (verdict.unresolvedOperands !== undefined && verdict.unresolvedOperands.length > 0);
64
57
  }
65
58
  function boundaryDeclared(verdict) {
66
59
  return denyJudgeSpoke(verdict) || verdict.outOfRootRead === true;
@@ -106,19 +99,18 @@ export function bashReadBoundaryProbe(boundary) {
106
99
  const cause = recursiveReadCause(detailed);
107
100
  return { reversible: false, mandated: true, ...(cause !== undefined ? { cause } : {}) };
108
101
  }
109
- if (detailed.reason === undefined) {
110
- return detailed.undecidedPaths !== undefined && detailed.undecidedPaths.length > 0 ? { reversible: false } : { reversible: true };
111
- }
112
- const compound = attributeRefusal((b) => classifyCompoundReadonlyDetailed(command, allowSet, b).reason, resolved, detailed.reason);
113
- if (compound === "declared")
114
- return { reversible: false, mandated: true };
115
- if (compound === "unread")
102
+ if (boundaryUnread(detailed))
116
103
  return { reversible: false };
117
- const loopRefusal = classifyBoundedReadonlyPollLoop(command, allowSet, resolved);
118
- if (loopRefusal === undefined)
104
+ if (detailed.reason === undefined)
105
+ return { reversible: true };
106
+ const loop = classifyBoundedReadonlyPollLoopDetailed(command, allowSet, resolved);
107
+ if (loop.reason === undefined)
119
108
  return { reversible: true };
120
- const loop = pollLoopBoundaryVerdict(command, allowSet, resolved, loopRefusal);
121
- return loop === "shape" ? { reversible: true } : loop === "declared" ? { reversible: false, mandated: true } : { reversible: false };
109
+ if (boundaryDeclared(loop))
110
+ return { reversible: false, mandated: true };
111
+ if (boundaryUnread(loop))
112
+ return { reversible: false };
113
+ return { reversible: true };
122
114
  };
123
115
  }
124
116
  export { FULL_SHELL_CONTRACT_ID } from "../../core/tool-catalog-entries.js";
@@ -4,7 +4,7 @@ import type { ExecutionEnv } from "../../internal/harness-types.js";
4
4
  import { type PdfModelCapabilities } from "./pdf.js";
5
5
  import { type ReadImageDownsamplerOption } from "./fs-shared.js";
6
6
  import { type ReminderDisclosureCounts } from "../../core/reminder-disclosure.js";
7
- /** design/319 (B ticket) — the Read tool's disclosure state, threaded into the PDF TEXT legs (the
7
+ /** The Read tool's disclosure state, threaded into the PDF TEXT legs (the
8
8
  * two `pdftotext` extraction arms — the only PDF returns with a model-facing text projection of
9
9
  * the document; the native document block and rendered page images have no text to scan). Shares
10
10
  * the Read closure's throttle windows so a PDF and its text read dedup on the same file key. */
@@ -21,7 +21,7 @@ type ReadPdfReturn = string | {
21
21
  details: unknown;
22
22
  };
23
23
  /**
24
- * PDF read pipeline (CC FileReadTool parity — mechanism取证 + limits in fs/pdf.ts):
24
+ * PDF read pipeline (CC FileReadTool parity — mechanism + limits in fs/pdf.ts):
25
25
  * - no `pages` → whole file as a native `document` block, gated at ≤{@link PDF_TARGET_RAW_SIZE} raw and
26
26
  * ≤{@link PDF_INLINE_PAGE_THRESHOLD} pages (page count via `pdfinfo`, byte-scan fallback; unknown = fail-open,
27
27
  * CC-identical — the size gate still bounds the request);
@@ -30,11 +30,11 @@ type ReadPdfReturn = string | {
30
30
  * degradation with the working alternative, never a fake success.
31
31
  * Wire discipline: the base64 payload rides `details.file` only while ≤48K chars (same OMIT rule as the
32
32
  * image variant — a bigger card would be dropped whole by the card projector's 4×cap and blind the shell).
33
- * structured-card audit item B (2026-08-05): that budget management assumed `"document"` was on `CC_DETAIL_TYPES`, which
34
- * it was not — every `document` card, sized or not, was dropped at the gate, making the 48K rule dead
35
- * code and the pages/fallback-level disclosure invisible to a host. The word is registered now.
33
+ * The budget rule only means anything while `"document"` is registered on `CC_DETAIL_TYPES`: without
34
+ * that word every `document` card, sized or not, is dropped at the gate, which makes the 48K rule dead
35
+ * code and the pages/fallback-level disclosure invisible to a host.
36
36
  *
37
- * Degradation chain v2 (裁定: the brain-level placeholder is NOT the end state): when the SERVING model
37
+ * Degradation chain (the brain-level placeholder is NOT the end state): when the SERVING model
38
38
  * cannot take a native document block (`caps.document === false` — e.g. any openai-compatible API), the
39
39
  * whole-PDF path degrades IN THE TOOL (the only layer holding env.exec), best first:
40
40
  * 1. `pdftotext -layout` text extraction → the content arrives as TEXT (Read byte-cap discipline applies);
@@ -42,10 +42,10 @@ type ReadPdfReturn = string | {
42
42
  * pages via the existing `pdftoppm` pipeline (note directs `pages` for more);
43
43
  * 3. honest placeholder explaining WHY levels 1–2 did not run + the Bash self-help.
44
44
  * Every degraded return carries `details.fallback = { level, reason }` (telemetry on the structured frame).
45
- * `caps` absent ⇒ fully capable (byte-compat: native document block; the brain placeholder still guards).
45
+ * `caps` absent ⇒ fully capable (native document block; the brain placeholder still guards).
46
46
  */
47
47
  export declare function readPdfFile(env: ExecutionEnv, path: string, key: string, pages: string | undefined, signal: AbortSignal | undefined, downsamplerOpt: ReadImageDownsamplerOption, cwd: string, preRead?: Uint8Array, caps?: PdfModelCapabilities, readDeny?: import("./read-deny.js").ReadDenyMatcher, disclosure?: PdfReminderDisclosure): Promise<ReadPdfReturn>;
48
- /** E1: readPdfFile's own return type stays `ReadPdfReturn` (its INTERNAL string-means-error dispatch
48
+ /** readPdfFile's own return type stays `ReadPdfReturn` (its INTERNAL string-means-error dispatch
49
49
  * contract, shared with pdfPagesToImageBlocks) — the isError flag is applied once, here, at the tool's
50
50
  * actual execute() boundary, not inside the helper. */
51
51
  export declare function pdfResultToToolReturn(r: ReadPdfReturn): ReturnType<typeof errorResult> | Exclude<ReadPdfReturn, string>;
@@ -5,10 +5,10 @@ import type { CwdRef } from "./fs-shared.js";
5
5
  /**
6
6
  * The Grep card's details assembly, PURE over the engine text ({mode, offset} from the request) —
7
7
  * exported so the text→structured mapping is pinnable with synthetic texts (the byte-truncation and
8
- * fenced-partial shapes are impractical to construct through a live tool call). #313 moved PATH
9
- * IDENTITY off the text and onto the engines' served rows (both legs supply them now); the counts
10
- * and totals below still read the engine's own honesty markers out of the text, which is what keeps
11
- * this seam the honesty boundary.
8
+ * fenced-partial shapes are impractical to construct through a live tool call). PATH IDENTITY comes
9
+ * off the engines' served rows, not the text (both legs supply them); the counts and totals below
10
+ * still read the engine's own honesty markers out of the text, which is what keeps this seam the
11
+ * honesty boundary.
12
12
  */
13
13
  export declare function grepDetailFields(text: string, mode: "files_with_matches" | "content" | "count", offset?: number, structuredRows?: readonly import("./search.js").GrepRow[]): Record<string, unknown>;
14
14
  export declare function createGrepTool(env: ExecutionEnv, rootCanonical: string, additionalRoots?: readonly string[], readDeny?: ReadDenyMatcher, readFace?: ReadFace, cwdRef?: CwdRef): AgentTool;
@@ -1,6 +1,6 @@
1
1
  import { Type } from "typebox";
2
2
  import { defineTool, errorResult } from "../../core/tools.js";
3
- import { resolveKey, violationText, violationDetails } from "./safety.js";
3
+ import { clipSpelling, pathFamilyOf, resolveKey, violationText, violationDetails, WIN32_NAMESPACE_REFUSAL_TEXT } from "./safety.js";
4
4
  import { runGrepDetailed, runGlobDetailed, invalidGlobTokens } from "./search.js";
5
5
  import { toolFace } from "../../core/tool-catalog-entries.js";
6
6
  import { pathTargetBaseOf, splitAbsoluteGlobPattern } from "../../core/effective-path-target.js";
@@ -205,7 +205,10 @@ export function createGlobTool(env, rootCanonical, additionalRoots, readDeny, re
205
205
  let path = declaredTarget === undefined ? undefined : pathTargetValue(args, declaredTarget);
206
206
  const { max_results } = args;
207
207
  if (path === undefined) {
208
- const split = splitAbsoluteGlobPattern(pattern);
208
+ const split = splitAbsoluteGlobPattern(pattern, pathFamilyOf({ root: rootCanonical }));
209
+ if (split !== undefined && "refused" in split) {
210
+ return errorResult(`Error (Glob): pattern "${clipSpelling(pattern)}" ${WIN32_NAMESPACE_REFUSAL_TEXT[split.refused]}; refused (${split.refused}).`);
211
+ }
209
212
  if (split) {
210
213
  path = split.baseDir;
211
214
  pattern = split.relativePattern;