approval-md 0.1.0 → 0.3.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 (416) hide show
  1. package/README.md +629 -559
  2. package/SPEC.md +99 -24
  3. package/dist/src/adapters/agentmail.d.ts +426 -0
  4. package/dist/src/adapters/agentmail.js +2 -2
  5. package/dist/src/adapters/conformance.d.ts +149 -0
  6. package/dist/src/adapters/contract.d.ts +628 -0
  7. package/dist/src/adapters/contract.js +110 -16
  8. package/dist/src/adapters/contract.js.map +1 -1
  9. package/dist/src/adapters/email.d.ts +324 -0
  10. package/dist/src/adapters/env-passphrase.d.ts +93 -0
  11. package/dist/src/adapters/public.d.ts +11 -0
  12. package/dist/src/adapters/public.js +11 -0
  13. package/dist/src/adapters/public.js.map +1 -0
  14. package/dist/src/adapters/registry.d.ts +59 -0
  15. package/dist/src/adapters/registry.js +2 -1
  16. package/dist/src/adapters/registry.js.map +1 -1
  17. package/dist/src/adapters/smtp.d.ts +213 -0
  18. package/dist/src/adapters/vault-provider.d.ts +114 -0
  19. package/dist/src/adapters/vault-provider.js +3 -3
  20. package/dist/src/adapters/zzz.d.ts +66 -0
  21. package/dist/src/adapters/zzz.js +299 -0
  22. package/dist/src/adapters/zzz.js.map +1 -0
  23. package/dist/src/channels/batch.d.ts +109 -0
  24. package/dist/src/channels/cli.d.ts +193 -0
  25. package/dist/src/channels/conformance.d.ts +92 -0
  26. package/dist/src/channels/contract.d.ts +656 -0
  27. package/dist/src/channels/contract.js +200 -7
  28. package/dist/src/channels/contract.js.map +1 -1
  29. package/dist/src/channels/payload-view.d.ts +35 -0
  30. package/dist/src/channels/render-queue.d.ts +149 -0
  31. package/dist/src/channels/tagging.d.ts +196 -0
  32. package/dist/src/channels/telegram.d.ts +1944 -0
  33. package/dist/src/channels/telegram.js +218 -23
  34. package/dist/src/channels/telegram.js.map +1 -1
  35. package/dist/src/channels/web.d.ts +350 -0
  36. package/dist/src/channels/web.js +17 -0
  37. package/dist/src/channels/web.js.map +1 -1
  38. package/dist/src/cli/adapter.d.ts +90 -0
  39. package/dist/src/cli/adapter.js +25 -15
  40. package/dist/src/cli/adapter.js.map +1 -1
  41. package/dist/src/cli/amend.d.ts +59 -0
  42. package/dist/src/cli/amend.js +214 -30
  43. package/dist/src/cli/amend.js.map +1 -1
  44. package/dist/src/cli/args.d.ts +43 -0
  45. package/dist/src/cli/attest.d.ts +50 -0
  46. package/dist/src/cli/attest.js +134 -7
  47. package/dist/src/cli/attest.js.map +1 -1
  48. package/dist/src/cli/audit-card.d.ts +62 -0
  49. package/dist/src/cli/audit.d.ts +59 -0
  50. package/dist/src/cli/channel-telegram.d.ts +879 -0
  51. package/dist/src/cli/channel-telegram.js +311 -13
  52. package/dist/src/cli/channel-telegram.js.map +1 -1
  53. package/dist/src/cli/channel-web.d.ts +131 -0
  54. package/dist/src/cli/channel.d.ts +80 -0
  55. package/dist/src/cli/channel.js +9 -0
  56. package/dist/src/cli/channel.js.map +1 -1
  57. package/dist/src/cli/checkpoint-tap.d.ts +169 -0
  58. package/dist/src/cli/codex-bridge.d.ts +819 -0
  59. package/dist/src/cli/codex-bridge.js +1607 -0
  60. package/dist/src/cli/codex-bridge.js.map +1 -0
  61. package/dist/src/cli/codex.d.ts +2 -0
  62. package/dist/src/cli/codex.js +469 -0
  63. package/dist/src/cli/codex.js.map +1 -0
  64. package/dist/src/cli/coverage.d.ts +61 -0
  65. package/dist/src/cli/daemon.d.ts +120 -0
  66. package/dist/src/cli/daemon.js +4 -1
  67. package/dist/src/cli/daemon.js.map +1 -1
  68. package/dist/src/cli/doctor.d.ts +129 -0
  69. package/dist/src/cli/doctor.js +586 -17
  70. package/dist/src/cli/doctor.js.map +1 -1
  71. package/dist/src/cli/env.d.ts +65 -0
  72. package/dist/src/cli/execute.d.ts +202 -0
  73. package/dist/src/cli/execute.js +25 -2
  74. package/dist/src/cli/execute.js.map +1 -1
  75. package/dist/src/cli/exit-codes.d.ts +73 -0
  76. package/dist/src/cli/feedback.d.ts +60 -0
  77. package/dist/src/cli/gate-window.d.ts +40 -0
  78. package/dist/src/cli/gate.d.ts +68 -0
  79. package/dist/src/cli/git-scope.d.ts +190 -0
  80. package/dist/src/cli/gloss-attach.d.ts +85 -0
  81. package/dist/src/cli/gloss-codex-child.d.ts +9 -0
  82. package/dist/src/cli/gloss-codex.d.ts +24 -0
  83. package/dist/src/cli/gloss-options.d.ts +42 -0
  84. package/dist/src/cli/gloss.d.ts +265 -0
  85. package/dist/src/cli/help.d.ts +107 -0
  86. package/dist/src/cli/help.js +320 -93
  87. package/dist/src/cli/help.js.map +1 -1
  88. package/dist/src/cli/hook-codex.d.ts +126 -0
  89. package/dist/src/cli/hook-codex.js +226 -0
  90. package/dist/src/cli/hook-codex.js.map +1 -0
  91. package/dist/src/cli/hook.d.ts +787 -0
  92. package/dist/src/cli/hook.js +1235 -181
  93. package/dist/src/cli/hook.js.map +1 -1
  94. package/dist/src/cli/import.d.ts +35 -0
  95. package/dist/src/cli/import.js +1 -1
  96. package/dist/src/cli/import.js.map +1 -1
  97. package/dist/src/cli/init.d.ts +84 -0
  98. package/dist/src/cli/init.js +2 -2
  99. package/dist/src/cli/init.js.map +1 -1
  100. package/dist/src/cli/instructions.d.ts +23 -0
  101. package/dist/src/cli/journal.d.ts +41 -0
  102. package/dist/src/cli/log-advance.d.ts +287 -0
  103. package/dist/src/cli/log-advance.js +102 -11
  104. package/dist/src/cli/log-advance.js.map +1 -1
  105. package/dist/src/cli/log-anchor.d.ts +176 -0
  106. package/dist/src/cli/log-checkpoint.d.ts +22 -0
  107. package/dist/src/cli/log-sync.d.ts +243 -0
  108. package/dist/src/cli/log-verbs.d.ts +16 -0
  109. package/dist/src/cli/log-verbs.js +7 -1
  110. package/dist/src/cli/log-verbs.js.map +1 -1
  111. package/dist/src/cli/long-help.d.ts +70 -0
  112. package/dist/src/cli/main.d.ts +77 -0
  113. package/dist/src/cli/main.js +159 -7
  114. package/dist/src/cli/main.js.map +1 -1
  115. package/dist/src/cli/mcp.d.ts +52 -0
  116. package/dist/src/cli/paths.d.ts +56 -0
  117. package/dist/src/cli/payload.d.ts +58 -0
  118. package/dist/src/cli/policy-apply.d.ts +195 -0
  119. package/dist/src/cli/policy-apply.js +573 -0
  120. package/dist/src/cli/policy-apply.js.map +1 -0
  121. package/dist/src/cli/policy.d.ts +43 -0
  122. package/dist/src/cli/policy.js +14 -1
  123. package/dist/src/cli/policy.js.map +1 -1
  124. package/dist/src/cli/preflight.d.ts +501 -0
  125. package/dist/src/cli/preflight.js +689 -45
  126. package/dist/src/cli/preflight.js.map +1 -1
  127. package/dist/src/cli/progress.d.ts +78 -0
  128. package/dist/src/cli/prompt.d.ts +209 -0
  129. package/dist/src/cli/quickstart.d.ts +46 -0
  130. package/dist/src/cli/quickstart.js +297 -0
  131. package/dist/src/cli/quickstart.js.map +1 -0
  132. package/dist/src/cli/records.d.ts +34 -0
  133. package/dist/src/cli/render.d.ts +22 -0
  134. package/dist/src/cli/sandbox.d.ts +51 -0
  135. package/dist/src/cli/sandbox.js +17 -1
  136. package/dist/src/cli/sandbox.js.map +1 -1
  137. package/dist/src/cli/scaffold.d.ts +79 -0
  138. package/dist/src/cli/scaffold.js +1 -1
  139. package/dist/src/cli/setup-adapter.d.ts +137 -0
  140. package/dist/src/cli/setup-adapter.js +38 -4
  141. package/dist/src/cli/setup-adapter.js.map +1 -1
  142. package/dist/src/cli/setup-channel.d.ts +126 -0
  143. package/dist/src/cli/setup-channel.js +28 -1
  144. package/dist/src/cli/setup-channel.js.map +1 -1
  145. package/dist/src/cli/setup-checkpoint.d.ts +57 -0
  146. package/dist/src/cli/setup-common.d.ts +277 -0
  147. package/dist/src/cli/setup-common.js +3 -2
  148. package/dist/src/cli/setup-common.js.map +1 -1
  149. package/dist/src/cli/setup-flow.d.ts +287 -0
  150. package/dist/src/cli/setup-service.d.ts +96 -0
  151. package/dist/src/cli/setup.d.ts +204 -0
  152. package/dist/src/cli/setup.js +94 -2
  153. package/dist/src/cli/setup.js.map +1 -1
  154. package/dist/src/cli/style.d.ts +320 -0
  155. package/dist/src/cli/token.d.ts +39 -0
  156. package/dist/src/cli/up.d.ts +155 -0
  157. package/dist/src/cli/up.js +119 -53
  158. package/dist/src/cli/up.js.map +1 -1
  159. package/dist/src/cli/usage.d.ts +37 -0
  160. package/dist/src/cli/values.d.ts +40 -0
  161. package/dist/src/cli/values.js +3 -4
  162. package/dist/src/cli/values.js.map +1 -1
  163. package/dist/src/cli/vault.d.ts +59 -0
  164. package/dist/src/cli/vault.js +2 -2
  165. package/dist/src/cli/vault.js.map +1 -1
  166. package/dist/src/cli/verb-registry.d.ts +76 -0
  167. package/dist/src/cli/verb-registry.js +344 -11
  168. package/dist/src/cli/verb-registry.js.map +1 -1
  169. package/dist/src/cli/wordmark.d.ts +31 -0
  170. package/dist/src/cli/wordmark.js +2 -2
  171. package/dist/src/codex/broker.d.ts +229 -0
  172. package/dist/src/codex/broker.js +548 -0
  173. package/dist/src/codex/broker.js.map +1 -0
  174. package/dist/src/codex/doctor.d.ts +13 -0
  175. package/dist/src/codex/doctor.js +41 -0
  176. package/dist/src/codex/doctor.js.map +1 -0
  177. package/dist/src/codex/manifest.d.ts +49 -0
  178. package/dist/src/codex/manifest.js +103 -0
  179. package/dist/src/codex/manifest.js.map +1 -0
  180. package/dist/src/codex/runner.d.ts +178 -0
  181. package/dist/src/codex/runner.js +231 -0
  182. package/dist/src/codex/runner.js.map +1 -0
  183. package/dist/src/codex/serve.d.ts +56 -0
  184. package/dist/src/codex/serve.js +98 -0
  185. package/dist/src/codex/serve.js.map +1 -0
  186. package/dist/src/codex/templates.d.ts +41 -0
  187. package/dist/src/codex/templates.js +319 -0
  188. package/dist/src/codex/templates.js.map +1 -0
  189. package/dist/src/codex/trust.d.ts +19 -0
  190. package/dist/src/codex/trust.js +183 -0
  191. package/dist/src/codex/trust.js.map +1 -0
  192. package/dist/src/codex/workspace-commit.d.ts +219 -0
  193. package/dist/src/codex/workspace-commit.js +549 -0
  194. package/dist/src/codex/workspace-commit.js.map +1 -0
  195. package/dist/src/codex/workspace-plan.d.ts +131 -0
  196. package/dist/src/codex/workspace-plan.js +561 -0
  197. package/dist/src/codex/workspace-plan.js.map +1 -0
  198. package/dist/src/core/actor.d.ts +2 -0
  199. package/dist/src/core/actor.js +5 -0
  200. package/dist/src/core/actor.js.map +1 -0
  201. package/dist/src/core/advance-cycle.d.ts +221 -0
  202. package/dist/src/core/advance-cycle.js +66 -2
  203. package/dist/src/core/advance-cycle.js.map +1 -1
  204. package/dist/src/core/agents-md.d.ts +278 -0
  205. package/dist/src/core/agents-md.js +33 -31
  206. package/dist/src/core/agents-md.js.map +1 -1
  207. package/dist/src/core/apply-patch.d.ts +49 -0
  208. package/dist/src/core/apply-patch.js +266 -0
  209. package/dist/src/core/apply-patch.js.map +1 -0
  210. package/dist/src/core/attest.d.ts +635 -0
  211. package/dist/src/core/attest.js +326 -4
  212. package/dist/src/core/attest.js.map +1 -1
  213. package/dist/src/core/audit.d.ts +510 -0
  214. package/dist/src/core/audit.js +13 -0
  215. package/dist/src/core/audit.js.map +1 -1
  216. package/dist/src/core/budgets.d.ts +238 -0
  217. package/dist/src/core/channel-owner.d.ts +213 -0
  218. package/dist/src/core/channel-owner.js +358 -0
  219. package/dist/src/core/channel-owner.js.map +1 -0
  220. package/dist/src/core/checkpoint.d.ts +500 -0
  221. package/dist/src/core/child-env.d.ts +88 -0
  222. package/dist/src/core/clock.d.ts +52 -0
  223. package/dist/src/core/command-class.d.ts +697 -0
  224. package/dist/src/core/command-class.js +713 -25
  225. package/dist/src/core/command-class.js.map +1 -1
  226. package/dist/src/core/commit-guard.d.ts +272 -0
  227. package/dist/src/core/commit-guard.js +424 -0
  228. package/dist/src/core/commit-guard.js.map +1 -0
  229. package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
  230. package/dist/src/core/coverage-sources/gh.d.ts +48 -0
  231. package/dist/src/core/coverage-sources/git.d.ts +101 -0
  232. package/dist/src/core/coverage.d.ts +217 -0
  233. package/dist/src/core/credential-spec.d.ts +72 -0
  234. package/dist/src/core/daemon-actor.d.ts +45 -0
  235. package/dist/src/core/daemon-actor.js +54 -0
  236. package/dist/src/core/daemon-actor.js.map +1 -0
  237. package/dist/src/core/dark-session.d.ts +432 -0
  238. package/dist/src/core/dark-session.js +266 -82
  239. package/dist/src/core/dark-session.js.map +1 -1
  240. package/dist/src/core/decision-refusal.d.ts +206 -0
  241. package/dist/src/core/decision-refusal.js +24 -2
  242. package/dist/src/core/decision-refusal.js.map +1 -1
  243. package/dist/src/core/env-file.d.ts +455 -0
  244. package/dist/src/core/env-file.js +60 -1
  245. package/dist/src/core/env-file.js.map +1 -1
  246. package/dist/src/core/execute.d.ts +871 -0
  247. package/dist/src/core/execute.js +59 -8
  248. package/dist/src/core/execute.js.map +1 -1
  249. package/dist/src/core/frontmatter.d.ts +78 -0
  250. package/dist/src/core/gate-window.d.ts +312 -0
  251. package/dist/src/core/gate.d.ts +1449 -0
  252. package/dist/src/core/gate.js +149 -14
  253. package/dist/src/core/gate.js.map +1 -1
  254. package/dist/src/core/gesture-refusal.d.ts +166 -0
  255. package/dist/src/core/gesture-refusal.js +188 -0
  256. package/dist/src/core/gesture-refusal.js.map +1 -0
  257. package/dist/src/core/git-run.d.ts +73 -0
  258. package/dist/src/core/harness-version.d.ts +157 -0
  259. package/dist/src/core/harness-version.js +4 -1
  260. package/dist/src/core/harness-version.js.map +1 -1
  261. package/dist/src/core/harness-wait.d.ts +55 -0
  262. package/dist/src/core/head-retry.d.ts +107 -0
  263. package/dist/src/core/instance.d.ts +310 -0
  264. package/dist/src/core/instance.js +113 -0
  265. package/dist/src/core/instance.js.map +1 -1
  266. package/dist/src/core/intake-limits.d.ts +247 -0
  267. package/dist/src/core/jcs.d.ts +52 -0
  268. package/dist/src/core/journal.d.ts +144 -0
  269. package/dist/src/core/live-draw.d.ts +436 -0
  270. package/dist/src/core/log-reconcile.d.ts +89 -0
  271. package/dist/src/core/log-subscribe.d.ts +36 -0
  272. package/dist/src/core/log-subscribe.js +162 -0
  273. package/dist/src/core/log-subscribe.js.map +1 -0
  274. package/dist/src/core/log.d.ts +316 -0
  275. package/dist/src/core/log.js.map +1 -1
  276. package/dist/src/core/loop.d.ts +274 -0
  277. package/dist/src/core/loop.js +11 -0
  278. package/dist/src/core/loop.js.map +1 -1
  279. package/dist/src/core/md-fence.d.ts +41 -0
  280. package/dist/src/core/money.d.ts +147 -0
  281. package/dist/src/core/payload-census.d.ts +74 -0
  282. package/dist/src/core/payload-store.d.ts +175 -0
  283. package/dist/src/core/payload.d.ts +71 -0
  284. package/dist/src/core/policy-diff.d.ts +292 -0
  285. package/dist/src/core/policy-diff.js +27 -4
  286. package/dist/src/core/policy-diff.js.map +1 -1
  287. package/dist/src/core/policy-expectations.d.ts +199 -0
  288. package/dist/src/core/policy-explain.d.ts +160 -0
  289. package/dist/src/core/policy-explain.js +63 -3
  290. package/dist/src/core/policy-explain.js.map +1 -1
  291. package/dist/src/core/policy-load.d.ts +567 -0
  292. package/dist/src/core/policy-load.js +36 -6
  293. package/dist/src/core/policy-load.js.map +1 -1
  294. package/dist/src/core/policy-match.d.ts +324 -0
  295. package/dist/src/core/policy-match.js +72 -9
  296. package/dist/src/core/policy-match.js.map +1 -1
  297. package/dist/src/core/policy-proposal.d.ts +317 -0
  298. package/dist/src/core/policy-proposal.js +102 -2
  299. package/dist/src/core/policy-proposal.js.map +1 -1
  300. package/dist/src/core/prompt-layout.d.ts +221 -0
  301. package/dist/src/core/protected-path-guard.d.ts +566 -0
  302. package/dist/src/core/protected-path-guard.js +848 -55
  303. package/dist/src/core/protected-path-guard.js.map +1 -1
  304. package/dist/src/core/question-preempted.d.ts +141 -0
  305. package/dist/src/core/question-preempted.js +152 -0
  306. package/dist/src/core/question-preempted.js.map +1 -0
  307. package/dist/src/core/read-scope.d.ts +172 -0
  308. package/dist/src/core/read-scope.js +252 -0
  309. package/dist/src/core/read-scope.js.map +1 -0
  310. package/dist/src/core/registration.d.ts +25 -0
  311. package/dist/src/core/reindex.d.ts +99 -0
  312. package/dist/src/core/sampler.d.ts +313 -0
  313. package/dist/src/core/sandbox.d.ts +371 -0
  314. package/dist/src/core/sandbox.js +190 -1
  315. package/dist/src/core/sandbox.js.map +1 -1
  316. package/dist/src/core/seal.d.ts +165 -0
  317. package/dist/src/core/sender-identity.d.ts +476 -0
  318. package/dist/src/core/sender-identity.js +572 -0
  319. package/dist/src/core/sender-identity.js.map +1 -0
  320. package/dist/src/core/shlex.d.ts +102 -0
  321. package/dist/src/core/shlex.js +159 -0
  322. package/dist/src/core/shlex.js.map +1 -0
  323. package/dist/src/core/state.d.ts +505 -0
  324. package/dist/src/core/task-file.d.ts +185 -0
  325. package/dist/src/core/telegram-config.d.ts +93 -0
  326. package/dist/src/core/token.d.ts +409 -0
  327. package/dist/src/core/token.js +21 -38
  328. package/dist/src/core/token.js.map +1 -1
  329. package/dist/src/core/validate.d.ts +138 -0
  330. package/dist/src/core/values.d.ts +147 -0
  331. package/dist/src/core/values.js +36 -1
  332. package/dist/src/core/values.js.map +1 -1
  333. package/dist/src/core/vault.d.ts +291 -0
  334. package/dist/src/core/verified-snapshot.d.ts +204 -0
  335. package/dist/src/core/verify.d.ts +336 -0
  336. package/dist/src/core/version.d.ts +8 -0
  337. package/dist/src/core/wysiwys.d.ts +370 -0
  338. package/dist/src/daemon/advance-child.d.ts +39 -0
  339. package/dist/src/daemon/advance.d.ts +476 -0
  340. package/dist/src/daemon/advance.js +25 -4
  341. package/dist/src/daemon/advance.js.map +1 -1
  342. package/dist/src/daemon/audit.d.ts +87 -0
  343. package/dist/src/daemon/daemon.d.ts +1180 -0
  344. package/dist/src/daemon/daemon.js +9 -0
  345. package/dist/src/daemon/daemon.js.map +1 -1
  346. package/dist/src/daemon/dark-session.d.ts +64 -0
  347. package/dist/src/daemon/draw-child.d.ts +36 -0
  348. package/dist/src/daemon/draw.d.ts +154 -0
  349. package/dist/src/daemon/git-evidence.d.ts +173 -0
  350. package/dist/src/daemon/git-evidence.js +1 -1
  351. package/dist/src/daemon/projection.d.ts +180 -0
  352. package/dist/src/daemon/prune.d.ts +207 -0
  353. package/dist/src/mcp/http.d.ts +113 -0
  354. package/dist/src/mcp/server.d.ts +265 -0
  355. package/dist/src/mcp/server.js +17 -1
  356. package/dist/src/mcp/server.js.map +1 -1
  357. package/docs/adapter-api.md +106 -0
  358. package/docs/cli-reference.md +1316 -63
  359. package/docs/codex-enforced-session.md +103 -0
  360. package/docs/codex-workspace-broker.md +118 -0
  361. package/package.json +14 -2
  362. package/schema/codex-instance.schema.json +82 -0
  363. package/schema/event.schema.json +539 -9
  364. package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
  365. package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
  366. package/schema/fixtures/event/invalid/approval-granted-sender-hashed-false.json +20 -0
  367. package/schema/fixtures/event/invalid/approval-granted-sender-hashed-raw-id.json +20 -0
  368. package/schema/fixtures/event/invalid/audit-gesture-refused-human-actor.json +16 -0
  369. package/schema/fixtures/event/invalid/audit-gesture-refused-no-actor-no-sender.json +15 -0
  370. package/schema/fixtures/event/invalid/audit-gesture-refused-unknown-gesture.json +16 -0
  371. package/schema/fixtures/event/invalid/audit-question-preempted-agent-actor.json +16 -0
  372. package/schema/fixtures/event/invalid/audit-question-preempted-no-question-id.json +16 -0
  373. package/schema/fixtures/event/invalid/audit-question-preempted-unknown-source.json +15 -0
  374. package/schema/fixtures/event/invalid/gate-path-signed-off-absolute-path.json +14 -0
  375. package/schema/fixtures/event/invalid/gate-path-signed-off-agent-actor.json +14 -0
  376. package/schema/fixtures/event/invalid/gate-path-signed-off-missing-path.json +13 -0
  377. package/schema/fixtures/event/valid/approval-granted-sender-hashed.json +20 -0
  378. package/schema/fixtures/event/valid/audit-gesture-refused-review-note.json +21 -0
  379. package/schema/fixtures/event/valid/audit-gesture-refused-sender-key-unavailable.json +19 -0
  380. package/schema/fixtures/event/valid/audit-gesture-refused.json +19 -0
  381. package/schema/fixtures/event/valid/audit-question-preempted-no-verdict.json +16 -0
  382. package/schema/fixtures/event/valid/audit-question-preempted.json +20 -0
  383. package/schema/fixtures/event/valid/gate-path-signed-off.json +14 -0
  384. package/schema/fixtures/event/valid/harness-kind-claude-code.json +23 -0
  385. package/schema/fixtures/event/valid/harness-kind-codex.json +23 -0
  386. package/schema/fixtures/event/valid/harness-kind-cursor.json +23 -0
  387. package/schema/fixtures/event/valid/harness-kind-grok.json +23 -0
  388. package/schema/fixtures/event/valid/harness-kind-muse.json +23 -0
  389. package/schema/fixtures/policy/invalid/senders-half-keyed.json +20 -0
  390. package/schema/fixtures/policy/valid/canonical.json +1 -1
  391. package/schema/fixtures/policy/valid/senders-keyed.json +24 -0
  392. package/schema/fixtures/policy-md/valid/canonical.md +1 -1
  393. package/schema/fixtures/policy-md/valid/with-values.md +5 -7
  394. package/schema/fixtures/values/invalid/class-shaped.json +1 -1
  395. package/schema/fixtures/values/invalid/duplicate-entry.json +1 -1
  396. package/schema/fixtures/values/invalid/non-string-item.json +1 -1
  397. package/schema/fixtures/values/invalid/over-cap.json +1 -1
  398. package/schema/fixtures/values/invalid/unknown-key.json +1 -1
  399. package/schema/fixtures/values/invalid/version-float.json +1 -0
  400. package/schema/fixtures/values/invalid/version-integer.json +1 -0
  401. package/schema/fixtures/values/invalid/version-wrong-string.json +1 -0
  402. package/schema/fixtures/values/valid/empty-lists.json +2 -3
  403. package/schema/fixtures/values/valid/full.json +5 -7
  404. package/schema/fixtures/values/valid/minimal.json +1 -1
  405. package/schema/fixtures/values-md/invalid/schema-invalid.md +5 -3
  406. package/schema/fixtures/values-md/invalid/two-blocks.md +3 -3
  407. package/schema/fixtures/values-md/invalid/unterminated.md +2 -2
  408. package/schema/fixtures/values-md/invalid/version-1.md +69 -0
  409. package/schema/fixtures/values-md/invalid/version-unquoted.md +64 -0
  410. package/schema/fixtures/values-md/invalid/yaml-error.md +2 -2
  411. package/schema/fixtures/values-md/valid/absent.md +1 -1
  412. package/schema/fixtures/values-md/valid/with-values.md +5 -7
  413. package/schema/policy.schema.json +75 -3
  414. package/schema/values.schema.json +7 -11
  415. package/templates/codex/README.md +9 -0
  416. package/schema/fixtures/values/invalid/version-string.json +0 -1
