@lannguyensi/harness 0.63.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 (702) hide show
  1. package/CHANGELOG.md +90 -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 -338
  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 -705
  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 -378
  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 +15 -2607
  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 -243
  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/register-gate-group.d.ts +5 -0
  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 +5 -0
  145. package/dist/cli/register-operator-lifecycle.js +20 -0
  146. package/dist/cli/register-operator-lifecycle.js.map +1 -0
  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-setup-group.d.ts +5 -0
  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.d.ts +5 -0
  160. package/dist/cli/remove/register.js +25 -0
  161. package/dist/cli/remove/register.js.map +1 -0
  162. package/dist/cli/shell-quote.d.ts +7 -0
  163. package/dist/cli/shell-quote.js +17 -0
  164. package/dist/cli/shell-quote.js.map +1 -0
  165. package/dist/cli/uninstall/index.d.ts +4 -2
  166. package/dist/cli/uninstall/index.js +15 -7
  167. package/dist/cli/uninstall/index.js.map +1 -1
  168. package/dist/cli/uninstall/register.d.ts +5 -0
  169. package/dist/cli/uninstall/register.js +171 -0
  170. package/dist/cli/uninstall/register.js.map +1 -0
  171. package/dist/cli/uninstall/snapshot.d.ts +15 -0
  172. package/dist/cli/uninstall/snapshot.js +38 -0
  173. package/dist/cli/uninstall/snapshot.js.map +1 -1
  174. package/dist/cli/validate/checks.d.ts +0 -77
  175. package/dist/cli/validate/checks.js +3 -1049
  176. package/dist/cli/validate/checks.js.map +1 -1
  177. package/dist/cli/validate/index.js +19 -15
  178. package/dist/cli/validate/index.js.map +1 -1
  179. package/dist/index.d.ts +0 -3
  180. package/dist/index.js +0 -3
  181. package/dist/index.js.map +1 -1
  182. package/dist/io/claude-mcp.d.ts +1 -1
  183. package/dist/io/claude-mcp.js +27 -14
  184. package/dist/io/claude-mcp.js.map +1 -1
  185. package/dist/io/harness-lock.js +2 -2
  186. package/dist/io/harness-lock.js.map +1 -1
  187. package/dist/io/lock.d.ts +0 -26
  188. package/dist/io/lock.js +10 -27
  189. package/dist/io/lock.js.map +1 -1
  190. package/dist/io/merge-settings.js +6 -4
  191. package/dist/io/merge-settings.js.map +1 -1
  192. package/dist/io/project-name.d.ts +22 -39
  193. package/dist/io/project-name.js +25 -42
  194. package/dist/io/project-name.js.map +1 -1
  195. package/dist/io/read-regular-file.d.ts +103 -40
  196. package/dist/io/read-regular-file.js +196 -35
  197. package/dist/io/read-regular-file.js.map +1 -1
  198. package/dist/io/restart-hints.js +3 -6
  199. package/dist/io/restart-hints.js.map +1 -1
  200. package/dist/io/version-compare.d.ts +1 -3
  201. package/dist/io/version-compare.js +1 -3
  202. package/dist/io/version-compare.js.map +1 -1
  203. package/dist/io/write-regular-file.d.ts +30 -0
  204. package/dist/io/write-regular-file.js +85 -0
  205. package/dist/io/write-regular-file.js.map +1 -0
  206. package/dist/overrides/index.d.ts +1 -0
  207. package/dist/overrides/index.js +1 -0
  208. package/dist/overrides/index.js.map +1 -1
  209. package/dist/overrides/merge-layers.d.ts +43 -0
  210. package/dist/overrides/merge-layers.js +76 -0
  211. package/dist/overrides/merge-layers.js.map +1 -0
  212. package/dist/overrides/merge.d.ts +16 -0
  213. package/dist/overrides/merge.js +21 -8
  214. package/dist/overrides/merge.js.map +1 -1
  215. package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -69
  216. package/dist/policy-packs/builtin/branch-protection-runtime.js +12 -84
  217. package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
  218. package/dist/policy-packs/builtin/branch-protection.d.ts +7 -30
  219. package/dist/policy-packs/builtin/branch-protection.js +56 -89
  220. package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
  221. package/dist/policy-packs/config-check.d.ts +7 -5
  222. package/dist/policy-packs/config-check.js +2 -2
  223. package/dist/policy-packs/config-check.js.map +1 -1
  224. package/dist/policy-packs/expand.d.ts +1 -3
  225. package/dist/policy-packs/expand.js +5 -42
  226. package/dist/policy-packs/expand.js.map +1 -1
  227. package/dist/policy-packs/index.d.ts +3 -3
  228. package/dist/policy-packs/index.js +2 -2
  229. package/dist/policy-packs/index.js.map +1 -1
  230. package/dist/policy-packs/registry.d.ts +9 -38
  231. package/dist/policy-packs/registry.js +5 -65
  232. package/dist/policy-packs/registry.js.map +1 -1
  233. package/dist/policy-packs/runtime.d.ts +0 -4
  234. package/dist/policy-packs/runtime.js +9 -22
  235. package/dist/policy-packs/runtime.js.map +1 -1
  236. package/dist/policy-packs/types.d.ts +0 -19
  237. package/dist/policy-packs/ux-compare.d.ts +1 -11
  238. package/dist/policy-packs/ux-compare.js +6 -42
  239. package/dist/policy-packs/ux-compare.js.map +1 -1
  240. package/dist/policy-packs/ux-drift-check.d.ts +5 -5
  241. package/dist/policy-packs/ux-drift-check.js +17 -22
  242. package/dist/policy-packs/ux-drift-check.js.map +1 -1
  243. package/dist/policy-packs/version-check.d.ts +5 -26
  244. package/dist/policy-packs/version-check.js +19 -74
  245. package/dist/policy-packs/version-check.js.map +1 -1
  246. package/dist/probes/memory.d.ts +1 -1
  247. package/dist/probes/memory.js +1 -1
  248. package/dist/probes/memory.js.map +1 -1
  249. package/dist/runtime/agent-facing.d.ts +9 -0
  250. package/dist/runtime/agent-facing.js +28 -14
  251. package/dist/runtime/agent-facing.js.map +1 -1
  252. package/dist/runtime/bounded-text.d.ts +15 -0
  253. package/dist/runtime/bounded-text.js +27 -0
  254. package/dist/runtime/bounded-text.js.map +1 -0
  255. package/dist/runtime/git-branch.d.ts +125 -0
  256. package/dist/runtime/git-branch.js +381 -0
  257. package/dist/runtime/git-branch.js.map +1 -0
  258. package/dist/runtime/hermetic-spawn-guard.d.ts +2 -2
  259. package/dist/runtime/hermetic-spawn-guard.js +24 -34
  260. package/dist/runtime/hermetic-spawn-guard.js.map +1 -1
  261. package/dist/runtime/home-dir.js +3 -2
  262. package/dist/runtime/home-dir.js.map +1 -1
  263. package/dist/runtime/tool-name-aliases.d.ts +0 -6
  264. package/dist/runtime/tool-name-aliases.js +5 -18
  265. package/dist/runtime/tool-name-aliases.js.map +1 -1
  266. package/dist/schema/grounding.d.ts +7 -54
  267. package/dist/schema/grounding.js +10 -12
  268. package/dist/schema/grounding.js.map +1 -1
  269. package/dist/schema/hooks.d.ts +39 -136
  270. package/dist/schema/hooks.js +3 -6
  271. package/dist/schema/hooks.js.map +1 -1
  272. package/dist/schema/index.d.ts +114 -3828
  273. package/dist/schema/index.js +41 -80
  274. package/dist/schema/index.js.map +1 -1
  275. package/dist/schema/memory.d.ts +54 -131
  276. package/dist/schema/memory.js +2 -2
  277. package/dist/schema/memory.js.map +1 -1
  278. package/dist/schema/policy-packs.d.ts +3 -45
  279. package/dist/schema/policy-packs.js +7 -13
  280. package/dist/schema/policy-packs.js.map +1 -1
  281. package/dist/schema/policy-ux.d.ts +7 -0
  282. package/dist/schema/policy-ux.js +18 -0
  283. package/dist/schema/policy-ux.js.map +1 -0
  284. package/dist/schema/removed-keys.d.ts +185 -0
  285. package/dist/schema/removed-keys.js +531 -0
  286. package/dist/schema/removed-keys.js.map +1 -0
  287. package/dist/schema/tools.d.ts +30 -268
  288. package/dist/schema/tools.js +4 -4
  289. package/dist/schema/tools.js.map +1 -1
  290. package/package.json +5 -16
  291. package/dist/cli/approve/branch-protection.d.ts +0 -69
  292. package/dist/cli/approve/branch-protection.js +0 -144
  293. package/dist/cli/approve/branch-protection.js.map +0 -1
  294. package/dist/cli/approve/risk.d.ts +0 -112
  295. package/dist/cli/approve/risk.js +0 -197
  296. package/dist/cli/approve/risk.js.map +0 -1
  297. package/dist/cli/approve/stdin-report.d.ts +0 -57
  298. package/dist/cli/approve/stdin-report.js +0 -145
  299. package/dist/cli/approve/stdin-report.js.map +0 -1
  300. package/dist/cli/approve/understanding.d.ts +0 -410
  301. package/dist/cli/approve/understanding.js +0 -996
  302. package/dist/cli/approve/understanding.js.map +0 -1
  303. package/dist/cli/audit.d.ts +0 -80
  304. package/dist/cli/audit.js +0 -252
  305. package/dist/cli/audit.js.map +0 -1
  306. package/dist/cli/delegate/index.d.ts +0 -76
  307. package/dist/cli/delegate/index.js +0 -443
  308. package/dist/cli/delegate/index.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/rogue-ledger.d.ts +0 -53
  319. package/dist/cli/doctor/rogue-ledger.js +0 -153
  320. package/dist/cli/doctor/rogue-ledger.js.map +0 -1
  321. package/dist/cli/doctor/session-start-preflight-setup-version.d.ts +0 -83
  322. package/dist/cli/doctor/session-start-preflight-setup-version.js +0 -114
  323. package/dist/cli/doctor/session-start-preflight-setup-version.js.map +0 -1
  324. package/dist/cli/doctor/settings-drift.d.ts +0 -25
  325. package/dist/cli/doctor/settings-drift.js +0 -213
  326. package/dist/cli/doctor/settings-drift.js.map +0 -1
  327. package/dist/cli/doctor/toolchain-parity.d.ts +0 -63
  328. package/dist/cli/doctor/toolchain-parity.js +0 -154
  329. package/dist/cli/doctor/toolchain-parity.js.map +0 -1
  330. package/dist/cli/doctor/ug-auto-approvals.d.ts +0 -40
  331. package/dist/cli/doctor/ug-auto-approvals.js +0 -91
  332. package/dist/cli/doctor/ug-auto-approvals.js.map +0 -1
  333. package/dist/cli/doctor/ug-delegations.d.ts +0 -26
  334. package/dist/cli/doctor/ug-delegations.js +0 -121
  335. package/dist/cli/doctor/ug-delegations.js.map +0 -1
  336. package/dist/cli/doctor/ug-inflight.d.ts +0 -35
  337. package/dist/cli/doctor/ug-inflight.js +0 -57
  338. package/dist/cli/doctor/ug-inflight.js.map +0 -1
  339. package/dist/cli/doctor/understanding-mode-env.d.ts +0 -51
  340. package/dist/cli/doctor/understanding-mode-env.js +0 -98
  341. package/dist/cli/doctor/understanding-mode-env.js.map +0 -1
  342. package/dist/cli/dry-run.d.ts +0 -46
  343. package/dist/cli/dry-run.js +0 -250
  344. package/dist/cli/dry-run.js.map +0 -1
  345. package/dist/cli/event-input.d.ts +0 -28
  346. package/dist/cli/event-input.js +0 -73
  347. package/dist/cli/event-input.js.map +0 -1
  348. package/dist/cli/explain-action.d.ts +0 -20
  349. package/dist/cli/explain-action.js +0 -27
  350. package/dist/cli/explain-action.js.map +0 -1
  351. package/dist/cli/explain-policy.d.ts +0 -135
  352. package/dist/cli/explain-policy.js +0 -266
  353. package/dist/cli/explain-policy.js.map +0 -1
  354. package/dist/cli/explain.d.ts +0 -31
  355. package/dist/cli/explain.js +0 -159
  356. package/dist/cli/explain.js.map +0 -1
  357. package/dist/cli/gc/index.d.ts +0 -63
  358. package/dist/cli/gc/index.js +0 -566
  359. package/dist/cli/gc/index.js.map +0 -1
  360. package/dist/cli/pack/approve-escape.d.ts +0 -19
  361. package/dist/cli/pack/approve-escape.js +0 -190
  362. package/dist/cli/pack/approve-escape.js.map +0 -1
  363. package/dist/cli/pack/auto-approve-path.d.ts +0 -146
  364. package/dist/cli/pack/auto-approve-path.js +0 -462
  365. package/dist/cli/pack/auto-approve-path.js.map +0 -1
  366. package/dist/cli/pack/hook-codex-post-tool-use.d.ts +0 -25
  367. package/dist/cli/pack/hook-codex-post-tool-use.js +0 -160
  368. package/dist/cli/pack/hook-codex-post-tool-use.js.map +0 -1
  369. package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +0 -48
  370. package/dist/cli/pack/hook-codex-pre-tool-use.js +0 -474
  371. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +0 -1
  372. package/dist/cli/pack/hook-codex-stop.d.ts +0 -35
  373. package/dist/cli/pack/hook-codex-stop.js +0 -329
  374. package/dist/cli/pack/hook-codex-stop.js.map +0 -1
  375. package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +0 -24
  376. package/dist/cli/pack/hook-codex-user-prompt-submit.js +0 -93
  377. package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +0 -1
  378. package/dist/cli/pack/hook-post-merge-gate-record.d.ts +0 -37
  379. package/dist/cli/pack/hook-post-merge-gate-record.js +0 -190
  380. package/dist/cli/pack/hook-post-merge-gate-record.js.map +0 -1
  381. package/dist/cli/pack/hook-post-merge-gate.d.ts +0 -34
  382. package/dist/cli/pack/hook-post-merge-gate.js +0 -277
  383. package/dist/cli/pack/hook-post-merge-gate.js.map +0 -1
  384. package/dist/cli/pack/hook-post-tool-use.d.ts +0 -45
  385. package/dist/cli/pack/hook-post-tool-use.js +0 -137
  386. package/dist/cli/pack/hook-post-tool-use.js.map +0 -1
  387. package/dist/cli/pack/hook-pre-tool-use.d.ts +0 -92
  388. package/dist/cli/pack/hook-pre-tool-use.js +0 -1328
  389. package/dist/cli/pack/hook-pre-tool-use.js.map +0 -1
  390. package/dist/cli/pack/hook-runtime-reality.d.ts +0 -63
  391. package/dist/cli/pack/hook-runtime-reality.js +0 -210
  392. package/dist/cli/pack/hook-runtime-reality.js.map +0 -1
  393. package/dist/cli/pack/hook-solution-acceptance-writeguard.d.ts +0 -32
  394. package/dist/cli/pack/hook-solution-acceptance-writeguard.js +0 -337
  395. package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +0 -1
  396. package/dist/cli/pack/hook-solution-acceptance.d.ts +0 -157
  397. package/dist/cli/pack/hook-solution-acceptance.js +0 -530
  398. package/dist/cli/pack/hook-solution-acceptance.js.map +0 -1
  399. package/dist/cli/pack/hook-stay-in-scope.d.ts +0 -37
  400. package/dist/cli/pack/hook-stay-in-scope.js +0 -128
  401. package/dist/cli/pack/hook-stay-in-scope.js.map +0 -1
  402. package/dist/cli/pack/hook-subagent-start.d.ts +0 -23
  403. package/dist/cli/pack/hook-subagent-start.js +0 -88
  404. package/dist/cli/pack/hook-subagent-start.js.map +0 -1
  405. package/dist/cli/pack/hook-subagent-stop.d.ts +0 -19
  406. package/dist/cli/pack/hook-subagent-stop.js +0 -41
  407. package/dist/cli/pack/hook-subagent-stop.js.map +0 -1
  408. package/dist/cli/pack/hook-track-active-claim.d.ts +0 -27
  409. package/dist/cli/pack/hook-track-active-claim.js +0 -275
  410. package/dist/cli/pack/hook-track-active-claim.js.map +0 -1
  411. package/dist/cli/pack/transcript-report-scan.d.ts +0 -71
  412. package/dist/cli/pack/transcript-report-scan.js +0 -359
  413. package/dist/cli/pack/transcript-report-scan.js.map +0 -1
  414. package/dist/cli/pack/understanding-report-schema-hint.d.ts +0 -26
  415. package/dist/cli/pack/understanding-report-schema-hint.js +0 -120
  416. package/dist/cli/pack/understanding-report-schema-hint.js.map +0 -1
  417. package/dist/cli/pack/upgrade.d.ts +0 -32
  418. package/dist/cli/pack/upgrade.js +0 -273
  419. package/dist/cli/pack/upgrade.js.map +0 -1
  420. package/dist/cli/pause/index.d.ts +0 -113
  421. package/dist/cli/pause/index.js +0 -251
  422. package/dist/cli/pause/index.js.map +0 -1
  423. package/dist/cli/pause-check.d.ts +0 -22
  424. package/dist/cli/pause-check.js +0 -54
  425. package/dist/cli/pause-check.js.map +0 -1
  426. package/dist/cli/policy/intercept.d.ts +0 -233
  427. package/dist/cli/policy/intercept.js +0 -1020
  428. package/dist/cli/policy/intercept.js.map +0 -1
  429. package/dist/cli/policy/risk-envelope-enrichment.d.ts +0 -40
  430. package/dist/cli/policy/risk-envelope-enrichment.js +0 -108
  431. package/dist/cli/policy/risk-envelope-enrichment.js.map +0 -1
  432. package/dist/cli/record/index.d.ts +0 -81
  433. package/dist/cli/record/index.js +0 -348
  434. package/dist/cli/record/index.js.map +0 -1
  435. package/dist/cli/resolve-env.d.ts +0 -32
  436. package/dist/cli/resolve-env.js +0 -47
  437. package/dist/cli/resolve-env.js.map +0 -1
  438. package/dist/cli/session-export/index.d.ts +0 -46
  439. package/dist/cli/session-export/index.js +0 -169
  440. package/dist/cli/session-export/index.js.map +0 -1
  441. package/dist/cli/session-export/redact.d.ts +0 -22
  442. package/dist/cli/session-export/redact.js +0 -47
  443. package/dist/cli/session-export/redact.js.map +0 -1
  444. package/dist/cli/session-export/transcript.d.ts +0 -24
  445. package/dist/cli/session-export/transcript.js +0 -164
  446. package/dist/cli/session-export/transcript.js.map +0 -1
  447. package/dist/cli/session-start/branch-check.d.ts +0 -18
  448. package/dist/cli/session-start/branch-check.js +0 -140
  449. package/dist/cli/session-start/branch-check.js.map +0 -1
  450. package/dist/cli/session-start/index.d.ts +0 -121
  451. package/dist/cli/session-start/index.js +0 -591
  452. package/dist/cli/session-start/index.js.map +0 -1
  453. package/dist/cli/session-start/shared-options.d.ts +0 -103
  454. package/dist/cli/session-start/shared-options.js +0 -107
  455. package/dist/cli/session-start/shared-options.js.map +0 -1
  456. package/dist/cli/session-start/stale-base-check.d.ts +0 -46
  457. package/dist/cli/session-start/stale-base-check.js +0 -352
  458. package/dist/cli/session-start/stale-base-check.js.map +0 -1
  459. package/dist/cli/session-start/toolchain-parity.d.ts +0 -267
  460. package/dist/cli/session-start/toolchain-parity.js +0 -797
  461. package/dist/cli/session-start/toolchain-parity.js.map +0 -1
  462. package/dist/cli/smoke/assertions.d.ts +0 -46
  463. package/dist/cli/smoke/assertions.js +0 -170
  464. package/dist/cli/smoke/assertions.js.map +0 -1
  465. package/dist/cli/smoke/index.d.ts +0 -76
  466. package/dist/cli/smoke/index.js +0 -245
  467. package/dist/cli/smoke/index.js.map +0 -1
  468. package/dist/cli/smoke/runner.d.ts +0 -55
  469. package/dist/cli/smoke/runner.js +0 -134
  470. package/dist/cli/smoke/runner.js.map +0 -1
  471. package/dist/cli/smoke/stream-parser.d.ts +0 -65
  472. package/dist/cli/smoke/stream-parser.js +0 -115
  473. package/dist/cli/smoke/stream-parser.js.map +0 -1
  474. package/dist/cli/test-risk.d.ts +0 -26
  475. package/dist/cli/test-risk.js +0 -34
  476. package/dist/cli/test-risk.js.map +0 -1
  477. package/dist/io/display-path.d.ts +0 -11
  478. package/dist/io/display-path.js +0 -29
  479. package/dist/io/display-path.js.map +0 -1
  480. package/dist/io/duration.d.ts +0 -5
  481. package/dist/io/duration.js +0 -50
  482. package/dist/io/duration.js.map +0 -1
  483. package/dist/io/extract.d.ts +0 -79
  484. package/dist/io/extract.js +0 -226
  485. package/dist/io/extract.js.map +0 -1
  486. package/dist/io/ledger-record.d.ts +0 -83
  487. package/dist/io/ledger-record.js +0 -301
  488. package/dist/io/ledger-record.js.map +0 -1
  489. package/dist/io/read-json-dir-entries.d.ts +0 -36
  490. package/dist/io/read-json-dir-entries.js +0 -48
  491. package/dist/io/read-json-dir-entries.js.map +0 -1
  492. package/dist/io/safe-json-parse.d.ts +0 -5
  493. package/dist/io/safe-json-parse.js +0 -21
  494. package/dist/io/safe-json-parse.js.map +0 -1
  495. package/dist/policies/index.d.ts +0 -5
  496. package/dist/policies/index.js +0 -6
  497. package/dist/policies/index.js.map +0 -1
  498. package/dist/policies/ledger-client.d.ts +0 -113
  499. package/dist/policies/ledger-client.js +0 -500
  500. package/dist/policies/ledger-client.js.map +0 -1
  501. package/dist/policies/producers.d.ts +0 -12
  502. package/dist/policies/producers.js +0 -61
  503. package/dist/policies/producers.js.map +0 -1
  504. package/dist/policies/requires.d.ts +0 -75
  505. package/dist/policies/requires.js +0 -240
  506. package/dist/policies/requires.js.map +0 -1
  507. package/dist/policies/timestamp.d.ts +0 -14
  508. package/dist/policies/timestamp.js +0 -36
  509. package/dist/policies/timestamp.js.map +0 -1
  510. package/dist/policy-packs/builtin/permission-profiles.d.ts +0 -11
  511. package/dist/policy-packs/builtin/permission-profiles.js +0 -74
  512. package/dist/policy-packs/builtin/permission-profiles.js.map +0 -1
  513. package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +0 -286
  514. package/dist/policy-packs/builtin/post-merge-gate-runtime.js +0 -397
  515. package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +0 -1
  516. package/dist/policy-packs/builtin/post-merge-gate.d.ts +0 -56
  517. package/dist/policy-packs/builtin/post-merge-gate.js +0 -347
  518. package/dist/policy-packs/builtin/post-merge-gate.js.map +0 -1
  519. package/dist/policy-packs/builtin/solution-acceptance-reconnect.d.ts +0 -50
  520. package/dist/policy-packs/builtin/solution-acceptance-reconnect.js +0 -151
  521. package/dist/policy-packs/builtin/solution-acceptance-reconnect.js.map +0 -1
  522. package/dist/policy-packs/builtin/solution-acceptance-runtime.d.ts +0 -323
  523. package/dist/policy-packs/builtin/solution-acceptance-runtime.js +0 -672
  524. package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +0 -1
  525. package/dist/policy-packs/builtin/solution-acceptance.d.ts +0 -45
  526. package/dist/policy-packs/builtin/solution-acceptance.js +0 -226
  527. package/dist/policy-packs/builtin/solution-acceptance.js.map +0 -1
  528. package/dist/policy-packs/builtin/understanding-before-execution/active-claim.d.ts +0 -25
  529. package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js +0 -94
  530. package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js.map +0 -1
  531. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.d.ts +0 -35
  532. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js +0 -86
  533. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js.map +0 -1
  534. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +0 -210
  535. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +0 -361
  536. package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +0 -1
  537. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +0 -304
  538. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +0 -734
  539. package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +0 -1
  540. package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.d.ts +0 -36
  541. package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js +0 -73
  542. package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js.map +0 -1
  543. package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +0 -19
  544. package/dist/policy-packs/builtin/understanding-before-execution/index.js +0 -83
  545. package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +0 -1
  546. package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.d.ts +0 -135
  547. package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js +0 -618
  548. package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js.map +0 -1
  549. package/dist/policy-packs/builtin/understanding-before-execution/ledger.d.ts +0 -25
  550. package/dist/policy-packs/builtin/understanding-before-execution/ledger.js +0 -56
  551. package/dist/policy-packs/builtin/understanding-before-execution/ledger.js.map +0 -1
  552. package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.d.ts +0 -20
  553. package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js +0 -93
  554. package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js.map +0 -1
  555. package/dist/policy-packs/builtin/understanding-before-execution/markers.d.ts +0 -126
  556. package/dist/policy-packs/builtin/understanding-before-execution/markers.js +0 -245
  557. package/dist/policy-packs/builtin/understanding-before-execution/markers.js.map +0 -1
  558. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.d.ts +0 -29
  559. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js +0 -82
  560. package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js.map +0 -1
  561. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.d.ts +0 -71
  562. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js +0 -175
  563. package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js.map +0 -1
  564. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +0 -620
  565. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +0 -1047
  566. package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +0 -1
  567. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.d.ts +0 -128
  568. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js +0 -213
  569. package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js.map +0 -1
  570. package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.d.ts +0 -129
  571. package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js +0 -166
  572. package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js.map +0 -1
  573. package/dist/policy-packs/builtin/understanding-before-execution/task-markers.d.ts +0 -164
  574. package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js +0 -275
  575. package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js.map +0 -1
  576. package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +0 -1
  577. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +0 -10
  578. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +0 -1
  579. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +0 -526
  580. package/dist/policy-packs/builtin/understanding-before-execution.js +0 -1074
  581. package/dist/policy-packs/builtin/understanding-before-execution.js.map +0 -1
  582. package/dist/policy-packs/permission-translator.d.ts +0 -9
  583. package/dist/policy-packs/permission-translator.js +0 -76
  584. package/dist/policy-packs/permission-translator.js.map +0 -1
  585. package/dist/runtime/action-envelope.d.ts +0 -64
  586. package/dist/runtime/action-envelope.js +0 -46
  587. package/dist/runtime/action-envelope.js.map +0 -1
  588. package/dist/runtime/approval-signing.d.ts +0 -111
  589. package/dist/runtime/approval-signing.js +0 -384
  590. package/dist/runtime/approval-signing.js.map +0 -1
  591. package/dist/runtime/bash-match-facts.d.ts +0 -60
  592. package/dist/runtime/bash-match-facts.js +0 -196
  593. package/dist/runtime/bash-match-facts.js.map +0 -1
  594. package/dist/runtime/bash-match-registry.d.ts +0 -112
  595. package/dist/runtime/bash-match-registry.js +0 -406
  596. package/dist/runtime/bash-match-registry.js.map +0 -1
  597. package/dist/runtime/bash-prefix-parse.d.ts +0 -31
  598. package/dist/runtime/bash-prefix-parse.js +0 -576
  599. package/dist/runtime/bash-prefix-parse.js.map +0 -1
  600. package/dist/runtime/command-normalize.d.ts +0 -658
  601. package/dist/runtime/command-normalize.js +0 -2410
  602. package/dist/runtime/command-normalize.js.map +0 -1
  603. package/dist/runtime/deletion-target-resolve.d.ts +0 -28
  604. package/dist/runtime/deletion-target-resolve.js +0 -1078
  605. package/dist/runtime/deletion-target-resolve.js.map +0 -1
  606. package/dist/runtime/destructive-shell-floor.d.ts +0 -19
  607. package/dist/runtime/destructive-shell-floor.js +0 -611
  608. package/dist/runtime/destructive-shell-floor.js.map +0 -1
  609. package/dist/runtime/environment-resolver.d.ts +0 -36
  610. package/dist/runtime/environment-resolver.js +0 -138
  611. package/dist/runtime/environment-resolver.js.map +0 -1
  612. package/dist/runtime/git-context.d.ts +0 -201
  613. package/dist/runtime/git-context.js +0 -422
  614. package/dist/runtime/git-context.js.map +0 -1
  615. package/dist/runtime/index.d.ts +0 -12
  616. package/dist/runtime/index.js +0 -13
  617. package/dist/runtime/index.js.map +0 -1
  618. package/dist/runtime/intercept.d.ts +0 -494
  619. package/dist/runtime/intercept.js +0 -1313
  620. package/dist/runtime/intercept.js.map +0 -1
  621. package/dist/runtime/kube-context.d.ts +0 -16
  622. package/dist/runtime/kube-context.js +0 -63
  623. package/dist/runtime/kube-context.js.map +0 -1
  624. package/dist/runtime/kubectl-target-parse.d.ts +0 -31
  625. package/dist/runtime/kubectl-target-parse.js +0 -249
  626. package/dist/runtime/kubectl-target-parse.js.map +0 -1
  627. package/dist/runtime/ledger-add.d.ts +0 -16
  628. package/dist/runtime/ledger-add.js +0 -150
  629. package/dist/runtime/ledger-add.js.map +0 -1
  630. package/dist/runtime/ledger-writer.d.ts +0 -27
  631. package/dist/runtime/ledger-writer.js +0 -46
  632. package/dist/runtime/ledger-writer.js.map +0 -1
  633. package/dist/runtime/pause-sentinel.d.ts +0 -60
  634. package/dist/runtime/pause-sentinel.js +0 -156
  635. package/dist/runtime/pause-sentinel.js.map +0 -1
  636. package/dist/runtime/pending-approval.d.ts +0 -23
  637. package/dist/runtime/pending-approval.js +0 -67
  638. package/dist/runtime/pending-approval.js.map +0 -1
  639. package/dist/runtime/read-only-bash.d.ts +0 -141
  640. package/dist/runtime/read-only-bash.js +0 -2204
  641. package/dist/runtime/read-only-bash.js.map +0 -1
  642. package/dist/runtime/recovery-git-commit.d.ts +0 -22
  643. package/dist/runtime/recovery-git-commit.js +0 -284
  644. package/dist/runtime/recovery-git-commit.js.map +0 -1
  645. package/dist/runtime/reject-malformed-session-id.d.ts +0 -8
  646. package/dist/runtime/reject-malformed-session-id.js +0 -16
  647. package/dist/runtime/reject-malformed-session-id.js.map +0 -1
  648. package/dist/runtime/risk-classifier.d.ts +0 -38
  649. package/dist/runtime/risk-classifier.js +0 -311
  650. package/dist/runtime/risk-classifier.js.map +0 -1
  651. package/dist/runtime/session-id.d.ts +0 -113
  652. package/dist/runtime/session-id.js +0 -193
  653. package/dist/runtime/session-id.js.map +0 -1
  654. package/dist/runtime/shell-word.d.ts +0 -62
  655. package/dist/runtime/shell-word.js +0 -410
  656. package/dist/runtime/shell-word.js.map +0 -1
  657. package/dist/runtime/task-providers/agent-tasks.d.ts +0 -103
  658. package/dist/runtime/task-providers/agent-tasks.js +0 -245
  659. package/dist/runtime/task-providers/agent-tasks.js.map +0 -1
  660. package/dist/runtime/when-eval.d.ts +0 -62
  661. package/dist/runtime/when-eval.js +0 -212
  662. package/dist/runtime/when-eval.js.map +0 -1
  663. package/dist/runtime/workflow-policies.d.ts +0 -207
  664. package/dist/runtime/workflow-policies.js +0 -596
  665. package/dist/runtime/workflow-policies.js.map +0 -1
  666. package/dist/schema/audit.d.ts +0 -71
  667. package/dist/schema/audit.js +0 -32
  668. package/dist/schema/audit.js.map +0 -1
  669. package/dist/schema/doctor.d.ts +0 -25
  670. package/dist/schema/doctor.js +0 -23
  671. package/dist/schema/doctor.js.map +0 -1
  672. package/dist/schema/environments.d.ts +0 -215
  673. package/dist/schema/environments.js +0 -101
  674. package/dist/schema/environments.js.map +0 -1
  675. package/dist/schema/extract.d.ts +0 -9
  676. package/dist/schema/extract.js +0 -86
  677. package/dist/schema/extract.js.map +0 -1
  678. package/dist/schema/permission-profiles.d.ts +0 -2292
  679. package/dist/schema/permission-profiles.js +0 -60
  680. package/dist/schema/permission-profiles.js.map +0 -1
  681. package/dist/schema/policies.d.ts +0 -974
  682. package/dist/schema/policies.js +0 -298
  683. package/dist/schema/policies.js.map +0 -1
  684. package/dist/schema/requires.d.ts +0 -131
  685. package/dist/schema/requires.js +0 -88
  686. package/dist/schema/requires.js.map +0 -1
  687. package/dist/schema/risk.d.ts +0 -144
  688. package/dist/schema/risk.js +0 -194
  689. package/dist/schema/risk.js.map +0 -1
  690. package/dist/schema/session-start-preflight.d.ts +0 -10
  691. package/dist/schema/session-start-preflight.js +0 -106
  692. package/dist/schema/session-start-preflight.js.map +0 -1
  693. package/dist/schema/stale-base-check.d.ts +0 -18
  694. package/dist/schema/stale-base-check.js +0 -37
  695. package/dist/schema/stale-base-check.js.map +0 -1
  696. package/dist/schema/toolchain-parity.d.ts +0 -21
  697. package/dist/schema/toolchain-parity.js +0 -48
  698. package/dist/schema/toolchain-parity.js.map +0 -1
  699. package/dist/schema/workflows.d.ts +0 -519
  700. package/dist/schema/workflows.js +0 -81
  701. package/dist/schema/workflows.js.map +0 -1
  702. package/scripts/runtime-reality-docker-probe.mjs +0 -71
