@lannguyensi/harness 0.64.0 → 1.0.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 (710) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +46 -42
  3. package/dist/cli/add/index.js +17 -21
  4. package/dist/cli/add/index.js.map +1 -1
  5. package/dist/cli/adopt/derive.d.ts +2 -2
  6. package/dist/cli/adopt/derive.js +2 -19
  7. package/dist/cli/adopt/derive.js.map +1 -1
  8. package/dist/cli/adopt/index.d.ts +1 -1
  9. package/dist/cli/adopt/index.js +1 -12
  10. package/dist/cli/adopt/index.js.map +1 -1
  11. package/dist/cli/apply/apply.d.ts +20 -35
  12. package/dist/cli/apply/apply.js +61 -136
  13. package/dist/cli/apply/apply.js.map +1 -1
  14. package/dist/cli/apply/generate-codex-config.js +10 -58
  15. package/dist/cli/apply/generate-codex-config.js.map +1 -1
  16. package/dist/cli/apply/generate-memory-index.js +1 -2
  17. package/dist/cli/apply/generate-memory-index.js.map +1 -1
  18. package/dist/cli/apply/generate-opencode-config.d.ts +2 -10
  19. package/dist/cli/apply/generate-opencode-config.js +74 -113
  20. package/dist/cli/apply/generate-opencode-config.js.map +1 -1
  21. package/dist/cli/apply/generate-settings.d.ts +11 -64
  22. package/dist/cli/apply/generate-settings.js +27 -132
  23. package/dist/cli/apply/generate-settings.js.map +1 -1
  24. package/dist/cli/apply/index.d.ts +1 -1
  25. package/dist/cli/apply/index.js +1 -1
  26. package/dist/cli/apply/index.js.map +1 -1
  27. package/dist/cli/apply/install-codex-config.d.ts +153 -1
  28. package/dist/cli/apply/install-codex-config.js +445 -70
  29. package/dist/cli/apply/install-codex-config.js.map +1 -1
  30. package/dist/cli/apply/next-steps.d.ts +7 -0
  31. package/dist/cli/apply/next-steps.js +13 -1
  32. package/dist/cli/apply/next-steps.js.map +1 -1
  33. package/dist/cli/bounded-stdin.d.ts +0 -23
  34. package/dist/cli/bounded-stdin.js +2 -49
  35. package/dist/cli/bounded-stdin.js.map +1 -1
  36. package/dist/cli/describe.d.ts +1 -1
  37. package/dist/cli/describe.js +0 -3
  38. package/dist/cli/describe.js.map +1 -1
  39. package/dist/cli/diff/engine.d.ts +0 -11
  40. package/dist/cli/diff/engine.js +1 -17
  41. package/dist/cli/diff/engine.js.map +1 -1
  42. package/dist/cli/diff/index.js +14 -25
  43. package/dist/cli/diff/index.js.map +1 -1
  44. package/dist/cli/doctor/claude-mcp.d.ts +4 -19
  45. package/dist/cli/doctor/claude-mcp.js +11 -22
  46. package/dist/cli/doctor/claude-mcp.js.map +1 -1
  47. package/dist/cli/doctor/codex.d.ts +12 -14
  48. package/dist/cli/doctor/codex.js +31 -144
  49. package/dist/cli/doctor/codex.js.map +1 -1
  50. package/dist/cli/doctor/format.js +23 -345
  51. package/dist/cli/doctor/format.js.map +1 -1
  52. package/dist/cli/doctor/hook-liveness.d.ts +56 -0
  53. package/dist/cli/doctor/hook-liveness.js +455 -0
  54. package/dist/cli/doctor/hook-liveness.js.map +1 -0
  55. package/dist/cli/doctor/index.d.ts +13 -87
  56. package/dist/cli/doctor/index.js +57 -713
  57. package/dist/cli/doctor/index.js.map +1 -1
  58. package/dist/cli/doctor/opencode.d.ts +2 -1
  59. package/dist/cli/doctor/opencode.js.map +1 -1
  60. package/dist/cli/doctor/types.d.ts +21 -387
  61. package/dist/cli/doctor/types.js.map +1 -1
  62. package/dist/cli/drain-stdio.d.ts +31 -0
  63. package/dist/cli/drain-stdio.js +76 -0
  64. package/dist/cli/drain-stdio.js.map +1 -0
  65. package/dist/cli/export.d.ts +3 -1
  66. package/dist/cli/export.js +7 -16
  67. package/dist/cli/export.js.map +1 -1
  68. package/dist/cli/gate/codex-disable.d.ts +29 -0
  69. package/dist/cli/gate/codex-disable.js +195 -0
  70. package/dist/cli/gate/codex-disable.js.map +1 -0
  71. package/dist/cli/gate/codex-enable.d.ts +41 -0
  72. package/dist/cli/gate/codex-enable.js +127 -0
  73. package/dist/cli/gate/codex-enable.js.map +1 -0
  74. package/dist/cli/gate/codex-snapshot.d.ts +208 -0
  75. package/dist/cli/gate/codex-snapshot.js +402 -0
  76. package/dist/cli/gate/codex-snapshot.js.map +1 -0
  77. package/dist/cli/gate/disable.d.ts +9 -0
  78. package/dist/cli/gate/disable.js +263 -28
  79. package/dist/cli/gate/disable.js.map +1 -1
  80. package/dist/cli/gate/enable.d.ts +26 -6
  81. package/dist/cli/gate/enable.js +152 -80
  82. package/dist/cli/gate/enable.js.map +1 -1
  83. package/dist/cli/gate/link-chain.d.ts +53 -0
  84. package/dist/cli/gate/link-chain.js +122 -0
  85. package/dist/cli/gate/link-chain.js.map +1 -0
  86. package/dist/cli/gate/snapshot.d.ts +289 -12
  87. package/dist/cli/gate/snapshot.js +481 -22
  88. package/dist/cli/gate/snapshot.js.map +1 -1
  89. package/dist/cli/index.d.ts +0 -9
  90. package/dist/cli/index.js +9 -2131
  91. package/dist/cli/index.js.map +1 -1
  92. package/dist/cli/init/composer.d.ts +3 -6
  93. package/dist/cli/init/composer.js +6 -370
  94. package/dist/cli/init/composer.js.map +1 -1
  95. package/dist/cli/init/dependencies.d.ts +1 -2
  96. package/dist/cli/init/dependencies.js +4 -80
  97. package/dist/cli/init/dependencies.js.map +1 -1
  98. package/dist/cli/init/detect.js +5 -4
  99. package/dist/cli/init/detect.js.map +1 -1
  100. package/dist/cli/init/interactive.d.ts +1 -23
  101. package/dist/cli/init/interactive.js +33 -247
  102. package/dist/cli/init/interactive.js.map +1 -1
  103. package/dist/cli/init/profiles.d.ts +2 -2
  104. package/dist/cli/init/profiles.js +51 -245
  105. package/dist/cli/init/profiles.js.map +1 -1
  106. package/dist/cli/init/templates.d.ts +2 -37
  107. package/dist/cli/init/templates.js +25 -1237
  108. package/dist/cli/init/templates.js.map +1 -1
  109. package/dist/cli/list.d.ts +1 -1
  110. package/dist/cli/list.js +1 -38
  111. package/dist/cli/list.js.map +1 -1
  112. package/dist/cli/loader.d.ts +15 -1
  113. package/dist/cli/loader.js +56 -39
  114. package/dist/cli/loader.js.map +1 -1
  115. package/dist/cli/main.js +7 -2
  116. package/dist/cli/main.js.map +1 -1
  117. package/dist/cli/migrate-home/index.js +2 -2
  118. package/dist/cli/migrate-home/index.js.map +1 -1
  119. package/dist/cli/pack/add.js +1 -1
  120. package/dist/cli/pack/add.js.map +1 -1
  121. package/dist/cli/pack/hook-bootstrap.d.ts +5 -164
  122. package/dist/cli/pack/hook-bootstrap.js +15 -291
  123. package/dist/cli/pack/hook-bootstrap.js.map +1 -1
  124. package/dist/cli/pack/hook-branch-protection.d.ts +28 -21
  125. package/dist/cli/pack/hook-branch-protection.js +365 -340
  126. package/dist/cli/pack/hook-branch-protection.js.map +1 -1
  127. package/dist/cli/pack/index.d.ts +0 -1
  128. package/dist/cli/pack/index.js +0 -1
  129. package/dist/cli/pack/index.js.map +1 -1
  130. package/dist/cli/pack/list.js +1 -6
  131. package/dist/cli/pack/list.js.map +1 -1
  132. package/dist/cli/pack/mutate.d.ts +7 -9
  133. package/dist/cli/pack/mutate.js +6 -9
  134. package/dist/cli/pack/mutate.js.map +1 -1
  135. package/dist/cli/pack/reseed.d.ts +2 -2
  136. package/dist/cli/pack/reseed.js +16 -22
  137. package/dist/cli/pack/reseed.js.map +1 -1
  138. package/dist/cli/{delegate/register.d.ts → register-gate-group.d.ts} +1 -1
  139. package/dist/cli/register-gate-group.js +348 -0
  140. package/dist/cli/register-gate-group.js.map +1 -0
  141. package/dist/cli/register-inspect-group.d.ts +6 -0
  142. package/dist/cli/register-inspect-group.js +189 -0
  143. package/dist/cli/register-inspect-group.js.map +1 -0
  144. package/dist/cli/register-operator-lifecycle.d.ts +1 -1
  145. package/dist/cli/register-operator-lifecycle.js +3 -100
  146. package/dist/cli/register-operator-lifecycle.js.map +1 -1
  147. package/dist/cli/register-pack-group.d.ts +5 -0
  148. package/dist/cli/register-pack-group.js +134 -0
  149. package/dist/cli/register-pack-group.js.map +1 -0
  150. package/dist/cli/{register-audit-group.d.ts → register-setup-group.d.ts} +1 -1
  151. package/dist/cli/register-setup-group.js +495 -0
  152. package/dist/cli/register-setup-group.js.map +1 -0
  153. package/dist/cli/remove/index.d.ts +0 -14
  154. package/dist/cli/remove/index.js +2 -115
  155. package/dist/cli/remove/index.js.map +1 -1
  156. package/dist/cli/remove/mutate.d.ts +0 -2
  157. package/dist/cli/remove/mutate.js +1 -19
  158. package/dist/cli/remove/mutate.js.map +1 -1
  159. package/dist/cli/remove/register.js +2 -19
  160. package/dist/cli/remove/register.js.map +1 -1
  161. package/dist/cli/shell-quote.d.ts +7 -0
  162. package/dist/cli/shell-quote.js +17 -0
  163. package/dist/cli/shell-quote.js.map +1 -0
  164. package/dist/cli/uninstall/index.d.ts +4 -2
  165. package/dist/cli/uninstall/index.js +15 -7
  166. package/dist/cli/uninstall/index.js.map +1 -1
  167. package/dist/cli/uninstall/register.js +6 -4
  168. package/dist/cli/uninstall/register.js.map +1 -1
  169. package/dist/cli/uninstall/snapshot.d.ts +15 -0
  170. package/dist/cli/uninstall/snapshot.js +38 -0
  171. package/dist/cli/uninstall/snapshot.js.map +1 -1
  172. package/dist/cli/validate/checks.d.ts +0 -77
  173. package/dist/cli/validate/checks.js +3 -1049
  174. package/dist/cli/validate/checks.js.map +1 -1
  175. package/dist/cli/validate/index.js +19 -15
  176. package/dist/cli/validate/index.js.map +1 -1
  177. package/dist/index.d.ts +0 -3
  178. package/dist/index.js +0 -3
  179. package/dist/index.js.map +1 -1
  180. package/dist/io/claude-mcp.d.ts +1 -1
  181. package/dist/io/claude-mcp.js +27 -14
  182. package/dist/io/claude-mcp.js.map +1 -1
  183. package/dist/io/harness-lock.js +2 -2
  184. package/dist/io/harness-lock.js.map +1 -1
  185. package/dist/io/lock.d.ts +0 -26
  186. package/dist/io/lock.js +10 -27
  187. package/dist/io/lock.js.map +1 -1
  188. package/dist/io/merge-settings.js +6 -4
  189. package/dist/io/merge-settings.js.map +1 -1
  190. package/dist/io/project-name.d.ts +22 -39
  191. package/dist/io/project-name.js +25 -42
  192. package/dist/io/project-name.js.map +1 -1
  193. package/dist/io/read-regular-file.d.ts +103 -40
  194. package/dist/io/read-regular-file.js +196 -35
  195. package/dist/io/read-regular-file.js.map +1 -1
  196. package/dist/io/restart-hints.js +3 -6
  197. package/dist/io/restart-hints.js.map +1 -1
  198. package/dist/io/version-compare.d.ts +1 -3
  199. package/dist/io/version-compare.js +1 -3
  200. package/dist/io/version-compare.js.map +1 -1
  201. package/dist/io/write-regular-file.d.ts +30 -0
  202. package/dist/io/write-regular-file.js +85 -0
  203. package/dist/io/write-regular-file.js.map +1 -0
  204. package/dist/overrides/index.d.ts +1 -0
  205. package/dist/overrides/index.js +1 -0
  206. package/dist/overrides/index.js.map +1 -1
  207. package/dist/overrides/merge-layers.d.ts +43 -0
  208. package/dist/overrides/merge-layers.js +76 -0
  209. package/dist/overrides/merge-layers.js.map +1 -0
  210. package/dist/overrides/merge.d.ts +16 -0
  211. package/dist/overrides/merge.js +21 -8
  212. package/dist/overrides/merge.js.map +1 -1
  213. package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -69
  214. package/dist/policy-packs/builtin/branch-protection-runtime.js +12 -84
  215. package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
  216. package/dist/policy-packs/builtin/branch-protection.d.ts +7 -30
  217. package/dist/policy-packs/builtin/branch-protection.js +56 -89
  218. package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
  219. package/dist/policy-packs/config-check.d.ts +7 -5
  220. package/dist/policy-packs/config-check.js +2 -2
  221. package/dist/policy-packs/config-check.js.map +1 -1
  222. package/dist/policy-packs/expand.d.ts +1 -3
  223. package/dist/policy-packs/expand.js +5 -42
  224. package/dist/policy-packs/expand.js.map +1 -1
  225. package/dist/policy-packs/index.d.ts +3 -3
  226. package/dist/policy-packs/index.js +2 -2
  227. package/dist/policy-packs/index.js.map +1 -1
  228. package/dist/policy-packs/registry.d.ts +9 -38
  229. package/dist/policy-packs/registry.js +5 -65
  230. package/dist/policy-packs/registry.js.map +1 -1
  231. package/dist/policy-packs/runtime.d.ts +0 -4
  232. package/dist/policy-packs/runtime.js +9 -22
  233. package/dist/policy-packs/runtime.js.map +1 -1
  234. package/dist/policy-packs/types.d.ts +0 -19
  235. package/dist/policy-packs/ux-compare.d.ts +1 -11
  236. package/dist/policy-packs/ux-compare.js +6 -42
  237. package/dist/policy-packs/ux-compare.js.map +1 -1
  238. package/dist/policy-packs/ux-drift-check.d.ts +5 -5
  239. package/dist/policy-packs/ux-drift-check.js +17 -22
  240. package/dist/policy-packs/ux-drift-check.js.map +1 -1
  241. package/dist/policy-packs/version-check.d.ts +5 -26
  242. package/dist/policy-packs/version-check.js +19 -74
  243. package/dist/policy-packs/version-check.js.map +1 -1
  244. package/dist/probes/memory.d.ts +1 -1
  245. package/dist/probes/memory.js +1 -1
  246. package/dist/probes/memory.js.map +1 -1
  247. package/dist/runtime/agent-facing.d.ts +9 -0
  248. package/dist/runtime/agent-facing.js +28 -14
  249. package/dist/runtime/agent-facing.js.map +1 -1
  250. package/dist/runtime/bounded-text.d.ts +15 -0
  251. package/dist/runtime/bounded-text.js +27 -0
  252. package/dist/runtime/bounded-text.js.map +1 -0
  253. package/dist/runtime/git-branch.d.ts +125 -0
  254. package/dist/runtime/git-branch.js +381 -0
  255. package/dist/runtime/git-branch.js.map +1 -0
  256. package/dist/runtime/hermetic-spawn-guard.d.ts +2 -2
  257. package/dist/runtime/hermetic-spawn-guard.js +24 -34
  258. package/dist/runtime/hermetic-spawn-guard.js.map +1 -1
  259. package/dist/runtime/home-dir.js +3 -2
  260. package/dist/runtime/home-dir.js.map +1 -1
  261. package/dist/runtime/tool-name-aliases.d.ts +0 -6
  262. package/dist/runtime/tool-name-aliases.js +5 -18
  263. package/dist/runtime/tool-name-aliases.js.map +1 -1
  264. package/dist/schema/grounding.d.ts +7 -54
  265. package/dist/schema/grounding.js +10 -12
  266. package/dist/schema/grounding.js.map +1 -1
  267. package/dist/schema/hooks.d.ts +39 -136
  268. package/dist/schema/hooks.js +3 -6
  269. package/dist/schema/hooks.js.map +1 -1
  270. package/dist/schema/index.d.ts +114 -3828
  271. package/dist/schema/index.js +41 -80
  272. package/dist/schema/index.js.map +1 -1
  273. package/dist/schema/memory.d.ts +54 -131
  274. package/dist/schema/memory.js +2 -2
  275. package/dist/schema/memory.js.map +1 -1
  276. package/dist/schema/policy-packs.d.ts +3 -45
  277. package/dist/schema/policy-packs.js +7 -13
  278. package/dist/schema/policy-packs.js.map +1 -1
  279. package/dist/schema/policy-ux.d.ts +7 -0
  280. package/dist/schema/policy-ux.js +18 -0
  281. package/dist/schema/policy-ux.js.map +1 -0
  282. package/dist/schema/removed-keys.d.ts +185 -0
  283. package/dist/schema/removed-keys.js +531 -0
  284. package/dist/schema/removed-keys.js.map +1 -0
  285. package/dist/schema/tools.d.ts +30 -268
  286. package/dist/schema/tools.js +4 -4
  287. package/dist/schema/tools.js.map +1 -1
  288. package/package.json +5 -16
  289. package/dist/cli/approve/branch-protection.d.ts +0 -69
  290. package/dist/cli/approve/branch-protection.js +0 -144
  291. package/dist/cli/approve/branch-protection.js.map +0 -1
  292. package/dist/cli/approve/risk.d.ts +0 -112
  293. package/dist/cli/approve/risk.js +0 -197
  294. package/dist/cli/approve/risk.js.map +0 -1
  295. package/dist/cli/approve/stdin-report.d.ts +0 -57
  296. package/dist/cli/approve/stdin-report.js +0 -145
  297. package/dist/cli/approve/stdin-report.js.map +0 -1
  298. package/dist/cli/approve/understanding.d.ts +0 -410
  299. package/dist/cli/approve/understanding.js +0 -996
  300. package/dist/cli/approve/understanding.js.map +0 -1
  301. package/dist/cli/audit.d.ts +0 -80
  302. package/dist/cli/audit.js +0 -252
  303. package/dist/cli/audit.js.map +0 -1
  304. package/dist/cli/delegate/index.d.ts +0 -76
  305. package/dist/cli/delegate/index.js +0 -444
  306. package/dist/cli/delegate/index.js.map +0 -1
  307. package/dist/cli/delegate/register.js +0 -90
  308. package/dist/cli/delegate/register.js.map +0 -1
  309. package/dist/cli/doctor/auto-approve-mode.d.ts +0 -37
  310. package/dist/cli/doctor/auto-approve-mode.js +0 -80
  311. package/dist/cli/doctor/auto-approve-mode.js.map +0 -1
  312. package/dist/cli/doctor/bypass-without-auto-approve.d.ts +0 -38
  313. package/dist/cli/doctor/bypass-without-auto-approve.js +0 -95
  314. package/dist/cli/doctor/bypass-without-auto-approve.js.map +0 -1
  315. package/dist/cli/doctor/codex-config-drift.d.ts +0 -28
  316. package/dist/cli/doctor/codex-config-drift.js +0 -240
  317. package/dist/cli/doctor/codex-config-drift.js.map +0 -1
  318. package/dist/cli/doctor/expire-on-tool-match.d.ts +0 -15
  319. package/dist/cli/doctor/expire-on-tool-match.js +0 -58
  320. package/dist/cli/doctor/expire-on-tool-match.js.map +0 -1
  321. package/dist/cli/doctor/rogue-ledger.d.ts +0 -53
  322. package/dist/cli/doctor/rogue-ledger.js +0 -153
  323. package/dist/cli/doctor/rogue-ledger.js.map +0 -1
  324. package/dist/cli/doctor/session-start-preflight-setup-version.d.ts +0 -83
  325. package/dist/cli/doctor/session-start-preflight-setup-version.js +0 -114
  326. package/dist/cli/doctor/session-start-preflight-setup-version.js.map +0 -1
  327. package/dist/cli/doctor/settings-drift.d.ts +0 -25
  328. package/dist/cli/doctor/settings-drift.js +0 -213
  329. package/dist/cli/doctor/settings-drift.js.map +0 -1
  330. package/dist/cli/doctor/toolchain-parity.d.ts +0 -63
  331. package/dist/cli/doctor/toolchain-parity.js +0 -154
  332. package/dist/cli/doctor/toolchain-parity.js.map +0 -1
  333. package/dist/cli/doctor/ug-auto-approvals.d.ts +0 -40
  334. package/dist/cli/doctor/ug-auto-approvals.js +0 -91
  335. package/dist/cli/doctor/ug-auto-approvals.js.map +0 -1
  336. package/dist/cli/doctor/ug-delegations.d.ts +0 -26
  337. package/dist/cli/doctor/ug-delegations.js +0 -121
  338. package/dist/cli/doctor/ug-delegations.js.map +0 -1
  339. package/dist/cli/doctor/ug-inflight.d.ts +0 -35
  340. package/dist/cli/doctor/ug-inflight.js +0 -57
  341. package/dist/cli/doctor/ug-inflight.js.map +0 -1
  342. package/dist/cli/doctor/understanding-mode-env.d.ts +0 -51
  343. package/dist/cli/doctor/understanding-mode-env.js +0 -98
  344. package/dist/cli/doctor/understanding-mode-env.js.map +0 -1
  345. package/dist/cli/dry-run.d.ts +0 -58
  346. package/dist/cli/dry-run.js +0 -283
  347. package/dist/cli/dry-run.js.map +0 -1
  348. package/dist/cli/enriched-event.d.ts +0 -35
  349. package/dist/cli/enriched-event.js +0 -60
  350. package/dist/cli/enriched-event.js.map +0 -1
  351. package/dist/cli/event-input.d.ts +0 -28
  352. package/dist/cli/event-input.js +0 -73
  353. package/dist/cli/event-input.js.map +0 -1
  354. package/dist/cli/explain-action.d.ts +0 -25
  355. package/dist/cli/explain-action.js +0 -57
  356. package/dist/cli/explain-action.js.map +0 -1
  357. package/dist/cli/explain-policy.d.ts +0 -147
  358. package/dist/cli/explain-policy.js +0 -248
  359. package/dist/cli/explain-policy.js.map +0 -1
  360. package/dist/cli/explain.d.ts +0 -31
  361. package/dist/cli/explain.js +0 -159
  362. package/dist/cli/explain.js.map +0 -1
  363. package/dist/cli/gc/index.d.ts +0 -63
  364. package/dist/cli/gc/index.js +0 -566
  365. package/dist/cli/gc/index.js.map +0 -1
  366. package/dist/cli/pack/approve-escape.d.ts +0 -19
  367. package/dist/cli/pack/approve-escape.js +0 -190
  368. package/dist/cli/pack/approve-escape.js.map +0 -1
  369. package/dist/cli/pack/auto-approve-path.d.ts +0 -146
  370. package/dist/cli/pack/auto-approve-path.js +0 -462
  371. package/dist/cli/pack/auto-approve-path.js.map +0 -1
  372. package/dist/cli/pack/hook-codex-post-tool-use.d.ts +0 -25
  373. package/dist/cli/pack/hook-codex-post-tool-use.js +0 -160
  374. package/dist/cli/pack/hook-codex-post-tool-use.js.map +0 -1
  375. package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +0 -48
  376. package/dist/cli/pack/hook-codex-pre-tool-use.js +0 -474
  377. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +0 -1
  378. package/dist/cli/pack/hook-codex-stop.d.ts +0 -35
  379. package/dist/cli/pack/hook-codex-stop.js +0 -329
  380. package/dist/cli/pack/hook-codex-stop.js.map +0 -1
  381. package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +0 -24
  382. package/dist/cli/pack/hook-codex-user-prompt-submit.js +0 -93
  383. package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +0 -1
  384. package/dist/cli/pack/hook-post-merge-gate-record.d.ts +0 -37
  385. package/dist/cli/pack/hook-post-merge-gate-record.js +0 -190
  386. package/dist/cli/pack/hook-post-merge-gate-record.js.map +0 -1
  387. package/dist/cli/pack/hook-post-merge-gate.d.ts +0 -34
  388. package/dist/cli/pack/hook-post-merge-gate.js +0 -277
  389. package/dist/cli/pack/hook-post-merge-gate.js.map +0 -1
  390. package/dist/cli/pack/hook-post-tool-use.d.ts +0 -45
  391. package/dist/cli/pack/hook-post-tool-use.js +0 -137
  392. package/dist/cli/pack/hook-post-tool-use.js.map +0 -1
  393. package/dist/cli/pack/hook-pre-tool-use.d.ts +0 -92
  394. package/dist/cli/pack/hook-pre-tool-use.js +0 -1328
  395. package/dist/cli/pack/hook-pre-tool-use.js.map +0 -1
  396. package/dist/cli/pack/hook-runtime-reality.d.ts +0 -63
  397. package/dist/cli/pack/hook-runtime-reality.js +0 -210
  398. package/dist/cli/pack/hook-runtime-reality.js.map +0 -1
  399. package/dist/cli/pack/hook-solution-acceptance-writeguard.d.ts +0 -32
  400. package/dist/cli/pack/hook-solution-acceptance-writeguard.js +0 -438
  401. package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +0 -1
  402. package/dist/cli/pack/hook-solution-acceptance.d.ts +0 -157
  403. package/dist/cli/pack/hook-solution-acceptance.js +0 -530
  404. package/dist/cli/pack/hook-solution-acceptance.js.map +0 -1
  405. package/dist/cli/pack/hook-stay-in-scope.d.ts +0 -37
  406. package/dist/cli/pack/hook-stay-in-scope.js +0 -128
  407. package/dist/cli/pack/hook-stay-in-scope.js.map +0 -1
  408. package/dist/cli/pack/hook-subagent-start.d.ts +0 -23
  409. package/dist/cli/pack/hook-subagent-start.js +0 -88
  410. package/dist/cli/pack/hook-subagent-start.js.map +0 -1
  411. package/dist/cli/pack/hook-subagent-stop.d.ts +0 -19
  412. package/dist/cli/pack/hook-subagent-stop.js +0 -41
  413. package/dist/cli/pack/hook-subagent-stop.js.map +0 -1
  414. package/dist/cli/pack/hook-track-active-claim.d.ts +0 -27
  415. package/dist/cli/pack/hook-track-active-claim.js +0 -275
  416. package/dist/cli/pack/hook-track-active-claim.js.map +0 -1
  417. package/dist/cli/pack/transcript-report-scan.d.ts +0 -71
  418. package/dist/cli/pack/transcript-report-scan.js +0 -359
  419. package/dist/cli/pack/transcript-report-scan.js.map +0 -1
  420. package/dist/cli/pack/understanding-report-schema-hint.d.ts +0 -26
  421. package/dist/cli/pack/understanding-report-schema-hint.js +0 -120
  422. package/dist/cli/pack/understanding-report-schema-hint.js.map +0 -1
  423. package/dist/cli/pack/upgrade.d.ts +0 -32
  424. package/dist/cli/pack/upgrade.js +0 -273
  425. package/dist/cli/pack/upgrade.js.map +0 -1
  426. package/dist/cli/pause/index.d.ts +0 -113
  427. package/dist/cli/pause/index.js +0 -251
  428. package/dist/cli/pause/index.js.map +0 -1
  429. package/dist/cli/pause-check.d.ts +0 -22
  430. package/dist/cli/pause-check.js +0 -54
  431. package/dist/cli/pause-check.js.map +0 -1
  432. package/dist/cli/policy/intercept.d.ts +0 -233
  433. package/dist/cli/policy/intercept.js +0 -1022
  434. package/dist/cli/policy/intercept.js.map +0 -1
  435. package/dist/cli/policy/risk-envelope-enrichment.d.ts +0 -40
  436. package/dist/cli/policy/risk-envelope-enrichment.js +0 -110
  437. package/dist/cli/policy/risk-envelope-enrichment.js.map +0 -1
  438. package/dist/cli/record/index.d.ts +0 -81
  439. package/dist/cli/record/index.js +0 -348
  440. package/dist/cli/record/index.js.map +0 -1
  441. package/dist/cli/register-audit-group.js +0 -91
  442. package/dist/cli/register-audit-group.js.map +0 -1
  443. package/dist/cli/resolve-env.d.ts +0 -32
  444. package/dist/cli/resolve-env.js +0 -46
  445. package/dist/cli/resolve-env.js.map +0 -1
  446. package/dist/cli/session-export/index.d.ts +0 -46
  447. package/dist/cli/session-export/index.js +0 -169
  448. package/dist/cli/session-export/index.js.map +0 -1
  449. package/dist/cli/session-export/redact.d.ts +0 -22
  450. package/dist/cli/session-export/redact.js +0 -47
  451. package/dist/cli/session-export/redact.js.map +0 -1
  452. package/dist/cli/session-export/transcript.d.ts +0 -24
  453. package/dist/cli/session-export/transcript.js +0 -164
  454. package/dist/cli/session-export/transcript.js.map +0 -1
  455. package/dist/cli/session-start/branch-check.d.ts +0 -18
  456. package/dist/cli/session-start/branch-check.js +0 -140
  457. package/dist/cli/session-start/branch-check.js.map +0 -1
  458. package/dist/cli/session-start/index.d.ts +0 -121
  459. package/dist/cli/session-start/index.js +0 -591
  460. package/dist/cli/session-start/index.js.map +0 -1
  461. package/dist/cli/session-start/shared-options.d.ts +0 -103
  462. package/dist/cli/session-start/shared-options.js +0 -107
  463. package/dist/cli/session-start/shared-options.js.map +0 -1
  464. package/dist/cli/session-start/stale-base-check.d.ts +0 -46
  465. package/dist/cli/session-start/stale-base-check.js +0 -352
  466. package/dist/cli/session-start/stale-base-check.js.map +0 -1
  467. package/dist/cli/session-start/toolchain-parity.d.ts +0 -267
  468. package/dist/cli/session-start/toolchain-parity.js +0 -797
  469. package/dist/cli/session-start/toolchain-parity.js.map +0 -1
  470. package/dist/cli/smoke/assertions.d.ts +0 -46
  471. package/dist/cli/smoke/assertions.js +0 -170
  472. package/dist/cli/smoke/assertions.js.map +0 -1
  473. package/dist/cli/smoke/index.d.ts +0 -76
  474. package/dist/cli/smoke/index.js +0 -245
  475. package/dist/cli/smoke/index.js.map +0 -1
  476. package/dist/cli/smoke/runner.d.ts +0 -55
  477. package/dist/cli/smoke/runner.js +0 -134
  478. package/dist/cli/smoke/runner.js.map +0 -1
  479. package/dist/cli/smoke/stream-parser.d.ts +0 -65
  480. package/dist/cli/smoke/stream-parser.js +0 -115
  481. package/dist/cli/smoke/stream-parser.js.map +0 -1
  482. package/dist/cli/test-risk.d.ts +0 -27
  483. package/dist/cli/test-risk.js +0 -38
  484. package/dist/cli/test-risk.js.map +0 -1
  485. package/dist/io/display-path.d.ts +0 -11
  486. package/dist/io/display-path.js +0 -29
  487. package/dist/io/display-path.js.map +0 -1
  488. package/dist/io/duration.d.ts +0 -5
  489. package/dist/io/duration.js +0 -50
  490. package/dist/io/duration.js.map +0 -1
  491. package/dist/io/extract.d.ts +0 -79
  492. package/dist/io/extract.js +0 -226
  493. package/dist/io/extract.js.map +0 -1
  494. package/dist/io/ledger-record.d.ts +0 -83
  495. package/dist/io/ledger-record.js +0 -301
  496. package/dist/io/ledger-record.js.map +0 -1
  497. package/dist/io/read-json-dir-entries.d.ts +0 -36
  498. package/dist/io/read-json-dir-entries.js +0 -48
  499. package/dist/io/read-json-dir-entries.js.map +0 -1
  500. package/dist/io/safe-json-parse.d.ts +0 -5
  501. package/dist/io/safe-json-parse.js +0 -21
  502. package/dist/io/safe-json-parse.js.map +0 -1
  503. package/dist/policies/index.d.ts +0 -5
  504. package/dist/policies/index.js +0 -6
  505. package/dist/policies/index.js.map +0 -1
  506. package/dist/policies/ledger-client.d.ts +0 -113
  507. package/dist/policies/ledger-client.js +0 -500
  508. package/dist/policies/ledger-client.js.map +0 -1
  509. package/dist/policies/producers.d.ts +0 -12
  510. package/dist/policies/producers.js +0 -61
  511. package/dist/policies/producers.js.map +0 -1
  512. package/dist/policies/requires.d.ts +0 -75
  513. package/dist/policies/requires.js +0 -240
  514. package/dist/policies/requires.js.map +0 -1
  515. package/dist/policies/timestamp.d.ts +0 -14
  516. package/dist/policies/timestamp.js +0 -36
  517. package/dist/policies/timestamp.js.map +0 -1
  518. package/dist/policy-packs/builtin/permission-profiles.d.ts +0 -11
  519. package/dist/policy-packs/builtin/permission-profiles.js +0 -74
  520. package/dist/policy-packs/builtin/permission-profiles.js.map +0 -1
  521. package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +0 -286
  522. package/dist/policy-packs/builtin/post-merge-gate-runtime.js +0 -397
  523. package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +0 -1
  524. package/dist/policy-packs/builtin/post-merge-gate.d.ts +0 -56
  525. package/dist/policy-packs/builtin/post-merge-gate.js +0 -347
  526. package/dist/policy-packs/builtin/post-merge-gate.js.map +0 -1
  527. package/dist/policy-packs/builtin/solution-acceptance-reconnect.d.ts +0 -50
  528. package/dist/policy-packs/builtin/solution-acceptance-reconnect.js +0 -151
  529. package/dist/policy-packs/builtin/solution-acceptance-reconnect.js.map +0 -1
  530. package/dist/policy-packs/builtin/solution-acceptance-runtime.d.ts +0 -323
  531. package/dist/policy-packs/builtin/solution-acceptance-runtime.js +0 -672
  532. package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +0 -1
  533. package/dist/policy-packs/builtin/solution-acceptance.d.ts +0 -45
  534. package/dist/policy-packs/builtin/solution-acceptance.js +0 -226
  535. package/dist/policy-packs/builtin/solution-acceptance.js.map +0 -1
  536. package/dist/policy-packs/builtin/understanding-before-execution/active-claim.d.ts +0 -25
  537. package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js +0 -94
  538. package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js.map +0 -1
  539. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.d.ts +0 -35
  540. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js +0 -86
  541. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js.map +0 -1
  542. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +0 -210
  543. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +0 -361
  544. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +0 -1
  545. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +0 -304
  546. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +0 -734
  547. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +0 -1
  548. package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.d.ts +0 -36
  549. package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js +0 -73
  550. package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js.map +0 -1
  551. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +0 -19
  552. package/dist/policy-packs/builtin/understanding-before-execution/index.js +0 -83
  553. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +0 -1
  554. package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.d.ts +0 -135
  555. package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js +0 -643
  556. package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js.map +0 -1
  557. package/dist/policy-packs/builtin/understanding-before-execution/ledger.d.ts +0 -25
  558. package/dist/policy-packs/builtin/understanding-before-execution/ledger.js +0 -56
  559. package/dist/policy-packs/builtin/understanding-before-execution/ledger.js.map +0 -1
  560. package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.d.ts +0 -20
  561. package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js +0 -106
  562. package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js.map +0 -1
  563. package/dist/policy-packs/builtin/understanding-before-execution/markers.d.ts +0 -126
  564. package/dist/policy-packs/builtin/understanding-before-execution/markers.js +0 -245
  565. package/dist/policy-packs/builtin/understanding-before-execution/markers.js.map +0 -1
  566. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.d.ts +0 -29
  567. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js +0 -82
  568. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js.map +0 -1
  569. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.d.ts +0 -71
  570. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js +0 -175
  571. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js.map +0 -1
  572. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +0 -625
  573. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +0 -1076
  574. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +0 -1
  575. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.d.ts +0 -128
  576. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js +0 -213
  577. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js.map +0 -1
  578. package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.d.ts +0 -129
  579. package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js +0 -166
  580. package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js.map +0 -1
  581. package/dist/policy-packs/builtin/understanding-before-execution/task-markers.d.ts +0 -164
  582. package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js +0 -275
  583. package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js.map +0 -1
  584. package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +0 -1
  585. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +0 -10
  586. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +0 -1
  587. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +0 -526
  588. package/dist/policy-packs/builtin/understanding-before-execution.js +0 -1078
  589. package/dist/policy-packs/builtin/understanding-before-execution.js.map +0 -1
  590. package/dist/policy-packs/permission-translator.d.ts +0 -9
  591. package/dist/policy-packs/permission-translator.js +0 -76
  592. package/dist/policy-packs/permission-translator.js.map +0 -1
  593. package/dist/runtime/action-envelope.d.ts +0 -64
  594. package/dist/runtime/action-envelope.js +0 -46
  595. package/dist/runtime/action-envelope.js.map +0 -1
  596. package/dist/runtime/approval-signing.d.ts +0 -111
  597. package/dist/runtime/approval-signing.js +0 -384
  598. package/dist/runtime/approval-signing.js.map +0 -1
  599. package/dist/runtime/bash-match-facts.d.ts +0 -60
  600. package/dist/runtime/bash-match-facts.js +0 -196
  601. package/dist/runtime/bash-match-facts.js.map +0 -1
  602. package/dist/runtime/bash-match-registry.d.ts +0 -112
  603. package/dist/runtime/bash-match-registry.js +0 -406
  604. package/dist/runtime/bash-match-registry.js.map +0 -1
  605. package/dist/runtime/bash-prefix-parse.d.ts +0 -31
  606. package/dist/runtime/bash-prefix-parse.js +0 -576
  607. package/dist/runtime/bash-prefix-parse.js.map +0 -1
  608. package/dist/runtime/command-normalize.d.ts +0 -658
  609. package/dist/runtime/command-normalize.js +0 -2410
  610. package/dist/runtime/command-normalize.js.map +0 -1
  611. package/dist/runtime/deletion-target-resolve.d.ts +0 -28
  612. package/dist/runtime/deletion-target-resolve.js +0 -1078
  613. package/dist/runtime/deletion-target-resolve.js.map +0 -1
  614. package/dist/runtime/destructive-shell-floor.d.ts +0 -19
  615. package/dist/runtime/destructive-shell-floor.js +0 -611
  616. package/dist/runtime/destructive-shell-floor.js.map +0 -1
  617. package/dist/runtime/environment-resolver.d.ts +0 -36
  618. package/dist/runtime/environment-resolver.js +0 -138
  619. package/dist/runtime/environment-resolver.js.map +0 -1
  620. package/dist/runtime/git-context.d.ts +0 -201
  621. package/dist/runtime/git-context.js +0 -422
  622. package/dist/runtime/git-context.js.map +0 -1
  623. package/dist/runtime/index.d.ts +0 -12
  624. package/dist/runtime/index.js +0 -13
  625. package/dist/runtime/index.js.map +0 -1
  626. package/dist/runtime/intercept.d.ts +0 -623
  627. package/dist/runtime/intercept.js +0 -1384
  628. package/dist/runtime/intercept.js.map +0 -1
  629. package/dist/runtime/kube-context.d.ts +0 -16
  630. package/dist/runtime/kube-context.js +0 -63
  631. package/dist/runtime/kube-context.js.map +0 -1
  632. package/dist/runtime/kubectl-target-parse.d.ts +0 -31
  633. package/dist/runtime/kubectl-target-parse.js +0 -249
  634. package/dist/runtime/kubectl-target-parse.js.map +0 -1
  635. package/dist/runtime/ledger-add.d.ts +0 -16
  636. package/dist/runtime/ledger-add.js +0 -150
  637. package/dist/runtime/ledger-add.js.map +0 -1
  638. package/dist/runtime/ledger-writer.d.ts +0 -27
  639. package/dist/runtime/ledger-writer.js +0 -46
  640. package/dist/runtime/ledger-writer.js.map +0 -1
  641. package/dist/runtime/pause-sentinel.d.ts +0 -60
  642. package/dist/runtime/pause-sentinel.js +0 -156
  643. package/dist/runtime/pause-sentinel.js.map +0 -1
  644. package/dist/runtime/pending-approval.d.ts +0 -23
  645. package/dist/runtime/pending-approval.js +0 -67
  646. package/dist/runtime/pending-approval.js.map +0 -1
  647. package/dist/runtime/read-only-bash.d.ts +0 -141
  648. package/dist/runtime/read-only-bash.js +0 -2204
  649. package/dist/runtime/read-only-bash.js.map +0 -1
  650. package/dist/runtime/recovery-git-commit.d.ts +0 -22
  651. package/dist/runtime/recovery-git-commit.js +0 -284
  652. package/dist/runtime/recovery-git-commit.js.map +0 -1
  653. package/dist/runtime/reject-malformed-session-id.d.ts +0 -8
  654. package/dist/runtime/reject-malformed-session-id.js +0 -16
  655. package/dist/runtime/reject-malformed-session-id.js.map +0 -1
  656. package/dist/runtime/risk-classifier.d.ts +0 -38
  657. package/dist/runtime/risk-classifier.js +0 -311
  658. package/dist/runtime/risk-classifier.js.map +0 -1
  659. package/dist/runtime/session-id.d.ts +0 -113
  660. package/dist/runtime/session-id.js +0 -193
  661. package/dist/runtime/session-id.js.map +0 -1
  662. package/dist/runtime/shell-word.d.ts +0 -62
  663. package/dist/runtime/shell-word.js +0 -410
  664. package/dist/runtime/shell-word.js.map +0 -1
  665. package/dist/runtime/task-providers/agent-tasks.d.ts +0 -105
  666. package/dist/runtime/task-providers/agent-tasks.js +0 -247
  667. package/dist/runtime/task-providers/agent-tasks.js.map +0 -1
  668. package/dist/runtime/when-eval.d.ts +0 -62
  669. package/dist/runtime/when-eval.js +0 -212
  670. package/dist/runtime/when-eval.js.map +0 -1
  671. package/dist/runtime/workflow-policies.d.ts +0 -207
  672. package/dist/runtime/workflow-policies.js +0 -596
  673. package/dist/runtime/workflow-policies.js.map +0 -1
  674. package/dist/schema/audit.d.ts +0 -71
  675. package/dist/schema/audit.js +0 -32
  676. package/dist/schema/audit.js.map +0 -1
  677. package/dist/schema/doctor.d.ts +0 -25
  678. package/dist/schema/doctor.js +0 -23
  679. package/dist/schema/doctor.js.map +0 -1
  680. package/dist/schema/environments.d.ts +0 -215
  681. package/dist/schema/environments.js +0 -101
  682. package/dist/schema/environments.js.map +0 -1
  683. package/dist/schema/extract.d.ts +0 -9
  684. package/dist/schema/extract.js +0 -86
  685. package/dist/schema/extract.js.map +0 -1
  686. package/dist/schema/permission-profiles.d.ts +0 -2292
  687. package/dist/schema/permission-profiles.js +0 -60
  688. package/dist/schema/permission-profiles.js.map +0 -1
  689. package/dist/schema/policies.d.ts +0 -974
  690. package/dist/schema/policies.js +0 -298
  691. package/dist/schema/policies.js.map +0 -1
  692. package/dist/schema/requires.d.ts +0 -131
  693. package/dist/schema/requires.js +0 -88
  694. package/dist/schema/requires.js.map +0 -1
  695. package/dist/schema/risk.d.ts +0 -144
  696. package/dist/schema/risk.js +0 -194
  697. package/dist/schema/risk.js.map +0 -1
  698. package/dist/schema/session-start-preflight.d.ts +0 -10
  699. package/dist/schema/session-start-preflight.js +0 -106
  700. package/dist/schema/session-start-preflight.js.map +0 -1
  701. package/dist/schema/stale-base-check.d.ts +0 -18
  702. package/dist/schema/stale-base-check.js +0 -37
  703. package/dist/schema/stale-base-check.js.map +0 -1
  704. package/dist/schema/toolchain-parity.d.ts +0 -21
  705. package/dist/schema/toolchain-parity.js +0 -48
  706. package/dist/schema/toolchain-parity.js.map +0 -1
  707. package/dist/schema/workflows.d.ts +0 -519
  708. package/dist/schema/workflows.js +0 -81
  709. package/dist/schema/workflows.js.map +0 -1
  710. package/scripts/runtime-reality-docker-probe.mjs +0 -71
