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
@@ -0,0 +1,312 @@
1
+ /**
2
+ * The open window (amended SPEC.md §5.2, APRV-214): a human-only, time-boxed
3
+ * suspension of the harness gate's POLICY, so the gate can be debugged from
4
+ * inside a session it would otherwise refuse everything to.
5
+ *
6
+ * ## Why this exists
7
+ *
8
+ * `cli/hook.ts` fails closed on every axis, which is right, and which means the
9
+ * moment the gate itself is broken (an unattested policy, a drifted
10
+ * attestation, a hung daemon, a dark channel) every command a session issues
11
+ * dies, including the ones a person would use to repair it. The only escape
12
+ * before this was hand-editing the hook out of `.claude/settings.json`: an
13
+ * ungated session nobody records, which is the exact failure this project
14
+ * exists to prevent.
15
+ *
16
+ * ## Where the state lives, and why it lives there
17
+ *
18
+ * In the log, as `gate.opened` / `gate.closed`, and NOWHERE else. The
19
+ * `.approval/env` precedent (`cli/init.ts`) states the rule this follows: a
20
+ * file the runtime reads on its own authority lets anything able to write that
21
+ * file act as the human. A window flag in a dotfile would be exactly that, and
22
+ * an agent that can write files is the party the window is a bypass for.
23
+ *
24
+ * The consequence is deliberate and is the property that keeps this safe: a log
25
+ * the hook cannot read, or cannot verify, yields NO window and the hook denies
26
+ * as it always did. The window suspends the policy; it never suspends the log.
27
+ *
28
+ * ## What is derived rather than written
29
+ *
30
+ * Nothing is appended when a window lapses. A reader derives the window from
31
+ * the latest `gate.opened`: it is open when no `gate.closed` names its seq and
32
+ * the moment of asking is before its expiry. Expiry is `ts` plus `duration`,
33
+ * both of which are on the record, and the runtime authored the `ts` at the
34
+ * write boundary (`core/clock.ts`), so an opener cannot author the length of
35
+ * their own window. `expires_at` rides along for a human reading the log; a
36
+ * record claiming one BEYOND `ts + duration` reads as the shorter of the two,
37
+ * and a duration over {@link MAX_WINDOW_MS} is clamped at read time as well as
38
+ * refused at write time. Every path through this file resolves an ambiguity by
39
+ * shortening the window, never by lengthening it.
40
+ *
41
+ * ## What this module does not do
42
+ *
43
+ * It does not decide anything about a command. The hook classifies inside an
44
+ * open window exactly as it does outside one, still denies `log.mutate`, still
45
+ * denies every class the policy reserves to human hands, and still denies a
46
+ * command the classifier cannot read. All this module offers is the derived
47
+ * window and the three appends, each through `core/log.ts`'s `appendEvent` with
48
+ * a compare-and-append precondition (§11.1 invariant 5).
49
+ *
50
+ * `core/gate.ts`'s `startHarnessExecution` is deliberately NOT reused for the
51
+ * bypass record: it refuses on an unattested policy, on manual, on the loop
52
+ * floor and on budget, which are the very things being bypassed. What is reused
53
+ * is the mechanism, `appendEvent` with `expectedHead` under a head-moved retry.
54
+ */
55
+ import { type ClockOptions } from "./clock.js";
56
+ import { type HarnessProvenance } from "./harness-version.js";
57
+ import { type AppendError, type AppendOptions, type EventRecord } from "./log.js";
58
+ /** What an open window suspends. One value at v0.1, matching the schema enum. */
59
+ export declare const GATE_WINDOW_SCOPE = "hook";
60
+ /** The duration `approval gate open` uses when none is asked for. */
61
+ export declare const DEFAULT_WINDOW = "30m";
62
+ /**
63
+ * The longest window anyone may open, enforced at BOTH ends: `openWindow`
64
+ * refuses a longer one, and {@link openGateWindow} clamps a record claiming one
65
+ * so that a hand-written `gate.opened` buys no more time than the ceremony
66
+ * would have granted.
67
+ *
68
+ * A day, because the window's purpose is one debugging session and because a
69
+ * bypass that outlives the person's attention is a bypass nobody is watching.
70
+ */
71
+ export declare const MAX_WINDOW_MS: number;
72
+ /**
73
+ * The verb-level refusal codes of the open window. **Frozen union**, in the
74
+ * same sense as `GATE_REFUSAL_CODES`, `EXECUTION_REFUSAL_CODES`,
75
+ * `AUDIT_REFUSAL_CODES`, `DARK_SESSION_CODES` and `HOOK_DENY_CODES`: a caller
76
+ * branches on these, so members are added and never repurposed (SPEC.md §11.1
77
+ * invariant 6, which this makes the sixth such union).
78
+ *
79
+ * Every one of them appends nothing.
80
+ */
81
+ export declare const GATE_WINDOW_REFUSAL_CODES: readonly [
82
+ /**
83
+ * The actor is not `human:`-prefixed. Opening a window is the one act that
84
+ * suspends the policy, so an agent able to perform it could authorize its own
85
+ * next command. Refused here in code, and again in `event.schema.json`.
86
+ */
87
+ "actor-not-human",
88
+ /** No reason was given. A bypass nobody stated a reason for cannot be reviewed. */
89
+ "gate-reason-required",
90
+ /**
91
+ * The duration is over {@link MAX_WINDOW_MS}, zero, negative, or unreadable.
92
+ * One code for the family because the repair is one sentence: ask for a
93
+ * shorter window, spelled the way SPEC.md §5.2 spells durations.
94
+ */
95
+ "gate-duration-too-long",
96
+ /** A window is already open. Close it, or wait for it to lapse. */
97
+ "gate-already-open",
98
+ /**
99
+ * No window is open. `close` says so rather than appending a record that
100
+ * closes nothing, and a bypass asked for with no window behind it at all says
101
+ * so rather than recording a bypass nothing authorized.
102
+ */
103
+ "gate-not-open",
104
+ /**
105
+ * The window a caller DECIDED under is gone by the time the bypass is
106
+ * recorded (APRV-294).
107
+ *
108
+ * Distinct from `gate-not-open`, and the difference is the fact each states.
109
+ * That one says there was no window to begin with, which is the ordinary
110
+ * closed gate. This one says a window stood when the verdict was formed and
111
+ * does not stand at the append: a human closed it, it lapsed, or a later
112
+ * `gate.opened` superseded the one the caller named. The refusal names the
113
+ * `gate.closed` seq that ended it, or the expiry it ran past, so a reviewer
114
+ * holding the log alone can place the boundary.
115
+ *
116
+ * The repair is a retry, and it is a retry of an ordinary gated tool call:
117
+ * nothing is appended here, nothing ran, and the next invocation derives the
118
+ * window from its own read and is answered by the policy where there is none.
119
+ * A refusal on this path is therefore not a failed execution and accrues no
120
+ * loop-safety streak (SPEC.md §10.2), because no execution was started for it.
121
+ */
122
+ "gate-window-closed",
123
+ /**
124
+ * Stdin is not a terminal (or `--json` was asked for). The ceremony is a
125
+ * person typing a word, and a prompt a pipe could answer is a ceremony a
126
+ * harness shell tool can perform.
127
+ */
128
+ "gate-stdin-not-tty",
129
+ /** The typed confirmation was not exactly `understood`. Includes EOF. */
130
+ "gate-confirmation-mismatch",
131
+ /** The log could not be opened. */
132
+ "log-unreadable",
133
+ /** The log's last line is truncated: a crashed write, repaired by a human. */
134
+ "log-torn-tail",
135
+ /** The chain does not verify, so no window may be derived from it. */
136
+ "log-corrupt",
137
+ /** The append itself was refused; `append` carries the writer's own code. */
138
+ "append-failed"];
139
+ export type GateWindowRefusalCode = (typeof GATE_WINDOW_REFUSAL_CODES)[number];
140
+ /** A refusal from this module. Nothing was appended. */
141
+ export interface GateWindowRefusal {
142
+ ok: false;
143
+ code: GateWindowRefusalCode;
144
+ message: string;
145
+ /** The underlying writer error, when `code` is `append-failed`. */
146
+ append?: AppendError;
147
+ }
148
+ /** An open window, as derived from the log. */
149
+ export interface OpenWindow {
150
+ /** The `seq` of the `gate.opened` record. Every bypass names it. */
151
+ seq: number;
152
+ /** The runtime-stamped instant the window opened. */
153
+ openedAt: string;
154
+ /** The human who opened it. */
155
+ openedBy: string;
156
+ /** Why, in their words. */
157
+ reason: string;
158
+ /** The effective length, after the {@link MAX_WINDOW_MS} clamp. */
159
+ durationMs: number;
160
+ /** The effective expiry: the earlier of `ts + duration` and the claim. */
161
+ expiresAt: string;
162
+ /** How many `gate.bypassed` records name this window so far. */
163
+ bypassCount: number;
164
+ }
165
+ /** A successful append, with the window the caller may now report. */
166
+ export interface GateWindowResult {
167
+ ok: true;
168
+ record: EventRecord;
169
+ window: OpenWindow;
170
+ }
171
+ /** A successful close: the record, and the window it ended. */
172
+ export interface GateCloseResult {
173
+ ok: true;
174
+ record: EventRecord;
175
+ closed: OpenWindow;
176
+ }
177
+ /** Options every write here accepts: the injected clock, plus append tuning. */
178
+ export interface GateWindowOptions extends ClockOptions {
179
+ schemaDir?: string;
180
+ append?: AppendOptions;
181
+ /** Lowers the head-moved attempt bound; never raises it. */
182
+ retryOnHeadMoved?: number;
183
+ }
184
+ /**
185
+ * The window open at `now`, or `null`.
186
+ *
187
+ * Pure over the records it is given, so every caller (the hook, the CLI verb,
188
+ * `approval status`) derives the same fact from the same log and none of them
189
+ * reads a clock of its own.
190
+ *
191
+ * Only the LATEST `gate.opened` is considered. An older one that was never
192
+ * closed is not a second window: the ceremony refuses to open a second while
193
+ * one stands, so an unclosed older record is either lapsed or superseded, and
194
+ * treating it as live would let a stale record outlive the window a human
195
+ * actually opened.
196
+ *
197
+ * Every ambiguity resolves closed. An unreadable duration, a missing reason, a
198
+ * `ts` that does not parse: each yields `null` rather than a window nobody can
199
+ * state the bounds of.
200
+ */
201
+ export declare function openGateWindow(records: readonly EventRecord[], now?: Date | number): OpenWindow | null;
202
+ /** Milliseconds left on a window at `now`, floored at zero. */
203
+ export declare function remainingMs(window: OpenWindow, now?: Date | number): number;
204
+ /** What `approval gate open` asks for, already parsed by its caller. */
205
+ export interface OpenWindowInput {
206
+ /** The duration as typed (`30m`), recorded verbatim on the event. */
207
+ durationText: string;
208
+ /** The same duration in milliseconds, as the caller parsed it. */
209
+ durationMs: number;
210
+ /** Why the window is being opened. */
211
+ reason: string;
212
+ }
213
+ /**
214
+ * Append `gate.opened`, after establishing that the actor is a human, the
215
+ * duration is inside the cap, and no window is already open.
216
+ *
217
+ * One `tick()` supplies BOTH the record's `ts` and its `expires_at`, so the two
218
+ * cannot disagree by a scheduling delay and the derived expiry is exactly the
219
+ * claimed one on a record this runtime wrote.
220
+ */
221
+ export declare function openWindow(logPath: string, input: OpenWindowInput, actor: string, options?: GateWindowOptions): GateWindowResult | GateWindowRefusal;
222
+ /**
223
+ * Append `gate.closed` for whatever window stands.
224
+ *
225
+ * No confirmation anywhere on this path: closing only ever TIGHTENS, and a
226
+ * ceremony guarding the safe direction is a ceremony people learn to type past.
227
+ */
228
+ export declare function closeWindow(logPath: string, actor: string, options?: GateWindowOptions & {
229
+ note?: string;
230
+ }): GateCloseResult | GateWindowRefusal;
231
+ /** One gated tool call the hook is about to allow because a window is open. */
232
+ export interface GateBypassInput {
233
+ /** The harness tool the call came through. */
234
+ tool: string;
235
+ /** The one-line headline, already truncated to the hook's `SUMMARY_LIMIT`. */
236
+ summary: string;
237
+ /** The classes the command resolved to. At least one. */
238
+ classes: readonly string[];
239
+ /** The `payload_hash` of the binding bytes. */
240
+ payloadHash: string;
241
+ sessionId?: string;
242
+ toolUseId?: string;
243
+ cwd?: string;
244
+ /**
245
+ * Which harness binary is printing the allow, and at what version (APRV-227).
246
+ *
247
+ * Derived by the hook process from its own event and its own PATH and handed
248
+ * in here; copied into the payload verbatim when present, omitted entirely
249
+ * when absent. Nothing reads it back — the window was authorized by a human's
250
+ * `gate.opened` and this pair moves no part of that (SPEC.md §11.1 invariant
251
+ * 4, and `core/harness-version.ts`'s header). What it does is let a reviewer
252
+ * of a bypass see which binary was standing in front of the gate at the time,
253
+ * which on this path is the record a human actually goes back and reads.
254
+ */
255
+ harness?: HarnessProvenance;
256
+ }
257
+ /**
258
+ * The window verdict a caller already reached, handed to the append that
259
+ * records it (APRV-294).
260
+ *
261
+ * ## Why the append takes the caller's read
262
+ *
263
+ * On 2026-09-07 two hook invocations disagreed about one window inside a
264
+ * minute: the first decided "open" from its own verified read and took the
265
+ * bypass path, and the append re-read, derived no window from the fresher
266
+ * bytes, and refused `gate-not-open`. Both reads were honest and the pair was
267
+ * not: the verdict was formed on one view of the log and acted on another, and
268
+ * the refusal named a state ("no window is open") that had never been true for
269
+ * the invocation being refused.
270
+ *
271
+ * So the decision travels with the write. `read` is the verified read the
272
+ * caller derived its window from, used by the FIRST append attempt, which makes
273
+ * the decision and the record one read rather than two. `openedSeq` is the
274
+ * window that decision named, and it outlives the seed: a `head-moved` retry
275
+ * re-reads (it must — the head it would chain onto has moved), and the window
276
+ * it then derives is compared against this seq, so a window that ended in
277
+ * between refuses {@link GATE_WINDOW_REFUSAL_CODES}'s `gate-window-closed`
278
+ * naming what ended it rather than the bare `gate-not-open`.
279
+ *
280
+ * Nothing here reads unverified bytes as verified: `read` is the caller's own
281
+ * verified read, and every retry past the first performs its own (§11.1
282
+ * invariant 1).
283
+ */
284
+ export interface GateBypassDecision {
285
+ /** The `seq` of the `gate.opened` the caller's verdict was decided under. */
286
+ openedSeq: number;
287
+ /** The verified read that verdict was formed on. The first attempt uses it. */
288
+ read?: {
289
+ records: readonly EventRecord[];
290
+ head: {
291
+ seq: number;
292
+ hash: string;
293
+ } | null;
294
+ };
295
+ }
296
+ /**
297
+ * Record a bypassed tool call, BEFORE its allow is printed.
298
+ *
299
+ * The order is record-then-allow for the same reason `recordUnattended`'s is
300
+ * (§11.1 invariant 8): a bypassed command that ran and left no record is the
301
+ * one state this whole feature must not be able to reach, so an append failure
302
+ * is the caller's deny.
303
+ *
304
+ * The window is re-derived on every attempt past the first. A head that moved
305
+ * says the read was stale, so the next attempt re-reads, re-derives, and appends
306
+ * against the head it saw; a window that lapsed or was closed refuses rather
307
+ * than recording a bypass nothing authorized. Which refusal depends on what the
308
+ * caller stated: with a {@link GateBypassDecision} in hand the refusal is
309
+ * `gate-window-closed` and names the record or the expiry that ended the window,
310
+ * and with none it is the historical `gate-not-open`.
311
+ */
312
+ export declare function recordGateBypass(logPath: string, input: GateBypassInput, actor: string, options?: GateWindowOptions, decided?: GateBypassDecision): GateWindowResult | GateWindowRefusal;