@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
@@ -4,9 +4,34 @@ import * as path from "node:path";
4
4
  import { parse as parseTomlDocument, TomlError } from "smol-toml";
5
5
  import { atomicWriteFile } from "../../io/atomic-write.js";
6
6
  import { EX_FAIL, HarnessExitError } from "../exit-codes.js";
7
+ // Import cycle: codex-snapshot.ts imports this module too. It is safe because
8
+ // neither module touches the other's bindings at top level; they are used only
9
+ // inside function bodies. Keep it that way (no top-level use of these three).
10
+ import { codexConfigFlag, listCodexSnapshots, nameInstallConfig, readCodexSnapshot, retireCodexSnapshot, } from "../gate/codex-snapshot.js";
11
+ import { kernelEntry, linkChain, walkLinkChain } from "../gate/link-chain.js";
12
+ import { namesSameEntry, sha256Hex } from "../gate/snapshot.js";
7
13
  export const CODEX_MANAGED_SOURCE_PREFIX = "# Harness Codex hook wiring.";
8
14
  export const CODEX_MANAGED_BEGIN = "# BEGIN harness-managed codex hooks";
9
15
  export const CODEX_MANAGED_END = "# END harness-managed codex hooks";
16
+ /**
17
+ * The comment line the installer writes directly under the BEGIN fence,
18
+ * followed by the block's generation: the sha256 of the generated content
19
+ * the block holds (`codexBlockGeneration`). `harness gate disable --runtime
20
+ * codex` records it in its snapshot, and a snapshot whose recorded generation
21
+ * differs from the block's is one a later install re-rendered the block over:
22
+ * it is retired as superseded and never applied, wherever it sits and whatever
23
+ * backup files exist. A comment adds, removes and reorders no hook entry, so
24
+ * Codex keeps every hook at the position its trust state was recorded for.
25
+ * The same content renders the same line, so an install of an unchanged
26
+ * manifest stays a no-op.
27
+ */
28
+ export const CODEX_BLOCK_GENERATION_PREFIX = "# harness block generation: ";
29
+ const BLOCK_GENERATION_LINE_RE = /^# harness block generation: ([0-9a-f]{64})$/;
30
+ /** The generation of a block holding `renderedContent` (the generated
31
+ * content as the block holds it, without its trailing newline). */
32
+ function codexBlockGeneration(renderedContent) {
33
+ return sha256Hex(renderedContent);
34
+ }
10
35
  /**
11
36
  * Thrown instead of a plain `Error` when the install refuses rather than
12
37
  * guesses (a duplicate/moved BEGIN marker, or a foreign table wedged
@@ -1159,10 +1184,12 @@ function ensureTrailingNewline(s) {
1159
1184
  return s.endsWith("\n") ? s : `${s}\n`;
1160
1185
  }
1161
1186
  function buildManagedBlock(generatedContent, generatedPath) {
1187
+ const rendered = ensureTrailingNewline(generatedContent).trimEnd();
1162
1188
  return [
1163
1189
  `${CODEX_MANAGED_SOURCE_PREFIX} Generated source: ${generatedPath}`,
1164
1190
  CODEX_MANAGED_BEGIN,
1165
- ensureTrailingNewline(generatedContent).trimEnd(),
1191
+ `${CODEX_BLOCK_GENERATION_PREFIX}${codexBlockGeneration(rendered)}`,
1192
+ rendered,
1166
1193
  CODEX_MANAGED_END,
1167
1194
  "",
1168
1195
  ].join("\n");
@@ -1391,40 +1418,6 @@ export function assertConfigSemanticInvariant(currentContent, nextContent, confi
1391
1418
  "(if one exists), or file an issue with the config shape that triggered this.", configPath);
1392
1419
  }
1393
1420
  }
1394
- /**
1395
- * Follows a dangling link chain hop by hop with `readlink` and returns the
1396
- * first path in it that does not exist, so a dangling refusal names the
1397
- * missing file rather than the first hop (which may be an existing
1398
- * intermediate link). Each relative link text is resolved against the
1399
- * physical directory of the link holding it, as the kernel does. Returns
1400
- * undefined when the chain cannot be walked (it changed under us, or a
1401
- * hop is not readable); the caller then words the refusal generically.
1402
- */
1403
- function missingEndOfLinkChain(start) {
1404
- const MAX_HOPS = 40;
1405
- let current = start;
1406
- for (let hop = 0; hop < MAX_HOPS; hop++) {
1407
- let next;
1408
- try {
1409
- const linkText = fs.readlinkSync(current);
1410
- next = path.resolve(fs.realpathSync(path.dirname(current)), linkText);
1411
- }
1412
- catch {
1413
- return undefined;
1414
- }
1415
- let nextStat;
1416
- try {
1417
- nextStat = fs.lstatSync(next);
1418
- }
1419
- catch (err) {
1420
- return err.code === "ENOENT" ? next : undefined;
1421
- }
1422
- if (!nextStat.isSymbolicLink())
1423
- return undefined;
1424
- current = next;
1425
- }
1426
- return undefined;
1427
- }
1428
1421
  /**
1429
1422
  * Resolves a symlinked config path to the regular file it points at (task
1430
1423
  * 1637fbc8). `atomicWriteFile` renames a temp file over its destination,
@@ -1433,9 +1426,13 @@ function missingEndOfLinkChain(start) {
1433
1426
  * resolved target instead keeps the link intact. A non-symlink path
1434
1427
  * (including a missing one) is returned unchanged. A dangling link, an
1435
1428
  * unresolvable chain (a loop, a permission error) or a link to anything
1436
- * other than a regular file is refused before anything is written.
1429
+ * other than a regular file is refused before anything is written. The
1430
+ * chain is walked as the kernel walks it (`walkLinkChain`): a `..` after a
1431
+ * directory link climbs out of the directory that link leads to, so the file
1432
+ * written is the one a read through the path gives. The path itself is taken
1433
+ * as given; a caller passes a spelling with `..` through `kernelEntry` first.
1437
1434
  */