@@ -33,46 +33,37 @@
33
33
  * to occupy and against it carrying control characters anywhere
34
34
  * downstream.
35
35
  *
36
- * WHAT A REJECTION LOOKS LIKE. `deriveProjectName` (`src/runtime/git-
37
- * context.ts`) validates its own return value at every exit, so a
38
- * checkout directory whose basename contains a control character now
39
- * takes the same path a `".."` basename already took: the helper returns
40
- * `null`, no project override layer is looked up for that repository,
41
- * and the base/machine value applies unchanged. There is no error and no
42
- * warning; the operator sees the host-wide value instead of a per-repo
43
- * one (`harness doctor`'s setup-version finding then carries
44
- * `projectName: null` and renders no `(project: X)` suffix). An explicit
45
- * `--project` carrying a control character is instead reported:
36
+ * WHAT A REJECTION LOOKS LIKE. An explicit `--project` carrying a control
37
+ * character or a path-escaping shape is reported, not silently used:
46
38
  * `resolvePaths` resolves no project layer for it, and
47
39
  * `substituteProject` (`src/probes/memory.ts`) degrades to the "no
48
40
  * project supplied" branch, which `harness doctor` surfaces as its
49
41
  * rejected-`--project` warn line.
50
42
  *
51
- * Exported (task c88461c1, review round 3 residual; task `1c4eb3ea`
52
- * of the batch-44 follow-up run) so `resolvePaths` (`src/cli/loader.ts`)
53
- * can apply the SAME guard at its own `path.join` sink, defense in
54
- * depth: this function already rejects an unsafe name at every
55
- * `deriveProjectName` exit, but an `opts.project` reaching
56
- * `resolvePaths`' OWN sink from anywhere else (a caller building
57
- * `LoaderOptions` by hand, a future producer) had no equivalent check
58
- * of its own until now. Applied a THIRD time at `substituteProject`'s
59
- * own sink (`src/probes/memory.ts`, task `e904f25a`): an invalid name
60
- * there degrades to the "no project supplied" branch instead of being
61
- * interpolated into the `{project}` placeholder. Applied a FOURTH time
62
- * at `buildLockEntries`' own sink (`src/io/harness-lock.ts`, task
63
- * `b5e6ccb0`): an invalid name there skips the templated directory's
64
- * lock entry instead of the raw value being interpolated into the path
65
- * this function stats, hashes and writes into `harness.lock`.
43
+ * Exported (task c88461c1; task `1c4eb3ea` of the batch-44 follow-up run)
44
+ * so `resolvePaths` (`src/cli/loader.ts`) can apply the SAME guard at
45
+ * its own `path.join` sink, defense in depth: an `opts.project`
46
+ * reaching `resolvePaths` from anywhere (the explicit `--project`
47
+ * flag, a caller building `LoaderOptions` by hand, a future producer)
48
+ * is checked there. Applied a SECOND time at
49
+ * `substituteProject`'s own sink (`src/probes/memory.ts`, task
50
+ * `e904f25a`): an invalid name there degrades to the "no project
51
+ * supplied" branch instead of being interpolated into the `{project}`
52
+ * placeholder. Applied a THIRD time at `buildLockEntries`' own sink
53
+ * (`src/io/harness-lock.ts`, task `b5e6ccb0`): an invalid name there
54
+ * skips the templated directory's lock entry instead of the raw value
55
+ * being interpolated into the path this function stats, hashes and
56
+ * writes into `harness.lock`.
66
57
  * `resolvePaths`, `substituteProject` and `buildLockEntries` are now all