@@ -30,9 +30,11 @@ import { isAbsolute, join, resolve as resolvePathSegments } from "node:path";
30
30
  import { explain, isActionClass } from "../core/policy-explain.js";
31
31
  import { loadPolicy, POLICY_FILENAMES } from "../core/policy-load.js";
32
32
  import { commandPolicyAmend } from "./amend.js";
33
+ import { commandPolicyApply } from "./policy-apply.js";
33
34
  import { boolFlag, parseFlags, stringFlag } from "./args.js";
34
35
  import { commandPolicyAttest } from "./attest.js";
35
36
  import { EXIT_IO, EXIT_OK, EXIT_USAGE } from "./exit-codes.js";
37
+ import { resolveScratchRoots } from "./hook.js";
36
38
  import { POLICY_CHECK_HELP, POLICY_HELP, POLICY_TEST_HELP } from "./help.js";
37
39
  import { relPath, style } from "./style.js";
38
40
  import { usageErrorText } from "./usage.js";
@@ -189,7 +191,13 @@ function runVerb(argv, streams, cwd, helpText) {
189
191
  if (!check.ok)
190
192
  return ioError(streams, json, check.message);
191
193
  }
192
- const explanation = explain(loadPolicy(options), actionClass, reversibleFlag === null ? {} : { reversible: reversibleFlag === "true" });
194
+ const explanation = explain(loadPolicy(options), actionClass, {
195
+ ...(reversibleFlag === null ? {} : { reversible: reversibleFlag === "true" }),
196
+ // APRV-347. Resolved HERE, where the process may touch a disk, so the read
197
+ // scope a reader is shown is the one this machine would actually enforce
198
+ // rather than a description of the key.
199
+ systemReadRoots: resolveScratchRoots(cwd),
200
+ });
193
201
  if (json) {
194
202
  streams.out(`${JSON.stringify(explanation)}\n`);
195
203
  }