1438
- function resolveConfigSymlink(requestedPath) {
1435
+ export function resolveConfigSymlink(requestedPath) {
1439
1436
  let linkStat;
1440
1437
  try {
1441
1438
  linkStat = fs.lstatSync(requestedPath);
@@ -1448,24 +1445,41 @@ function resolveConfigSymlink(requestedPath) {
1448
1445
  }
1449
1446
  if (!linkStat.isSymbolicLink())
1450
1447
  return requestedPath;
1451
- let resolved;
1448
+ // The gate's link walker decides where the chain ends, resolving every hop
1449
+ // as the kernel does. The JavaScript realpath folds `d/..` before it looks at
1450
+ // `d`: on its own it would call a link that reaches a file dangling, refuse
1451
+ // one the kernel resolves, or resolve one that reaches nothing to another
1452
+ // file. The refusal names the end of the chain, not the first hop (which may
1453
+ // be an existing link).
1454
+ const walked = walkLinkChain(requestedPath);
1455
+ if (walked.end === "dangling") {
1456
+ throw new CodexInstallRefusalError(`Codex config ${requestedPath} is a dangling symlink (its link chain ends at ` +
1457
+ `${walked.chain[walked.chain.length - 1]}, which does not exist); refusing to install, ` +
1458
+ `nothing was written. Create the link's target file (or point the link at an ` +
1459
+ `existing config) and re-run.`, requestedPath);
1460
+ }
1461
+ const cannotResolve = (cause) => new CodexInstallRefusalError(`Codex config ${requestedPath} is a symlink that cannot be resolved (${cause}); ` +
1462
+ `refusing to install, nothing was written. Fix the link chain and re-run.`, requestedPath);
1463
+ // The kernel's own lookup of the path is what Codex reads through.
1464
+ let read;
1452
1465
  try {
1453
- resolved = fs.realpathSync(requestedPath);
1466
+ read = fs.statSync(requestedPath);
1454
1467
  }
1455
1468
  catch (err) {
1456
1469
  const e = err;
1457
- if (e.code === "ENOENT") {
1458
- const missing = missingEndOfLinkChain(requestedPath);
1459
- throw new CodexInstallRefusalError(`Codex config ${requestedPath} is a dangling symlink (its link chain ends at ` +
1460
- `${missing ?? "a missing file"}, which does not exist); refusing to install, ` +
1461
- `nothing was written. Create the link's target file (or point the link at an ` +
1462
- `existing config) and re-run.`, requestedPath);
1463
- }
1464
- throw new CodexInstallRefusalError(`Codex config ${requestedPath} is a symlink that cannot be resolved ` +
1465
- `(${e.code ?? "error"}: ${e.message}); refusing to install, nothing was written. ` +
1466
- `Fix the link chain and re-run.`, requestedPath);
1467
- }
1468
- if (!fs.statSync(resolved).isFile()) {
1470
+ throw cannotResolve(`${e.code ?? "error"}: ${e.message}`);
1471
+ }
1472
+ if (walked.end !== "target")
1473
+ throw cannotResolve(`the link chain ends in a ${walked.end}`);
1474
+ const resolved = walked.chain[walked.chain.length - 1] ?? requestedPath;
1475
+ const atEnd = fs.statSync(resolved);
1476
+ // Defence in depth: the walker and the kernel have to agree on the file, and
1477
+ // a disagreement of any kind (a walker defect, a platform difference in how
1478
+ // a text is read) would otherwise write a file Codex never reads.
1479
+ if (read.dev !== atEnd.dev || read.ino !== atEnd.ino) {
1480
+ throw cannotResolve(`a read through it reaches another file than ${resolved}`);
1481
+ }
1482
+ if (!atEnd.isFile()) {
1469
1483
  throw new CodexInstallRefusalError(`Codex config ${requestedPath} is a symlink to ${resolved}, which is not a regular ` +
1470
1484
  `file; refusing to install, nothing was written. Point the link at a config file and re-run.`, requestedPath);
1471
1485
  }
@@ -1729,8 +1743,24 @@ function assertKeptHookTablesAreOperatorOwned(kept, currentContent, generatedCon
1729
1743
  }
1730
1744
  }
1731
1745
  export function planCodexConfigInstall(opts) {
1746
+ try {
1747
+ return planCodexConfigInstallUnnamed(opts);
1748
+ }
1749
+ catch (err) {
1750
+ // Every refusal below names the bare install command; the call's config
1751
+ // is added here, once, where it is known.
1752
+ if (err instanceof CodexInstallRefusalError && opts.configPath !== undefined) {
1753
+ throw new CodexInstallRefusalError(nameInstallConfig(err.message, kernelEntry(opts.configPath)), err.configPath);
1754
+ }
1755
+ throw err;
1756
+ }
1757
+ }
1758
+ function planCodexConfigInstallUnnamed(opts) {
1732
1759
  validateCodexManagedConfig(opts.generatedContent);
1733
- const requestedPath = opts.configPath ?? defaultCodexConfigPath(opts.homeDir);
1760
+ // A `..` after a directory link leads elsewhere than a lexical fold of the
1761
+ // spelling: every path built from it (the temp file, the backup) goes
1762
+ // through the directory the kernel reaches.
1763
+ const requestedPath = kernelEntry(opts.configPath ?? defaultCodexConfigPath(opts.homeDir));
1734
1764
  const configPath = resolveConfigSymlink(requestedPath);
1735
1765
  const linkPath = configPath !== requestedPath ? requestedPath : undefined;
1736
1766
  const viaLink = linkPath !== undefined ? ` (via symlink ${linkPath})` : "";
@@ -1801,6 +1831,7 @@ export function planCodexConfigInstall(opts) {
1801
1831
  return {
1802
1832
  configPath,
1803
1833
  ...(linkPath !== undefined ? { linkPath } : {}),
1834
+ ...(opts.configPath !== undefined ? { namedConfigPath: requestedPath } : {}),
1804
1835
  generatedPath: opts.generatedPath,
1805
1836
  currentContent,
1806
1837
  nextContent,
@@ -1817,13 +1848,60 @@ export function planCodexConfigInstall(opts) {
1817
1848
  function timestampForBackup(now) {
1818
1849
  return now.toISOString().replace(/[:.]/g, "-");
1819
1850
  }
1851
+ const INSTALL_BACKUP_STAMP_RE = /^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z$/;
1852
+ /** The time of the newest install that rewrote the config at `filePath`, in
1853
+ * epoch milliseconds, read from the `<filePath>.harness-backup-<timestamp>`
1854
+ * files `writeCodexConfigInstall` leaves beside it (one per write of an
1855
+ * existing config), or null when there is none. `harness gate enable
1856
+ * --runtime codex` uses it to tell a snapshot taken before a re-install
1857
+ * (whose units that install re-rendered) from one taken after it. Reads the
1858
+ * directory only. */
1859
+ export function latestCodexInstallBackupMs(filePath) {
1860
+ return latestCodexInstallBackup(filePath)?.ms ?? null;
1861
+ }
1862
+ /** Like {@link latestCodexInstallBackupMs}, and also the path of the newest
1863
+ * backup file, so a message can name the install that dated a snapshot. A
1864
+ * backup whose name spells the file in another letter case or normalization
1865
+ * form (an install that ran through `Config.toml` for `config.toml` on a
1866
+ * filesystem that folds those) counts when both spellings are one entry
1867
+ * (`namesSameEntry`); on a filesystem that keeps them apart, another file's
1868
+ * backups never do. */
1869
+ export function latestCodexInstallBackup(filePath) {
1870
+ const dir = path.dirname(filePath);
1871
+ const base = path.basename(filePath);
1872
+ const marker = ".harness-backup-";
1873
+ let names;
1874
+ try {
1875
+ names = fs.readdirSync(dir);
1876
+ }
1877
+ catch {
1878
+ return null;
1879
+ }
1880
+ let latest = null;
1881
+ for (const name of names) {
1882
+ const at = name.lastIndexOf(marker);
1883
+ if (at <= 0)
1884
+ continue;
1885
+ const spelled = name.slice(0, at);
1886
+ if (!namesSameEntry(dir, spelled, base, { symlinks: true }))
1887
+ continue;
1888
+ const m = INSTALL_BACKUP_STAMP_RE.exec(name.slice(at + marker.length));
1889
+ if (m === null)
1890
+ continue;
1891
+ const ms = Date.parse(`${m[1]}T${m[2]}:${m[3]}:${m[4]}.${m[5]}Z`);
1892
+ if (!Number.isNaN(ms) && (latest === null || ms > latest.ms)) {
1893
+ latest = { ms, path: path.join(dir, name) };
1894
+ }
1895
+ }
1896
+ return latest;
1897
+ }
1820
1898
  /** The config holds operator secrets (API tokens under `[mcp_servers.*]`,
1821
1899
  * Codex hook trust hashes); the install must never widen its permissions.
1822
1900
  * Preserves the existing file's own mode for both the rewritten config and
1823
1901
  * its backup, and falls back to `0o600` (owner read/write only) when
1824
1902
  * creating a config that did not exist before this install, rather than
1825
1903
  * `atomicWriteFile`'s own `0o644` default. */
1826
- function existingFileMode(filePath) {
1904
+ export function existingFileMode(filePath) {
1827
1905
  try {
1828
1906
  return fs.statSync(filePath).mode & 0o777;
1829
1907
  }
@@ -1834,28 +1912,325 @@ function existingFileMode(filePath) {
1834
1912
  return 0o600;
1835
1913
  }
1836
1914
  }
1837
- export function writeCodexConfigInstall(plan, opts = {}) {
1838
- if (!plan.changed)
1839
- return { ...plan, written: false };
1840
- fs.mkdirSync(path.dirname(plan.configPath), { recursive: true });
1915
+ /** Identity of a file as the filesystem sees it, so a snapshot's recorded
1916
+ * path (the link, the target, or a hard link) is matched to the config by
1917
+ * what it is, not by how it is spelled. */
1918
+ function fileIdentity(filePath) {
1919
+ try {
1920
+ const st = fs.statSync(filePath);
1921
+ return `${st.dev}:${st.ino}`;
1922
+ }
1923
+ catch {
1924
+ return null;
1925
+ }
1926
+ }
1927
+ /** Whether `recorded` names the file `target` with identity `targetId`
1928
+ * (taken before the install replaced it): the same absolute path, or the
1929
+ * same device and inode, which covers a symlink and a hard link to it. */
1930
+ function namesFile(recorded, target, targetId) {
1931
+ if (path.resolve(recorded) === path.resolve(target))
1932
+ return true;
1933
+ const recordedId = fileIdentity(recorded);
1934
+ return targetId !== null && recordedId !== null && targetId === recordedId;
1935
+ }
1936
+ /** The live Codex gate snapshots, beside the requested path, beside every
1937
+ * further hop of its link chain and beside the target, that
1938
+ * were taken from the config an install is about to rewrite. Read before the
1939
+ * write: the write replaces the file, which changes its inode. A snapshot
1940
+ * that cannot be read is not matched; it is reported so the operator knows
1941
+ * the gate will refuse on it. */
1942
+ function findSnapshotsOfConfig(plan) {
1943
+ const requested = plan.linkPath ?? plan.configPath;
1944
+ const id = fileIdentity(plan.configPath);
1945
+ // A snapshot sits beside the spelling the gate was run through, and every
1946
+ // hop of the chain from the requested path to the target is such a spelling.
1947
+ // One directory under two spellings (a symlinked directory) is read once:
1948
+ // a snapshot found twice would be renamed once and then fail to rename.
1949
+ const dirs = [];
1950
+ const seenDirs = new Set();
1951
+ for (const spelled of [...linkChain(requested), plan.configPath]) {
1952
+ const dir = path.dirname(spelled);
1953
+ let physical = dir;
1954
+ try {
1955
+ physical = fs.realpathSync.native(dir);
1956
+ }
1957
+ catch {
1958
+ // A directory that cannot be resolved is compared by its spelling.
1959
+ }
1960
+ if (seenDirs.has(physical))
1961
+ continue;
1962
+ seenDirs.add(physical);
1963
+ // Listed as spelled, except that a `..` is taken through the directory the
1964
+ // kernel reaches: the listing joins names to the directory, which folds it.
1965
+ dirs.push(dir.split(path.sep).includes("..") ? physical : dir);
1966
+ }
1967
+ const matched = [];
1968
+ const unreadable = [];
1969
+ for (const dir of dirs) {
1970
+ for (const snapPath of listCodexSnapshots(dir)) {
1971
+ const read = readCodexSnapshot(snapPath);
1972
+ if (!read.ok) {
1973
+ unreadable.push(snapPath);
1974
+ continue;
1975
+ }
1976
+ const recorded = read.snapshot.configPath;
1977
+ if (namesFile(recorded, plan.configPath, id) || namesFile(recorded, requested, id))
1978
+ matched.push(snapPath);
1979
+ }
1980
+ }
1981
+ return { matched, unreadable };
1982
+ }
1983
+ /**
1984
+ * Writes the install. A live gate snapshot of the config holds the hook
1985
+ * lines of the block this write replaces, so enabling it later would put an
1986
+ * outdated line back: every such snapshot (beside every hop of the requested
1987
+ * path's link chain and beside the target) is renamed to `*.superseded.json` right after the
1988
+ * write, whatever backup files exist. A rename that fails never fails the
1989
+ * install, which is already on disk: it is a warning (`snapshotWarnings`,
1990
+ * printed by the caller) naming the snapshot and the move-aside step. A
1991
+ * snapshot this cannot find (beside a link outside that chain) records the
1992
+ * block's generation marker, which this write changes when the content
1993
+ * changes, so `gate enable` and `gate disable` retire it on sight. The
1994
+ * backup-file dating in the gate stays as a further line of defence for a
1995
+ * snapshot without a marker (taken before the marker existed).
1996
+ */
1997
+ export function writeCodexConfigInstall(planned, opts = {}) {
1998
+ if (!planned.changed)
1999
+ return { ...planned, written: false };
2000
+ fs.mkdirSync(path.dirname(planned.configPath), { recursive: true });
2001
+ // A config directory that did not exist at plan time, spelled with `..`
2002
+ // after a directory link, could not be resolved then (`kernelEntry` keeps
2003
+ // such a spelling). It exists now, so the paths built from the spelling (the
2004
+ // temp file, the snapshot listing) go through the directory the kernel
2005
+ // reaches instead of a lexical fold into another one.
2006
+ const plan = { ...planned, configPath: kernelEntry(planned.configPath) };
2007
+ // The summary was built from the plan-time spelling: name the path written.
2008
+ if (plan.configPath !== planned.configPath) {
2009
+ plan.summary = plan.summary.replace(planned.configPath, () => plan.configPath);
2010
+ }
1841
2011
  const mode = existingFileMode(plan.configPath);
2012
+ const snapshots = findSnapshotsOfConfig(plan);
1842
2013
  // Only back up a config that actually existed before this install (task
1843
2014
  // 461ec064): a fresh install has nothing to protect, and writing a
1844
2015
  // 0-byte backup for it misreported a write that never happened.
2016
+ let result;
1845
2017
  if (!plan.configExisted) {
1846
2018
  atomicWriteFile(plan.configPath, plan.nextContent, { mode });
1847
- return { ...plan, written: true };
1848
- }
1849
- // A symlinked config's backup sits beside the link (task 1637fbc8), not
1850
- // beside the resolved target: the config holds secrets, and the target's
1851
- // directory is typically a dotfiles git work tree where an untracked
1852
- // backup is one `git add` away from being pushed. The backup is a fresh
1853
- // file, so it need not share the target's filesystem; only the atomic
1854
- // write of the target itself (temp file plus rename) must.
1855
- const backupBase = plan.linkPath ?? plan.configPath;
1856
- const backupPath = `${backupBase}.harness-backup-${timestampForBackup(opts.now ?? new Date())}`;
1857
- atomicWriteFile(backupPath, plan.currentContent, { mode });
1858
- atomicWriteFile(plan.configPath, plan.nextContent, { mode });
1859
- return { ...plan, backupPath, written: true };
2019
+ result = { ...plan, written: true };
2020
+ }
2021
+ else {
2022
+ // A symlinked config's backup sits beside the link (task 1637fbc8), not
2023
+ // beside the resolved target: the config holds secrets, and the target's
2024
+ // directory is typically a dotfiles git work tree where an untracked
2025
+ // backup is one `git add` away from being pushed. The backup is a fresh
2026
+ // file, so it need not share the target's filesystem; only the atomic
2027
+ // write of the target itself (temp file plus rename) must.
2028
+ const backupBase = plan.linkPath ?? plan.configPath;
2029
+ const backupPath = `${backupBase}.harness-backup-${timestampForBackup(opts.now ?? new Date())}`;
2030
+ atomicWriteFile(backupPath, plan.currentContent, { mode });
2031
+ atomicWriteFile(plan.configPath, plan.nextContent, { mode });
2032
+ result = { ...plan, backupPath, written: true };
2033
+ }
2034
+ const superseded = [];
2035
+ const warnings = snapshots.unreadable.map((p) => `the Codex gate snapshot ${p} cannot be read, so the install could not tell whether it belongs to ` +
2036
+ `this config; \`harness gate enable --runtime codex${codexConfigFlag(plan.namedConfigPath ?? null)}\` will refuse on it ` +
2037
+ "until you move it out of this directory.");
2038
+ for (const snapPath of snapshots.matched) {
2039
+ try {
2040
+ superseded.push(retireCodexSnapshot(snapPath, "superseded", (m) => new Error(m), "the config was installed, but "));
2041
+ }
2042
+ catch (err) {
2043
+ warnings.push(err.message);
2044
+ }
2045
+ }
2046
+ if (superseded.length > 0)
2047
+ result.supersededSnapshots = superseded;
2048
+ if (warnings.length > 0) {
2049
+ result.snapshotWarnings = warnings;
2050
+ }
2051
+ return result;
2052
+ }
2053
+ const HOOK_UNIT_HEADER_RE = /^\[\[hooks\.([A-Za-z][A-Za-z0-9_]*)\]\]$/;
2054
+ /**
2055
+ * The harness-owned hook units of the fenced managed block in `text`, with
2056
+ * exact offsets, for `harness gate` (the operator's switch for a blocking
2057
+ * hook). It reuses the installer's own range scan (`findManagedRange`), so
2058
+ * the refusals that scan raises (a duplicate BEGIN marker, a foreign table
2059
+ * wedged inside the block) apply here unchanged, and adds the stricter
2060
+ * reading an edit needs: the block must be fenced by BEGIN and a closing END
2061
+ * marker line, every non-blank line inside it must be a comment or part of a
2062
+ * unit of the exact shape the generator writes, and no harness hook comment
2063
+ * may sit outside the block (`assertNoOrphanHarnessHookTable`). Anything else
2064
+ * refuses instead of guessing which bytes are harness-owned. Returns null
2065
+ * when the file holds no managed block. The block's generation marker is read
2066
+ * too, never required: a block without it reads as `generation: null`.
2067
+ * Reads only; the file is never touched.
2068
+ */
2069
+ export function readCodexManagedHookUnits(text, configPath) {
2070
+ const range = findManagedRange(text, configPath);
2071
+ if (range === null)
2072
+ return null;
2073
+ const refuse = (why) => refuseHookBlockEdit(configPath, why);
2074
+ const beginLine = findMarkerLine(text, CODEX_MANAGED_BEGIN, "prefix", range.start, range.end);
2075
+ if (beginLine === -1) {
2076
+ return refuse(`the harness block has no '${CODEX_MANAGED_BEGIN}' fence (written by an older install); ` +
2077
+ "re-run `harness apply --runtime codex --install` once to rewrite it with fences");
2078
+ }
2079
+ assertNoOrphanHarnessHookTable(text, configPath, range);
2080
+ const endLine = lineStartAt(text, range.end - 1);
2081
+ // A drifted END (a foreign table between the last unit and the END marker)
2082
+ // ends the range before that table, so the range's last line is not the
2083
+ // END marker line and the same check refuses it.
2084
+ if (!createMarkerLineProbe(text)(endLine, CODEX_MANAGED_END, "whole")) {
2085
+ return refuse(`the block is not closed by a '${CODEX_MANAGED_END}' marker line right after its hook tables ` +
2086
+ "(move any table that sits between the last hook unit and the END marker to below the END " +
2087
+ "marker, or re-run `harness apply --runtime codex --install` to rewrite the block)");
2088
+ }
2089
+ const isMarkerLine = createMarkerLineProbe(text);
2090
+ const units = [];
2091
+ let pos = lineEndAfter(text, beginLine);
2092
+ const lineAt = (at) => text.slice(at, lineEndAfter(text, at)).trim();
2093
+ // Only the line right under BEGIN carries the generation; it is a comment,
2094
+ // so the scan below passes over it like the generated header.
2095
+ const generation = pos < endLine ? (BLOCK_GENERATION_LINE_RE.exec(lineAt(pos))?.[1] ?? null) : null;
2096
+ while (pos < endLine) {
2097
+ const trimmed = lineAt(pos);
2098
+ const isUnitComment = trimmed.startsWith("#") && isMarkerLine(pos, HARNESS_HOOK_COMMENT_PREFIX, "prefix");
2099
+ if (trimmed === "" || (trimmed.startsWith("#") && !isUnitComment)) {
2100
+ if (units.length > 0 && trimmed !== "") {
2101
+ return refuse(`line ${lineNumberAt(text, pos)} inside the block is a comment between hook units`);
2102
+ }
2103
+ pos = lineEndAfter(text, pos);
2104
+ continue;
2105
+ }
2106
+ if (!isUnitComment) {
2107
+ return refuse(`line ${lineNumberAt(text, pos)} inside the block is not part of a generated hook unit`);
2108
+ }
2109
+ const id = HOOK_ID_LINE_RE.exec(trimmed)?.[1];
2110
+ if (id === undefined) {
2111
+ return refuse(`the hook comment at line ${lineNumberAt(text, pos)} is not in the generated shape`);
2112
+ }
2113
+ const unitStart = pos;
2114
+ const body = [];
2115
+ let lastLineAt = pos;
2116
+ pos = lineEndAfter(text, pos);
2117
+ while (pos < endLine && lineAt(pos) !== "" && !lineAt(pos).startsWith("#")) {
2118
+ body.push(lineAt(pos));
2119
+ lastLineAt = pos;
2120
+ pos = lineEndAfter(text, pos);
2121
+ }
2122
+ units.push(parseHookUnit(id, body, unitStart, lastLineAt, text, refuse));
2123
+ }
2124
+ return { units, generation };
2125
+ }
2126
+ function refuseHookBlockEdit(configPath, why) {
2127
+ throw new CodexInstallRefusalError(`Codex config ${configPath}: ${why}; refusing to edit the harness-managed hook block. ` +
2128
+ "The file is untouched.", configPath);
2129
+ }
2130
+ function parseHookUnit(id, body, start, lastLineAt, text, refuse) {
2131
+ const where = `the hook unit at line ${lineNumberAt(text, start)}`;
2132
+ const header = HOOK_UNIT_HEADER_RE.exec(body[0] ?? "");
2133
+ const shapeOk = header !== null &&
2134
+ (body.length === 2 || (body.length === 3 && body[1].startsWith("matcher = "))) &&
2135
+ body[body.length - 1].startsWith("hooks = [");
2136
+ if (!shapeOk) {
2137
+ return refuse(`${where} is not the generated shape (header, optional matcher, hooks array)`);
2138
+ }
2139
+ let doc;
2140
+ try {
2141
+ doc = parseToml(body.join("\n"));
2142
+ }
2143
+ catch (err) {
2144
+ return refuse(`${where} does not parse as TOML (${describeTomlParseError(err)})`);
2145
+ }
2146
+ const event = header[1];
2147
+ const hooksTable = isTomlTable(doc) ? doc.hooks : undefined;
2148
+ const entries = isTomlTable(hooksTable) ? hooksTable[event] : undefined;
2149
+ const entry = Array.isArray(entries) && entries.length === 1 ? entries[0] : undefined;
2150
+ if (!isTomlTable(entry) || !Array.isArray(entry.hooks)) {
2151
+ return refuse(`${where} does not define one ${event} entry with a hooks array`);
2152
+ }
2153
+ const matcher = entry.matcher;
2154
+ if (matcher !== undefined && typeof matcher !== "string") {
2155
+ return refuse(`${where} has a matcher that is not a string`);
2156
+ }
2157
+ const commands = entry.hooks.flatMap((h) => isTomlTable(h) && typeof h.command === "string" ? [h.command] : []);
2158
+ const rawLine = text.slice(lastLineAt, lineEndAfter(text, lastLineAt));
2159
+ return {
2160
+ id,
2161
+ event,
2162
+ matcher: matcher ?? null,
2163
+ commands,
2164
+ disabled: entry.hooks.length === 0,
2165
+ start,
2166
+ hooksStart: lastLineAt + (rawLine.length - rawLine.trimStart().length),
2167
+ hooksEnd: lastLineAt + rawLine.trimEnd().length,
2168
+ };
2169
+ }
2170
+ /**
2171
+ * The safety net for a gate edit of the managed block. First the installer's
2172
+ * own semantic invariant (both documents parse, and everything outside the
2173
+ * hook event arrays is deep-equal), then the part that invariant leaves out
2174
+ * on purpose, compared entry by entry: per hook event the arrays have the
2175
+ * same length, every entry is deep-equal to its counterpart except exactly
2176
+ * `expected.counts[event]` entries, and each of those differs only in its
2177
+ * `hooks` array (emptied by a neutralise, filled again by a restore). So a
2178
+ * gate edit can neither drop, add or reorder an entry nor move a key from one
2179
+ * entry to another, and Codex keeps every other hook at the position its
2180
+ * trust state was recorded for.
2181
+ */
2182
+ export function assertCodexHookEditInvariant(before, after, configPath, expected) {
2183
+ assertConfigSemanticInvariant(before, after, configPath);
2184
+ const eventArrays = (doc) => {
2185
+ const arrays = new Map();
2186
+ const hooks = isTomlTable(doc) ? doc.hooks : undefined;
2187
+ if (!isTomlTable(hooks))
2188
+ return arrays;
2189
+ for (const [key, value] of Object.entries(hooks)) {
2190
+ if (Array.isArray(value))
2191
+ arrays.set(key, value);
2192
+ }
2193
+ return arrays;
2194
+ };
2195
+ const same = (a, b) => firstDifferingKeyPath(a, b, []) === null;
2196
+ const withHooks = (entry, hooks) => isTomlTable(entry) ? { ...entry, hooks } : entry;
2197
+ const hooksOf = (entry) => isTomlTable(entry) ? entry.hooks : undefined;
2198
+ const emptied = (entry) => {
2199
+ const hooks = hooksOf(entry);
2200
+ return Array.isArray(hooks) && hooks.length === 0;
2201
+ };
2202
+ const filled = (entry) => {
2203
+ const hooks = hooksOf(entry);
2204
+ return Array.isArray(hooks) && hooks.length > 0;
2205
+ };
2206
+ const refuse = (event, why) => {
2207
+ throw new CodexInstallRefusalError(`Codex config ${configPath}: the gate edit would ${why} in the '${event}' hook entries; ` +
2208
+ "refusing to write. The file is untouched.", configPath);
2209
+ };
2210
+ const was = eventArrays(parseToml(before));
2211
+ const now = eventArrays(parseToml(after));
2212
+ for (const event of new Set([...was.keys(), ...now.keys(), ...Object.keys(expected.counts)])) {
2213
+ const a = was.get(event) ?? [];
2214
+ const b = now.get(event) ?? [];
2215
+ if (a.length !== b.length) {
2216
+ refuse(event, `change the number of entries from ${a.length} to ${b.length}`);
2217
+ }
2218
+ let changed = 0;
2219
+ for (let i = 0; i < a.length; i += 1) {
2220
+ if (same(a[i], b[i]))
2221
+ continue;
2222
+ changed += 1;
2223
+ const relationHolds = expected.direction === "neutralise"
2224
+ ? filled(a[i]) && emptied(b[i]) && same(withHooks(a[i], []), b[i])
2225
+ : emptied(a[i]) && filled(b[i]) && same(withHooks(b[i], []), a[i]);
2226
+ if (!relationHolds) {
2227
+ refuse(event, `change entry ${i} by more than its hooks array`);
2228
+ }
2229
+ }
2230
+ const want = expected.counts[event] ?? 0;
2231
+ if (changed !== want) {
2232
+ refuse(event, `change ${changed} entries, expected ${want}`);
2233
+ }
2234
+ }
1860
2235
  }
1861
2236
  //# sourceMappingURL=install-codex-config.js.map