@@ -5,36 +5,21 @@ import { parseProbedVersion, compareVersionFloor } from "../../io/version-compar
5
5
  import { resolveGeneratedDir } from "../../io/generated-dir.js";
6
6
  import { inspectMemory, projectRejectionWarns } from "../../probes/memory.js";
7
7
  import { RealMcpProbe, probeAll, } from "../../probes/mcp.js";
8
+ import { formatPostureWarning, } from "../../schema/index.js";
8
9
  import { EVIDENCE_LEDGER_DB_ENV, GROUNDING_MCP_SERVER_NAME, } from "../apply/generate-settings.js";
9
10
  import { parsePackSource } from "../../policy-packs/source.js";
10
11
  import { resolveBuiltin } from "../../policy-packs/registry.js";
11
- import { expandPolicyPacks } from "../../policy-packs/index.js";
12
12
  import { checkPolicyPackConfigs } from "../../policy-packs/config-check.js";
13
13
  import { checkPolicyPackVersions } from "../../policy-packs/version-check.js";
14
14
  import { checkPolicyPackUxDrift } from "../../policy-packs/ux-drift-check.js";
15
15
  import { selectRuntime } from "../apply/apply.js";
16
16
  import { lastApplyPath, readLastApply } from "../../io/last-apply.js";