@@ -222,6 +230,11 @@ export function commandPolicy(argv, streams, cwd) {
222
230
  // It writes too, and for the same reason it lives in its own file.
223
231
  case "amend":
224
232
  return commandPolicyAmend(rest, streams, cwd);
233
+ // APRV-343. It writes the policy FILE, which nothing else in this CLI does,
234
+ // and then hands over to the amendment above so the edit and its
235
+ // attestation stay one act.
236
+ case "apply":
237
+ return commandPolicyApply(rest, streams, cwd);
225
238
  default:
226
239
  return usageError(streams, wantsJson(argv), `unknown subcommand ${JSON.stringify(sub)} for \`approval policy\``, POLICY_HELP);
227
240
  }
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/cli/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,aAAa,EAAoB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAA0B,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAyB,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,KAAK,GAA6B;IACtC,cAAc,EAAE,QAAQ;IACxB,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,QAAQ;IACjB,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,SAAS;CAChB,CAAC;AAEF,SAAS,SAAS,CAAC,IAAc;IAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,UAAU,CAAC,OAAgB,EAAE,IAAa,EAAE,OAAe,EAAE,QAAgB;IACpF,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;;QAC/E,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,OAAO,CAAC,OAAgB,EAAE,IAAa,EAAE,OAAe;IAC/D,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;;QAC5E,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,IAAI,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,GAAW;IAC1C,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC5E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,IAAI,yBAAyB,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACxF,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,IAAI,oCAAoC,EAAE,CAAC;IACpF,CAAC;IACD,IAAI,CAAC;QACH,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,IAAI,qBAAqB,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,2EAA2E;AAC3E,SAAS,SAAS,CAAC,WAAwB;IACzC,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC9C,IAAI,WAAW,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QACrC,OAAO,MAAM,QAAQ,kBAAkB,WAAW,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC;IACzE,CAAC;IACD,IAAI,WAAW,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,IAAI,mBAAmB,CAAC;QACrE,OAAO,MAAM,QAAQ,wBAAwB,MAAM,KAAK,WAAW,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC;IAC7F,CAAC;IACD,OAAO,MAAM,QAAQ,EAAE,CAAC;AAC1B,CAAC;AAED,oFAAoF;AACpF,SAAS,YAAY,CAAC,QAAgB;IACpC,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,MAAM,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAwB,EACxB,GAAW,EACX,EAAE,GAAU,KAAK,EAAE;IAEnB,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAClD,EAAE,CAAC,KAAK,CACN,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC;QACpC,CAAC,CAAC,sBAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE;QAChF,CAAC,CAAC,IAAI,CACT,CACF,CAAC;IACF,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IACrC,4EAA4E;IAC5E,8CAA8C;IAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpF,OAAO,GAAG,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,mFAAmF;AACnF,SAAS,OAAO,CAAC,IAAc,EAAE,OAAgB,EAAE,GAAW,EAAE,QAAgB;IAC9E,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE3E,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,QAAQ,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,uBAAuB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,UAAU,CACf,OAAO,EACP,IAAI,EACJ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,+EAA+E,EAC7G,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAChE,IAAI,cAAc,KAAK,IAAI,IAAI,cAAc,KAAK,MAAM,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;QACvF,OAAO,UAAU,CACf,OAAO,EACP,IAAI,EACJ,2CAA2C,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,EAC3E,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAE5D,2EAA2E;IAC3E,2EAA2E;IAC3E,oDAAoD;IACpD,MAAM,OAAO,GACX,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;IAEtE,MAAM,MAAM,GACV,OAAO,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CACzB,UAAU,CAAC,OAAO,CAAC,EACnB,WAAW,EACX,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,cAAc,KAAK,MAAM,EAAE,CACzE,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,IAAc,EAAE,OAAgB,EAAE,GAAW;IACzE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE3B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,UAAU,CACf,OAAO,EACP,SAAS,CAAC,IAAI,CAAC,EACf,0CAA0C,EAC1C,WAAW,CACZ,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,IAAI,CAAC,CAAC;QAChC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACxD,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACvD,2EAA2E;QAC3E,wEAAwE;QACxE,KAAK,QAAQ;YACX,OAAO,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QACjD,2EAA2E;QAC3E,mEAAmE;QACnE,KAAK,OAAO;YACV,OAAO,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAChD;YACE,OAAO,UAAU,CACf,OAAO,EACP,SAAS,CAAC,IAAI,CAAC,EACf,sBAAsB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,0BAA0B,EACnE,WAAW,CACZ,CAAC;IACN,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/cli/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,501 @@
1
+ /**
2
+ * The startup preflight (APRV-215): is the code about to run the code that is
3
+ * on origin, and is the build behind it the one the sources describe?
4
+ *
5
+ * ## The four manual steps this replaces
6
+ *
7
+ * Deploying the APRV-212 fix in the primary checkout took `git fetch`, a
8
+ * judgment call about whether the ten upstream commits touched
9
+ * `.approval/log/events.jsonl` while the working log was dirty, `git pull
10
+ * --ff-only`, and `npm run build`. Three of those are typing; the second is the
11
+ * one a human cannot make from `git status` alone, because `git status` does not
12
+ * say what the *upstream range* changed. Carter's standing view is that manual
13
+ * git steps for the human are a defect rather than a runbook, so the judgment
14
+ * moves here and the typing moves with it.
15
+ *
16
+ * ## What it is allowed to do
17
+ *
18
+ * Read git, and at most four writes: a `--ff-only` merge, `npm run build`,
19
+ * when the merge refused over an untracked file under `backlog/tasks/`
20
+ * that main already contains, clearing that file out of the way (APRV-300, and
21
+ * the rules it obeys are in {@link reconcileUntrackedTaskFiles}), and the one
22
+ * `approval log sync` performs on its behalf (APRV-346, below).
23
+ *
24
+ * It never resets, never stashes, never checks anything out, and never touches
25
+ * the working log ITSELF. That list is not conservatism for its own sake — it is
26
+ * fork 2 of 2026-08-20 (APRV-104's notes, and the reason `approval log sync`
27
+ * exists at all): a working `events.jsonl` rewound through git underneath a live
28
+ * appender is two chains where there was one. `--ff-only` cannot rewind a file
29
+ * that upstream did not change, and when upstream DID change it while the
30
+ * working copy is dirty, the file is moved by `cli/log-sync.ts` and by nothing
31
+ * here.
32
+ *
33
+ * ## The routine collision, and the one that is not (APRV-346)
34
+ *
35
+ * Every records advance moves `origin/main`'s `.approval/log/events.jsonl`
36
+ * while the hook keeps appending locally, so "upstream changed the log and so
37
+ * did this working copy" is the NORMAL state of the primary checkout after a
38
+ * merge rather than an edge case. Refusing it sent the operator to `approval log
39
+ * sync` and then back to `approval up` every single time, which is a two-step
40
+ * ritual for a state the preflight can already tell apart from a fork.
41
+ *
42
+ * So the collision is now a question rather than a verdict: is the working log a
43
+ * byte-for-byte EXTENSION of the committed one (main's records 1..N unchanged,
44
+ * local N+1.. following) or are they two chains that share a prefix and then
45
+ * differ? {@link planLogSync} asks `core/log-reconcile.ts` — the same comparison
46
+ * `log sync` and doctor's `log-drift` ask — and answers a plan or `null`:
47
+ *
48
+ * - a plan, and {@link runPreflight} calls `logSync` itself. Not a
49
+ * reimplementation of it: the APRV-215 ceremony (one hold of the append lock,
50
+ * snapshot, baseline, fast-forward, reconcile, rebuild the projections,
51
+ * post-verify) stays the single implementation, and this module supplies a
52
+ * caller rather than a copy;
53
+ * - `null`, and the old `up-preflight-log-diverged` refusal stands unchanged.
54
+ * A fork, a log that does not verify, a log at some path other than the
55
+ * repository's own, or any OTHER upstream-touched path locally modified all
56
+ * answer `null`. Every one of those is a judgment, and this module makes none.
57
+ *
58
+ * ## Refusals, not repairs
59
+ *
60
+ * Four codes, each firing for exactly one condition. The first three are
61
+ * evaluated in this order, before anything is written:
62
+ *
63
+ * - `up-preflight-behind-ahead` — `origin/<branch>..HEAD` is non-empty. Local
64
+ * commits exist that the remote does not have. A fast-forward is not the
65
+ * operation for that state, and guessing which side to keep is a decision.
66
+ * - `up-preflight-log-diverged` — the upstream range changes the working log or
67
+ * the queue projection, the working copy has uncommitted changes to them, AND
68
+ * the two chains are not in a prefix relationship (or cannot be compared at
69
+ * all). This is the case the human could not judge by eye, and it is `approval
70
+ * log sync`'s whole subject. The routine case — a working log that merely
71
+ * extends the committed one — is reconciled rather than refused (APRV-346).
72
+ * - `up-preflight-dirty-protected` — some OTHER path the upstream range changes
73
+ * is locally modified, so `git merge --ff-only` would refuse to overwrite it.
74
+ * Named separately because the repair is different: look at the edit and
75
+ * decide, or start on the current build with `--no-preflight`.
76
+ *
77
+ * The fourth is answered after the merge has already refused, and only for the
78
+ * one path shape where two checkouts routinely author one file (APRV-300):
79
+ *
80
+ * - `up-preflight-task-file-conflict` — an untracked file under
81
+ * `backlog/tasks/` stopped the fast-forward, and it holds lines the incoming
82
+ * copy does not. See {@link reconcileUntrackedTaskFiles} for what happens
83
+ * when it holds none, and why that is a claim rather than an assumption.
84
+ *
85
+ * `git reset --hard` appears in none of them, and never will: it is the command
86
+ * that turns "your checkout is confusing" into "your work is gone".
87
+ *
88
+ * A fourth refusal reports a write that failed rather than a judgment:
89
+ * `up-preflight-failed` carries the step and, for the build, the exit code
90
+ * `npm run build` came back with. The runtime does not start after it, because the whole point
91
+ * of the rebuild is that a daemon and a hook running compiled-away code is the
92
+ * defect being fixed (APRV-301); `--no-build` is how an operator says they
93
+ * meant to run the stale build anyway.
94
+ *
95
+ * ## A fetch that fails is weather
96
+ *
97
+ * A laptop on a train has no origin to compare against. That is not a reason to
98
+ * refuse to run a gate — the log is local, the policy is local, and the human is
99
+ * holding the phone. A failed fetch is reported as a warning and the runtime
100
+ * starts on the build it has, saying so.
101
+ *
102
+ * ## Two callers, one judgment
103
+ *
104
+ * `approval up` (and therefore `approval daemon run --with-channels`) acts on
105
+ * it; `approval doctor`'s `main-behind-origin` row reports it. Doctor passes
106
+ * `fetch: false`, because a report is not allowed to make a network call the
107
+ * operator did not ask for, and says out loud that its answer is only as fresh
108
+ * as the last fetch.
109
+ */
110
+ import type { EventRecord } from "../core/log.js";
111
+ import { type LogRelation } from "../core/log-reconcile.js";
112
+ import type { DoctorCheck } from "./doctor.js";
113
+ import { type RunbookStep } from "./style.js";
114
+ /**
115
+ * The installation root: the directory holding `cli.js`, `src/`, `dist/`.
116
+ *
117
+ * Derived from this module's own location rather than from `cwd`, because the
118
+ * question is "is the code I am running stale", and the answer must not change
119
+ * when the operator runs the CLI from somewhere else. Compiled, this file is
120
+ * `<root>/dist/src/cli/preflight.js`, hence three levels up.
121
+ */
122
+ export declare function installationRoot(): string;
123
+ /** Thrown out of the source walk so a real I/O denial can become exit 4. */
124
+ export declare class ScanError extends Error {
125
+ }
126
+ /**
127
+ * Is the built CLI at least as new as the sources it was built from?
128
+ *
129
+ * The marker is `dist/src/cli/main.js` — the exact file `cli.js` loads, so the
130
+ * thing being timestamped is the thing that will actually run. It is compared
131
+ * against the newest mtime under `src/` and of `tsconfig.json` (a compiler
132
+ * option change invalidates a build as surely as an edit does).
133
+ *
134
+ * Three shapes are distinguished because their repairs differ:
135
+ *
136
+ * - `cli.js` present, `dist/` absent — the placeholder-binary shape from the
137
+ * ceremony. The loader exists, so the checkout *looks* installed; nothing
138
+ * behind it does.
139
+ * - marker older than sources — the stale-checkout shape. Verbs that exist in
140
+ * `src/` are missing from the binary.
141
+ * - no `src/` at all — a published install, where freshness is not a question
142
+ * that can be asked. `skip`, not a silent pass.
143
+ *
144
+ * Note the self-reference: doctor itself runs *from* `dist`, so a completely
145
+ * absent `dist` means `cli.js` already refused and this code never ran. The
146
+ * check is still implemented for that shape because `--root` can point it at
147
+ * another tree, and because "the binary you ran is not the tree you edited" is
148
+ * exactly the confusion it exists to name.
149
+ */
150
+ export declare function checkBuildFreshness(root: string): DoctorCheck;
151
+ /**
152
+ * Is `root`'s build older than `root`'s sources?
153
+ *
154
+ * `null` when the question does not apply — a published install with no `src/`,
155
+ * or a tree that is not an installation at all. A caller that wants the full
156
+ * three-way answer asks {@link checkBuildFreshness}; this is the boolean the
157
+ * preflight acts on, and "cannot tell" must not read as "stale" or the preflight
158
+ * would rebuild a tree it has no business compiling.
159
+ */
160
+ export declare function distStale(root: string): boolean | null;
161
+ /** What the preflight did, or would have done. Frozen: it is a `--json` field. */
162
+ export type PreflightAction =
163
+ /** Already at the remote tip with a build no older than the sources. */
164
+ "none"
165
+ /** Only the build was behind. */
166
+ | "rebuild"
167
+ /** Only the checkout was behind. */
168
+ | "fast-forward"
169
+ /** Both. The ordinary shape after a few days away. */
170
+ | "fast-forward+rebuild"
171
+ /** The build was older than the sources and `--no-build` said to leave it. */
172
+ | "build-skipped"
173
+ /** The checkout was behind, the build is now stale, and `--no-build` said so. */
174
+ | "fast-forward+build-skipped"
175
+ /** A refusal: nothing was touched. */
176
+ | "refused"
177
+ /** `--no-preflight`, or a checkout git cannot answer questions about. */
178
+ | "skipped"
179
+ /** The fetch did not reach the remote. Weather, not a fault. */
180
+ | "fetch-failed";
181
+ /** The machine-readable refusal codes. Frozen public API, distinct by repair. */
182
+ export declare const PREFLIGHT_REFUSAL_CODES: readonly ["up-preflight-behind-ahead", "up-preflight-log-diverged", "up-preflight-dirty-protected", "up-preflight-task-file-conflict"];
183
+ export type PreflightRefusalCode = (typeof PREFLIGHT_REFUSAL_CODES)[number];
184
+ /** The facts, exactly as they are carried on the `--json` stream. */
185
+ export interface PreflightFacts {
186
+ behind_by: number;
187
+ ahead_by: number;
188
+ log_touched: boolean;
189
+ dist_stale: boolean;
190
+ action: PreflightAction;
191
+ /**
192
+ * True when the preflight rebuilt and the runtime therefore re-executed into
193
+ * the fresh build rather than carrying on in the process that dated it.
194
+ *
195
+ * Always false from {@link inspectPreflight}: inspection builds nothing, so
196
+ * it can never be the reason a process was replaced. Doctor's row reads that
197
+ * answer and never this one.
198
+ */
199
+ reexec: boolean;
200
+ /**
201
+ * True when `approval log sync`'s reconcile ran on this preflight's behalf
202
+ * (APRV-346), which is the one write here that touches the working log.
203
+ *
204
+ * Always false from {@link inspectPreflight}, for the same reason `reexec` is:
205
+ * inspection performs nothing, so it can never be the thing that did this.
206
+ * What inspection answers instead is {@link PreflightReport}'s `sync`, which
207
+ * is the plan rather than the deed.
208
+ */
209
+ log_synced: boolean;
210
+ }
211
+ /**
212
+ * The reconcile the preflight would hand to `approval log sync`, or has.
213
+ *
214
+ * Present on a report only when the protected-path collision is the routine one
215
+ * (APRV-346): the working chain and the committed chain stand in a prefix
216
+ * relationship, so adopting the longer one extends and never rewinds. A fork,
217
+ * or a chain that cannot be verified, has no plan — it has a refusal.
218
+ */
219
+ export interface PreflightSyncPlan {
220
+ /** How the working chain stands relative to the committed one at the target. */
221
+ relation: LogRelation;
222
+ /** Records the working chain holds beyond the committed one: what is kept. */
223
+ kept: number;
224
+ }
225
+ /** A refusal, in the APRV-129 runbook's own vocabulary. */
226
+ export interface PreflightRefusal {
227
+ code: PreflightRefusalCode;
228
+ headline: string;
229
+ state: string[];
230
+ steps: RunbookStep[];
231
+ footer: string[];
232
+ /** The one command a machine caller should run next, unadorned. */
233
+ next: string;
234
+ }
235
+ /** What {@link inspectPreflight} answers. */
236
+ export type PreflightReport = {
237
+ ok: true;
238
+ facts: PreflightFacts;
239
+ /** One sentence, for the human line and for doctor's `detail`. */
240
+ detail: string;
241
+ /** A fetch that did not reach the remote, or `null`. */
242
+ warning: string | null;
243
+ /** The commit a fast-forward would move to, when there is one. */
244
+ target: string | null;
245
+ /** Where the judgment was made. `null` when there was no repository. */
246
+ root: string | null;
247
+ /**
248
+ * The reconcile this preflight would ask `approval log sync` for, or
249
+ * `null` when the working log needs nothing (APRV-346).
250
+ */
251
+ sync: PreflightSyncPlan | null;
252
+ } | {
253
+ ok: false;
254
+ facts: PreflightFacts;
255
+ refusal: PreflightRefusal;
256
+ root: string;
257
+ };
258
+ export interface PreflightInput {
259
+ /** The working log, which also names the repository (as doctor's log-drift does). */
260
+ logPath: string;
261
+ /** The queue projection, the second path a fast-forward must not clobber. */
262
+ queuePath: string;
263
+ /** The installation whose `dist/` is dated against its `src/`. */
264
+ root: string;
265
+ /** Ask the remote, or judge against the last fetch. Doctor passes `false`. */
266
+ fetch: boolean;
267
+ /** Defaults to `origin`. */
268
+ remote?: string;
269
+ /** Defaults to the checked-out branch, or `main` on a detached HEAD. */
270
+ branch?: string;
271
+ /**
272
+ * Run the package's build when `dist/` is older than the sources. Defaults to
273
+ * `true`, which is the whole point of the preflight; `false` is `--no-build`.
274
+ *
275
+ * Opting out changes what the preflight DOES, never what it SAYS: the
276
+ * fast-forward still happens, `dist_stale` still reports the truth, and the
277
+ * action settles on `build-skipped` so neither the human line nor a machine
278
+ * caller can read "started" as "started on the code that was merged".
279
+ *
280
+ * {@link inspectPreflight} ignores it, because inspection builds nothing.
281
+ */
282
+ build?: boolean;
283
+ }
284
+ /**
285
+ * The whole judgment, and not one byte of action.
286
+ *
287
+ * Every write the preflight is allowed to make lives in {@link runPreflight};
288
+ * this function reads. That split is what lets doctor report the same facts
289
+ * without any risk of doctor repairing something, which doctor has never done.
290
+ */
291
+ export declare function inspectPreflight(input: PreflightInput): PreflightReport;
292
+ /** What the reconcile actually did, once `approval log sync` had run it. */
293
+ export interface PreflightSynced {
294
+ /** The commit the checkout ended on. */
295
+ commit: string;
296
+ /** Local records the reconcile put back on top of it. */
297
+ kept: number;
298
+ relation: LogRelation;
299
+ remote: string;
300
+ branch: string;
301
+ }
302
+ /** What {@link runPreflight} did, with the facts as they ended up. */
303
+ export type PreflightOutcome = {
304
+ ok: true;
305
+ facts: PreflightFacts;
306
+ detail: string;
307
+ warning: string | null;
308
+ /** Present when a rebuild happened: the caller must become this child. */
309
+ reexec?: ReexecPlan;
310
+ /** Present when the reconcile ran: what it fast-forwarded and kept. */
311
+ synced?: PreflightSynced;
312
+ } | {
313
+ ok: false;
314
+ facts: PreflightFacts;
315
+ refusal: PreflightRefusal;
316
+ }
317
+ /** A write the preflight attempted and could not complete. Also a refusal. */
318
+ | {
319
+ ok: false;
320
+ facts: PreflightFacts;
321
+ failed: {
322
+ step: string;
323
+ message: string;
324
+ };
325
+ };
326
+ /**
327
+ * Inspect, then perform at most a fast-forward and a build.
328
+ *
329
+ * `npm run build` is spawned rather than shelled, with the checkout as its cwd,
330
+ * so nothing here depends on the operator's shell or on `npm` being on a
331
+ * particular PATH entry. Its output is discarded and its exit status is the
332
+ * whole answer: a build that fails is a failed preflight, and the runtime does
333
+ * not start on a half-compiled tree.
334
+ */
335
+ export declare function runPreflight(input: PreflightInput, spawnBuild?: (root: string) => {
336
+ ok: boolean;
337
+ message: string;
338
+ }): PreflightOutcome;
339
+ /** Where the fresh build lives, and what to run it with. */
340
+ export interface ReexecPlan {
341
+ /** `<root>/dist/src/cli/main.js` — resolved from the CHECKOUT, never from `import.meta`. */
342
+ entry: string;
343
+ /** This process's own argv, plus `--no-preflight` so the child cannot loop. */
344
+ argv: string[];
345
+ }
346
+ /**
347
+ * Run the fresh build in a child process and become its exit code.
348
+ *
349
+ * `stdio: "inherit"` so the child owns the terminal exactly as the parent would
350
+ * have: the daemon's lines, the token panel, a channel's prompts and an
351
+ * operator's ctrl-c all behave as though no re-exec happened. SIGINT and
352
+ * SIGTERM are forwarded rather than handled, because the child is the writer
353
+ * and the shutdown sequence that matters is its own.
354
+ *
355
+ * A child killed by the signal we forwarded exits 0: the operator asked the
356
+ * runtime to stop and it stopped, which is a clean stop under any spelling.
357
+ * Any other signal is reported as an I/O failure, because a writer that
358
+ * vanished is a fact about the machine rather than a decision of the runtime.
359
+ */
360
+ export declare function reexecFreshBuild(plan: ReexecPlan, cwd: string): Promise<number>;
361
+ /**
362
+ * The preflight's two lines on the event stream.
363
+ *
364
+ * They live here rather than in `cli/up.ts` because `approval daemon run` runs
365
+ * the same preflight and must print the same lines, and `daemon.ts` cannot
366
+ * import `up.ts` (the cycle APRV-110 already routes around with a dynamic
367
+ * import). `UpEvent` includes this union, so the `--json` stream stays one union
368
+ * of additive shapes with no field added to any shape that already existed.
369
+ */
370
+ export type PreflightEvent = ({
371
+ event: "preflight";
372
+ commit: string | null;
373
+ detail: string;
374
+ } & PreflightFacts) | {
375
+ event: "preflight_warning";
376
+ message: string;
377
+ }
378
+ /**
379
+ * The reconcile, when there was one (APRV-346). A third additive shape rather
380
+ * than a field on `preflight`: a consumer that already parses that line must
381
+ * not have to learn a key to keep working, and this is a different fact —
382
+ * what `approval log sync` did, not what the preflight found.
383
+ */
384
+ | ({
385
+ event: "preflight_sync";
386
+ } & PreflightSynced)
387
+ /**
388
+ * The attested policy is not on the remote yet (APRV-342). Emitted only when
389
+ * that is TRUE: `up` reports the interregnum and never refuses on it, because
390
+ * a policy amendment waiting on a pull request is a normal state of a
391
+ * repository and not a reason to refuse to run the gate.
392
+ */
393
+ | {
394
+ event: "preflight_policy";
395
+ detail: string;
396
+ fix: string | null;
397
+ };
398
+ /** One preflight line as a human sentence, and where it belongs. */
399
+ export declare function describePreflightEvent(event: PreflightEvent): {
400
+ text: string;
401
+ stderr: boolean;
402
+ };
403
+ /** How a caller emits one line. `up` and `daemon run` route theirs identically. */
404
+ export type PreflightEmit = (event: PreflightEvent) => void;
405
+ /**
406
+ * The policy file `--policy` names, or the one `--dir` (else `cwd`) holds.
407
+ *
408
+ * Discovery, not a load: this answers WHICH FILE, so the preflight can compare
409
+ * its attested hash against the remote's copy (APRV-342) before either caller
410
+ * has loaded a policy. The order is `core/policy-load.ts`'s own, so the file
411
+ * named here is the file the runtime will go on to enforce. `null` when there is
412
+ * no such file, which is not a finding — `approval doctor`'s `policy` rows are
413
+ * where an absent policy is somebody's problem.
414
+ */
415
+ export declare function preflightPolicyPath(policyFlag: string | null, dirFlag: string | null, cwd: string): string | null;
416
+ export interface StartupPreflightInput {
417
+ logPath: string;
418
+ queuePath: string;
419
+ /**
420
+ * The policy file, for the `attested-policy-on-main` line (APRV-342). `null`
421
+ * where the caller could not name one, and the line is then not emitted:
422
+ * there is nothing to compare, which is not a finding.
423
+ */
424
+ policyPath?: string | null;
425
+ /** The installation whose `dist/` is dated. `null` means "ask this build". */
426
+ root: string | null;
427
+ remote: string | null;
428
+ branch: string | null;
429
+ /** `false` is `--no-build`: fast-forward, but leave a stale `dist/` alone. */
430
+ build: boolean;
431
+ emit: PreflightEmit;
432
+ /** Where a refusal is written. One line under `--json`, a runbook otherwise. */
433
+ refuse: (text: string) => void;
434
+ json: boolean;
435
+ }
436
+ /**
437
+ * Run the preflight, print what it did, and answer whether the caller may start.
438
+ *
439
+ * `ok: false` carries nothing but the fact: everything a human or a machine
440
+ * needs has already been written by `refuse`, and the caller's only remaining
441
+ * job is to return the exit code.
442
+ */
443
+ export declare function startupPreflight(input: StartupPreflightInput): {
444
+ ok: boolean;
445
+ reexec: ReexecPlan | null;
446
+ };
447
+ /**
448
+ * A preflight refusal, on both surfaces (APRV-129).
449
+ *
450
+ * The human surface is the runbook: the code, the state, one runnable command
451
+ * per numbered line, and the rationale compressed into the footer. The machine
452
+ * surface is one object carrying the stable code and the same facts the success
453
+ * path carries, so a supervisor can branch on `error.code` without reading a
454
+ * word of it.
455
+ */
456
+ export declare function renderPreflightRefusal(outcome: PreflightOutcome & {
457
+ ok: false;
458
+ }, json: boolean): string;
459
+ /**
460
+ * `main-behind-origin`, doctor's twenty-first row.
461
+ *
462
+ * It makes no network call (`fetch: false`), for the reason every doctor row
463
+ * makes none it was not asked for: doctor is a report, and a report that reached
464
+ * the network to be more accurate would be doing something on its own account.
465
+ * So the answer is as fresh as the last fetch, and the detail says so.
466
+ *
467
+ * `fix` strings stay inside `FIX_COMMAND_PREFIXES`: they name `approval` verbs,
468
+ * never `git`. That constraint predates this row and is the right one — a repair
469
+ * line telling an operator to reset a branch would be doctor making a decision.
470
+ */
471
+ /**
472
+ * `attested-policy-on-main`, doctor's row for the interregnum (APRV-342).
473
+ *
474
+ * Between a policy amendment and its pull request merging there is a window
475
+ * where the attestation is in the log and the amended `APPROVAL.md` is in the
476
+ * working tree, and `origin/main` carries neither. A fresh checkout of main in
477
+ * that window has the OLD policy with no attestation covering it, and every
478
+ * gate operation there refuses `policy-not-attested`.
479
+ *
480
+ * Nothing said so. On 2026-09-16 `approval up` ran its preflight in exactly that
481
+ * state and reported "already at the remote tip"; doctor's `attestation` row
482
+ * passed, because the LOCAL file is attested and that row asks a different
483
+ * question. This row asks the missing one: is the policy the log vouches for the
484
+ * policy `origin/<branch>` carries?
485
+ *
486
+ * Read-only, and networkless. The remote tip is read from the last fetch, like
487
+ * every other answer doctor gives about a remote, and the `policy-amend-<seq>`
488
+ * branch is looked for among the remote-tracking refs rather than asked of
489
+ * GitHub: a report that reached the network to be more accurate would be doing
490
+ * something on its own account.
491
+ */
492
+ export declare function checkAttestedPolicyOnMain(input: {
493
+ policyPath: string;
494
+ /** The log, verified, in append order. Doctor's own records; `up` re-reads. */
495
+ records: readonly EventRecord[];
496
+ /** The repository the policy lives in, or `null` when it is not in one. */
497
+ root: string | null;
498
+ remote?: string;
499
+ branch?: string;
500
+ }): DoctorCheck;
501
+ export declare function checkMainBehindOrigin(logPath: string, queuePath: string, root: string): DoctorCheck;