67
58
  * guarded; one `{project}` sink is NOT: `generate-memory-index.ts`'s own
68
59
  * substitution still interpolates an operator-supplied `--project` value
69
60
  * into a path unvalidated, left unguarded (reached only via the explicit
70
- * CLI flag, not this module's derivation; see CHANGELOG.md for the
71
- * reservation/follow-up). That one call site calls this function
72
- * nowhere, so it inherits NOTHING from the control-character screen
73
- * above either: a caller reading this comment should not assume this
74
- * function guards every `{project}`-shaped sink in the codebase, for
75
- * path escapes or for control characters.
61
+ * `--project` CLI flag; see CHANGELOG.md for the reservation/follow-up).
62
+ * That one call site calls this function nowhere, so it inherits NOTHING
63
+ * from the control-character screen above either: a caller reading
64
+ * this comment should not assume this function guards every
65
+ * `{project}`-shaped sink in the codebase, for path escapes or for
66
+ * control characters.
76
67
  */
77
68
  export declare function isValidProjectName(name: string): boolean;
78
69
  /**
@@ -96,14 +87,6 @@ export declare function isValidProjectName(name: string): boolean;
96
87
  * field (`src/cli/list.ts`, and with it the text table derived from
97
88
  * it).
98
89
  *
99
- * The `session_start_preflight.setup` finding's `(project: X)` suffix is
100
- * also wrapped, as defense in depth rather than as an echo of a rejected
101
- * value: `harness doctor` sets that finding's `projectName` only when
102
- * `resolvePaths` actually resolved a project layer FILE, which requires
103
- * the name to have passed {@link isValidProjectName} first. The wrap
104
- * stays so a hand-built finding or a future producer cannot reintroduce
105
- * a forged line through that one call site.
106
- *
107
90
  * Strips (rather than escapes) every character in
108
91
  * {@link PROJECT_NAME_CONTROL_CHARS}. A name with no control character
109
92
  * (`..`, `a/b`, every ordinary shape) passes through unchanged. Report
@@ -10,9 +10,9 @@
10
10
  // documents for `src/policies/duration.ts`, `src/policies/extract.ts`,
11
11
  // `src/runtime/ledger-record.ts` and `src/runtime/expand-home.ts`: a
12
12
  // utility needed below its original layer moves down rather than the
13
- // importing layer's boundary being relaxed. `src/runtime/git-context.ts`
14
- // re-exports both names so every existing consumer that imports them from
15
- // `../runtime/git-context.js` keeps working unchanged.
13
+ // importing layer's boundary being relaxed. This module is the home of
14
+ // both helpers: every consumer imports them from `src/io/project-name.ts`
15
+ // directly.
16
16
  /**
17
17
  * Every C0 control character (U+0000 to U+001F, so NUL, LF, CR and ESC
18
18
  * among them), DEL (U+007F), and every C1 control character (U+0080 to
@@ -65,46 +65,37 @@ const PROJECT_NAME_CONTROL_CHARS_GLOBAL = new RegExp(PROJECT_NAME_CONTROL_CHARS.
65
65
  * to occupy and against it carrying control characters anywhere
66
66
  * downstream.
67
67
  *
68
- * WHAT A REJECTION LOOKS LIKE. `deriveProjectName` (`src/runtime/git-
69
- * context.ts`) validates its own return value at every exit, so a
70
- * checkout directory whose basename contains a control character now
71
- * takes the same path a `".."` basename already took: the helper returns
72
- * `null`, no project override layer is looked up for that repository,
73
- * and the base/machine value applies unchanged. There is no error and no
74
- * warning; the operator sees the host-wide value instead of a per-repo
75
- * one (`harness doctor`'s setup-version finding then carries
76
- * `projectName: null` and renders no `(project: X)` suffix). An explicit
77
- * `--project` carrying a control character is instead reported:
68
+ * WHAT A REJECTION LOOKS LIKE. An explicit `--project` carrying a control
69
+ * character or a path-escaping shape is reported, not silently used:
78
70
  * `resolvePaths` resolves no project layer for it, and
79
71
  * `substituteProject` (`src/probes/memory.ts`) degrades to the "no
80
72
  * project supplied" branch, which `harness doctor` surfaces as its
81
73
  * rejected-`--project` warn line.
82
74
  *
83
- * Exported (task c88461c1, review round 3 residual; task `1c4eb3ea`
84
- * of the batch-44 follow-up run) so `resolvePaths` (`src/cli/loader.ts`)
85
- * can apply the SAME guard at its own `path.join` sink, defense in
86
- * depth: this function already rejects an unsafe name at every
87
- * `deriveProjectName` exit, but an `opts.project` reaching
88
- * `resolvePaths`' OWN sink from anywhere else (a caller building
89
- * `LoaderOptions` by hand, a future producer) had no equivalent check
90
- * of its own until now. Applied a THIRD time at `substituteProject`'s
91
- * own sink (`src/probes/memory.ts`, task `e904f25a`): an invalid name
92
- * there degrades to the "no project supplied" branch instead of being
93
- * interpolated into the `{project}` placeholder. Applied a FOURTH time
94
- * at `buildLockEntries`' own sink (`src/io/harness-lock.ts`, task
95
- * `b5e6ccb0`): an invalid name there skips the templated directory's
96
- * lock entry instead of the raw value being interpolated into the path
97
- * this function stats, hashes and writes into `harness.lock`.
75
+ * Exported (task c88461c1; task `1c4eb3ea` of the batch-44 follow-up run)
76
+ * so `resolvePaths` (`src/cli/loader.ts`) can apply the SAME guard at
77
+ * its own `path.join` sink, defense in depth: an `opts.project`
78
+ * reaching `resolvePaths` from anywhere (the explicit `--project`
79
+ * flag, a caller building `LoaderOptions` by hand, a future producer)
80
+ * is checked there. Applied a SECOND time at
81
+ * `substituteProject`'s own sink (`src/probes/memory.ts`, task
82
+ * `e904f25a`): an invalid name there degrades to the "no project
83
+ * supplied" branch instead of being interpolated into the `{project}`
84
+ * placeholder. Applied a THIRD time at `buildLockEntries`' own sink
85
+ * (`src/io/harness-lock.ts`, task `b5e6ccb0`): an invalid name there
86
+ * skips the templated directory's lock entry instead of the raw value
87
+ * being interpolated into the path this function stats, hashes and
88
+ * writes into `harness.lock`.
98
89
  * `resolvePaths`, `substituteProject` and `buildLockEntries` are now all
99
90
  * guarded; one `{project}` sink is NOT: `generate-memory-index.ts`'s own
100
91
  * substitution still interpolates an operator-supplied `--project` value
101
92
  * into a path unvalidated, left unguarded (reached only via the explicit
102
- * CLI flag, not this module's derivation; see CHANGELOG.md for the
103
- * reservation/follow-up). That one call site calls this function
104
- * nowhere, so it inherits NOTHING from the control-character screen
105
- * above either: a caller reading this comment should not assume this
106
- * function guards every `{project}`-shaped sink in the codebase, for
107
- * path escapes or for control characters.
93
+ * `--project` CLI flag; see CHANGELOG.md for the reservation/follow-up).
94
+ * That one call site calls this function nowhere, so it inherits NOTHING
95
+ * from the control-character screen above either: a caller reading
96
+ * this comment should not assume this function guards every
97
+ * `{project}`-shaped sink in the codebase, for path escapes or for
98
+ * control characters.
108
99
  */