17
- import { checkHookBudgetLedgerMargin, checkPolicyRiskWithoutEnvScope, checkSolutionAcceptanceKnobIgnored, checkSolutionAcceptanceProducer, checkTemplatePolicyDrift, checkTriggerBoundaryDrift, checkWorkflows, createDefaultGitIgnoreProbe, } from "../validate/checks.js";
18
- import { isDerivedPolicy } from "../../runtime/workflow-policies.js";
19
- import { resolveScopedProjectName } from "../../runtime/git-context.js";
20
- import { loadManifest, resolvePaths } from "../loader.js";
17
+ import { loadManifest } from "../loader.js";
21
18
  import { countCodexDiagnostics, findOnPath, runCodexTargetChecks, } from "./codex.js";
22
19
  import { countOpencodeDiagnostics, runOpencodeTargetChecks, } from "./opencode.js";
23
20
  import { checkNpmBinPath } from "./npm-bin-path.js";
24
- import { scanForRogueLedgers } from "./rogue-ledger.js";
25
21
  import { buildClaudeMcpRegistration } from "./claude-mcp.js";
26
- import { checkUnderstandingModeEnvDivergence, isUnderstandingPackEnabled, } from "./understanding-mode-env.js";
27
- import { checkAutoApproveMode } from "./auto-approve-mode.js";
28
- import { checkBypassWithoutAutoApprove } from "./bypass-without-auto-approve.js";
29
- import { checkSessionStartPreflightSetupVersion, } from "./session-start-preflight-setup-version.js";
30
- import { SESSION_START_PREFLIGHT_SETUP_BUILD_MIN_VERSION } from "../../schema/session-start-preflight.js";
31
- import { runDoctorToolchainParity, } from "./toolchain-parity.js";
32
- import { buildUgAutoApprovals, DEFAULT_RECENT_SESSIONS } from "./ug-auto-approvals.js";
33
- import { buildUgDelegations } from "./ug-delegations.js";
34
- import { buildUgInflight } from "./ug-inflight.js";
35
- import { buildSettingsDrift } from "./settings-drift.js";
36
- import { buildCodexConfigDrift, isCodexOptedIntoAutoApprove } from "./codex-config-drift.js";
37
- import { LOCK_BASENAME } from "../../io/harness-lock.js";
22
+ import { buildHookLiveness, countHookLiveness, livenessRuntimes } from "./hook-liveness.js";
38
23
  import { isDoctorTarget, KNOWN_DOCTOR_TARGETS, } from "./types.js";
