approval-md 0.0.1 → 0.1.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 (522) hide show
  1. package/LICENSE +176 -0
  2. package/NOTICE +5 -0
  3. package/README.md +909 -4
  4. package/SPEC.md +445 -32
  5. package/cli.js +29 -3
  6. package/dist/src/adapters/agentmail.js +1200 -0
  7. package/dist/src/adapters/agentmail.js.map +1 -0
  8. package/dist/src/adapters/conformance.js +461 -0
  9. package/dist/src/adapters/conformance.js.map +1 -0
  10. package/dist/src/adapters/contract.js +941 -0
  11. package/dist/src/adapters/contract.js.map +1 -0
  12. package/dist/src/adapters/email.js +749 -0
  13. package/dist/src/adapters/email.js.map +1 -0
  14. package/dist/src/adapters/env-passphrase.js +132 -0
  15. package/dist/src/adapters/env-passphrase.js.map +1 -0
  16. package/dist/src/adapters/registry.js +76 -0
  17. package/dist/src/adapters/registry.js.map +1 -0
  18. package/dist/src/adapters/smtp.js +499 -0
  19. package/dist/src/adapters/smtp.js.map +1 -0
  20. package/dist/src/adapters/vault-provider.js +161 -0
  21. package/dist/src/adapters/vault-provider.js.map +1 -0
  22. package/dist/src/channels/batch.js +121 -0
  23. package/dist/src/channels/batch.js.map +1 -0
  24. package/dist/src/channels/cli.js +468 -0
  25. package/dist/src/channels/cli.js.map +1 -0
  26. package/dist/src/channels/conformance.js +445 -0
  27. package/dist/src/channels/conformance.js.map +1 -0
  28. package/dist/src/channels/contract.js +494 -0
  29. package/dist/src/channels/contract.js.map +1 -0
  30. package/dist/src/channels/payload-view.js +43 -0
  31. package/dist/src/channels/payload-view.js.map +1 -0
  32. package/dist/src/channels/render-queue.js +564 -0
  33. package/dist/src/channels/render-queue.js.map +1 -0
  34. package/dist/src/channels/tagging.js +723 -0
  35. package/dist/src/channels/tagging.js.map +1 -0
  36. package/dist/src/channels/telegram.js +3190 -0
  37. package/dist/src/channels/telegram.js.map +1 -0
  38. package/dist/src/channels/web.js +903 -0
  39. package/dist/src/channels/web.js.map +1 -0
  40. package/dist/src/cli/adapter.js +278 -0
  41. package/dist/src/cli/adapter.js.map +1 -0
  42. package/dist/src/cli/amend.js +2171 -0
  43. package/dist/src/cli/amend.js.map +1 -0
  44. package/dist/src/cli/args.js +86 -0
  45. package/dist/src/cli/args.js.map +1 -0
  46. package/dist/src/cli/attest.js +307 -0
  47. package/dist/src/cli/attest.js.map +1 -0
  48. package/dist/src/cli/audit-card.js +201 -0
  49. package/dist/src/cli/audit-card.js.map +1 -0
  50. package/dist/src/cli/audit.js +460 -0
  51. package/dist/src/cli/audit.js.map +1 -0
  52. package/dist/src/cli/channel-telegram.js +2063 -0
  53. package/dist/src/cli/channel-telegram.js.map +1 -0
  54. package/dist/src/cli/channel-web.js +357 -0
  55. package/dist/src/cli/channel-web.js.map +1 -0
  56. package/dist/src/cli/channel.js +438 -0
  57. package/dist/src/cli/channel.js.map +1 -0
  58. package/dist/src/cli/checkpoint-tap.js +238 -0
  59. package/dist/src/cli/checkpoint-tap.js.map +1 -0
  60. package/dist/src/cli/coverage.js +343 -0
  61. package/dist/src/cli/coverage.js.map +1 -0
  62. package/dist/src/cli/daemon.js +631 -0
  63. package/dist/src/cli/daemon.js.map +1 -0
  64. package/dist/src/cli/doctor.js +2648 -0
  65. package/dist/src/cli/doctor.js.map +1 -0
  66. package/dist/src/cli/env.js +302 -0
  67. package/dist/src/cli/env.js.map +1 -0
  68. package/dist/src/cli/execute.js +1682 -0
  69. package/dist/src/cli/execute.js.map +1 -0
  70. package/dist/src/cli/exit-codes.js +82 -0
  71. package/dist/src/cli/exit-codes.js.map +1 -0
  72. package/dist/src/cli/feedback.js +205 -0
  73. package/dist/src/cli/feedback.js.map +1 -0
  74. package/dist/src/cli/gate-window.js +294 -0
  75. package/dist/src/cli/gate-window.js.map +1 -0
  76. package/dist/src/cli/gate.js +557 -0
  77. package/dist/src/cli/gate.js.map +1 -0
  78. package/dist/src/cli/git-scope.js +295 -0
  79. package/dist/src/cli/git-scope.js.map +1 -0
  80. package/dist/src/cli/gloss-attach.js +107 -0
  81. package/dist/src/cli/gloss-attach.js.map +1 -0
  82. package/dist/src/cli/gloss-codex-child.js +149 -0
  83. package/dist/src/cli/gloss-codex-child.js.map +1 -0
  84. package/dist/src/cli/gloss-codex.js +255 -0
  85. package/dist/src/cli/gloss-codex.js.map +1 -0
  86. package/dist/src/cli/gloss-options.js +79 -0
  87. package/dist/src/cli/gloss-options.js.map +1 -0
  88. package/dist/src/cli/gloss.js +362 -0
  89. package/dist/src/cli/gloss.js.map +1 -0
  90. package/dist/src/cli/help.js +2217 -0
  91. package/dist/src/cli/help.js.map +1 -0
  92. package/dist/src/cli/hook.js +2743 -0
  93. package/dist/src/cli/hook.js.map +1 -0
  94. package/dist/src/cli/import.js +175 -0
  95. package/dist/src/cli/import.js.map +1 -0
  96. package/dist/src/cli/init.js +336 -0
  97. package/dist/src/cli/init.js.map +1 -0
  98. package/dist/src/cli/instructions.js +262 -0
  99. package/dist/src/cli/instructions.js.map +1 -0
  100. package/dist/src/cli/journal.js +238 -0
  101. package/dist/src/cli/journal.js.map +1 -0
  102. package/dist/src/cli/log-advance.js +749 -0
  103. package/dist/src/cli/log-advance.js.map +1 -0
  104. package/dist/src/cli/log-anchor.js +387 -0
  105. package/dist/src/cli/log-anchor.js.map +1 -0
  106. package/dist/src/cli/log-checkpoint.js +128 -0
  107. package/dist/src/cli/log-checkpoint.js.map +1 -0
  108. package/dist/src/cli/log-sync.js +849 -0
  109. package/dist/src/cli/log-sync.js.map +1 -0
  110. package/dist/src/cli/log-verbs.js +354 -0
  111. package/dist/src/cli/log-verbs.js.map +1 -0
  112. package/dist/src/cli/long-help.js +148 -0
  113. package/dist/src/cli/long-help.js.map +1 -0
  114. package/dist/src/cli/main.js +1056 -0
  115. package/dist/src/cli/main.js.map +1 -0
  116. package/dist/src/cli/mcp.js +306 -0
  117. package/dist/src/cli/mcp.js.map +1 -0
  118. package/dist/src/cli/paths.js +79 -0
  119. package/dist/src/cli/paths.js.map +1 -0
  120. package/dist/src/cli/payload.js +253 -0
  121. package/dist/src/cli/payload.js.map +1 -0
  122. package/dist/src/cli/policy.js +229 -0
  123. package/dist/src/cli/policy.js.map +1 -0
  124. package/dist/src/cli/preflight.js +888 -0
  125. package/dist/src/cli/preflight.js.map +1 -0
  126. package/dist/src/cli/progress.js +112 -0
  127. package/dist/src/cli/progress.js.map +1 -0
  128. package/dist/src/cli/prompt.js +312 -0
  129. package/dist/src/cli/prompt.js.map +1 -0
  130. package/dist/src/cli/records.js +66 -0
  131. package/dist/src/cli/records.js.map +1 -0
  132. package/dist/src/cli/render.js +132 -0
  133. package/dist/src/cli/render.js.map +1 -0
  134. package/dist/src/cli/sandbox.js +150 -0
  135. package/dist/src/cli/sandbox.js.map +1 -0
  136. package/dist/src/cli/scaffold.js +137 -0
  137. package/dist/src/cli/scaffold.js.map +1 -0
  138. package/dist/src/cli/setup-adapter.js +475 -0
  139. package/dist/src/cli/setup-adapter.js.map +1 -0
  140. package/dist/src/cli/setup-channel.js +635 -0
  141. package/dist/src/cli/setup-channel.js.map +1 -0
  142. package/dist/src/cli/setup-checkpoint.js +196 -0
  143. package/dist/src/cli/setup-checkpoint.js.map +1 -0
  144. package/dist/src/cli/setup-common.js +376 -0
  145. package/dist/src/cli/setup-common.js.map +1 -0
  146. package/dist/src/cli/setup-flow.js +476 -0
  147. package/dist/src/cli/setup-flow.js.map +1 -0
  148. package/dist/src/cli/setup-service.js +308 -0
  149. package/dist/src/cli/setup-service.js.map +1 -0
  150. package/dist/src/cli/setup.js +473 -0
  151. package/dist/src/cli/setup.js.map +1 -0
  152. package/dist/src/cli/style.js +469 -0
  153. package/dist/src/cli/style.js.map +1 -0
  154. package/dist/src/cli/token.js +274 -0
  155. package/dist/src/cli/token.js.map +1 -0
  156. package/dist/src/cli/up.js +847 -0
  157. package/dist/src/cli/up.js.map +1 -0
  158. package/dist/src/cli/usage.js +91 -0
  159. package/dist/src/cli/usage.js.map +1 -0
  160. package/dist/src/cli/values.js +189 -0
  161. package/dist/src/cli/values.js.map +1 -0
  162. package/dist/src/cli/vault.js +362 -0
  163. package/dist/src/cli/vault.js.map +1 -0
  164. package/dist/src/cli/verb-registry.js +2173 -0
  165. package/dist/src/cli/verb-registry.js.map +1 -0
  166. package/dist/src/cli/wordmark.js +52 -0
  167. package/dist/src/cli/wordmark.js.map +1 -0
  168. package/dist/src/core/advance-cycle.js +200 -0
  169. package/dist/src/core/advance-cycle.js.map +1 -0
  170. package/dist/src/core/agents-md.js +747 -0
  171. package/dist/src/core/agents-md.js.map +1 -0
  172. package/dist/src/core/attest.js +577 -0
  173. package/dist/src/core/attest.js.map +1 -0
  174. package/dist/src/core/audit.js +882 -0
  175. package/dist/src/core/audit.js.map +1 -0
  176. package/dist/src/core/budgets.js +449 -0
  177. package/dist/src/core/budgets.js.map +1 -0
  178. package/dist/src/core/checkpoint.js +738 -0
  179. package/dist/src/core/checkpoint.js.map +1 -0
  180. package/dist/src/core/child-env.js +86 -0
  181. package/dist/src/core/child-env.js.map +1 -0
  182. package/dist/src/core/clock.js +43 -0
  183. package/dist/src/core/clock.js.map +1 -0
  184. package/dist/src/core/command-class.js +2321 -0
  185. package/dist/src/core/command-class.js.map +1 -0
  186. package/dist/src/core/coverage-sources/adapter.js +71 -0
  187. package/dist/src/core/coverage-sources/adapter.js.map +1 -0
  188. package/dist/src/core/coverage-sources/gh.js +136 -0
  189. package/dist/src/core/coverage-sources/gh.js.map +1 -0
  190. package/dist/src/core/coverage-sources/git.js +269 -0
  191. package/dist/src/core/coverage-sources/git.js.map +1 -0
  192. package/dist/src/core/coverage.js +337 -0
  193. package/dist/src/core/coverage.js.map +1 -0
  194. package/dist/src/core/credential-spec.js +23 -0
  195. package/dist/src/core/credential-spec.js.map +1 -0
  196. package/dist/src/core/dark-session.js +714 -0
  197. package/dist/src/core/dark-session.js.map +1 -0
  198. package/dist/src/core/decision-refusal.js +265 -0
  199. package/dist/src/core/decision-refusal.js.map +1 -0
  200. package/dist/src/core/env-file.js +837 -0
  201. package/dist/src/core/env-file.js.map +1 -0
  202. package/dist/src/core/execute.js +1233 -0
  203. package/dist/src/core/execute.js.map +1 -0
  204. package/dist/src/core/frontmatter.js +100 -0
  205. package/dist/src/core/frontmatter.js.map +1 -0
  206. package/dist/src/core/gate-window.js +506 -0
  207. package/dist/src/core/gate-window.js.map +1 -0
  208. package/dist/src/core/gate.js +2947 -0
  209. package/dist/src/core/gate.js.map +1 -0
  210. package/dist/src/core/git-run.js +93 -0
  211. package/dist/src/core/git-run.js.map +1 -0
  212. package/dist/src/core/harness-version.js +210 -0
  213. package/dist/src/core/harness-version.js.map +1 -0
  214. package/dist/src/core/harness-wait.js +58 -0
  215. package/dist/src/core/harness-wait.js.map +1 -0
  216. package/dist/src/core/head-retry.js +121 -0
  217. package/dist/src/core/head-retry.js.map +1 -0
  218. package/dist/src/core/instance.js +319 -0
  219. package/dist/src/core/instance.js.map +1 -0
  220. package/dist/src/core/intake-limits.js +350 -0
  221. package/dist/src/core/intake-limits.js.map +1 -0
  222. package/dist/src/core/jcs.js +132 -0
  223. package/dist/src/core/jcs.js.map +1 -0
  224. package/dist/src/core/journal.js +200 -0
  225. package/dist/src/core/journal.js.map +1 -0
  226. package/dist/src/core/live-draw.js +703 -0
  227. package/dist/src/core/live-draw.js.map +1 -0
  228. package/dist/src/core/log-reconcile.js +136 -0
  229. package/dist/src/core/log-reconcile.js.map +1 -0
  230. package/dist/src/core/log.js +546 -0
  231. package/dist/src/core/log.js.map +1 -0
  232. package/dist/src/core/loop.js +476 -0
  233. package/dist/src/core/loop.js.map +1 -0
  234. package/dist/src/core/md-fence.js +74 -0
  235. package/dist/src/core/md-fence.js.map +1 -0
  236. package/dist/src/core/money.js +195 -0
  237. package/dist/src/core/money.js.map +1 -0
  238. package/dist/src/core/payload-census.js +146 -0
  239. package/dist/src/core/payload-census.js.map +1 -0
  240. package/dist/src/core/payload-store.js +340 -0
  241. package/dist/src/core/payload-store.js.map +1 -0
  242. package/dist/src/core/payload.js +80 -0
  243. package/dist/src/core/payload.js.map +1 -0
  244. package/dist/src/core/policy-diff.js +565 -0
  245. package/dist/src/core/policy-diff.js.map +1 -0
  246. package/dist/src/core/policy-expectations.js +394 -0
  247. package/dist/src/core/policy-expectations.js.map +1 -0
  248. package/dist/src/core/policy-explain.js +230 -0
  249. package/dist/src/core/policy-explain.js.map +1 -0
  250. package/dist/src/core/policy-load.js +524 -0
  251. package/dist/src/core/policy-load.js.map +1 -0
  252. package/dist/src/core/policy-match.js +467 -0
  253. package/dist/src/core/policy-match.js.map +1 -0
  254. package/dist/src/core/policy-proposal.js +458 -0
  255. package/dist/src/core/policy-proposal.js.map +1 -0
  256. package/dist/src/core/prompt-layout.js +422 -0
  257. package/dist/src/core/prompt-layout.js.map +1 -0
  258. package/dist/src/core/protected-path-guard.js +1087 -0
  259. package/dist/src/core/protected-path-guard.js.map +1 -0
  260. package/dist/src/core/registration.js +39 -0
  261. package/dist/src/core/registration.js.map +1 -0
  262. package/dist/src/core/reindex.js +336 -0
  263. package/dist/src/core/reindex.js.map +1 -0
  264. package/dist/src/core/sampler.js +388 -0
  265. package/dist/src/core/sampler.js.map +1 -0
  266. package/dist/src/core/sandbox.js +424 -0
  267. package/dist/src/core/sandbox.js.map +1 -0
  268. package/dist/src/core/seal.js +290 -0
  269. package/dist/src/core/seal.js.map +1 -0
  270. package/dist/src/core/state.js +1009 -0
  271. package/dist/src/core/state.js.map +1 -0
  272. package/dist/src/core/task-file.js +464 -0
  273. package/dist/src/core/task-file.js.map +1 -0
  274. package/dist/src/core/telegram-config.js +114 -0
  275. package/dist/src/core/telegram-config.js.map +1 -0
  276. package/dist/src/core/token.js +578 -0
  277. package/dist/src/core/token.js.map +1 -0
  278. package/dist/src/core/validate.js +0 -0
  279. package/dist/src/core/validate.js.map +1 -0
  280. package/dist/src/core/values.js +153 -0
  281. package/dist/src/core/values.js.map +1 -0
  282. package/dist/src/core/vault.js +612 -0
  283. package/dist/src/core/vault.js.map +1 -0
  284. package/dist/src/core/verified-snapshot.js +506 -0
  285. package/dist/src/core/verified-snapshot.js.map +1 -0
  286. package/dist/src/core/verify.js +549 -0
  287. package/dist/src/core/verify.js.map +1 -0
  288. package/dist/src/core/version.js +9 -0
  289. package/dist/src/core/version.js.map +1 -0
  290. package/dist/src/core/wysiwys.js +728 -0
  291. package/dist/src/core/wysiwys.js.map +1 -0
  292. package/dist/src/daemon/advance-child.js +78 -0
  293. package/dist/src/daemon/advance-child.js.map +1 -0
  294. package/dist/src/daemon/advance.js +849 -0
  295. package/dist/src/daemon/advance.js.map +1 -0
  296. package/dist/src/daemon/audit.js +90 -0
  297. package/dist/src/daemon/audit.js.map +1 -0
  298. package/dist/src/daemon/daemon.js +1988 -0
  299. package/dist/src/daemon/daemon.js.map +1 -0
  300. package/dist/src/daemon/dark-session.js +119 -0
  301. package/dist/src/daemon/dark-session.js.map +1 -0
  302. package/dist/src/daemon/draw-child.js +132 -0
  303. package/dist/src/daemon/draw-child.js.map +1 -0
  304. package/dist/src/daemon/draw.js +458 -0
  305. package/dist/src/daemon/draw.js.map +1 -0
  306. package/dist/src/daemon/git-evidence.js +345 -0
  307. package/dist/src/daemon/git-evidence.js.map +1 -0
  308. package/dist/src/daemon/projection.js +233 -0
  309. package/dist/src/daemon/projection.js.map +1 -0
  310. package/dist/src/daemon/prune.js +376 -0
  311. package/dist/src/daemon/prune.js.map +1 -0
  312. package/dist/src/mcp/http.js +343 -0
  313. package/dist/src/mcp/http.js.map +1 -0
  314. package/dist/src/mcp/server.js +594 -0
  315. package/dist/src/mcp/server.js.map +1 -0
  316. package/docs/cli-reference.md +5363 -0
  317. package/package.json +43 -4
  318. package/schema/.gitkeep +0 -0
  319. package/schema/LICENSE +117 -0
  320. package/schema/envelope.schema.json +137 -0
  321. package/schema/event.schema.json +1810 -0
  322. package/schema/fixtures/envelope/invalid/action-missing-idempotency-key.json +15 -0
  323. package/schema/fixtures/envelope/invalid/action-unknown-class-format.json +14 -0
  324. package/schema/fixtures/envelope/invalid/confidence-out-of-range.json +11 -0
  325. package/schema/fixtures/envelope/invalid/est-cost-bare-number.json +14 -0
  326. package/schema/fixtures/envelope/invalid/est-cost-noncanonical-string.json +14 -0
  327. package/schema/fixtures/envelope/invalid/malformed-assignee.json +10 -0
  328. package/schema/fixtures/envelope/invalid/malformed-created-by.json +7 -0
  329. package/schema/fixtures/envelope/invalid/malformed-max-latency.json +11 -0
  330. package/schema/fixtures/envelope/invalid/malformed-payload-hash.json +14 -0
  331. package/schema/fixtures/envelope/invalid/max-cost-bare-number.json +11 -0
  332. package/schema/fixtures/envelope/invalid/missing-origin.json +3 -0
  333. package/schema/fixtures/envelope/invalid/negative-est-cost.json +14 -0
  334. package/schema/fixtures/envelope/invalid/unknown-state.json +7 -0
  335. package/schema/fixtures/envelope/invalid/unknown-top-level-field.json +8 -0
  336. package/schema/fixtures/envelope/valid/action-payload-hash.json +17 -0
  337. package/schema/fixtures/envelope/valid/actions-without-budget.json +18 -0
  338. package/schema/fixtures/envelope/valid/canonical.json +25 -0
  339. package/schema/fixtures/envelope/valid/minimal.json +7 -0
  340. package/schema/fixtures/envelope/valid/multi-action-executed.json +30 -0
  341. package/schema/fixtures/envelope/valid/record-write-stage.json +22 -0
  342. package/schema/fixtures/event/invalid/approval-granted-agent-actor.json +15 -0
  343. package/schema/fixtures/event/invalid/approval-granted-empty-batch-delivery-id.json +17 -0
  344. package/schema/fixtures/event/invalid/approval-granted-fifth-reaction.json +16 -0
  345. package/schema/fixtures/event/invalid/approval-granted-missing-actor.json +14 -0
  346. package/schema/fixtures/event/invalid/approval-requested-missing-action-key.json +14 -0
  347. package/schema/fixtures/event/invalid/approval-withdrawn-agent-policy-drift.json +15 -0
  348. package/schema/fixtures/event/invalid/approval-withdrawn-missing-reason.json +15 -0
  349. package/schema/fixtures/event/invalid/approval-withdrawn-system-actor.json +15 -0
  350. package/schema/fixtures/event/invalid/audit-decision-refused-human-actor.json +17 -0
  351. package/schema/fixtures/event/invalid/audit-decision-refused-missing-code.json +16 -0
  352. package/schema/fixtures/event/invalid/audit-reviewed-agent-actor.json +15 -0
  353. package/schema/fixtures/event/invalid/audit-reviewed-loved-no-note.json +16 -0
  354. package/schema/fixtures/event/invalid/audit-reviewed-system-actor.json +15 -0
  355. package/schema/fixtures/event/invalid/bad-actor-prefix.json +15 -0
  356. package/schema/fixtures/event/invalid/est-cost-bare-number.json +17 -0
  357. package/schema/fixtures/event/invalid/execution-completed-fabricated-exit-code.json +16 -0
  358. package/schema/fixtures/event/invalid/execution-completed-provider-ref-empty-id.json +18 -0
  359. package/schema/fixtures/event/invalid/execution-completed-provider-ref-extra-field.json +19 -0
  360. package/schema/fixtures/event/invalid/execution-completed-provider-ref-id-not-string.json +18 -0
  361. package/schema/fixtures/event/invalid/execution-completed-provider-ref-missing-adapter.json +17 -0
  362. package/schema/fixtures/event/invalid/execution-failed-open-reported-by.json +16 -0
  363. package/schema/fixtures/event/invalid/execution-indeterminate-open-reason.json +14 -0
  364. package/schema/fixtures/event/invalid/execution-reconciled-agent-actor.json +17 -0
  365. package/schema/fixtures/event/invalid/execution-started-negative-env-stripped.json +16 -0
  366. package/schema/fixtures/event/invalid/gate-bypassed-missing-opened-seq.json +15 -0
  367. package/schema/fixtures/event/invalid/gate-closed-non-integer-opened-seq.json +13 -0
  368. package/schema/fixtures/event/invalid/gate-opened-agent-actor.json +16 -0
  369. package/schema/fixtures/event/invalid/gate-organ-attested-absolute-path.json +14 -0
  370. package/schema/fixtures/event/invalid/gate-organ-attested-agent-actor.json +14 -0
  371. package/schema/fixtures/event/invalid/gate-organ-attested-missing-organ-path.json +13 -0
  372. package/schema/fixtures/event/invalid/harness-unknown-kind.json +18 -0
  373. package/schema/fixtures/event/invalid/harness-version-multiline.json +16 -0
  374. package/schema/fixtures/event/invalid/log-checkpoint-agent-actor.json +17 -0
  375. package/schema/fixtures/event/invalid/log-checkpoint-missing-signature.json +16 -0
  376. package/schema/fixtures/event/invalid/log-checkpoint-short-signed-hash.json +17 -0
  377. package/schema/fixtures/event/invalid/log-checkpoint-unknown-signature-alg.json +17 -0
  378. package/schema/fixtures/event/invalid/malformed-ts.json +15 -0
  379. package/schema/fixtures/event/invalid/missing-alg.json +14 -0
  380. package/schema/fixtures/event/invalid/missing-hash.json +14 -0
  381. package/schema/fixtures/event/invalid/non-integer-seq.json +15 -0
  382. package/schema/fixtures/event/invalid/payload-pruned-human-actor.json +14 -0
  383. package/schema/fixtures/event/invalid/payload-pruned-missing-hash.json +14 -0
  384. package/schema/fixtures/event/invalid/policy-declined-agent-actor.json +15 -0
  385. package/schema/fixtures/event/invalid/policy-proposed-missing-diff.json +19 -0
  386. package/schema/fixtures/event/invalid/policy-proposed-system-actor.json +26 -0
  387. package/schema/fixtures/event/invalid/short-hash.json +15 -0
  388. package/schema/fixtures/event/invalid/unknown-alg.json +15 -0
  389. package/schema/fixtures/event/invalid/unknown-event-type.json +15 -0
  390. package/schema/fixtures/event/invalid/unknown-top-level-field.json +16 -0
  391. package/schema/fixtures/event/valid/approval-expired.json +15 -0
  392. package/schema/fixtures/event/valid/approval-granted-batch.json +19 -0
  393. package/schema/fixtures/event/valid/approval-granted-reaction.json +16 -0
  394. package/schema/fixtures/event/valid/approval-granted.json +15 -0
  395. package/schema/fixtures/event/valid/approval-rejected.json +15 -0
  396. package/schema/fixtures/event/valid/approval-requested.json +19 -0
  397. package/schema/fixtures/event/valid/approval-revoked.json +15 -0
  398. package/schema/fixtures/event/valid/approval-withdrawn-policy-drift.json +17 -0
  399. package/schema/fixtures/event/valid/approval-withdrawn.json +16 -0
  400. package/schema/fixtures/event/valid/audit-decision-refused.json +20 -0
  401. package/schema/fixtures/event/valid/audit-reviewed-reaction.json +17 -0
  402. package/schema/fixtures/event/valid/audit-reviewed.json +15 -0
  403. package/schema/fixtures/event/valid/audit-sampled.json +14 -0
  404. package/schema/fixtures/event/valid/budget-exceeded.json +21 -0
  405. package/schema/fixtures/event/valid/envelope-drift.json +16 -0
  406. package/schema/fixtures/event/valid/execution-completed-harness-report.json +16 -0
  407. package/schema/fixtures/event/valid/execution-completed-provider-ref.json +18 -0
  408. package/schema/fixtures/event/valid/execution-completed.json +15 -0
  409. package/schema/fixtures/event/valid/execution-failed-harness-report.json +16 -0
  410. package/schema/fixtures/event/valid/execution-failed.json +15 -0
  411. package/schema/fixtures/event/valid/execution-indeterminate.json +15 -0
  412. package/schema/fixtures/event/valid/execution-reconciled.json +17 -0
  413. package/schema/fixtures/event/valid/execution-started-env-stripped.json +17 -0
  414. package/schema/fixtures/event/valid/execution-started.json +14 -0
  415. package/schema/fixtures/event/valid/gate-bypassed-harness-version.json +18 -0
  416. package/schema/fixtures/event/valid/gate-bypassed.json +19 -0
  417. package/schema/fixtures/event/valid/gate-closed.json +14 -0
  418. package/schema/fixtures/event/valid/gate-opened.json +16 -0
  419. package/schema/fixtures/event/valid/gate-organ-attested.json +14 -0
  420. package/schema/fixtures/event/valid/genesis-null-prev.json +14 -0
  421. package/schema/fixtures/event/valid/log-checkpoint.json +17 -0
  422. package/schema/fixtures/event/valid/payload-pruned-orphan.json +13 -0
  423. package/schema/fixtures/event/valid/payload-pruned.json +17 -0
  424. package/schema/fixtures/event/valid/policy-declined.json +16 -0
  425. package/schema/fixtures/event/valid/policy-proposed.json +35 -0
  426. package/schema/fixtures/event/valid/policy-updated.json +14 -0
  427. package/schema/fixtures/event/valid/reconciliation-required.json +18 -0
  428. package/schema/fixtures/event/valid/reconciliation-satisfied.json +17 -0
  429. package/schema/fixtures/event/valid/route-accepted.json +15 -0
  430. package/schema/fixtures/event/valid/route-proposed.json +16 -0
  431. package/schema/fixtures/event/valid/spec-example.json +15 -0
  432. package/schema/fixtures/event/valid/task-registered-harness-version.json +23 -0
  433. package/schema/fixtures/event/valid/task-registered.json +14 -0
  434. package/schema/fixtures/hash/known-answer-pre-121.json +74 -0
  435. package/schema/fixtures/hash/known-answer.json +74 -0
  436. package/schema/fixtures/policy/invalid/bad-approval-ttl.json +7 -0
  437. package/schema/fixtures/policy/invalid/bad-web-port.json +4 -0
  438. package/schema/fixtures/policy/invalid/checkpoint-key-not-base64.json +6 -0
  439. package/schema/fixtures/policy/invalid/class-rule-missing-autonomy.json +9 -0
  440. package/schema/fixtures/policy/invalid/empty-class-key.json +6 -0
  441. package/schema/fixtures/policy/invalid/live-rate-on-human-only.json +7 -0
  442. package/schema/fixtures/policy/invalid/malformed-class-key.json +6 -0
  443. package/schema/fixtures/policy/invalid/missing-version.json +8 -0
  444. package/schema/fixtures/policy/invalid/negative-limit.json +9 -0
  445. package/schema/fixtures/policy/invalid/non-numeric-limit.json +9 -0
  446. package/schema/fixtures/policy/invalid/non-positive-max-pending.json +9 -0
  447. package/schema/fixtures/policy/invalid/on-expiry-grant.json +8 -0
  448. package/schema/fixtures/policy/invalid/payload-retention-bare-number.json +4 -0
  449. package/schema/fixtures/policy/invalid/payload-retention-compound.json +4 -0
  450. package/schema/fixtures/policy/invalid/payload-retention-fractional.json +4 -0
  451. package/schema/fixtures/policy/invalid/payload-retention-zero.json +4 -0
  452. package/schema/fixtures/policy/invalid/protected-paths-escape.json +4 -0
  453. package/schema/fixtures/policy/invalid/protected-paths-glob.json +4 -0
  454. package/schema/fixtures/policy/invalid/retro-rate-on-human-only.json +7 -0
  455. package/schema/fixtures/policy/invalid/retro-rate-on-manual.json +7 -0
  456. package/schema/fixtures/policy/invalid/retro-rate-zero.json +7 -0
  457. package/schema/fixtures/policy/invalid/sample-rate-too-high.json +5 -0
  458. package/schema/fixtures/policy/invalid/sampling-secret-env-empty.json +7 -0
  459. package/schema/fixtures/policy/invalid/sampling-secret-env-not-string.json +6 -0
  460. package/schema/fixtures/policy/invalid/skew-tolerance-compound.json +6 -0
  461. package/schema/fixtures/policy/invalid/unknown-autonomy.json +7 -0
  462. package/schema/fixtures/policy/invalid/unknown-class-rule-key.json +6 -0
  463. package/schema/fixtures/policy/invalid/unknown-top-level-key.json +7 -0
  464. package/schema/fixtures/policy/invalid/vault-passphrase-env-empty.json +6 -0
  465. package/schema/fixtures/policy/invalid/vault-passphrase-literal.json +6 -0
  466. package/schema/fixtures/policy/invalid/version-not-string.json +4 -0
  467. package/schema/fixtures/policy/valid/canonical.json +47 -0
  468. package/schema/fixtures/policy/valid/checkpoint-keys.json +18 -0
  469. package/schema/fixtures/policy/valid/class-approvers-limits.json +25 -0
  470. package/schema/fixtures/policy/valid/class-retro-rate.json +17 -0
  471. package/schema/fixtures/policy/valid/global-budgets.json +19 -0
  472. package/schema/fixtures/policy/valid/human-only.json +9 -0
  473. package/schema/fixtures/policy/valid/minimal.json +6 -0
  474. package/schema/fixtures/policy/valid/protected-paths.json +10 -0
  475. package/schema/fixtures/policy/valid/record-namespace.json +13 -0
  476. package/schema/fixtures/policy/valid/request-volume-limits.json +26 -0
  477. package/schema/fixtures/policy/valid/retention-and-sampling-secret.json +16 -0
  478. package/schema/fixtures/policy/valid/skew-tolerance.json +15 -0
  479. package/schema/fixtures/policy/valid/vault-passphrase-env.json +14 -0
  480. package/schema/fixtures/policy/valid/wildcards.json +15 -0
  481. package/schema/fixtures/policy-md/invalid/alias-bomb.md +15 -0
  482. package/schema/fixtures/policy-md/invalid/no-fence.md +7 -0
  483. package/schema/fixtures/policy-md/invalid/protected-route-not-a-subclass.md +16 -0
  484. package/schema/fixtures/policy-md/invalid/schema-invalid-autonomy.md +16 -0
  485. package/schema/fixtures/policy-md/invalid/schema-invalid-read-proof.md +17 -0
  486. package/schema/fixtures/policy-md/invalid/two-fences.md +19 -0
  487. package/schema/fixtures/policy-md/invalid/unclosed-fence.md +11 -0
  488. package/schema/fixtures/policy-md/invalid/wrong-info-string.md +11 -0
  489. package/schema/fixtures/policy-md/invalid/yaml-syntax-error.md +13 -0
  490. package/schema/fixtures/policy-md/precedence/both/APPROVAL.md +7 -0
  491. package/schema/fixtures/policy-md/precedence/both/APPROVALS.md +7 -0
  492. package/schema/fixtures/policy-md/precedence/fallback-only/APPROVALS.md +7 -0
  493. package/schema/fixtures/policy-md/valid/canonical.md +50 -0
  494. package/schema/fixtures/policy-md/valid/daemon-read-proof.md +18 -0
  495. package/schema/fixtures/policy-md/valid/minimal.md +3 -0
  496. package/schema/fixtures/policy-md/valid/prose-lookalikes.md +54 -0
  497. package/schema/fixtures/policy-md/valid/routed-protected-paths.md +49 -0
  498. package/schema/fixtures/policy-md/valid/with-values.md +79 -0
  499. package/schema/fixtures/sample-record/invalid/bad-date-time.json +4 -0
  500. package/schema/fixtures/sample-record/invalid/missing-required-field.json +3 -0
  501. package/schema/fixtures/sample-record/invalid/unknown-top-level-field.json +5 -0
  502. package/schema/fixtures/sample-record/invalid/wrong-type.json +4 -0
  503. package/schema/fixtures/sample-record/valid/minimal.json +4 -0
  504. package/schema/fixtures/sample-record/valid/with-note.json +5 -0
  505. package/schema/fixtures/values/invalid/class-shaped.json +9 -0
  506. package/schema/fixtures/values/invalid/duplicate-entry.json +4 -0
  507. package/schema/fixtures/values/invalid/non-string-item.json +4 -0
  508. package/schema/fixtures/values/invalid/over-cap.json +26 -0
  509. package/schema/fixtures/values/invalid/unknown-key.json +5 -0
  510. package/schema/fixtures/values/invalid/version-string.json +1 -0
  511. package/schema/fixtures/values/valid/empty-lists.json +7 -0
  512. package/schema/fixtures/values/valid/full.json +20 -0
  513. package/schema/fixtures/values/valid/minimal.json +1 -0
  514. package/schema/fixtures/values-md/invalid/schema-invalid.md +62 -0
  515. package/schema/fixtures/values-md/invalid/two-blocks.md +69 -0
  516. package/schema/fixtures/values-md/invalid/unterminated.md +61 -0
  517. package/schema/fixtures/values-md/invalid/yaml-error.md +63 -0
  518. package/schema/fixtures/values-md/valid/absent.md +50 -0
  519. package/schema/fixtures/values-md/valid/with-values.md +79 -0
  520. package/schema/policy.schema.json +481 -0
  521. package/schema/sample-record.schema.json +26 -0
  522. package/schema/values.schema.json +55 -0