109
100
  export function isValidProjectName(name) {
110
101
  if (name.length === 0)
@@ -136,14 +127,6 @@ export function isValidProjectName(name) {
136
127
  * field (`src/cli/list.ts`, and with it the text table derived from
137
128
  * it).
138
129
  *
139
- * The `session_start_preflight.setup` finding's `(project: X)` suffix is
140
- * also wrapped, as defense in depth rather than as an echo of a rejected
141
- * value: `harness doctor` sets that finding's `projectName` only when
142
- * `resolvePaths` actually resolved a project layer FILE, which requires
143
- * the name to have passed {@link isValidProjectName} first. The wrap
144
- * stays so a hand-built finding or a future producer cannot reintroduce
145
- * a forged line through that one call site.
146
- *
147
130
  * Strips (rather than escapes) every character in
148
131
  * {@link PROJECT_NAME_CONTROL_CHARS}. A name with no control character
149
132
  * (`..`, `a/b`, every ordinary shape) passes through unchanged. Report
@@ -1 +1 @@
1
- {"version":3,"file":"project-name.js","sourceRoot":"","sources":["../../src/io/project-name.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,yCAAyC;AACzC,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,2EAA2E;AAC3E,+DAA+D;AAC/D,wEAAwE;AACxE,wEAAwE;AACxE,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,yEAAyE;AACzE,0EAA0E;AAC1E,uDAAuD;AAEvD;;;;;;;GAOG;AACH,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,iCAAiC,GAAG,IAAI,MAAM,CAAC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"project-name.js","sourceRoot":"","sources":["../../src/io/project-name.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,yCAAyC;AACzC,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,2EAA2E;AAC3E,+DAA+D;AAC/D,wEAAwE;AACxE,wEAAwE;AACxE,uEAAuE;AACvE,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,0EAA0E;AAC1E,YAAY;AAEZ;;;;;;;GAOG;AACH,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,iCAAiC,GAAG,IAAI,MAAM,CAAC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC"}
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Result of a symlink-rejecting regular-file read. The kinds are deliberately
3
- * fine-grained because the gate readers need to keep their distinct deny
4
- * details (missing vs symlink vs not-regular) and one caller treats
5
- * exists-but-unreadable as "existence already satisfied the gate".
3
+ * fine-grained because the readers need to keep their distinct failure
4
+ * details (missing vs symlink vs not-regular); every caller treats
5
+ * `unreadable` (an oversized file included) as fail-closed.
6
6
  */
7
7
  export type RegularFileRead = {
8
8
  kind: "ok";
@@ -17,47 +17,110 @@ export type RegularFileRead = {
17
17
  kind: "unreadable";
18
18
  };
19
19
  /**
20
- * Result of a stat-only existence probe (see `probePathPresence`). No
21
- * `content`: this never reads the file, only classifies what lstat sees at
22
- * the path. `present` covers a symlink, a directory, or any other non-regular
23
- * node the caller wants to treat as "something is there" without yet reading
24
- * it or deciding whether it is a valid regular file.
20
+ * The most bytes a read returns by default. The current callers read small
21
+ * text records: the harness manifest and its override layers
22
+ * (`src/cli/loader.ts`) and, with a larger bound of their own, the Claude
23
+ * Code user-scope MCP registry (`src/io/claude-mcp.ts`). A file over the
24
+ * cap is refused as `unreadable` (fail-closed in every caller) before any
25
+ * byte is read: a sparse multi-gigabyte file at one of these paths
26
+ * otherwise makes the caller wait on bytes it never asked for, the same
27
+ * stall a FIFO used to cause.
25
28
  */
26
- export type PathPresence = {
27
- kind: "missing";
28
- } | {
29
- kind: "present";
30
- };
29
+ export declare const MAX_REGULAR_FILE_READ_BYTES: number;
30
+ /**
31
+ * Options of the readers below. They default to the strict read this module
32
+ * was built for (the 1 MiB cap, a symlink refused).
33
+ */
34
+ export interface BoundedReadOptions {
35
+ /**
36
+ * The most bytes the read returns; a file over it is refused as
37
+ * `unreadable` before any byte is read, exactly like the default cap.
38
+ * Defaults to {@link MAX_REGULAR_FILE_READ_BYTES}. A caller
39
+ * with a legitimately larger input (the Claude Code user registry) passes
40
+ * its own, larger bound and justifies
41
+ * it at the call site; there is deliberately no way to ask for no bound.
42
+ */
43
+ maxBytes?: number;
44
+ /**
45
+ * Follow a symbolic link at the path (the open drops `O_NOFOLLOW`). For a
46
+ * reader of a file the operator legitimately keeps behind a link
47
+ * (a dotfiles-managed manifest); it never weakens the
48
+ * rest: the type of the OPENED descriptor still decides, so a link to a
49
+ * FIFO, a device or a directory is `not-regular` and never blocks.
50
+ * Defaults to `false` (a link is refused as `symlink`).
51
+ */
52
+ followSymlinks?: boolean;
53
+ }
54
+ export type RegularFileBytesRead = {
55
+ kind: "ok";
56
+ bytes: Buffer;
57
+ } | Exclude<RegularFileRead, {
58
+ kind: "ok";
59
+ }>;
31
60
  /**
32
- * Read a marker/verdict file as utf8, refusing symlinks and non-regular
33
- * files. lstat (NOT stat): defense-in-depth against a symlink at the marker
34
- * path pointing at an arbitrary target the agent controls. In today's threat
35
- * model the agent has no Edit / Write / Bash path to plant such a symlink
36
- * (the same PreToolUse hook gates all three), but the gate contract is to
37
- * assume the agent is hostile, so the lstat reject is cheap insurance
61
+ * The one open-once, type-checked-on-the-descriptor, size-bounded read every
62
+ * by-path reader on a hook path stands on, returning raw bytes (a binary key
63
+ * file needs them, `readRegularFileBounded` decodes them). The cap and the
64
+ * symlink policy are options.
65
+ *
66
+ * The path is opened once, read-only, with `O_NOFOLLOW` (a symlink at the
67
+ * path is refused by the open itself) and `O_NONBLOCK` (opening a FIFO with
68
+ * no writer returns at once instead of waiting for one). The type of the
69
+ * OPENED descriptor then decides (`fstat`, never a separate stat of the
70
+ * path), and the content is read through that same descriptor, so nothing
71
+ * can be swapped in between a check and the read: a writer that replaces the
72
+ * file with a FIFO or a symlink after any earlier look gets `not-regular` /
73
+ * `symlink` back, not a read that blocks the hook past its budget (which the
74
+ * runtime treats as an allow). The descriptor is always closed. The size is
75
+ * bounded too: a file over the cap by `fstat` is refused as `unreadable`
76
+ * without a read, and the read itself stops one byte past the cap, so a file
77
+ * that grows after the `fstat` is bounded as well.
78
+ *
79
+ * Why refuse symlinks at all: defense-in-depth against a symlink at the
80
+ * path pointing at an arbitrary target the agent controls. The gate contract
81
+ * is to assume the agent is hostile, so the refusal is cheap insurance
38
82
  * (agent-tasks/d39f160e).
39
83
  *
40
- * This is THE shared implementation for every gate-marker read; a future
41
- * defensive fix belongs in `lstatOrNull`, above, and nowhere else. Its
42
- * lighter-weight sibling `probePathPresence`, below, shares this file for
43
- * the same reason: both stand on the same `lstatOrNull` helper, and a
44
- * caller that only needs to know "is anything there" before deciding
45
- * whether to pay for the full read (e.g. `verifyDelegation`'s
46
- * existence-before-path-hash check in
47
- * `src/policy-packs/builtin/understanding-before-execution/delegation-markers.ts`)
48
- * gets that from here instead of hand-rolling its own `lstatSync` try/catch.
84
+ * Platforms without `O_NOFOLLOW` (Windows): an `lstat` runs first and
85
+ * refuses a symlink or a non-regular node before the open, because the open
86
+ * alone would follow a link. That leaves the old lstat-to-open window on
87
+ * those platforms; there is no FIFO node on the filesystem there to swap in
88
+ * (named pipes live in a separate namespace), and `O_NONBLOCK` is a no-op
89
+ * flag that is simply left out. The descriptor type check still runs.
90
+ *
91
+ * A future defensive fix belongs here and in `classifyOpenFailure` /
92
+ * `lstatOrNull`, and nowhere else.
93
+ */
94
+ export declare function readRegularFileBytesBounded(filePath: string, opts?: BoundedReadOptions): RegularFileBytesRead;
95
+ /**
96
+ * {@link readRegularFileBytesBounded} decoded as utf8, for the by-path
97
+ * readers of a file a symlink at the path is acceptable for or a larger cap
98
+ * is justified (see {@link BoundedReadOptions}). Same five result kinds as
99
+ * {@link readRegularFileBytesBounded}; `missing` is the one a caller may
100
+ * treat as "legitimately absent", every other non-`ok` kind means something
101
+ * is at the path that must not be read as the file (a FIFO, a device, a
102
+ * directory, an oversized or unreadable file) and is fail-closed or
103
+ * explicitly reported by the caller.
104
+ */
105
+ export declare function readRegularFileBounded(filePath: string, opts?: BoundedReadOptions): RegularFileRead;
106
+ /**
107
+ * Thrown by {@link readTextFileBoundedOrThrow}. `code` is `ENOENT` for a
108
+ * path that is not there (so a caller's existing `ENOENT` branch keeps
109
+ * meaning "absent") and `E_<KIND>` (`E_SYMLINK`, `E_NOT_REGULAR`,
110
+ * `E_UNREADABLE`) for anything else, which never matches `ENOENT`.
49
111
  */
50
- export declare function readRegularFileRejectingSymlink(filePath: string): RegularFileRead;
112
+ export declare class BoundedReadError extends Error {
113
+ readonly code: string;
114
+ readonly kind: Exclude<RegularFileRead["kind"], "ok">;
115
+ constructor(filePath: string, kind: Exclude<RegularFileRead["kind"], "ok">);
116
+ }
51
117
  /**
52
- * Stat-only existence probe: "is anything there", nothing more. Uses the
53
- * same `lstatOrNull` helper (not `stat`) as `readRegularFileRejectingSymlink`
54
- * so a symlink or a directory answers `present`, not `missing`; this probe
55
- * cannot and does not classify WHAT is there (regular file, symlink,
56
- * directory), only whether lstat can see anything at all. A path lstat
57
- * cannot reach for any reason (absent, or unreachable: `EACCES`, `ENOTDIR`,
58
- * ...) comes back `missing`; lstat cannot distinguish those cases, so
59
- * neither does this probe. Callers that need the file-type distinction
60
- * (symlink vs directory vs regular) read the file instead, through
61
- * `readRegularFileRejectingSymlink`.
118
+ * {@link readRegularFileBounded} for the call sites that already wrap a
119
+ * `fs.readFileSync(path, "utf8")` in a try/catch (and, some of them, branch
120
+ * on `ENOENT`): the same bounded, non-blocking read, thrown as a
121
+ * {@link BoundedReadError} instead of returned, so the existing catch blocks
122
+ * keep their shape and every FIFO, device, directory or oversized file now
123
+ * lands in the catch block it would have reached on any other read error,
124
+ * rather than blocking the process.
62
125
  */
63
- export declare function probePathPresence(filePath: string): PathPresence;
126
+ export declare function readTextFileBoundedOrThrow(filePath: string, opts?: BoundedReadOptions): string;
@@ -1,11 +1,10 @@
1
1
  import * as fs from "node:fs";
2
2
  /**
3
- * The single `fs.lstatSync` call both exports below stand on. Returns `null`
3
+ * The single `fs.lstatSync` call the readers below stand on. Returns `null`
4
4
  * on any lstat failure (absent path, or unreachable for another reason:
5
5
  * `EACCES`, `ENOTDIR`, ...); lstat cannot distinguish those cases from each
6
- * other, so neither export tries to. A future defensive fix here (e.g.
7
- * closing the lstat/read race with `O_NOFOLLOW`, `ENOTDIR` handling) lands in
8
- * this one place and is inherited by both callers.
6
+ * other, so no caller tries to. A future defensive fix here
7
+ * (e.g. `ENOTDIR` handling) lands in this one place.
9
8
  */
10
9
  function lstatOrNull(filePath) {
11
10
  try {
@@ -16,25 +15,79 @@ function lstatOrNull(filePath) {
16
15
  }
17
16
  }
18
17
  /**
19
- * Read a marker/verdict file as utf8, refusing symlinks and non-regular
20
- * files. lstat (NOT stat): defense-in-depth against a symlink at the marker
21
- * path pointing at an arbitrary target the agent controls. In today's threat
22
- * model the agent has no Edit / Write / Bash path to plant such a symlink
23
- * (the same PreToolUse hook gates all three), but the gate contract is to
24
- * assume the agent is hostile, so the lstat reject is cheap insurance
25
- * (agent-tasks/d39f160e).
26
- *
27
- * This is THE shared implementation for every gate-marker read; a future
28
- * defensive fix belongs in `lstatOrNull`, above, and nowhere else. Its
29
- * lighter-weight sibling `probePathPresence`, below, shares this file for
30
- * the same reason: both stand on the same `lstatOrNull` helper, and a
31
- * caller that only needs to know "is anything there" before deciding
32
- * whether to pay for the full read (e.g. `verifyDelegation`'s
33
- * existence-before-path-hash check in
34
- * `src/policy-packs/builtin/understanding-before-execution/delegation-markers.ts`)
35
- * gets that from here instead of hand-rolling its own `lstatSync` try/catch.
18
+ * Open flags for the reads in this module. `O_NOFOLLOW` makes the open itself
19
+ * refuse a symbolic link at the final path component (`ELOOP`), so no
20
+ * earlier `lstat` is needed for a swap to race. `O_NONBLOCK` keeps an open
21
+ * of a FIFO with no writer from waiting for one: the open returns at once
22
+ * and the descriptor's type then refuses it. `O_NOFOLLOW` covers only the
23
+ * LAST path component; a symlinked parent directory is followed, as it was
24
+ * under the earlier lstat. `O_NOCTTY` is belt and braces for a tty node at
25
+ * the path. All three are POSIX-only flags; `fs.constants` leaves them
26
+ * `undefined` on Windows, where the code falls back to 0 (see
27
+ * `readRegularFileBytesBounded` for that fallback).
28
+ */
29
+ const O_NOFOLLOW = fs.constants.O_NOFOLLOW;
30
+ const O_NONBLOCK = fs.constants.O_NONBLOCK ?? 0;
31
+ /** A read here must never make a terminal the process's controlling one. */
32
+ const O_NOCTTY = fs.constants.O_NOCTTY ?? 0;
33
+ /**
34
+ * The most bytes a read returns by default. The current callers read small
35
+ * text records: the harness manifest and its override layers
36
+ * (`src/cli/loader.ts`) and, with a larger bound of their own, the Claude
37
+ * Code user-scope MCP registry (`src/io/claude-mcp.ts`). A file over the
38
+ * cap is refused as `unreadable` (fail-closed in every caller) before any
39
+ * byte is read: a sparse multi-gigabyte file at one of these paths
40
+ * otherwise makes the caller wait on bytes it never asked for, the same
41
+ * stall a FIFO used to cause.
42
+ */
43
+ export const MAX_REGULAR_FILE_READ_BYTES = 1024 * 1024;
44
+ const READ_CHUNK_BYTES = 64 * 1024;
45
+ /**
46
+ * Read the opened descriptor to EOF, never more than `maxBytes + 1` bytes: a
47
+ * file that grows after the `fstat` size check stays bounded too. Returns
48
+ * `null` when the file is over the cap. Any read error propagates to the
49
+ * caller.
50
+ */
51
+ function readDescriptorBounded(fd, maxBytes) {
52
+ const chunks = [];
53
+ let total = 0;
54
+ for (;;) {
55
+ const want = Math.min(READ_CHUNK_BYTES, maxBytes + 1 - total);
56
+ const chunk = Buffer.allocUnsafe(want);
57
+ const got = fs.readSync(fd, chunk, 0, want, null);
58
+ if (got === 0)
59
+ break;
60
+ total += got;
61
+ if (total > maxBytes)
62
+ return null;
63
+ chunks.push(got === want ? chunk : chunk.subarray(0, got));
64
+ }
65
+ return Buffer.concat(chunks);
66
+ }
67
+ /**
68
+ * Classify a failed open by what `lstat` sees at the path now, so the
69
+ * caller-visible kinds stay what they were when `lstat` came first: an
70
+ * unreachable path (absent, `ENOTDIR`, an unsearchable parent) is `missing`,
71
+ * a symlink (dangling included) is `symlink`, any other non-regular node is
72
+ * `not-regular`, and a regular file the open could not read (`EACCES`, ...)
73
+ * is `unreadable`. A path that raced into a different state between the
74
+ * failed open and this `lstat` still lands on one of the five kinds, never
75
+ * on `ok`.
36
76
  */
37
- export function readRegularFileRejectingSymlink(filePath) {
77
+ function classifyOpenFailure(filePath, followSymlinks = false) {
78
+ if (followSymlinks) {
79
+ // A link is followed by this read, so what matters is what it leads to:
80
+ // a dangling link (or an unreachable parent) is absent, exactly as a
81
+ // by-path read of it reports `ENOENT`; a link loop or an unreadable
82
+ // target is something there that cannot be read.
83
+ try {
84
+ return fs.statSync(filePath).isFile() ? { kind: "unreadable" } : { kind: "not-regular" };
85
+ }
86
+ catch (err) {
87
+ const code = err.code;
88
+ return code === "ENOENT" || code === "ENOTDIR" ? { kind: "missing" } : { kind: "unreadable" };
89
+ }
90
+ }
38
91
  const stat = lstatOrNull(filePath);
39
92
  if (stat === null)
40
93
  return { kind: "missing" };
@@ -42,26 +95,134 @@ export function readRegularFileRejectingSymlink(filePath) {
42
95
  return { kind: "symlink" };
43
96
  if (!stat.isFile())
44
97
  return { kind: "not-regular" };
98
+ return { kind: "unreadable" };
99
+ }
100
+ /**
101
+ * The one open-once, type-checked-on-the-descriptor, size-bounded read every
102
+ * by-path reader on a hook path stands on, returning raw bytes (a binary key
103
+ * file needs them, `readRegularFileBounded` decodes them). The cap and the
104
+ * symlink policy are options.
105
+ *
106
+ * The path is opened once, read-only, with `O_NOFOLLOW` (a symlink at the
107
+ * path is refused by the open itself) and `O_NONBLOCK` (opening a FIFO with
108
+ * no writer returns at once instead of waiting for one). The type of the
109
+ * OPENED descriptor then decides (`fstat`, never a separate stat of the
110
+ * path), and the content is read through that same descriptor, so nothing
111
+ * can be swapped in between a check and the read: a writer that replaces the
112
+ * file with a FIFO or a symlink after any earlier look gets `not-regular` /
113
+ * `symlink` back, not a read that blocks the hook past its budget (which the
114
+ * runtime treats as an allow). The descriptor is always closed. The size is
115
+ * bounded too: a file over the cap by `fstat` is refused as `unreadable`
116
+ * without a read, and the read itself stops one byte past the cap, so a file
117
+ * that grows after the `fstat` is bounded as well.
118
+ *
119
+ * Why refuse symlinks at all: defense-in-depth against a symlink at the
120
+ * path pointing at an arbitrary target the agent controls. The gate contract
121
+ * is to assume the agent is hostile, so the refusal is cheap insurance
122
+ * (agent-tasks/d39f160e).
123
+ *
124
+ * Platforms without `O_NOFOLLOW` (Windows): an `lstat` runs first and
125
+ * refuses a symlink or a non-regular node before the open, because the open
126
+ * alone would follow a link. That leaves the old lstat-to-open window on
127
+ * those platforms; there is no FIFO node on the filesystem there to swap in
128
+ * (named pipes live in a separate namespace), and `O_NONBLOCK` is a no-op
129
+ * flag that is simply left out. The descriptor type check still runs.
130
+ *
131
+ * A future defensive fix belongs here and in `classifyOpenFailure` /
132
+ * `lstatOrNull`, and nowhere else.
133
+ */
134
+ export function readRegularFileBytesBounded(filePath, opts = {}) {
135
+ const maxBytes = opts.maxBytes ?? MAX_REGULAR_FILE_READ_BYTES;
136
+ const noFollow = opts.followSymlinks !== true;
137
+ if (noFollow && O_NOFOLLOW === undefined) {
138
+ const stat = lstatOrNull(filePath);
139
+ if (stat === null)
140
+ return { kind: "missing" };
141
+ if (stat.isSymbolicLink())
142
+ return { kind: "symlink" };
143
+ if (!stat.isFile())
144
+ return { kind: "not-regular" };
145
+ }
146
+ let fd;
147
+ try {
148
+ fd = fs.openSync(filePath, fs.constants.O_RDONLY | (noFollow ? (O_NOFOLLOW ?? 0) : 0) | O_NONBLOCK | O_NOCTTY);
149
+ }
150
+ catch {
151
+ return classifyOpenFailure(filePath, !noFollow);
152
+ }
45
153
  try {
46
- return { kind: "ok", content: fs.readFileSync(filePath, "utf8") };
154
+ const st = fs.fstatSync(fd);
155
+ if (!st.isFile())
156
+ return { kind: "not-regular" };
157
+ if (st.size > maxBytes)
158
+ return { kind: "unreadable" };
159
+ const bytes = readDescriptorBounded(fd, maxBytes);
160
+ if (bytes === null)
161
+ return { kind: "unreadable" };
162
+ return { kind: "ok", bytes };
47
163
  }
48
164
  catch {
49
165
  return { kind: "unreadable" };
50
166
  }
167
+ finally {
168
+ try {
169
+ fs.closeSync(fd);
170
+ }
171
+ catch {
172
+ // Already gone; nothing left to release.
173
+ }
174
+ }
175
+ }
176
+ /**
177
+ * {@link readRegularFileBytesBounded} decoded as utf8, for the by-path
178
+ * readers of a file a symlink at the path is acceptable for or a larger cap
179
+ * is justified (see {@link BoundedReadOptions}). Same five result kinds as
180
+ * {@link readRegularFileBytesBounded}; `missing` is the one a caller may
181
+ * treat as "legitimately absent", every other non-`ok` kind means something
182
+ * is at the path that must not be read as the file (a FIFO, a device, a
183
+ * directory, an oversized or unreadable file) and is fail-closed or
184
+ * explicitly reported by the caller.
185
+ */
186
+ export function readRegularFileBounded(filePath, opts = {}) {
187
+ const read = readRegularFileBytesBounded(filePath, opts);
188
+ return read.kind === "ok" ? { kind: "ok", content: read.bytes.toString("utf8") } : read;
189
+ }
190
+ /**
191
+ * Thrown by {@link readTextFileBoundedOrThrow}. `code` is `ENOENT` for a
192
+ * path that is not there (so a caller's existing `ENOENT` branch keeps
193
+ * meaning "absent") and `E_<KIND>` (`E_SYMLINK`, `E_NOT_REGULAR`,
194
+ * `E_UNREADABLE`) for anything else, which never matches `ENOENT`.
195
+ */
196
+ export class BoundedReadError extends Error {
197
+ code;
198
+ kind;
199
+ constructor(filePath, kind) {
200
+ const code = kind === "missing" ? "ENOENT" : `E_${kind.toUpperCase().replace(/-/g, "_")}`;
201
+ super(`${code}: ${filePath} ${DESCRIBE_KIND[kind]}`);
202
+ this.name = "BoundedReadError";
203
+ this.code = code;
204
+ this.kind = kind;
205
+ }
51
206
  }
207
+ const DESCRIBE_KIND = {
208
+ missing: "does not exist",
209
+ symlink: "is a symbolic link (refused)",
210
+ "not-regular": "is not a regular file (refused without a read)",
211
+ unreadable: "is unreadable or larger than the read cap",
212
+ };
52
213
  /**
53
- * Stat-only existence probe: "is anything there", nothing more. Uses the
54
- * same `lstatOrNull` helper (not `stat`) as `readRegularFileRejectingSymlink`
55
- * so a symlink or a directory answers `present`, not `missing`; this probe
56
- * cannot and does not classify WHAT is there (regular file, symlink,
57
- * directory), only whether lstat can see anything at all. A path lstat
58
- * cannot reach for any reason (absent, or unreachable: `EACCES`, `ENOTDIR`,
59
- * ...) comes back `missing`; lstat cannot distinguish those cases, so
60
- * neither does this probe. Callers that need the file-type distinction
61
- * (symlink vs directory vs regular) read the file instead, through
62
- * `readRegularFileRejectingSymlink`.
214
+ * {@link readRegularFileBounded} for the call sites that already wrap a
215
+ * `fs.readFileSync(path, "utf8")` in a try/catch (and, some of them, branch
216
+ * on `ENOENT`): the same bounded, non-blocking read, thrown as a
217
+ * {@link BoundedReadError} instead of returned, so the existing catch blocks
218
+ * keep their shape and every FIFO, device, directory or oversized file now
219
+ * lands in the catch block it would have reached on any other read error,
220
+ * rather than blocking the process.
63
221
  */
64
- export function probePathPresence(filePath) {
65
- return lstatOrNull(filePath) === null ? { kind: "missing" } : { kind: "present" };
222
+ export function readTextFileBoundedOrThrow(filePath, opts = {}) {
223
+ const read = readRegularFileBounded(filePath, opts);
224
+ if (read.kind === "ok")
225
+ return read.content;
226
+ throw new BoundedReadError(filePath, read.kind);
66
227
  }
67
228
  //# sourceMappingURL=read-regular-file.js.map