39
24
  export { isDoctorTarget, KNOWN_DOCTOR_TARGETS };
40
25
  const HOME_PLACEHOLDER = "~";
@@ -341,8 +326,7 @@ function checkHookVersion(hook, versionProbe) {
341
326
  /**
342
327
  * Wraps a version probe with a per-full-argv cache, keyed on
343
328
  * `JSON.stringify(cmd)` so two commands sharing only `cmd[0]` (e.g.
344
- * `["understanding-gate", "--version"]` vs. `["understanding-gate",
345
- * "--check"]`) are never conflated into the same cache slot; only a
329
+ * `["some-bin", "--version"]` vs. `["some-bin", "--check"]`) are never conflated into the same cache slot; only a
346
330
  * byte-identical argv array is deduped. Exported standalone (task
347
331
  * ab634898) so this caching contract has its own focused
348
332
  * unit test independent of any particular pack's hook shape.
@@ -356,62 +340,6 @@ export function memoizeVersionProbe(probe) {
356
340
  return cache.get(key) ?? null;
357
341
  };
358
342
  }
359
- /**
360
- * Hook-level `min_version` floor on policy-pack-expanded hooks (task
361
- * ab634898). `checkHooks` above only walks `manifest.hooks[]`, but the
362
- * hooks Claude Code actually runs also include whatever
363
- * `expandPolicyPacks` contributes, e.g. understanding-before-execution's
364
- * UserPromptSubmit/Stop hooks, floored at understanding-gate 0.5.0
365
- * (see `src/policy-packs/builtin/understanding-before-execution.ts`).
366
- * Those pack-expanded hooks never reached `checkHookVersion`, so an
367
- * operator on an older understanding-gate saw a clean doctor report
368
- * even though the pause wiring (or the Understanding Report's 10th
369
- * section) was silently degraded below the declared floor.
370
- *
371
- * Reuses `checkHookVersion` verbatim so the warning wording matches the
372
- * manifest-hook case exactly. `versionProbe` is wrapped with a
373
- * per-command cache so two hooks that share one `version_command` (the
374
- * common case: user-prompt-submit and stop both probe
375
- * `understanding-gate --version`) spawn the underlying binary once, not
376
- * twice. Only below-floor / probe-failed / parse-failed results are
377
- * returned; a hook at or above its floor produces nothing, mirroring
378
- * the pack-level floor's "green ones produce nothing" contract
379
- * (`checkPolicyPackVersions`). Always warn, never error: the pack still
380
- * runs in degraded mode rather than failing outright.
381
- *
382
- * Expands against the runtime a plain `harness apply` would select
383
- * (`selectRuntime` in `src/cli/apply/apply.ts`: recorded in `.last-apply`,
384
- * inferred from its files, else the default), never `opts.target`:
385
- * `--target codex` / `--target opencode` additionally evaluate the
386
- * harness-side adapter health for that runtime, they do not change which
387
- * runtime is actually installed and running the hooks. Matches the
388
- * sibling pack-level check's `resolveBuiltin(pack, runtime)` further below
389
- * (task ab634898: keying this on `--target` produced a below-floor install
390
- * that showed no warning under `--target codex` and a spurious one under
391
- * `--target opencode`, where the pack never wires in the first place; task
392
- * 04b8abcf: expanding against the default instead of the applied runtime
393
- * made doctor and apply diverge on a codex-recorded machine).
394
- */
395
- function checkPolicyPackHookVersions(manifest, versionProbe, runtime) {
396
- const expansion = expandPolicyPacks(manifest, runtime);
397
- const dedupedProbe = memoizeVersionProbe(versionProbe);
398
- const gaps = [];
399
- for (const hook of expansion.hooks) {
400
- const version = checkHookVersion(hook, dedupedProbe);
401
- if (version && version.status === "warn" && hook.min_version) {
402
- gaps.push({
403
- name: hook.name,
404
- event: hook.event,
405
- declaredMinVersion: hook.min_version,
406
- kind: version.kind,
407
- actualVersion: version.actualVersion ?? null,
408
- versionCommand: hook.version_command ?? [],
409
- message: version.message,
410
- });
411
- }
412
- }
413
- return gaps;
414
- }
415
343
  function checkHooks(manifest, home, opts) {
416
344
  const versionProbe = opts.versionProbe ?? (() => null);
417
345
  return manifest.hooks.map((hook) => {
@@ -442,89 +370,15 @@ function checkHooks(manifest, home, opts) {
442
370
  return base({ status: "ok" });
443
371
  });
444
372
  }
445
- /** The literal prefix of a ledger tag — the part before the first `:`. */
446
- function ledgerTagPrefix(ledgerTag) {
447
- const colon = ledgerTag.indexOf(":");
448
- return colon === -1 ? ledgerTag : ledgerTag.slice(0, colon);
449
- }
450
- /**
451
- * Does any manifest hook plausibly *produce* `prefix`-tagged ledger
452
- * entries? The policy's own consumer hook (`policy.hook`) is excluded:
453
- * a gate that reads the tag cannot also be what satisfies it.
454
- *
455
- * "Plausibly produces" is a coarse substring match of the tag prefix
456
- * against the hook command — a producer is typically a SessionStart
457
- * runner like `agent-preflight` whose command names the domain. The
458
- * match is prefix-granular by necessity: the command is an opaque
459
- * shell string, and the full `preflight:${BRANCH}` tag never appears
460
- * in it literally. So the signal is asymmetric. "No producer found"
461
- * is reliable. "Producer found" is a heuristic that can give false
462
- * reassurance: a hook producing `preflight:${REPO}` will mask a
463
- * `preflight:${BRANCH}` gap, and a once-per-session producer will mask
464
- * a `within: 10m` window it cannot actually keep fresh. This check is
465
- * therefore a floor (it catches the total-absence case), not a proof
466
- * of satisfiability.
467
- */
468
- function hasProducerHook(manifest, policy, prefix) {
469
- // An empty prefix (a leading-colon tag like `:foo`) would
470
- // substring-match every hook command. Treat it as "no producer
471
- // identifiable" so the gap is surfaced rather than silently
472
- // suppressed by a vacuous match.
473
- if (prefix === "")
474
- return false;
475
- return manifest.hooks.some((h) => h.name !== policy.hook && h.command.includes(prefix));
476
- }
477
- function buildPolicies(manifest) {
478
- return manifest.policies.map((p) => {
479
- const report = {
480
- name: p.name,
481
- schemaValid: true,
482
- caveat: "schema valid; last-evaluated tracking ships in Phase 4",
483
- // F7 (review round 2): mark provenance so the rendered list can
484
- // append "(derived from workflows[])" instead of listing a
485
- // workflow-derived policy indistinguishably from a hand-authored
486
- // one. `doctor` loads via `loadManifest`, which now folds derived
487
- // policies in via `withDerivedPolicies` (F2), so this manifest's
488
- // `policies[]` already contains them.
489
- ...(isDerivedPolicy(p) ? { derived: true } : {}),
490
- };
491
- // Producer-gap check (task ce50df99): a `block` policy whose
492
- // required tag carries a `within` freshness window cannot stay
493
- // satisfied by a one-time action — it needs a recurring producer.
494
- // If no manifest hook produces the tag, the gate silently walls
495
- // off whatever it triggers on (the founding-incident lockout:
496
- // `preflight-before-investigation` blocking every `git status`).
497
- // Policies without `within` only need the tag to exist once, which
498
- // the normal review / PR workflow supplies, so they are not
499
- // flagged.
500
- //
501
- // Refinement (task f97e152f): a non-empty `producers:` array on
502
- // the policy itself is the schema's way of declaring the recovery
503
- // path. For example `dogfood-before-release` deliberately wants
504
- // the operator to record a manual smoke summary; an automatic
505
- // SessionStart producer would defeat the gate's purpose. When that
506
- // documented producer exists the warning would be a false positive
507
- // and is suppressed. The check still fires when both kinds are
508
- // absent. The `length === 0` clause is defensive: the schema
509
- // already enforces `producers: .min(1).optional()`, so a defined
510
- // array is guaranteed non-empty for any manifest that loaded.
511
- if (p.enforcement === "block" &&
512
- // operator_only: true (task 2cc73f55) policies declare no
513
- // requires: at all — there is no ledger_tag/within to go stale, so
514
- // there is nothing for a producer to keep fresh.
515
- p.requires !== undefined &&
516
- p.requires.within !== undefined &&
517
- (p.producers === undefined || p.producers.length === 0)) {
518
- const prefix = ledgerTagPrefix(p.requires.ledger_tag);
519
- if (!hasProducerHook(manifest, p, prefix)) {
520
- report.producerGap = {
521
- ledgerTag: p.requires.ledger_tag,
522
- within: p.requires.within,
523
- };
524
- }
525
- }
526
- return report;
527
- });
373
+ function packExpansionRuntimeReport(selection, warning) {
374
+ return {
375
+ ...(warning !== undefined ? { warning } : {}),
376
+ runtime: selection.runtime,
377
+ source: selection.runtimeSource,
378
+ ...(selection.previousRuntime !== undefined
379
+ ? { previousRuntime: selection.previousRuntime }
380
+ : {}),
381
+ };
528
382
  }
529
383
  /**
530
384
  * Declared-but-not-live policy pack check. `expandPolicyPacks` silently
@@ -536,37 +390,7 @@ function buildPolicies(manifest) {
536
390
  * Skipped (`enabled: false`) packs are NOT checked: they're not
537
391
  * expected to be live, and flagging them would flood the report.
538
392
  */
539
- /**
540
- * Sentinel "cannot tell" probe: shallow runs answer every ignoredness
541
- * question with `null` instead of spawning `git check-ignore`. Exported
542
- * (with the resolver below) so a test can pin the no-spawn contract by
543
- * identity instead of mocking `node:child_process`.
544
- */
545
- export const NULL_GIT_IGNORE_PROBE = () => null;
546
- /**
547
- * Probe resolution order: an explicit (test) probe always wins; `shallow`
548
- * degrades to the no-spawn sentinel, mirroring how the npm-bin probe and
549
- * MCP probes degrade; otherwise the real `git check-ignore` probe runs
550
- * against the process cwd.
551
- */
552
- export function resolveGitIgnoreProbe(opts) {
553
- if (opts.gitIgnoreProbe)
554
- return opts.gitIgnoreProbe;
555
- if (opts.shallow)
556
- return NULL_GIT_IGNORE_PROBE;
557
- return createDefaultGitIgnoreProbe();
558
- }
559
- function packExpansionRuntimeReport(selection, warning) {
560
- return {
561
- ...(warning !== undefined ? { warning } : {}),
562
- runtime: selection.runtime,
563
- source: selection.runtimeSource,
564
- ...(selection.previousRuntime !== undefined
565
- ? { previousRuntime: selection.previousRuntime }
566
- : {}),
567
- };
568
- }
569
- function buildPolicyPacks(manifest, versionProbe, gitIgnoreProbe, runtime) {
393
+ function buildPolicyPacks(manifest, runtime) {
570
394
  const unresolved = [];
571
395
  for (const pack of manifest.policy_packs) {
572
396
  if (!pack.enabled)
@@ -596,10 +420,10 @@ function buildPolicyPacks(manifest, versionProbe, gitIgnoreProbe, runtime) {
596
420
  configPath: issue.configPath,
597
421
  message: issue.message,
598
422
  }));
599
- const versionGaps = checkPolicyPackVersions(manifest, versionProbe).map((gap) => ({
423
+ const versionGaps = checkPolicyPackVersions(manifest).map((gap) => ({
600
424
  name: gap.packName,
601
425
  declaredMinVersion: gap.declaredMinVersion,
602
- actualVersion: gap.actualVersion,
426
+ actualVersion: null,
603
427
  message: gap.message,
604
428
  }));
605
429
  const uxDrift = checkPolicyPackUxDrift(manifest).map((drift) => ({
@@ -607,129 +431,7 @@ function buildPolicyPacks(manifest, versionProbe, gitIgnoreProbe, runtime) {
607
431
  fields: drift.fields,
608
432
  message: drift.message,
609
433
  }));
610
- // Same array as the producer check on purpose: countDiagnostics and the
611
- // renderers already tally / print `solutionAcceptance` by severity, so
612
- // the knob-ignored warning (task 24f6ceb9) inherits doctor parity with
613
- // `harness validate` for free — the #308 pattern.
614
- const solutionAcceptance = [
615
- ...checkSolutionAcceptanceProducer(manifest),
616
- ...checkSolutionAcceptanceKnobIgnored(manifest, gitIgnoreProbe),
617
- ];
618
- return { unresolved, configIssues, versionGaps, uxDrift, solutionAcceptance };
619
- }
620
- function buildWorkflows(manifest) {
621
- const entries = manifest.workflows.map((wf) => {
622
- const review = wf.steps.find((s) => s.kind === "review_subagent");
623
- const merge = wf.steps.find((s) => s.kind === "merge");
624
- return {
625
- name: wf.name,
626
- steps: wf.steps.length,
627
- reviewSpawn: review?.kind === "review_subagent" ? review.spawn : null,
628
- reviewTemplate: review?.kind === "review_subagent" ? (review.template ?? null) : null,
629
- mergeGate: merge?.kind === "merge" ? merge.gate : null,
630
- taskLabels: wf.when.task_label ?? [],
631
- };
632
- });
633
- // F3 (review round 2, 99f47307 Slice 1): doctor previously imported
634
- // validate's workflow-gate check nowhere, so a spawn: "required"
635
- // workflow with the merge gate unwired (or wired to the wrong hook
636
- // trigger, F5) showed green here even though `harness validate` errors
637
- // on it. Delegates to the shared `checkWorkflows` aggregate (review
638
- // round 3: the one list validate runs too, so the two cannot drift
639
- // again), mirroring `buildTemplateDrift` / `buildTriggerBoundaryDrift`.
640
- const workflowChecks = partitionDiagnosticsBySeverity(checkWorkflows(manifest));
641
- return {
642
- declared: manifest.workflows.length,
643
- templates: Object.keys(manifest.review_templates).length,
644
- entries,
645
- errors: workflowChecks.errors,
646
- warnings: workflowChecks.warnings,
647
- };
648
- }
649
- /**
650
- * Phase 7 #6 — Risk Gate wiring health. Counts the three Risk Gate
651
- * surfaces and flags the misconfigurations that make the gate inert or
652
- * silently fail-closed. Pure: manifest in, section out, no I/O.
653
- */
654
- function buildRiskGate(manifest) {
655
- const classifiers = manifest.risk.classifiers.length;
656
- const resolvers = manifest.environments.resolvers.length;
657
- const whenPolicies = manifest.policies.filter((p) => p.when !== undefined).length;
658
- const warnings = [];
659
- if (whenPolicies > 0 && classifiers === 0) {
660
- warnings.push(`${whenPolicies} policy(ies) declare \`when:\` but no \`risk.classifiers[]\` are declared; ` +
661
- `every action classifies as unclassified, so \`risk.*\` clauses match fail-closed ("unknown is not safe")`);
662
- }
663
- if (whenPolicies > 0 && resolvers === 0) {
664
- warnings.push(`${whenPolicies} policy(ies) declare \`when:\` but no \`environments.resolvers[]\` are declared; ` +
665
- `every action resolves to environment \`unknown\``);
666
- }
667
- if (whenPolicies === 0 && (classifiers > 0 || resolvers > 0)) {
668
- warnings.push("risk classifiers / environment resolvers are declared but no policy consumes them via `when:` — the Risk Gate is inert");
669
- }
670
- // Risk-clause policies that forgot to scope via `environment.name`.
671
- // Delegate to the shared validate check so doctor and `harness validate`
672
- // stay in parity (same logic, same clauses, same thresholds). The check
673
- // covers risk.severity_at_least, risk.category_in, AND action.reversible:
674
- // all three clauses fail-closed to matched=true on an unclassified action
675
- // per `runtime/when-eval.ts`. Map each Diagnostic message into a warning
676
- // string, mirroring the checkSolutionAcceptanceProducer pattern above.
677
- for (const diag of checkPolicyRiskWithoutEnvScope(manifest)) {
678
- warnings.push(diag.message);
679
- }
680
- return { classifiers, resolvers, whenPolicies, warnings };
681
- }
682
- /**
683
- * Template-policy drift (task adf037c1): shipped operator_only security
684
- * policies missing from an aged installed manifest. Delegates to the
685
- * shared validate check so `harness doctor` and `harness validate` stay
686
- * in parity. Each Diagnostic is a missing kill-switch defense and maps to
687
- * errorCount (see countDiagnostics), the doctor-convention signal that a
688
- * dogfood/CI run should fail until the manifest is caught up or the name
689
- * is explicitly acknowledged under doctor.ignore_template_drift.
690
- */
691
- /**
692
- * Splits a `Diagnostic[]` into the `{ errors, warnings }` message-array
693
- * shape every drift-style doctor section uses (task 037cfb7c review round
694
- * 3: `buildTemplateDrift` and `buildTriggerBoundaryDrift` had become
695
- * byte-identical bodies around two different `checkX(manifest)` calls;
696
- * this is the one place that split lives now).
697
- */
698
- function partitionDiagnosticsBySeverity(diags) {
699
- return {
700
- errors: diags.filter((d) => d.severity === "error").map((d) => d.message),
701
- warnings: diags.filter((d) => d.severity === "warning").map((d) => d.message),
702
- };
703
- }
704
- function buildTemplateDrift(manifest) {
705
- return partitionDiagnosticsBySeverity(checkTemplatePolicyDrift(manifest));
706
- }
707
- /**
708
- * Trigger-boundary drift (task 037cfb7c): shipped-by-name `bash_match`
709
- * triggers (hook- and policy-level) missing a boundary alternative the
710
- * template has, or missing a boundary group entirely. Doctor-only, like
711
- * `checkTemplatePolicyDrift` immediately above: `checkTriggerBoundaryDrift`
712
- * is deliberately not wired into validate's `runAssetChecks`, so
713
- * `harness validate` does not run it (only `harness doctor` does). Uses
714
- * the same `partitionDiagnosticsBySeverity` split as `buildTemplateDrift`
715
- * above: `checkTriggerBoundaryDrift` only emits `error`-severity
716
- * diagnostics today, but a future non-`error` diagnostic now surfaces in
717
- * `warnings` instead of being silently dropped.
718
- */
719
- function buildTriggerBoundaryDrift(manifest) {
720
- return partitionDiagnosticsBySeverity(checkTriggerBoundaryDrift(manifest));
721
- }
722
- /**
723
- * Hook-budget-vs-ledger-timeout margin (task d20a7e0c). Delegates to the
724
- * shared validate check so `harness doctor` and `harness validate` stay
725
- * in parity, mirroring `buildTemplateDrift` immediately above.
726
- * `checkHookBudgetLedgerMargin` only ever emits `error`-severity
727
- * diagnostics (an under-budgeted blocking hook is always a real
728
- * fail-open gap, never a stylistic warning), so every message maps
729
- * straight to `errors`.
730
- */
731
- function buildHookBudgetLedgerMargin(manifest) {
732
- return { errors: checkHookBudgetLedgerMargin(manifest).map((d) => d.message) };
434
+ return { unresolved, configIssues, versionGaps, uxDrift };
733
435
  }
734
436
  /**
735
437
  * Grounding wiring health (task 129e1b94). Only meaningful when an enabled
@@ -781,22 +483,16 @@ function buildGrounding(manifest, server, home) {
781
483
  catch {
782
484
  ledgerPathWritable = false;
783
485
  warnings.push(`evidence-ledger path ${ledgerPath} is not writable (and not creatable) — ` +
784
- `grounding-mcp cannot persist evidence; warn policies degrade non-blocking, ` +
785
- `block/require_approval policies DENY matching events (deny-degraded) while ` +
786
- `their evidence is unreadable (risk.degraded_fail_posture: fail_open restores ` +
787
- `the availability-first behaviour)`);
486
+ `grounding-mcp cannot persist evidence`);
788
487
  }
789
488
  return { ledgerPath, ledgerPathWritable, envOverride, warnings };
790
489
  }
791
- function manifestSection(manifest) {
490
+ function manifestSection(manifest, postureWarnings) {
792
491
  const topLevelKeys = [
793
492
  "grounding",
794
493
  "tools",
795
494
  "memory",
796
495
  "hooks",
797
- "policies",
798
- "workflows",
799
- "review_templates",
800
496
  ];
801
497
  const present = topLevelKeys.filter((k) => manifest[k] !== undefined).length;
802
498
  // Note: a corrupt manifest never reaches this point; loadManifest exits
@@ -805,7 +501,10 @@ function manifestSection(manifest) {
805
501
  // dropped. The exit-66-on-load path is the canonical signal.
806
502
  return {
807
503
  topLevelKeysPresent: present,
808
- warnings: [],
504
+ // Removed manifest keys / removed packs the load stripped and ignored,
505
+ // and sites that still call a removed command
506
+ // (src/schema/removed-keys.ts): each one is a warning here.
507
+ warnings: postureWarnings.map(formatPostureWarning),
809
508
  };
810
509
  }
811
510
  function countDiagnostics(report) {
@@ -844,57 +543,24 @@ function countDiagnostics(report) {
844
543
  if (h.version?.status === "warn")
845
544
  warningCount++;
846
545
  }
847
- for (const p of report.policies) {
848
- if (p.producerGap)
849
- warningCount++;
546
+ if (report.hookLiveness !== undefined) {
547
+ const liveness = countHookLiveness(report.hookLiveness);
548
+ errorCount += liveness.errorCount;
549
+ warningCount += liveness.warningCount;
850
550
  }
851
551
  errorCount += report.policyPacks.unresolved.length;
852
552
  errorCount += report.policyPacks.configIssues.length;
853
- // Pack-level min_version gaps are warn-not-error: the pack still
854
- // functions in degraded mode; only features gated on the newer
855
- // release are lost. Parallel to the hook-level version probe's
553
+ // Pack-level min_version gaps are warn-not-error: the pack itself works,
554
+ // only the declared floor cannot be enforced. Builtin packs ship with
555
+ // harness and have no probe, so today every gap is a
556
+ // `no_probe_registered` one. Parallel to the hook-level version probe's
856
557
  // `status: warn`.
857
558
  warningCount += report.policyPacks.versionGaps.length;
858
- // Hook-level min_version gaps on pack-expanded hooks (task ab634898):
859
- // always warn-not-error, mirroring both the pack-level floor above
860
- // and the manifest-declared hook floor in the `report.hooks` loop.
861
- warningCount += report.policyPackHookVersions.length;
862
- // Ux/producers drift is always warn: the pack still functions with the
559
+ // Ux drift is always warn: the pack still functions with the
863
560
  // stale wording, the operator is just missing a wording improvement.
864
561
  // Fix is opt-in (`harness pack reseed <name>`), so this never escalates
865
562
  // to an error the way an unresolved pack or a rejected config value does.
866
563
  warningCount += report.policyPacks.uxDrift.length;
867
- for (const d of report.policyPacks.solutionAcceptance) {
868
- if (d.severity === "error")
869
- errorCount++;
870
- else if (d.severity === "warning")
871
- warningCount++;
872
- }
873
- warningCount += report.riskGate.warnings.length;
874
- // Workflow gate wiring (F3) + weak-overlap (F1), review round 2,
875
- // 99f47307 Slice 1: an unwired/mis-wired merge gate is a real
876
- // silent-non-enforcement gap → errorCount; a weaker hand-authored
877
- // policy sharing the derived gate's surface is informational →
878
- // warningCount.
879
- errorCount += report.workflows.errors.length;
880
- warningCount += report.workflows.warnings.length;
881
- // Template-policy drift: each missing-or-downgraded shipped operator_only
882
- // security policy is a real defense gap → errorCount; stale opt-out
883
- // entries are warn-only (task adf037c1).
884
- errorCount += report.templateDrift.errors.length;
885
- warningCount += report.templateDrift.warnings.length;
886
- // Trigger-boundary drift (task 037cfb7c): every entry is a measured,
887
- // exploitable gate bypass (see checkTriggerBoundaryDrift's header),
888
- // mapped to errorCount, mirroring templateDrift.errors immediately
889
- // above; warnings mirrors templateDrift.warnings the same way (no
890
- // warning-severity diagnostic exists today, but the pathway is wired
891
- // so one would count instead of vanishing).
892
- errorCount += report.triggerBoundaryDrift.errors.length;
893
- warningCount += report.triggerBoundaryDrift.warnings.length;
894
- // Hook-budget-vs-ledger-timeout margin (task d20a7e0c): every entry is
895
- // a real fail-open gap, mirroring templateDrift.errors immediately
896
- // above.
897
- errorCount += report.hookBudgetLedgerMargin.errors.length;
898
564
  if (report.grounding !== undefined) {
899
565
  warningCount += report.grounding.warnings.length;
900
566
  }
@@ -909,53 +575,6 @@ function countDiagnostics(report) {
909
575
  }
910
576
  if (report.npmGlobalBin?.status === "warn")
911
577
  warningCount++;
912
- // Toolchain-parity drift (task 13919613): advisory-only, ALWAYS a
913
- // warning, never an error — a machine running a different Node/OW-Kit/
914
- // npm-global/MCP-set than a peer is a real drift signal worth flagging,
915
- // but never a hard failure the way a broken MCP server or a missing
916
- // required CLI is. `"skipped"` (--shallow) and `"no-peers"` (nothing to
917
- // compare yet) are informational states and contribute nothing here.
918
- if (report.toolchainParity) {
919
- for (const p of report.toolchainParity.peers) {
920
- if (p.status === "drift")
921
- warningCount++;
922
- }
923
- }
924
- // Understanding-gate mode env/config divergence (task 24abdecb):
925
- // always advisory, never an error — see understanding-mode-env.ts.
926
- if (report.understandingModeEnv)
927
- warningCount++;
928
- // ugAutoApprovals is informational only (ℹ), never contributes here.
929
- // ugDelegations is informational (ℹ) UNLESS it found an unreadable
930
- // file, in which case it rolls exactly one warning (ug-delegations.ts,
931
- // agent-tasks 37ad0b05), not one per unreadable file.
932
- if (report.ugDelegations && report.ugDelegations.unreadable > 0)
933
- warningCount++;
934
- // auto_approve configured outside grill_me (agent-tasks abfad738):
935
- // always advisory, never an error, see auto-approve-mode.ts.
936
- if (report.ugAutoApproveMode)
937
- warningCount++;
938
- // bypassPermissions observed, auto_approve missing/mismatched (task
939
- // 8f637efd): always advisory, never an error, see
940
- // bypass-without-auto-approve.ts.
941
- if (report.ugBypassWithoutAutoApprove)
942
- warningCount++;
943
- // session_start_preflight.setup below the build-capable preflight
944
- // floor (task 6993d9b5): always advisory, never an error, see
945
- // session-start-preflight-setup-version.ts.
946
- if (report.sessionStartPreflightSetupVersion)
947
- warningCount++;
948
- // ugInflight is informational only (ℹ) and never contributes here: a
949
- // stale or skipped record is exactly what `harness gc` sweeps, not a
950
- // tampering signal (see ug-inflight.ts / types.ts). Placed after every
951
- // line this function's own docs citation anchors rather than beside
952
- // its ugDelegations sibling above, for the same reason format.ts's
953
- // ugInflight local moved: docs/decisions/2026-08-27-ug-auto-mode-approval.md
954
- // cites a line here by exact number.
955
- if (report.settingsDrift)
956
- warningCount += report.settingsDrift.warnings.length;
957
- if (report.codexConfigDrift)
958
- warningCount += report.codexConfigDrift.warnings.length;
959
578
  if (report.memory.routerExecutable && !report.memory.routerExecutable.exists)
960
579
  errorCount++;
961
580
  if (!report.memory.routerExecutable)
@@ -980,26 +599,18 @@ function countDiagnostics(report) {
980
599
  errorCount += opencodeCounts.errorCount;
981
600
  warningCount += opencodeCounts.warningCount;
982
601
  }
983
- warningCount += report.rogueLedgerDbs.length;
984
602
  return { errorCount, warningCount };
985
603
  }
986
604
  export async function doctor(opts = {}) {
987
- // PLAIN load (task c88461c1, review round 3, decision D-028): every
605
+ // PLAIN load (task c88461c1): every
988
606
  // check this report builds from `manifest` below -- MCP/CLI/hook
989
- // probes, memory, policies, policy packs, workflows, the risk gate,
990
- // template and trigger-boundary drift, grounding, and everything
991
- // else -- reads the base/machine/explicit-`--project` manifest only,
607
+ // probes, memory, policy packs,
608
+ // grounding, and everything else -- reads the base/machine/explicit-`--project` manifest only,
992
609
  // an explicit `opts.project` still wins outright but NOTHING is
993
- // derived from cwd here. This mirrors `harness policy intercept`
994
- // (src/cli/policy/intercept.ts) and `harness dry-run`
995
- // (src/cli/dry-run.ts), which never consult a derived project layer
996
- // either, so `doctor` never reports this repo healthier or unhealthier
997
- // than what actually enforces. Only `checkSessionStartPreflightSetupVersion`
998
- // further down gets a project-scoped SECOND load: routing a derived
999
- // layer through THIS one, unrelated load would let it silently reach
1000
- // every other check in this report, for zero benefit to the one key
1001
- // that needs it.
1002
- const { manifest, resolved } = loadManifest(opts);
610
+ // derived from cwd here, so `doctor` reports the same manifest from any
611
+ // directory and never reports this repo healthier or unhealthier than the
612
+ // machine-level install it describes.
613
+ const { manifest, resolved, warnings: postureWarnings } = loadManifest(opts);
1003
614
  const home = opts.homeOverride ?? opts.homeDir ?? os.homedir();
1004
615
  const probe = opts.mcpProbe ?? new RealMcpProbe();
1005
616
  // Resolved ahead of the MCP / CLI checks (moved up from its previous
@@ -1058,160 +669,14 @@ export async function doctor(opts = {}) {
1058
669
  ...(opts.pathEnv !== undefined ? { pathEnv: opts.pathEnv } : {}),
1059
670
  ...(opts.versionProbe !== undefined ? { versionProbe: opts.versionProbe } : {}),
1060
671
  });
1061
- // One memoized probe shared across every doctor check that spawns
1062
- // `<binary> --version` (task 6993d9b5, round 2 F3/F4): `checkHooks`,
1063
- // `buildPolicyPacks`, the policy-pack-expanded hook walk
1064
- // (`checkPolicyPackHookVersions`, which already deduped internally but
1065
- // started from its own fresh cache) and the new
1066
- // session_start_preflight.setup check below all probe the same
1067
- // `["preflight", "--version"]` argv on a `min_version: 0.6.0` manifest.
1068
- // Without a shared cache that argv would spawn once per caller, per
1069
- // `doctor` run. `memoizeVersionProbe` (above) already existed for
1070
- // this; it just was not wired to the callers that predate the new
1071
- // check.
672
+ // One memoized probe for `checkHooks`: two manifest hooks that share one
673
+ // `version_command` spawn the underlying binary once per `doctor` run
674
+ // (task 6993d9b5, task ab634898).
1072
675
  const dedupedVersionProbe = memoizeVersionProbe(opts.versionProbe ?? (() => null));
1073
676
  const hooks = checkHooks(manifest, home, { versionProbe: dedupedVersionProbe });
1074
- // task 6993d9b5: independent of the generic hooks[] min_version walk
1075
- // above, see session-start-preflight-setup-version.ts for why.
1076
- //
1077
- // Per-repo scoping (task c88461c1, review round 2, decision D-021b;
1078
- // scope narrowed to THIS check only, review round 3, decision D-028):
1079
- // an explicit `opts.project` still wins outright; otherwise derive
1080
- // the project name from `opts.cwd` (defaulting to `process.cwd()`)
1081
- // via the SAME shared `deriveProjectName` helper `harness
1082
- // session-start preflight` and `harness explain-policy` feed their
1083
- // own SECOND load from. Without this, the check judged only the
1084
- // base/machine-override value, so it could warn (or stay silent)
1085
- // against the WRONG effective value for a repo whose cwd-derived
1086
- // project layer flips `setup` the other way, the exact drift the
1087
- // producer (src/cli/session-start/index.ts) and `explain-policy` do
1088
- // not have, since both already derive from cwd for this same key.
1089
- // Deliberately a SEPARATE load from `manifest` above, not a reuse:
1090
- // that load feeds every OTHER check in this report and must stay
1091
- // project-unaware (see the doctor() top comment); folding a derived
1092
- // layer into it would let it silently reach checks it was never
1093
- // meant to touch.
1094
- //
1095
- // `sessionStartPreflightProjectName` (task c88461c1, review round 3
1096
- // residual; narrowed by task 1c4eb3ea's round 2, D-027 item 2) is
1097
- // carried onto the finding ONLY when the scoped load below actually
1098
- // RESOLVED a project layer file (`resolved.projectLayer !== null`,
1099
- // the same signal `resolvePaths` already returns), not merely
1100
- // whenever `deriveProjectName`/`opts.project` produced a name to
1101
- // TRY. Round 1 set this to the attempted name unconditionally, so
1102
- // the `(project: X)` suffix `format.ts` renders was byte-identical
1103
- // whether or not a layer actually existed on disk: `projectName` is
1104
- // present for every cwd inside any git work tree, layer or no
1105
- // layer, which made docs/CLI.md's "distinguishable from a
1106
- // base/machine-decided value" claim false. This version instead
1107
- // only names the project when the base/machine value was genuinely
1108
- // overridden by (or the failed load genuinely attempted) that
1109
- // project's own layer file.
1110
- //
1111
- // Best-effort: a config/parse failure here degrades to `setup:
1112
- // false` (review round 3 residual; task `1c4eb3ea`), matching the
1113
- // producer's own `setupEnabled` catch (`src/cli/session-start/
1114
- // index.ts`). Task 1c4eb3ea's round 2 (D-027 item 3) additionally
1115
- // reports this failure as its own `layer_unresolvable` warning
1116
- // (below) instead of going fully silent, but ONLY when a project
1117
- // layer FILE actually exists to be unresolvable about; a failure
1118
- // that instead comes from the base/machine layers (no project layer
1119
- // on disk for this cwd at all) stays silent here exactly as before,
1120
- // since attributing it to "the project layer" would be wrong and
1121
- // `doctor()`'s own top-level `loadManifest(opts)` call above already
1122
- // surfaces a genuine base/machine parse failure by throwing before
1123
- // this point is ever reached.
1124
- const attemptedSessionStartPreflightProjectName = resolveScopedProjectName({
1125
- project: opts.project,
1126
- cwd: opts.cwd ?? process.cwd(),
1127
- fallback: null,
1128
- });
1129
- const scopedLoadOpts = {
1130
- ...opts,
1131
- project: attemptedSessionStartPreflightProjectName ?? undefined,
1132
- };
1133
- let sessionStartPreflightManifest = manifest;
1134
- let sessionStartPreflightProjectName = null;
1135
- let sessionStartPreflightLayerUnresolvable;
1136
- try {
1137
- const scopedLoad = loadManifest(scopedLoadOpts);
1138
- sessionStartPreflightManifest = scopedLoad.manifest;
1139
- if (scopedLoad.resolved.projectLayer !== null) {
1140
- sessionStartPreflightProjectName = attemptedSessionStartPreflightProjectName;
1141
- }
1142
- }
1143
- catch (err) {
1144
- // This catch itself IS reached in every shipped run with a malformed
1145
- // (or unreadable) project layer for the attempted name; what is
1146
- // actually UNREACHABLE TODAY is only the `unresolvableLayerPath ===
1147
- // null` sub-path below (task `1c4eb3ea`, round 2 mutation-probe
1148
- // replay found the round-1 probe on that line now SURVIVES, traced
1149
- // to this invariant): `doctor()`'s own PLAIN, unscoped
1150
- // `loadManifest(opts)` call at the very top of this function already
1151
- // reads the base manifest and every applicable machine-override
1152
- // layer `scopedLoadOpts` below ALSO reads (`scopedLoadOpts` differs
1153
- // from `opts` ONLY by adding `project`); that call has already
1154
- // succeeded by the time this line runs (a base/machine parse failure
1155
- // would have made `doctor()` itself reject before this point), so a
1156
- // throw reaching this catch can only come from the project layer
1157
- // `scopedLoadOpts.project` adds. `resolvePaths(scopedLoadOpts).projectLayer`
1158
- // therefore always resolves non-null here in every real invocation;
1159
- // the null-check below exists only so a FUTURE change to that "plain
1160
- // load first" invariant fails safe (silent, matching the producer's
1161
- // own `setupEnabled` catch) instead of leaking a stale pre-failure
1162
- // value, not because any fixture in this task's own suite can
1163
- // exercise it: constructing one would require the scoped load to
1164
- // fail for a reason the already-successful plain load could not also
1165
- // have hit, which is structurally impossible given the two calls
1166
- // read the identical base/machine layers.
1167
- //
1168
- // The assignment right below is itself UNOBSERVABLE today, in BOTH
1169
- // sub-paths: whenever `unresolvableLayerPath !== null` (every real
1170
- // invocation, per the invariant above), this degraded value is
1171
- // discarded outright by the `??` below, in favor of
1172
- // `sessionStartPreflightLayerUnresolvable`; the currently-
1173
- // unreachable `unresolvableLayerPath === null` sub-path never even
1174
- // runs to consume it either. It stays as a best-effort fallback for
1175
- // that future-invariant-change case, matching the producer's own
1176
- // `setupEnabled` catch, not because any path today actually reads it.
1177
- sessionStartPreflightManifest = {
1178
- ...manifest,
1179
- session_start_preflight: { ...manifest.session_start_preflight, setup: false },
1180
- };
1181
- // Same call the producer's own diagnostic makes
1182
- // (src/cli/session-start/index.ts): only names/warns about the
1183
- // project layer when `resolvePaths` itself can resolve one for
1184
- // this attempted name; otherwise the thrown error came from the
1185
- // base/machine layers, unrelated to project scoping, and this
1186
- // scoped-load catch stays silent about it (see the comment above).
1187
- // Deliberately unguarded, unlike the producer's copy: `resolvePaths`
1188
- // throws only on the HARNESS_ALLOW_REAL_GENERATED_DIR test-safety
1189
- // path, which the plain load at the top of doctor() has already
1190
- // passed; if that plain-load-first invariant ever moves, this line
1191
- // throws instead of degrading silently, and the producer's try/catch
1192
- // is the shape to copy.
1193
- const unresolvableLayerPath = resolvePaths(scopedLoadOpts).projectLayer;
1194
- if (unresolvableLayerPath !== null) {
1195
- sessionStartPreflightProjectName = attemptedSessionStartPreflightProjectName;
1196
- const errMessage = err instanceof Error ? err.message : String(err);
1197
- const errFirstLine = errMessage.split("\n")[0];
1198
- sessionStartPreflightLayerUnresolvable = {
1199
- kind: "layer_unresolvable",
1200
- actualVersion: null,
1201
- requiredVersion: SESSION_START_PREFLIGHT_SETUP_BUILD_MIN_VERSION,
1202
- message: `session_start_preflight.setup: the project-scoped manifest load failed ` +
1203
- `(${errFirstLine}); the effective setup value for this repo could not be ` +
1204
- `determined (project layer: ${unresolvableLayerPath})`,
1205
- projectName: sessionStartPreflightProjectName,
1206
- };
1207
- }
1208
- }
1209
- const sessionStartPreflightSetupVersion = sessionStartPreflightLayerUnresolvable ??
1210
- checkSessionStartPreflightSetupVersion(sessionStartPreflightManifest, dedupedVersionProbe, sessionStartPreflightProjectName);
1211
677
  // generatedDir resolved the same way apply.ts / interactive.ts resolve
1212
- // it, so buildClaudeMcpRegistration's
1213
- // desired projection carries SOLUTION_VERDICT_SIGNING_KEY too, and so
1214
- // the runtime below is read from the very `.last-apply` apply reads.
678
+ // it, so the runtime below is read from the very `.last-apply` apply
679
+ // reads.
1215
680
  const generatedDir = resolveGeneratedDir({
1216
681
  ...(opts.homeDir !== undefined ? { homeDir: opts.homeDir } : {}),
1217
682
  manifestPath: resolved.base,
@@ -1219,10 +684,9 @@ export async function doctor(opts = {}) {
1219
684
  });
1220
685
  // The runtime a plain `harness apply` would select, through apply's own
1221
686
  // `selectRuntime` (recorded, inferred or default; `--target` is an
1222
- // apply flag, not a doctor input). Pack expansion below uses it, so
1223
- // doctor checks the hooks the machine actually gets (task 04b8abcf).
1224
- // A malformed `.last-apply` must not kill doctor (base doctor never read
1225
- // it unless the understanding pack was declared): fall back to the
687
+ // apply flag, not a doctor input). The declared-but-not-live pack check
688
+ // below resolves packs against it (task 04b8abcf).
689
+ // A malformed `.last-apply` must not kill doctor: fall back to the
1226
690
  // default selection and warn, naming the file.
1227
691
  let lastApplyRecord = null;
1228
692
  let lastApplyWarning;
@@ -1235,14 +699,7 @@ export async function doctor(opts = {}) {
1235
699
  "expanding policy packs against the default runtime";
1236
700
  }
1237
701
  const applyRuntime = selectRuntime(undefined, lastApplyRecord, false);
1238
- const policies = buildPolicies(manifest);
1239
- const policyPacks = buildPolicyPacks(manifest, dedupedVersionProbe, resolveGitIgnoreProbe(opts), applyRuntime.runtime);
1240
- const policyPackHookVersions = checkPolicyPackHookVersions(manifest, dedupedVersionProbe, applyRuntime.runtime);
1241
- const workflows = buildWorkflows(manifest);
1242
- const riskGate = buildRiskGate(manifest);
1243
- const templateDrift = buildTemplateDrift(manifest);
1244
- const triggerBoundaryDrift = buildTriggerBoundaryDrift(manifest);
1245
- const hookBudgetLedgerMargin = buildHookBudgetLedgerMargin(manifest);
702
+ const policyPacks = buildPolicyPacks(manifest, applyRuntime.runtime);
1246
703
  const groundingServer = manifest.tools.mcp.find((m) => m.name === GROUNDING_MCP_SERVER_NAME && m.enabled !== false) ?? null;
1247
704
  const grounding = groundingServer !== null
1248
705
  ? buildGrounding(manifest, groundingServer, home)
@@ -1256,107 +713,21 @@ export async function doctor(opts = {}) {
1256
713
  const claudeMcp = manifest.tools.mcp.length > 0
1257
714
  ? await buildClaudeMcpRegistration(manifest, {
1258
715
  home,
1259
- generatedDir,
1260
716
  shallow: !!opts.shallow,
1261
717
  ...(opts.claudeMcpExec !== undefined ? { claudeMcpExec: opts.claudeMcpExec } : {}),
1262
718
  ...(opts.envOverride !== undefined ? { env: opts.envOverride } : {}),
1263
719
  })
1264
720
  : undefined;
1265
- const understandingModeEnv = checkUnderstandingModeEnvDivergence(manifest, opts.envOverride ?? process.env);
1266
- const ugAutoApproveMode = checkAutoApproveMode(manifest);
1267
- // ADR docs/decisions/2026-08-27-ug-auto-mode-approval.md slice 1
1268
- // (agent-tasks 74b4b17d), "Audit and doctor": the auto-approval
1269
- // listing + last-N metric, and the settings-drift compensating
1270
- // control for threat model (c)'s defaultMode/hook-roster plant. Both
1271
- // gated on the pack being declared and enabled (same gate as
1272
- // `understandingModeEnv` above) — a manifest that never uses the pack
1273
- // has no auto-approval markers or auto-approve config to drift.
1274
- const recentSessionsWindow = opts.recentSessions ?? DEFAULT_RECENT_SESSIONS;
1275
- if (!Number.isInteger(recentSessionsWindow) || recentSessionsWindow < 1) {
1276
- throw new Error(`doctor: recentSessions must be an integer >= 1, got ${JSON.stringify(opts.recentSessions)}`);
1277
- }
1278
- const understandingPackEnabled = isUnderstandingPackEnabled(manifest);
1279
- const ugAutoApprovals = understandingPackEnabled
1280
- ? buildUgAutoApprovals(generatedDir, { recentSessions: recentSessionsWindow })
1281
- : undefined;
1282
- // Slice 3 (agent-tasks 37ad0b05), same "Audit and doctor"
1283
- // section: delegations-on-disk metric from `.delegations/`, gated on
1284
- // the same pack-enabled check, computed even when the directory is
1285
- // absent (`delegationsDirPresent: false`, `total: 0`), the render
1286
- // layer (format.ts) is what stays silent for that case, mirroring
1287
- // `ugAutoApprovals`'s own `approvalsDirPresent` gate; see
1288
- // ug-delegations.ts.
1289
- const ugDelegations = understandingPackEnabled
1290
- ? buildUgDelegations(generatedDir, { ...(opts.now !== undefined ? { now: opts.now } : {}) })
1291
- : undefined;
1292
- // Subagent-gate slice 1: in-flight-records-on-disk metric from
1293
- // `.inflight/`, same gate and "computed even when the directory is
1294
- // absent" posture as `ugDelegations` immediately above; see
1295
- // ug-inflight.ts.
1296
- const ugInflight = understandingPackEnabled
1297
- ? buildUgInflight(generatedDir, { ...(opts.now !== undefined ? { now: opts.now } : {}) })
1298
- : undefined;
1299
- // Task 8f637efd ("Amendment: install default"): bypassPermissions
1300
- // observed (hook-side) but auto_approve missing/mismatched. Same gate
1301
- // and same recentSessions window as ugAutoApprovals, reading a
1302
- // different on-disk directory (.permission-mode-observations/, not
1303
- // .approvals/).
1304
- const ugBypassWithoutAutoApprove = understandingPackEnabled
1305
- ? checkBypassWithoutAutoApprove(manifest, generatedDir, {
1306
- recentSessions: recentSessionsWindow,
1307
- })
1308
- : undefined;
1309
- // Shared option shape both drift checks below take (same manifest,
1310
- // same generated dir, same lock, same cwd/home/env resolution), one
1311
- // literal instead of two near-identical ones (`buildSettingsDrift` and
1312
- // `buildCodexConfigDrift` both accept exactly this shape).
1313
- const driftCheckOpts = {
1314
- generatedDir,
1315
- lockPath: path.join(path.dirname(resolved.base), LOCK_BASENAME),
1316
- cwd: opts.cwd ?? process.cwd(),
1317
- home,
1318
- env: opts.envOverride ?? process.env,
1319
- };
1320
- // Settings-drift additionally requires `harness.generated/` to exist:
1321
- // without at least one prior `harness apply`, there is no baseline to
1322
- // compare against and nothing this check owns an opinion about (a
1323
- // fresh manifest that declares the pack but has never been applied
1324
- // must stay exactly as quiet as today — see the doctor-understanding-
1325
- // mode-env fixture that already asserts a bare "Environment"-less
1326
- // report for that exact shape).
1327
- const settingsDrift = understandingPackEnabled && fs.existsSync(generatedDir)
1328
- ? buildSettingsDrift(driftCheckOpts)
1329
- : undefined;
1330
- // Codex counterpart of `settingsDrift` (follow-up of slice 2 of the
1331
- // same ADR, agent-tasks f59ea0eb). Gated on the pack's
1332
- // `auto_approve.harnesses` actually listing `codex` rather than on
1333
- // `understandingPackEnabled` alone, and NOT gated on
1334
- // `harness.generated/` existing: unlike `permissions.defaultMode`,
1335
- // `approval_policy = "never"` is a live risk the moment it is present,
1336
- // whether or not a `harness apply` has ever run for this manifest (see
1337
- // codex-config-drift.ts's module header).
1338
- const codexConfigDrift = isCodexOptedIntoAutoApprove(manifest)
1339
- ? buildCodexConfigDrift(driftCheckOpts)
1340
- : undefined;
1341
- // Toolchain-parity on-demand comparison (task 13919613). Gated purely on
1342
- // `toolchain_parity.enabled` — mirrors `grounding`'s "only when the
1343
- // feature is actually in use" gating, so a manifest that never opted
1344
- // into the SessionStart companion sees no section at all here either.
1345
- const toolchainParity = manifest.toolchain_parity.enabled
1346
- ? await runDoctorToolchainParity(manifest, {
1347
- shallow: !!opts.shallow,
1348
- ...(opts.now !== undefined ? { now: opts.now } : {}),
1349
- ...opts.toolchainParityOptions,
721
+ const manifestSec = manifestSection(manifest, postureWarnings);
722
+ const livenessTargets = livenessRuntimes(applyRuntime.runtime, opts.target);
723
+ const hookLiveness = livenessTargets.length > 0
724
+ ? buildHookLiveness(manifest, {
725
+ home,
726
+ env: opts.envOverride ?? process.env,
727
+ runtimes: livenessTargets,
728
+ ...(opts.codexLiveConfigPath !== undefined ? { codexConfigPath: opts.codexLiveConfigPath } : {}),
1350
729
  })
1351
730
  : undefined;
1352
- const manifestSec = manifestSection(manifest);
1353
- const rogueLedgerDbs = scanForRogueLedgers({
1354
- homeDir: opts.rogueLedgerScanOptions?.homeDir ?? home,
1355
- cwd: opts.rogueLedgerScanOptions?.cwd ?? process.cwd(),
1356
- ...(opts.rogueLedgerScanOptions?.fsInterface !== undefined
1357
- ? { fsInterface: opts.rogueLedgerScanOptions.fsInterface }
1358
- : {}),
1359
- });
1360
731
  const partial = {
1361
732
  manifestPath: resolved.base,
1362
733
  manifestVersion: manifest.version,
@@ -1366,31 +737,12 @@ export async function doctor(opts = {}) {
1366
737
  tools,
1367
738
  memory,
1368
739
  hooks,
1369
- policies,
740
+ ...(hookLiveness !== undefined ? { hookLiveness } : {}),
1370
741
  policyPacks,
1371
- policyPackHookVersions,
1372
742
  packExpansionRuntime: packExpansionRuntimeReport(applyRuntime, lastApplyWarning),
1373
- workflows,
1374
- riskGate,
1375
- templateDrift,
1376
- triggerBoundaryDrift,
1377
- hookBudgetLedgerMargin,
1378
743
  ...(grounding !== undefined ? { grounding } : {}),
1379
744
  ...(claudeMcp !== undefined ? { claudeMcp } : {}),
1380
- ...(toolchainParity !== undefined ? { toolchainParity } : {}),
1381
- rogueLedgerDbs,
1382
745
  ...(npmGlobalBin !== undefined ? { npmGlobalBin } : {}),
1383
- ...(understandingModeEnv !== undefined ? { understandingModeEnv } : {}),
1384
- ...(ugAutoApprovals !== undefined ? { ugAutoApprovals } : {}),
1385
- ...(ugDelegations !== undefined ? { ugDelegations } : {}),
1386
- ...(ugInflight !== undefined ? { ugInflight } : {}),
1387
- ...(ugBypassWithoutAutoApprove !== undefined ? { ugBypassWithoutAutoApprove } : {}),
1388
- ...(sessionStartPreflightSetupVersion !== undefined
1389
- ? { sessionStartPreflightSetupVersion }
1390
- : {}),
1391
- ...(ugAutoApproveMode !== undefined ? { ugAutoApproveMode } : {}),
1392
- ...(settingsDrift !== undefined ? { settingsDrift } : {}),
1393
- ...(codexConfigDrift !== undefined ? { codexConfigDrift } : {}),
1394
746
  };
1395
747
  if (opts.target === "codex") {
1396
748
  const manifestDir = path.dirname(resolved.base);