@@ -0,0 +1,506 @@
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 { tick } from "./clock.js";
56
+ import {} from "./harness-version.js";
57
+ import { attemptsOf, withHeadRetry } from "./head-retry.js";
58
+ import { appendEvent, } from "./log.js";
59
+ import { parseDuration } from "./policy-load.js";
60
+ import { readVerifiedRecords } from "./state.js";
61
+ /** What an open window suspends. One value at v0.1, matching the schema enum. */
62
+ export const GATE_WINDOW_SCOPE = "hook";
63
+ /** The duration `approval gate open` uses when none is asked for. */
64
+ export const DEFAULT_WINDOW = "30m";
65
+ /**
66
+ * The longest window anyone may open, enforced at BOTH ends: `openWindow`
67
+ * refuses a longer one, and {@link openGateWindow} clamps a record claiming one
68
+ * so that a hand-written `gate.opened` buys no more time than the ceremony
69
+ * would have granted.
70
+ *
71
+ * A day, because the window's purpose is one debugging session and because a
72
+ * bypass that outlives the person's attention is a bypass nobody is watching.
73
+ */
74
+ export const MAX_WINDOW_MS = 24 * 60 * 60 * 1_000;
75
+ /**
76
+ * How many times a bypass append re-derives its window after a `head-moved`
77
+ * refusal. The same reasoning as `core/head-retry.ts`'s, whose helper performs
78
+ * the loop: a moved head says the read was stale, never that the answer is no,
79
+ * and re-deriving from a fresh verified read cannot launder a refusal into an
80
+ * allow.
81
+ *
82
+ * One attempt more than the gate writers' three, and deliberately so: a bypass
83
+ * record is what lets a session run a command at all while the gate is being
84
+ * repaired, and the log it is contending with is the busy one that made the
85
+ * repair necessary.
86
+ */
87
+ const HEAD_MOVED_ATTEMPTS = 4;
88
+ /** Actors permitted to open or close a window. Narrower than the event schema. */
89
+ const HUMAN_ACTOR = /^human:.+/u;
90
+ /** Actors a bypass record may name: whoever the harness was running as. */
91
+ const PRINCIPAL_ACTOR = /^(human|agent):.+/u;
92
+ /**
93
+ * The verb-level refusal codes of the open window. **Frozen union**, in the
94
+ * same sense as `GATE_REFUSAL_CODES`, `EXECUTION_REFUSAL_CODES`,
95
+ * `AUDIT_REFUSAL_CODES`, `DARK_SESSION_CODES` and `HOOK_DENY_CODES`: a caller
96
+ * branches on these, so members are added and never repurposed (SPEC.md §11.1
97
+ * invariant 6, which this makes the sixth such union).
98
+ *
99
+ * Every one of them appends nothing.
100
+ */
101
+ export const GATE_WINDOW_REFUSAL_CODES = [
102
+ /**
103
+ * The actor is not `human:`-prefixed. Opening a window is the one act that
104
+ * suspends the policy, so an agent able to perform it could authorize its own
105
+ * next command. Refused here in code, and again in `event.schema.json`.
106
+ */
107
+ "actor-not-human",
108
+ /** No reason was given. A bypass nobody stated a reason for cannot be reviewed. */
109
+ "gate-reason-required",
110
+ /**
111
+ * The duration is over {@link MAX_WINDOW_MS}, zero, negative, or unreadable.
112
+ * One code for the family because the repair is one sentence: ask for a
113
+ * shorter window, spelled the way SPEC.md §5.2 spells durations.
114
+ */
115
+ "gate-duration-too-long",
116
+ /** A window is already open. Close it, or wait for it to lapse. */
117
+ "gate-already-open",
118
+ /**
119
+ * No window is open. `close` says so rather than appending a record that
120
+ * closes nothing, and a bypass asked for with no window behind it at all says
121
+ * so rather than recording a bypass nothing authorized.
122
+ */
123
+ "gate-not-open",
124
+ /**
125
+ * The window a caller DECIDED under is gone by the time the bypass is
126
+ * recorded (APRV-294).
127
+ *
128
+ * Distinct from `gate-not-open`, and the difference is the fact each states.
129
+ * That one says there was no window to begin with, which is the ordinary
130
+ * closed gate. This one says a window stood when the verdict was formed and
131
+ * does not stand at the append: a human closed it, it lapsed, or a later
132
+ * `gate.opened` superseded the one the caller named. The refusal names the
133
+ * `gate.closed` seq that ended it, or the expiry it ran past, so a reviewer
134
+ * holding the log alone can place the boundary.
135
+ *
136
+ * The repair is a retry, and it is a retry of an ordinary gated tool call:
137
+ * nothing is appended here, nothing ran, and the next invocation derives the
138
+ * window from its own read and is answered by the policy where there is none.
139
+ * A refusal on this path is therefore not a failed execution and accrues no
140
+ * loop-safety streak (SPEC.md §10.2), because no execution was started for it.
141
+ */
142
+ "gate-window-closed",
143
+ /**
144
+ * Stdin is not a terminal (or `--json` was asked for). The ceremony is a
145
+ * person typing a word, and a prompt a pipe could answer is a ceremony a
146
+ * harness shell tool can perform.
147
+ */
148
+ "gate-stdin-not-tty",
149
+ /** The typed confirmation was not exactly `understood`. Includes EOF. */
150
+ "gate-confirmation-mismatch",
151
+ /** The log could not be opened. */
152
+ "log-unreadable",
153
+ /** The log's last line is truncated: a crashed write, repaired by a human. */
154
+ "log-torn-tail",
155
+ /** The chain does not verify, so no window may be derived from it. */
156
+ "log-corrupt",
157
+ /** The append itself was refused; `append` carries the writer's own code. */
158
+ "append-failed",
159
+ ];
160
+ // ---------------------------------------------------------------------------
161
+ // Derivation (pure)
162
+ // ---------------------------------------------------------------------------
163
+ function payloadOf(record) {
164
+ const payload = record.payload;
165
+ return typeof payload === "object" && payload !== null
166
+ ? payload
167
+ : {};
168
+ }
169
+ function stringField(payload, key) {
170
+ const value = payload[key];
171
+ return typeof value === "string" && value.length > 0 ? value : null;
172
+ }
173
+ function seqField(payload, key) {
174
+ const value = payload[key];
175
+ return typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : null;
176
+ }
177
+ /** Milliseconds of an RFC 3339 instant, or `null` when it does not parse. */
178
+ function millis(text) {
179
+ const parsed = Date.parse(text);
180
+ return Number.isNaN(parsed) ? null : parsed;
181
+ }
182
+ /**
183
+ * The window open at `now`, or `null`.
184
+ *
185
+ * Pure over the records it is given, so every caller (the hook, the CLI verb,
186
+ * `approval status`) derives the same fact from the same log and none of them
187
+ * reads a clock of its own.
188
+ *
189
+ * Only the LATEST `gate.opened` is considered. An older one that was never
190
+ * closed is not a second window: the ceremony refuses to open a second while
191
+ * one stands, so an unclosed older record is either lapsed or superseded, and
192
+ * treating it as live would let a stale record outlive the window a human
193
+ * actually opened.
194
+ *
195
+ * Every ambiguity resolves closed. An unreadable duration, a missing reason, a
196
+ * `ts` that does not parse: each yields `null` rather than a window nobody can
197
+ * state the bounds of.
198
+ */
199
+ export function openGateWindow(records, now = Date.now()) {
200
+ const nowMs = typeof now === "number" ? now : now.getTime();
201
+ let opened = null;
202
+ for (const record of records) {
203
+ if (record.event === "gate.opened")
204
+ opened = record;
205
+ }
206
+ if (opened === null)
207
+ return null;
208
+ // A close naming this opening ends it, wherever in the log it sits.
209
+ for (const record of records) {
210
+ if (record.event !== "gate.closed")
211
+ continue;
212
+ if (seqField(payloadOf(record), "opened_seq") === opened.seq)
213
+ return null;
214
+ }
215
+ const payload = payloadOf(opened);
216
+ const reason = stringField(payload, "reason");
217
+ const durationText = stringField(payload, "duration");
218
+ if (reason === null || durationText === null)
219
+ return null;
220
+ if (stringField(payload, "scope") !== GATE_WINDOW_SCOPE)
221
+ return null;
222
+ const asked = parseDuration(durationText);
223
+ if (asked === null || asked <= 0)
224
+ return null;
225
+ // The clamp at READ time, not only at write time: a `gate.opened` that
226
+ // reached the log by some other route may claim a week, and it buys a day.
227
+ const durationMs = Math.min(asked, MAX_WINDOW_MS);
228
+ const openedMs = millis(opened.ts);
229
+ if (openedMs === null)
230
+ return null;
231
+ // The shorter of the two, always. `ts + duration` is what the runtime
232
+ // authored; `expires_at` is a claim, and a claim may only shorten.
233
+ const derived = openedMs + durationMs;
234
+ const claimedText = stringField(payload, "expires_at");
235
+ const claimed = claimedText === null ? null : millis(claimedText);
236
+ const expiresMs = claimed === null ? derived : Math.min(derived, claimed);
237
+ if (nowMs >= expiresMs)
238
+ return null;
239
+ let bypassCount = 0;
240
+ for (const record of records) {
241
+ if (record.event !== "gate.bypassed")
242
+ continue;
243
+ if (seqField(payloadOf(record), "opened_seq") === opened.seq)
244
+ bypassCount += 1;
245
+ }
246
+ return {
247
+ seq: opened.seq,
248
+ openedAt: opened.ts,
249
+ openedBy: opened.actor,
250
+ reason,
251
+ durationMs,
252
+ expiresAt: new Date(expiresMs).toISOString(),
253
+ bypassCount,
254
+ };
255
+ }
256
+ /** Milliseconds left on a window at `now`, floored at zero. */
257
+ export function remainingMs(window, now = Date.now()) {
258
+ const nowMs = typeof now === "number" ? now : now.getTime();
259
+ const expiry = millis(window.expiresAt);
260
+ if (expiry === null)
261
+ return 0;
262
+ return Math.max(0, expiry - nowMs);
263
+ }
264
+ // ---------------------------------------------------------------------------
265
+ // Shared plumbing
266
+ // ---------------------------------------------------------------------------
267
+ function refuse(code, message, append) {
268
+ return append === undefined ? { ok: false, code, message } : { ok: false, code, message, append };
269
+ }
270
+ function readRecords(logPath, schemaDir) {
271
+ const read = readVerifiedRecords(logPath, schemaDir === undefined ? {} : { schemaDir });
272
+ if (read.ok)
273
+ return { ok: true, records: read.records, head: read.head };
274
+ // The reader's three codes are this union's three codes, spelled identically:
275
+ // a caller that knows one vocabulary knows both, and nothing is flattened.
276
+ return refuse(read.code, read.message);
277
+ }
278
+ function appendOptionsOf(options, head) {
279
+ return {
280
+ ...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
281
+ ...options.append,
282
+ expectedHead: head,
283
+ };
284
+ }
285
+ /**
286
+ * Append `gate.opened`, after establishing that the actor is a human, the
287
+ * duration is inside the cap, and no window is already open.
288
+ *
289
+ * One `tick()` supplies BOTH the record's `ts` and its `expires_at`, so the two
290
+ * cannot disagree by a scheduling delay and the derived expiry is exactly the
291
+ * claimed one on a record this runtime wrote.
292
+ */
293
+ export function openWindow(logPath, input, actor, options = {}) {
294
+ if (!HUMAN_ACTOR.test(actor)) {
295
+ return refuse("actor-not-human", `opening the gate requires a human actor matching ^human:.+, got ${JSON.stringify(actor)}; this is the one act that suspends the policy, so an agent must not perform it, and the log was left unchanged`);
296
+ }
297
+ const reason = input.reason.trim();
298
+ if (reason.length === 0) {
299
+ return refuse("gate-reason-required", "a window needs a reason (--reason): a bypass nobody stated a reason for is a bypass nobody can review, and the log was left unchanged");
300
+ }
301
+ if (!Number.isFinite(input.durationMs) || input.durationMs <= 0) {
302
+ return refuse("gate-duration-too-long", `--for ${JSON.stringify(input.durationText)} is not a positive duration; use a SPEC.md §5.2 duration such as 5m, 30m or 2h`);
303
+ }
304
+ if (input.durationMs > MAX_WINDOW_MS) {
305
+ return refuse("gate-duration-too-long", `--for ${JSON.stringify(input.durationText)} is longer than the 24h cap: a bypass that outlives the attention of the person who opened it is a bypass nobody is watching. Ask for a shorter window`);
306
+ }
307
+ const read = readRecords(logPath, options.schemaDir);
308
+ if (!read.ok)
309
+ return read;
310
+ const now = tick(options);
311
+ const nowMs = millis(now) ?? Date.now();
312
+ const standing = openGateWindow(read.records, nowMs);
313
+ if (standing !== null) {
314
+ return refuse("gate-already-open", `a window opened by ${standing.openedBy} at seq ${String(standing.seq)} is already open until ${standing.expiresAt}; close it with \`approval gate close\` or wait for it to lapse. Nothing was appended`);
315
+ }
316
+ const expiresAt = new Date(nowMs + input.durationMs).toISOString();
317
+ const appended = appendEvent(logPath, {
318
+ ts: now,
319
+ event: "gate.opened",
320
+ actor,
321
+ channel: "cli",
322
+ payload: {
323
+ expires_at: expiresAt,
324
+ duration: input.durationText,
325
+ reason,
326
+ scope: GATE_WINDOW_SCOPE,
327
+ },
328
+ }, appendOptionsOf(options, read.head));
329
+ if (!appended.ok) {
330
+ return refuse("append-failed", `the window was not opened: ${appended.error.code}: ${appended.error.message}`, appended.error);
331
+ }
332
+ return {
333
+ ok: true,
334
+ record: appended.record,
335
+ window: {
336
+ seq: appended.record.seq,
337
+ openedAt: appended.record.ts,
338
+ openedBy: actor,
339
+ reason,
340
+ durationMs: input.durationMs,
341
+ expiresAt,
342
+ bypassCount: 0,
343
+ },
344
+ };
345
+ }
346
+ // ---------------------------------------------------------------------------
347
+ // close
348
+ // ---------------------------------------------------------------------------
349
+ /**
350
+ * Append `gate.closed` for whatever window stands.
351
+ *
352
+ * No confirmation anywhere on this path: closing only ever TIGHTENS, and a
353
+ * ceremony guarding the safe direction is a ceremony people learn to type past.
354
+ */
355
+ export function closeWindow(logPath, actor, options = {}) {
356
+ if (!HUMAN_ACTOR.test(actor)) {
357
+ return refuse("actor-not-human", `closing the gate requires a human actor matching ^human:.+, got ${JSON.stringify(actor)}; the pair is one ceremony and both halves are the human's. The log was left unchanged`);
358
+ }
359
+ const read = readRecords(logPath, options.schemaDir);
360
+ if (!read.ok)
361
+ return read;
362
+ const now = tick(options);
363
+ const standing = openGateWindow(read.records, millis(now) ?? Date.now());
364
+ if (standing === null) {
365
+ return refuse("gate-not-open", "no window is open, so there is nothing to close; a lapsed window appends nothing when it lapses and needs no closing record. The log was left unchanged");
366
+ }
367
+ const note = options.note?.trim();
368
+ const appended = appendEvent(logPath, {
369
+ ts: now,
370
+ event: "gate.closed",
371
+ actor,
372
+ channel: "cli",
373
+ payload: {
374
+ opened_seq: standing.seq,
375
+ ...(note === undefined || note.length === 0 ? {} : { note }),
376
+ },
377
+ }, appendOptionsOf(options, read.head));
378
+ if (!appended.ok) {
379
+ return refuse("append-failed", `the window was not closed and is still open until ${standing.expiresAt}: ${appended.error.code}: ${appended.error.message}`, appended.error);
380
+ }
381
+ return { ok: true, record: appended.record, closed: standing };
382
+ }
383
+ /**
384
+ * Record a bypassed tool call, BEFORE its allow is printed.
385
+ *
386
+ * The order is record-then-allow for the same reason `recordUnattended`'s is
387
+ * (§11.1 invariant 8): a bypassed command that ran and left no record is the
388
+ * one state this whole feature must not be able to reach, so an append failure
389
+ * is the caller's deny.
390
+ *
391
+ * The window is re-derived on every attempt past the first. A head that moved
392
+ * says the read was stale, so the next attempt re-reads, re-derives, and appends
393
+ * against the head it saw; a window that lapsed or was closed refuses rather
394
+ * than recording a bypass nothing authorized. Which refusal depends on what the
395
+ * caller stated: with a {@link GateBypassDecision} in hand the refusal is
396
+ * `gate-window-closed` and names the record or the expiry that ended the window,
397
+ * and with none it is the historical `gate-not-open`.
398
+ */
399
+ export function recordGateBypass(logPath, input, actor, options = {}, decided) {
400
+ if (!PRINCIPAL_ACTOR.test(actor)) {
401
+ return refuse("actor-not-human", `a bypass record must name the principal the harness ran as, matching ^(human|agent):.+, got ${JSON.stringify(actor)}; the log was left unchanged`);
402
+ }
403
+ if (input.classes.length === 0) {
404
+ return refuse("gate-not-open", "a bypass record must name at least one class: a call with no class is the gate's own CLI, which the window has nothing to say about");
405
+ }
406
+ // The one implementation, shared with `core/gate.ts` and `core/execute.ts`
407
+ // since APRV-236. The ceiling stays this module's own — a bypass append is
408
+ // the record that lets a debugging session run at all, so it is worth one
409
+ // more attempt than the gate's writers get — and the mechanism is no longer
410
+ // a second copy of the loop.
411
+ //
412
+ // APRV-294: the caller's read seeds the FIRST attempt and no other. A
413
+ // `head-moved` retry exists precisely because the head it was going to chain
414
+ // onto has moved, so re-using the stale read would be appending against a
415
+ // precondition already known to be wrong.
416
+ let seed = decided?.read;
417
+ return withHeadRetry(attemptsOf(options.retryOnHeadMoved, HEAD_MOVED_ATTEMPTS), () => {
418
+ const use = seed;
419
+ seed = undefined;
420
+ return attemptBypass(logPath, input, actor, options, decided?.openedSeq ?? null, use);
421
+ });
422
+ }
423
+ /**
424
+ * The window a caller decided under is not the window the log now shows
425
+ * (APRV-294): say which of the three ways it ended, naming the record or the
426
+ * instant that ended it.
427
+ *
428
+ * Every branch appends nothing and every branch is the same verdict for the
429
+ * caller (deny, and retry through the ordinary gated path). What differs is the
430
+ * fact stated, and the fact is what a reviewer holding the log needs: a close is
431
+ * a person's act with a seq, a lapse is arithmetic over the opening record, and
432
+ * a supersession is a second window somebody opened.
433
+ */
434
+ function windowEnded(records, openedSeq, standing) {
435
+ const retry = "Nothing was appended and nothing ran, so this refusal is not a failed execution and accrues no loop-safety streak (SPEC.md §10.2); run the command again and it is answered by the policy, or by whatever window stands then.";
436
+ for (const record of records) {
437
+ if (record.event !== "gate.closed")
438
+ continue;
439
+ if (seqField(payloadOf(record), "opened_seq") !== openedSeq)
440
+ continue;
441
+ return refuse("gate-window-closed", `the window opened at seq ${String(openedSeq)} was closed by ${record.actor} at gate.closed seq ${String(record.seq)}, between the read this call's verdict was decided on and the record that would have authorized it. ${retry}`);
442
+ }
443
+ if (standing !== null) {
444
+ return refuse("gate-window-closed", `the window opened at seq ${String(openedSeq)} is no longer the standing one: a later window (seq ${String(standing.seq)}, opened by ${standing.openedBy}) supersedes it, and a bypass records the window it was decided under or none at all. ${retry}`);
445
+ }
446
+ for (const record of records) {
447
+ if (record.seq !== openedSeq)
448
+ continue;
449
+ const claimed = stringField(payloadOf(record), "expires_at");
450
+ return refuse("gate-window-closed", `the window opened at seq ${String(openedSeq)} lapsed${claimed === null ? "" : ` (expiry ${claimed})`} between the read this call's verdict was decided on and the record that would have authorized it; a lapse appends nothing when it arrives, which is why the log names no closing record. ${retry}`);
451
+ }
452
+ return refuse("gate-window-closed", `the verified log carries no gate.opened at seq ${String(openedSeq)}, so the window this call's verdict was decided under cannot be established from the records the append read. ${retry}`);
453
+ }
454
+ function attemptBypass(logPath, input, actor, options,
455
+ /** The window the caller decided under, or `null` when it stated none. */
456
+ openedSeq,
457
+ /** That decision's own verified read, on the first attempt only. */
458
+ seed) {
459
+ const read = seed === undefined
460
+ ? readRecords(logPath, options.schemaDir)
461
+ : { ok: true, records: [...seed.records], head: seed.head };
462
+ if (!read.ok)
463
+ return read;
464
+ const now = tick(options);
465
+ const window = openGateWindow(read.records, millis(now) ?? Date.now());
466
+ if (openedSeq !== null && (window === null || window.seq !== openedSeq)) {
467
+ // APRV-294. The caller reached a verdict under a named window, and these
468
+ // records do not carry it: say which window ended and how, rather than
469
+ // reporting the absence of any window at all.
470
+ return windowEnded(read.records, openedSeq, window);
471
+ }
472
+ if (window === null) {
473
+ return refuse("gate-not-open", "no window is open, so nothing may be bypassed; the hook denies as it does with no window at all. The log was left unchanged");
474
+ }
475
+ const appended = appendEvent(logPath, {
476
+ ts: now,
477
+ event: "gate.bypassed",
478
+ actor,
479
+ payload: {
480
+ opened_seq: window.seq,
481
+ tool: input.tool,
482
+ summary: input.summary,
483
+ classes: [...input.classes],
484
+ payload_hash: input.payloadHash,
485
+ ...(input.sessionId === undefined ? {} : { session_id: input.sessionId }),
486
+ ...(input.toolUseId === undefined ? {} : { tool_use_id: input.toolUseId }),
487
+ ...(input.cwd === undefined ? {} : { cwd: input.cwd }),
488
+ // APRV-227: both halves or neither.
489
+ ...(input.harness === undefined
490
+ ? {}
491
+ : {
492
+ harness: input.harness.harness,
493
+ harness_version: input.harness.harness_version,
494
+ }),
495
+ },
496
+ }, appendOptionsOf(options, read.head));
497
+ if (!appended.ok) {
498
+ return refuse("append-failed", `the bypass was not recorded, so nothing may run: ${appended.error.code}: ${appended.error.message}`, appended.error);
499
+ }
500
+ return {
501
+ ok: true,
502
+ record: appended.record,
503
+ window: { ...window, bypassCount: window.bypassCount + 1 },
504
+ };
505
+ }
506
+ //# sourceMappingURL=gate-window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-window.js","sourceRoot":"","sources":["../../../src/core/gate-window.ts"],"names":[],"mappings":"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"}