approval-md 0.0.1 → 0.2.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 (722) hide show
  1. package/LICENSE +176 -0
  2. package/NOTICE +5 -0
  3. package/README.md +940 -4
  4. package/SPEC.md +476 -34
  5. package/cli.js +29 -3
  6. package/dist/src/adapters/agentmail.d.ts +426 -0
  7. package/dist/src/adapters/agentmail.js +1200 -0
  8. package/dist/src/adapters/agentmail.js.map +1 -0
  9. package/dist/src/adapters/conformance.d.ts +149 -0
  10. package/dist/src/adapters/conformance.js +461 -0
  11. package/dist/src/adapters/conformance.js.map +1 -0
  12. package/dist/src/adapters/contract.d.ts +628 -0
  13. package/dist/src/adapters/contract.js +1035 -0
  14. package/dist/src/adapters/contract.js.map +1 -0
  15. package/dist/src/adapters/email.d.ts +324 -0
  16. package/dist/src/adapters/email.js +749 -0
  17. package/dist/src/adapters/email.js.map +1 -0
  18. package/dist/src/adapters/env-passphrase.d.ts +93 -0
  19. package/dist/src/adapters/env-passphrase.js +132 -0
  20. package/dist/src/adapters/env-passphrase.js.map +1 -0
  21. package/dist/src/adapters/public.d.ts +11 -0
  22. package/dist/src/adapters/public.js +11 -0
  23. package/dist/src/adapters/public.js.map +1 -0
  24. package/dist/src/adapters/registry.d.ts +59 -0
  25. package/dist/src/adapters/registry.js +77 -0
  26. package/dist/src/adapters/registry.js.map +1 -0
  27. package/dist/src/adapters/smtp.d.ts +213 -0
  28. package/dist/src/adapters/smtp.js +499 -0
  29. package/dist/src/adapters/smtp.js.map +1 -0
  30. package/dist/src/adapters/vault-provider.d.ts +114 -0
  31. package/dist/src/adapters/vault-provider.js +161 -0
  32. package/dist/src/adapters/vault-provider.js.map +1 -0
  33. package/dist/src/adapters/zzz.d.ts +66 -0
  34. package/dist/src/adapters/zzz.js +299 -0
  35. package/dist/src/adapters/zzz.js.map +1 -0
  36. package/dist/src/channels/batch.d.ts +109 -0
  37. package/dist/src/channels/batch.js +121 -0
  38. package/dist/src/channels/batch.js.map +1 -0
  39. package/dist/src/channels/cli.d.ts +193 -0
  40. package/dist/src/channels/cli.js +468 -0
  41. package/dist/src/channels/cli.js.map +1 -0
  42. package/dist/src/channels/conformance.d.ts +92 -0
  43. package/dist/src/channels/conformance.js +445 -0
  44. package/dist/src/channels/conformance.js.map +1 -0
  45. package/dist/src/channels/contract.d.ts +623 -0
  46. package/dist/src/channels/contract.js +494 -0
  47. package/dist/src/channels/contract.js.map +1 -0
  48. package/dist/src/channels/payload-view.d.ts +35 -0
  49. package/dist/src/channels/payload-view.js +43 -0
  50. package/dist/src/channels/payload-view.js.map +1 -0
  51. package/dist/src/channels/render-queue.d.ts +149 -0
  52. package/dist/src/channels/render-queue.js +564 -0
  53. package/dist/src/channels/render-queue.js.map +1 -0
  54. package/dist/src/channels/tagging.d.ts +196 -0
  55. package/dist/src/channels/tagging.js +723 -0
  56. package/dist/src/channels/tagging.js.map +1 -0
  57. package/dist/src/channels/telegram.d.ts +1832 -0
  58. package/dist/src/channels/telegram.js +3190 -0
  59. package/dist/src/channels/telegram.js.map +1 -0
  60. package/dist/src/channels/web.d.ts +341 -0
  61. package/dist/src/channels/web.js +903 -0
  62. package/dist/src/channels/web.js.map +1 -0
  63. package/dist/src/cli/adapter.d.ts +90 -0
  64. package/dist/src/cli/adapter.js +288 -0
  65. package/dist/src/cli/adapter.js.map +1 -0
  66. package/dist/src/cli/amend.d.ts +59 -0
  67. package/dist/src/cli/amend.js +2171 -0
  68. package/dist/src/cli/amend.js.map +1 -0
  69. package/dist/src/cli/args.d.ts +43 -0
  70. package/dist/src/cli/args.js +86 -0
  71. package/dist/src/cli/args.js.map +1 -0
  72. package/dist/src/cli/attest.d.ts +41 -0
  73. package/dist/src/cli/attest.js +307 -0
  74. package/dist/src/cli/attest.js.map +1 -0
  75. package/dist/src/cli/audit-card.d.ts +62 -0
  76. package/dist/src/cli/audit-card.js +201 -0
  77. package/dist/src/cli/audit-card.js.map +1 -0
  78. package/dist/src/cli/audit.d.ts +59 -0
  79. package/dist/src/cli/audit.js +460 -0
  80. package/dist/src/cli/audit.js.map +1 -0
  81. package/dist/src/cli/channel-telegram.d.ts +806 -0
  82. package/dist/src/cli/channel-telegram.js +2063 -0
  83. package/dist/src/cli/channel-telegram.js.map +1 -0
  84. package/dist/src/cli/channel-web.d.ts +131 -0
  85. package/dist/src/cli/channel-web.js +357 -0
  86. package/dist/src/cli/channel-web.js.map +1 -0
  87. package/dist/src/cli/channel.d.ts +71 -0
  88. package/dist/src/cli/channel.js +438 -0
  89. package/dist/src/cli/channel.js.map +1 -0
  90. package/dist/src/cli/checkpoint-tap.d.ts +169 -0
  91. package/dist/src/cli/checkpoint-tap.js +238 -0
  92. package/dist/src/cli/checkpoint-tap.js.map +1 -0
  93. package/dist/src/cli/codex.d.ts +2 -0
  94. package/dist/src/cli/codex.js +172 -0
  95. package/dist/src/cli/codex.js.map +1 -0
  96. package/dist/src/cli/coverage.d.ts +61 -0
  97. package/dist/src/cli/coverage.js +343 -0
  98. package/dist/src/cli/coverage.js.map +1 -0
  99. package/dist/src/cli/daemon.d.ts +120 -0
  100. package/dist/src/cli/daemon.js +631 -0
  101. package/dist/src/cli/daemon.js.map +1 -0
  102. package/dist/src/cli/doctor.d.ts +129 -0
  103. package/dist/src/cli/doctor.js +2762 -0
  104. package/dist/src/cli/doctor.js.map +1 -0
  105. package/dist/src/cli/env.d.ts +65 -0
  106. package/dist/src/cli/env.js +302 -0
  107. package/dist/src/cli/env.js.map +1 -0
  108. package/dist/src/cli/execute.d.ts +202 -0
  109. package/dist/src/cli/execute.js +1682 -0
  110. package/dist/src/cli/execute.js.map +1 -0
  111. package/dist/src/cli/exit-codes.d.ts +73 -0
  112. package/dist/src/cli/exit-codes.js +82 -0
  113. package/dist/src/cli/exit-codes.js.map +1 -0
  114. package/dist/src/cli/feedback.d.ts +60 -0
  115. package/dist/src/cli/feedback.js +205 -0
  116. package/dist/src/cli/feedback.js.map +1 -0
  117. package/dist/src/cli/gate-window.d.ts +40 -0
  118. package/dist/src/cli/gate-window.js +294 -0
  119. package/dist/src/cli/gate-window.js.map +1 -0
  120. package/dist/src/cli/gate.d.ts +68 -0
  121. package/dist/src/cli/gate.js +557 -0
  122. package/dist/src/cli/gate.js.map +1 -0
  123. package/dist/src/cli/git-scope.d.ts +190 -0
  124. package/dist/src/cli/git-scope.js +295 -0
  125. package/dist/src/cli/git-scope.js.map +1 -0
  126. package/dist/src/cli/gloss-attach.d.ts +85 -0
  127. package/dist/src/cli/gloss-attach.js +107 -0
  128. package/dist/src/cli/gloss-attach.js.map +1 -0
  129. package/dist/src/cli/gloss-codex-child.d.ts +9 -0
  130. package/dist/src/cli/gloss-codex-child.js +149 -0
  131. package/dist/src/cli/gloss-codex-child.js.map +1 -0
  132. package/dist/src/cli/gloss-codex.d.ts +24 -0
  133. package/dist/src/cli/gloss-codex.js +255 -0
  134. package/dist/src/cli/gloss-codex.js.map +1 -0
  135. package/dist/src/cli/gloss-options.d.ts +42 -0
  136. package/dist/src/cli/gloss-options.js +79 -0
  137. package/dist/src/cli/gloss-options.js.map +1 -0
  138. package/dist/src/cli/gloss.d.ts +265 -0
  139. package/dist/src/cli/gloss.js +362 -0
  140. package/dist/src/cli/gloss.js.map +1 -0
  141. package/dist/src/cli/help.d.ts +103 -0
  142. package/dist/src/cli/help.js +2339 -0
  143. package/dist/src/cli/help.js.map +1 -0
  144. package/dist/src/cli/hook-codex.d.ts +78 -0
  145. package/dist/src/cli/hook-codex.js +167 -0
  146. package/dist/src/cli/hook-codex.js.map +1 -0
  147. package/dist/src/cli/hook.d.ts +331 -0
  148. package/dist/src/cli/hook.js +2849 -0
  149. package/dist/src/cli/hook.js.map +1 -0
  150. package/dist/src/cli/import.d.ts +35 -0
  151. package/dist/src/cli/import.js +175 -0
  152. package/dist/src/cli/import.js.map +1 -0
  153. package/dist/src/cli/init.d.ts +84 -0
  154. package/dist/src/cli/init.js +336 -0
  155. package/dist/src/cli/init.js.map +1 -0
  156. package/dist/src/cli/instructions.d.ts +23 -0
  157. package/dist/src/cli/instructions.js +262 -0
  158. package/dist/src/cli/instructions.js.map +1 -0
  159. package/dist/src/cli/journal.d.ts +41 -0
  160. package/dist/src/cli/journal.js +238 -0
  161. package/dist/src/cli/journal.js.map +1 -0
  162. package/dist/src/cli/log-advance.d.ts +287 -0
  163. package/dist/src/cli/log-advance.js +840 -0
  164. package/dist/src/cli/log-advance.js.map +1 -0
  165. package/dist/src/cli/log-anchor.d.ts +176 -0
  166. package/dist/src/cli/log-anchor.js +387 -0
  167. package/dist/src/cli/log-anchor.js.map +1 -0
  168. package/dist/src/cli/log-checkpoint.d.ts +22 -0
  169. package/dist/src/cli/log-checkpoint.js +128 -0
  170. package/dist/src/cli/log-checkpoint.js.map +1 -0
  171. package/dist/src/cli/log-sync.d.ts +243 -0
  172. package/dist/src/cli/log-sync.js +849 -0
  173. package/dist/src/cli/log-sync.js.map +1 -0
  174. package/dist/src/cli/log-verbs.d.ts +16 -0
  175. package/dist/src/cli/log-verbs.js +360 -0
  176. package/dist/src/cli/log-verbs.js.map +1 -0
  177. package/dist/src/cli/long-help.d.ts +70 -0
  178. package/dist/src/cli/long-help.js +148 -0
  179. package/dist/src/cli/long-help.js.map +1 -0
  180. package/dist/src/cli/main.d.ts +77 -0
  181. package/dist/src/cli/main.js +1206 -0
  182. package/dist/src/cli/main.js.map +1 -0
  183. package/dist/src/cli/mcp.d.ts +52 -0
  184. package/dist/src/cli/mcp.js +306 -0
  185. package/dist/src/cli/mcp.js.map +1 -0
  186. package/dist/src/cli/paths.d.ts +56 -0
  187. package/dist/src/cli/paths.js +79 -0
  188. package/dist/src/cli/paths.js.map +1 -0
  189. package/dist/src/cli/payload.d.ts +58 -0
  190. package/dist/src/cli/payload.js +253 -0
  191. package/dist/src/cli/payload.js.map +1 -0
  192. package/dist/src/cli/policy.d.ts +43 -0
  193. package/dist/src/cli/policy.js +229 -0
  194. package/dist/src/cli/policy.js.map +1 -0
  195. package/dist/src/cli/preflight.d.ts +363 -0
  196. package/dist/src/cli/preflight.js +1175 -0
  197. package/dist/src/cli/preflight.js.map +1 -0
  198. package/dist/src/cli/progress.d.ts +78 -0
  199. package/dist/src/cli/progress.js +112 -0
  200. package/dist/src/cli/progress.js.map +1 -0
  201. package/dist/src/cli/prompt.d.ts +209 -0
  202. package/dist/src/cli/prompt.js +312 -0
  203. package/dist/src/cli/prompt.js.map +1 -0
  204. package/dist/src/cli/quickstart.d.ts +46 -0
  205. package/dist/src/cli/quickstart.js +297 -0
  206. package/dist/src/cli/quickstart.js.map +1 -0
  207. package/dist/src/cli/records.d.ts +34 -0
  208. package/dist/src/cli/records.js +66 -0
  209. package/dist/src/cli/records.js.map +1 -0
  210. package/dist/src/cli/render.d.ts +22 -0
  211. package/dist/src/cli/render.js +132 -0
  212. package/dist/src/cli/render.js.map +1 -0
  213. package/dist/src/cli/sandbox.d.ts +51 -0
  214. package/dist/src/cli/sandbox.js +150 -0
  215. package/dist/src/cli/sandbox.js.map +1 -0
  216. package/dist/src/cli/scaffold.d.ts +79 -0
  217. package/dist/src/cli/scaffold.js +137 -0
  218. package/dist/src/cli/scaffold.js.map +1 -0
  219. package/dist/src/cli/setup-adapter.d.ts +137 -0
  220. package/dist/src/cli/setup-adapter.js +509 -0
  221. package/dist/src/cli/setup-adapter.js.map +1 -0
  222. package/dist/src/cli/setup-channel.d.ts +117 -0
  223. package/dist/src/cli/setup-channel.js +635 -0
  224. package/dist/src/cli/setup-channel.js.map +1 -0
  225. package/dist/src/cli/setup-checkpoint.d.ts +57 -0
  226. package/dist/src/cli/setup-checkpoint.js +196 -0
  227. package/dist/src/cli/setup-checkpoint.js.map +1 -0
  228. package/dist/src/cli/setup-common.d.ts +275 -0
  229. package/dist/src/cli/setup-common.js +376 -0
  230. package/dist/src/cli/setup-common.js.map +1 -0
  231. package/dist/src/cli/setup-flow.d.ts +287 -0
  232. package/dist/src/cli/setup-flow.js +476 -0
  233. package/dist/src/cli/setup-flow.js.map +1 -0
  234. package/dist/src/cli/setup-service.d.ts +96 -0
  235. package/dist/src/cli/setup-service.js +308 -0
  236. package/dist/src/cli/setup-service.js.map +1 -0
  237. package/dist/src/cli/setup.d.ts +202 -0
  238. package/dist/src/cli/setup.js +473 -0
  239. package/dist/src/cli/setup.js.map +1 -0
  240. package/dist/src/cli/style.d.ts +320 -0
  241. package/dist/src/cli/style.js +469 -0
  242. package/dist/src/cli/style.js.map +1 -0
  243. package/dist/src/cli/token.d.ts +39 -0
  244. package/dist/src/cli/token.js +274 -0
  245. package/dist/src/cli/token.js.map +1 -0
  246. package/dist/src/cli/up.d.ts +155 -0
  247. package/dist/src/cli/up.js +849 -0
  248. package/dist/src/cli/up.js.map +1 -0
  249. package/dist/src/cli/usage.d.ts +37 -0
  250. package/dist/src/cli/usage.js +91 -0
  251. package/dist/src/cli/usage.js.map +1 -0
  252. package/dist/src/cli/values.d.ts +40 -0
  253. package/dist/src/cli/values.js +189 -0
  254. package/dist/src/cli/values.js.map +1 -0
  255. package/dist/src/cli/vault.d.ts +59 -0
  256. package/dist/src/cli/vault.js +362 -0
  257. package/dist/src/cli/vault.js.map +1 -0
  258. package/dist/src/cli/verb-registry.d.ts +76 -0
  259. package/dist/src/cli/verb-registry.js +2341 -0
  260. package/dist/src/cli/verb-registry.js.map +1 -0
  261. package/dist/src/cli/wordmark.d.ts +31 -0
  262. package/dist/src/cli/wordmark.js +52 -0
  263. package/dist/src/cli/wordmark.js.map +1 -0
  264. package/dist/src/codex/doctor.d.ts +13 -0
  265. package/dist/src/codex/doctor.js +41 -0
  266. package/dist/src/codex/doctor.js.map +1 -0
  267. package/dist/src/codex/manifest.d.ts +49 -0
  268. package/dist/src/codex/manifest.js +103 -0
  269. package/dist/src/codex/manifest.js.map +1 -0
  270. package/dist/src/codex/templates.d.ts +41 -0
  271. package/dist/src/codex/templates.js +319 -0
  272. package/dist/src/codex/templates.js.map +1 -0
  273. package/dist/src/codex/trust.d.ts +19 -0
  274. package/dist/src/codex/trust.js +183 -0
  275. package/dist/src/codex/trust.js.map +1 -0
  276. package/dist/src/codex/workspace-plan.d.ts +131 -0
  277. package/dist/src/codex/workspace-plan.js +561 -0
  278. package/dist/src/codex/workspace-plan.js.map +1 -0
  279. package/dist/src/core/actor.d.ts +2 -0
  280. package/dist/src/core/actor.js +5 -0
  281. package/dist/src/core/actor.js.map +1 -0
  282. package/dist/src/core/advance-cycle.d.ts +170 -0
  283. package/dist/src/core/advance-cycle.js +200 -0
  284. package/dist/src/core/advance-cycle.js.map +1 -0
  285. package/dist/src/core/agents-md.d.ts +276 -0
  286. package/dist/src/core/agents-md.js +747 -0
  287. package/dist/src/core/agents-md.js.map +1 -0
  288. package/dist/src/core/apply-patch.d.ts +49 -0
  289. package/dist/src/core/apply-patch.js +266 -0
  290. package/dist/src/core/apply-patch.js.map +1 -0
  291. package/dist/src/core/attest.d.ts +420 -0
  292. package/dist/src/core/attest.js +589 -0
  293. package/dist/src/core/attest.js.map +1 -0
  294. package/dist/src/core/audit.d.ts +492 -0
  295. package/dist/src/core/audit.js +882 -0
  296. package/dist/src/core/audit.js.map +1 -0
  297. package/dist/src/core/budgets.d.ts +238 -0
  298. package/dist/src/core/budgets.js +449 -0
  299. package/dist/src/core/budgets.js.map +1 -0
  300. package/dist/src/core/checkpoint.d.ts +500 -0
  301. package/dist/src/core/checkpoint.js +738 -0
  302. package/dist/src/core/checkpoint.js.map +1 -0
  303. package/dist/src/core/child-env.d.ts +88 -0
  304. package/dist/src/core/child-env.js +86 -0
  305. package/dist/src/core/child-env.js.map +1 -0
  306. package/dist/src/core/clock.d.ts +52 -0
  307. package/dist/src/core/clock.js +43 -0
  308. package/dist/src/core/clock.js.map +1 -0
  309. package/dist/src/core/command-class.d.ts +543 -0
  310. package/dist/src/core/command-class.js +2356 -0
  311. package/dist/src/core/command-class.js.map +1 -0
  312. package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
  313. package/dist/src/core/coverage-sources/adapter.js +71 -0
  314. package/dist/src/core/coverage-sources/adapter.js.map +1 -0
  315. package/dist/src/core/coverage-sources/gh.d.ts +48 -0
  316. package/dist/src/core/coverage-sources/gh.js +136 -0
  317. package/dist/src/core/coverage-sources/gh.js.map +1 -0
  318. package/dist/src/core/coverage-sources/git.d.ts +101 -0
  319. package/dist/src/core/coverage-sources/git.js +269 -0
  320. package/dist/src/core/coverage-sources/git.js.map +1 -0
  321. package/dist/src/core/coverage.d.ts +217 -0
  322. package/dist/src/core/coverage.js +337 -0
  323. package/dist/src/core/coverage.js.map +1 -0
  324. package/dist/src/core/credential-spec.d.ts +72 -0
  325. package/dist/src/core/credential-spec.js +23 -0
  326. package/dist/src/core/credential-spec.js.map +1 -0
  327. package/dist/src/core/dark-session.d.ts +331 -0
  328. package/dist/src/core/dark-session.js +714 -0
  329. package/dist/src/core/dark-session.js.map +1 -0
  330. package/dist/src/core/decision-refusal.d.ts +185 -0
  331. package/dist/src/core/decision-refusal.js +265 -0
  332. package/dist/src/core/decision-refusal.js.map +1 -0
  333. package/dist/src/core/env-file.d.ts +450 -0
  334. package/dist/src/core/env-file.js +837 -0
  335. package/dist/src/core/env-file.js.map +1 -0
  336. package/dist/src/core/execute.d.ts +858 -0
  337. package/dist/src/core/execute.js +1271 -0
  338. package/dist/src/core/execute.js.map +1 -0
  339. package/dist/src/core/frontmatter.d.ts +78 -0
  340. package/dist/src/core/frontmatter.js +100 -0
  341. package/dist/src/core/frontmatter.js.map +1 -0
  342. package/dist/src/core/gate-window.d.ts +312 -0
  343. package/dist/src/core/gate-window.js +506 -0
  344. package/dist/src/core/gate-window.js.map +1 -0
  345. package/dist/src/core/gate.d.ts +1364 -0
  346. package/dist/src/core/gate.js +3002 -0
  347. package/dist/src/core/gate.js.map +1 -0
  348. package/dist/src/core/git-run.d.ts +73 -0
  349. package/dist/src/core/git-run.js +93 -0
  350. package/dist/src/core/git-run.js.map +1 -0
  351. package/dist/src/core/harness-version.d.ts +157 -0
  352. package/dist/src/core/harness-version.js +211 -0
  353. package/dist/src/core/harness-version.js.map +1 -0
  354. package/dist/src/core/harness-wait.d.ts +55 -0
  355. package/dist/src/core/harness-wait.js +58 -0
  356. package/dist/src/core/harness-wait.js.map +1 -0
  357. package/dist/src/core/head-retry.d.ts +107 -0
  358. package/dist/src/core/head-retry.js +121 -0
  359. package/dist/src/core/head-retry.js.map +1 -0
  360. package/dist/src/core/instance.d.ts +253 -0
  361. package/dist/src/core/instance.js +319 -0
  362. package/dist/src/core/instance.js.map +1 -0
  363. package/dist/src/core/intake-limits.d.ts +247 -0
  364. package/dist/src/core/intake-limits.js +350 -0
  365. package/dist/src/core/intake-limits.js.map +1 -0
  366. package/dist/src/core/jcs.d.ts +52 -0
  367. package/dist/src/core/jcs.js +132 -0
  368. package/dist/src/core/jcs.js.map +1 -0
  369. package/dist/src/core/journal.d.ts +144 -0
  370. package/dist/src/core/journal.js +200 -0
  371. package/dist/src/core/journal.js.map +1 -0
  372. package/dist/src/core/live-draw.d.ts +436 -0
  373. package/dist/src/core/live-draw.js +703 -0
  374. package/dist/src/core/live-draw.js.map +1 -0
  375. package/dist/src/core/log-reconcile.d.ts +89 -0
  376. package/dist/src/core/log-reconcile.js +136 -0
  377. package/dist/src/core/log-reconcile.js.map +1 -0
  378. package/dist/src/core/log-subscribe.d.ts +36 -0
  379. package/dist/src/core/log-subscribe.js +162 -0
  380. package/dist/src/core/log-subscribe.js.map +1 -0
  381. package/dist/src/core/log.d.ts +278 -0
  382. package/dist/src/core/log.js +546 -0
  383. package/dist/src/core/log.js.map +1 -0
  384. package/dist/src/core/loop.d.ts +274 -0
  385. package/dist/src/core/loop.js +487 -0
  386. package/dist/src/core/loop.js.map +1 -0
  387. package/dist/src/core/md-fence.d.ts +41 -0
  388. package/dist/src/core/md-fence.js +74 -0
  389. package/dist/src/core/md-fence.js.map +1 -0
  390. package/dist/src/core/money.d.ts +147 -0
  391. package/dist/src/core/money.js +195 -0
  392. package/dist/src/core/money.js.map +1 -0
  393. package/dist/src/core/payload-census.d.ts +74 -0
  394. package/dist/src/core/payload-census.js +146 -0
  395. package/dist/src/core/payload-census.js.map +1 -0
  396. package/dist/src/core/payload-store.d.ts +175 -0
  397. package/dist/src/core/payload-store.js +340 -0
  398. package/dist/src/core/payload-store.js.map +1 -0
  399. package/dist/src/core/payload.d.ts +71 -0
  400. package/dist/src/core/payload.js +80 -0
  401. package/dist/src/core/payload.js.map +1 -0
  402. package/dist/src/core/policy-diff.d.ts +292 -0
  403. package/dist/src/core/policy-diff.js +588 -0
  404. package/dist/src/core/policy-diff.js.map +1 -0
  405. package/dist/src/core/policy-expectations.d.ts +199 -0
  406. package/dist/src/core/policy-expectations.js +394 -0
  407. package/dist/src/core/policy-expectations.js.map +1 -0
  408. package/dist/src/core/policy-explain.d.ts +150 -0
  409. package/dist/src/core/policy-explain.js +258 -0
  410. package/dist/src/core/policy-explain.js.map +1 -0
  411. package/dist/src/core/policy-load.d.ts +527 -0
  412. package/dist/src/core/policy-load.js +536 -0
  413. package/dist/src/core/policy-load.js.map +1 -0
  414. package/dist/src/core/policy-match.d.ts +281 -0
  415. package/dist/src/core/policy-match.js +478 -0
  416. package/dist/src/core/policy-match.js.map +1 -0
  417. package/dist/src/core/policy-proposal.d.ts +265 -0
  418. package/dist/src/core/policy-proposal.js +458 -0
  419. package/dist/src/core/policy-proposal.js.map +1 -0
  420. package/dist/src/core/prompt-layout.d.ts +221 -0
  421. package/dist/src/core/prompt-layout.js +422 -0
  422. package/dist/src/core/prompt-layout.js.map +1 -0
  423. package/dist/src/core/protected-path-guard.d.ts +453 -0
  424. package/dist/src/core/protected-path-guard.js +1566 -0
  425. package/dist/src/core/protected-path-guard.js.map +1 -0
  426. package/dist/src/core/registration.d.ts +25 -0
  427. package/dist/src/core/registration.js +39 -0
  428. package/dist/src/core/registration.js.map +1 -0
  429. package/dist/src/core/reindex.d.ts +99 -0
  430. package/dist/src/core/reindex.js +336 -0
  431. package/dist/src/core/reindex.js.map +1 -0
  432. package/dist/src/core/sampler.d.ts +313 -0
  433. package/dist/src/core/sampler.js +388 -0
  434. package/dist/src/core/sampler.js.map +1 -0
  435. package/dist/src/core/sandbox.d.ts +290 -0
  436. package/dist/src/core/sandbox.js +424 -0
  437. package/dist/src/core/sandbox.js.map +1 -0
  438. package/dist/src/core/seal.d.ts +165 -0
  439. package/dist/src/core/seal.js +290 -0
  440. package/dist/src/core/seal.js.map +1 -0
  441. package/dist/src/core/state.d.ts +505 -0
  442. package/dist/src/core/state.js +1009 -0
  443. package/dist/src/core/state.js.map +1 -0
  444. package/dist/src/core/task-file.d.ts +185 -0
  445. package/dist/src/core/task-file.js +464 -0
  446. package/dist/src/core/task-file.js.map +1 -0
  447. package/dist/src/core/telegram-config.d.ts +93 -0
  448. package/dist/src/core/telegram-config.js +114 -0
  449. package/dist/src/core/telegram-config.js.map +1 -0
  450. package/dist/src/core/token.d.ts +409 -0
  451. package/dist/src/core/token.js +561 -0
  452. package/dist/src/core/token.js.map +1 -0
  453. package/dist/src/core/validate.d.ts +138 -0
  454. package/dist/src/core/validate.js +0 -0
  455. package/dist/src/core/validate.js.map +1 -0
  456. package/dist/src/core/values.d.ts +137 -0
  457. package/dist/src/core/values.js +153 -0
  458. package/dist/src/core/values.js.map +1 -0
  459. package/dist/src/core/vault.d.ts +291 -0
  460. package/dist/src/core/vault.js +612 -0
  461. package/dist/src/core/vault.js.map +1 -0
  462. package/dist/src/core/verified-snapshot.d.ts +204 -0
  463. package/dist/src/core/verified-snapshot.js +506 -0
  464. package/dist/src/core/verified-snapshot.js.map +1 -0
  465. package/dist/src/core/verify.d.ts +336 -0
  466. package/dist/src/core/verify.js +549 -0
  467. package/dist/src/core/verify.js.map +1 -0
  468. package/dist/src/core/version.d.ts +8 -0
  469. package/dist/src/core/version.js +9 -0
  470. package/dist/src/core/version.js.map +1 -0
  471. package/dist/src/core/wysiwys.d.ts +370 -0
  472. package/dist/src/core/wysiwys.js +728 -0
  473. package/dist/src/core/wysiwys.js.map +1 -0
  474. package/dist/src/daemon/advance-child.d.ts +39 -0
  475. package/dist/src/daemon/advance-child.js +78 -0
  476. package/dist/src/daemon/advance-child.js.map +1 -0
  477. package/dist/src/daemon/advance.d.ts +466 -0
  478. package/dist/src/daemon/advance.js +849 -0
  479. package/dist/src/daemon/advance.js.map +1 -0
  480. package/dist/src/daemon/audit.d.ts +87 -0
  481. package/dist/src/daemon/audit.js +90 -0
  482. package/dist/src/daemon/audit.js.map +1 -0
  483. package/dist/src/daemon/daemon.d.ts +1180 -0
  484. package/dist/src/daemon/daemon.js +1988 -0
  485. package/dist/src/daemon/daemon.js.map +1 -0
  486. package/dist/src/daemon/dark-session.d.ts +64 -0
  487. package/dist/src/daemon/dark-session.js +119 -0
  488. package/dist/src/daemon/dark-session.js.map +1 -0
  489. package/dist/src/daemon/draw-child.d.ts +36 -0
  490. package/dist/src/daemon/draw-child.js +132 -0
  491. package/dist/src/daemon/draw-child.js.map +1 -0
  492. package/dist/src/daemon/draw.d.ts +154 -0
  493. package/dist/src/daemon/draw.js +458 -0
  494. package/dist/src/daemon/draw.js.map +1 -0
  495. package/dist/src/daemon/git-evidence.d.ts +173 -0
  496. package/dist/src/daemon/git-evidence.js +345 -0
  497. package/dist/src/daemon/git-evidence.js.map +1 -0
  498. package/dist/src/daemon/projection.d.ts +180 -0
  499. package/dist/src/daemon/projection.js +233 -0
  500. package/dist/src/daemon/projection.js.map +1 -0
  501. package/dist/src/daemon/prune.d.ts +207 -0
  502. package/dist/src/daemon/prune.js +376 -0
  503. package/dist/src/daemon/prune.js.map +1 -0
  504. package/dist/src/mcp/http.d.ts +113 -0
  505. package/dist/src/mcp/http.js +343 -0
  506. package/dist/src/mcp/http.js.map +1 -0
  507. package/dist/src/mcp/server.d.ts +265 -0
  508. package/dist/src/mcp/server.js +602 -0
  509. package/dist/src/mcp/server.js.map +1 -0
  510. package/docs/adapter-api.md +106 -0
  511. package/docs/cli-reference.md +5716 -0
  512. package/docs/codex-enforced-session.md +30 -0
  513. package/package.json +53 -4
  514. package/schema/.gitkeep +0 -0
  515. package/schema/LICENSE +117 -0
  516. package/schema/codex-instance.schema.json +82 -0
  517. package/schema/envelope.schema.json +137 -0
  518. package/schema/event.schema.json +1811 -0
  519. package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
  520. package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
  521. package/schema/fixtures/envelope/invalid/action-missing-idempotency-key.json +15 -0
  522. package/schema/fixtures/envelope/invalid/action-unknown-class-format.json +14 -0
  523. package/schema/fixtures/envelope/invalid/confidence-out-of-range.json +11 -0
  524. package/schema/fixtures/envelope/invalid/est-cost-bare-number.json +14 -0
  525. package/schema/fixtures/envelope/invalid/est-cost-noncanonical-string.json +14 -0
  526. package/schema/fixtures/envelope/invalid/malformed-assignee.json +10 -0
  527. package/schema/fixtures/envelope/invalid/malformed-created-by.json +7 -0
  528. package/schema/fixtures/envelope/invalid/malformed-max-latency.json +11 -0
  529. package/schema/fixtures/envelope/invalid/malformed-payload-hash.json +14 -0
  530. package/schema/fixtures/envelope/invalid/max-cost-bare-number.json +11 -0
  531. package/schema/fixtures/envelope/invalid/missing-origin.json +3 -0
  532. package/schema/fixtures/envelope/invalid/negative-est-cost.json +14 -0
  533. package/schema/fixtures/envelope/invalid/unknown-state.json +7 -0
  534. package/schema/fixtures/envelope/invalid/unknown-top-level-field.json +8 -0
  535. package/schema/fixtures/envelope/valid/action-payload-hash.json +17 -0
  536. package/schema/fixtures/envelope/valid/actions-without-budget.json +18 -0
  537. package/schema/fixtures/envelope/valid/canonical.json +25 -0
  538. package/schema/fixtures/envelope/valid/minimal.json +7 -0
  539. package/schema/fixtures/envelope/valid/multi-action-executed.json +30 -0
  540. package/schema/fixtures/envelope/valid/record-write-stage.json +22 -0
  541. package/schema/fixtures/event/invalid/approval-granted-agent-actor.json +15 -0
  542. package/schema/fixtures/event/invalid/approval-granted-empty-batch-delivery-id.json +17 -0
  543. package/schema/fixtures/event/invalid/approval-granted-fifth-reaction.json +16 -0
  544. package/schema/fixtures/event/invalid/approval-granted-missing-actor.json +14 -0
  545. package/schema/fixtures/event/invalid/approval-requested-missing-action-key.json +14 -0
  546. package/schema/fixtures/event/invalid/approval-withdrawn-agent-policy-drift.json +15 -0
  547. package/schema/fixtures/event/invalid/approval-withdrawn-missing-reason.json +15 -0
  548. package/schema/fixtures/event/invalid/approval-withdrawn-system-actor.json +15 -0
  549. package/schema/fixtures/event/invalid/audit-decision-refused-human-actor.json +17 -0
  550. package/schema/fixtures/event/invalid/audit-decision-refused-missing-code.json +16 -0
  551. package/schema/fixtures/event/invalid/audit-reviewed-agent-actor.json +15 -0
  552. package/schema/fixtures/event/invalid/audit-reviewed-loved-no-note.json +16 -0
  553. package/schema/fixtures/event/invalid/audit-reviewed-system-actor.json +15 -0
  554. package/schema/fixtures/event/invalid/bad-actor-prefix.json +15 -0
  555. package/schema/fixtures/event/invalid/est-cost-bare-number.json +17 -0
  556. package/schema/fixtures/event/invalid/execution-completed-fabricated-exit-code.json +16 -0
  557. package/schema/fixtures/event/invalid/execution-completed-provider-ref-empty-id.json +18 -0
  558. package/schema/fixtures/event/invalid/execution-completed-provider-ref-extra-field.json +19 -0
  559. package/schema/fixtures/event/invalid/execution-completed-provider-ref-id-not-string.json +18 -0
  560. package/schema/fixtures/event/invalid/execution-completed-provider-ref-missing-adapter.json +17 -0
  561. package/schema/fixtures/event/invalid/execution-failed-open-reported-by.json +16 -0
  562. package/schema/fixtures/event/invalid/execution-indeterminate-open-reason.json +14 -0
  563. package/schema/fixtures/event/invalid/execution-reconciled-agent-actor.json +17 -0
  564. package/schema/fixtures/event/invalid/execution-started-negative-env-stripped.json +16 -0
  565. package/schema/fixtures/event/invalid/gate-bypassed-missing-opened-seq.json +15 -0
  566. package/schema/fixtures/event/invalid/gate-closed-non-integer-opened-seq.json +13 -0
  567. package/schema/fixtures/event/invalid/gate-opened-agent-actor.json +16 -0
  568. package/schema/fixtures/event/invalid/gate-organ-attested-absolute-path.json +14 -0
  569. package/schema/fixtures/event/invalid/gate-organ-attested-agent-actor.json +14 -0
  570. package/schema/fixtures/event/invalid/gate-organ-attested-missing-organ-path.json +13 -0
  571. package/schema/fixtures/event/invalid/harness-unknown-kind.json +18 -0
  572. package/schema/fixtures/event/invalid/harness-version-multiline.json +16 -0
  573. package/schema/fixtures/event/invalid/log-checkpoint-agent-actor.json +17 -0
  574. package/schema/fixtures/event/invalid/log-checkpoint-missing-signature.json +16 -0
  575. package/schema/fixtures/event/invalid/log-checkpoint-short-signed-hash.json +17 -0
  576. package/schema/fixtures/event/invalid/log-checkpoint-unknown-signature-alg.json +17 -0
  577. package/schema/fixtures/event/invalid/malformed-ts.json +15 -0
  578. package/schema/fixtures/event/invalid/missing-alg.json +14 -0
  579. package/schema/fixtures/event/invalid/missing-hash.json +14 -0
  580. package/schema/fixtures/event/invalid/non-integer-seq.json +15 -0
  581. package/schema/fixtures/event/invalid/payload-pruned-human-actor.json +14 -0
  582. package/schema/fixtures/event/invalid/payload-pruned-missing-hash.json +14 -0
  583. package/schema/fixtures/event/invalid/policy-declined-agent-actor.json +15 -0
  584. package/schema/fixtures/event/invalid/policy-proposed-missing-diff.json +19 -0
  585. package/schema/fixtures/event/invalid/policy-proposed-system-actor.json +26 -0
  586. package/schema/fixtures/event/invalid/short-hash.json +15 -0
  587. package/schema/fixtures/event/invalid/unknown-alg.json +15 -0
  588. package/schema/fixtures/event/invalid/unknown-event-type.json +15 -0
  589. package/schema/fixtures/event/invalid/unknown-top-level-field.json +16 -0
  590. package/schema/fixtures/event/valid/approval-expired.json +15 -0
  591. package/schema/fixtures/event/valid/approval-granted-batch.json +19 -0
  592. package/schema/fixtures/event/valid/approval-granted-reaction.json +16 -0
  593. package/schema/fixtures/event/valid/approval-granted.json +15 -0
  594. package/schema/fixtures/event/valid/approval-rejected.json +15 -0
  595. package/schema/fixtures/event/valid/approval-requested.json +19 -0
  596. package/schema/fixtures/event/valid/approval-revoked.json +15 -0
  597. package/schema/fixtures/event/valid/approval-withdrawn-policy-drift.json +17 -0
  598. package/schema/fixtures/event/valid/approval-withdrawn.json +16 -0
  599. package/schema/fixtures/event/valid/audit-decision-refused.json +20 -0
  600. package/schema/fixtures/event/valid/audit-reviewed-reaction.json +17 -0
  601. package/schema/fixtures/event/valid/audit-reviewed.json +15 -0
  602. package/schema/fixtures/event/valid/audit-sampled.json +14 -0
  603. package/schema/fixtures/event/valid/budget-exceeded.json +21 -0
  604. package/schema/fixtures/event/valid/envelope-drift.json +16 -0
  605. package/schema/fixtures/event/valid/execution-completed-harness-report.json +16 -0
  606. package/schema/fixtures/event/valid/execution-completed-provider-ref.json +18 -0
  607. package/schema/fixtures/event/valid/execution-completed.json +15 -0
  608. package/schema/fixtures/event/valid/execution-failed-harness-report.json +16 -0
  609. package/schema/fixtures/event/valid/execution-failed.json +15 -0
  610. package/schema/fixtures/event/valid/execution-indeterminate.json +15 -0
  611. package/schema/fixtures/event/valid/execution-reconciled.json +17 -0
  612. package/schema/fixtures/event/valid/execution-started-env-stripped.json +17 -0
  613. package/schema/fixtures/event/valid/execution-started.json +14 -0
  614. package/schema/fixtures/event/valid/gate-bypassed-harness-version.json +18 -0
  615. package/schema/fixtures/event/valid/gate-bypassed.json +19 -0
  616. package/schema/fixtures/event/valid/gate-closed.json +14 -0
  617. package/schema/fixtures/event/valid/gate-opened.json +16 -0
  618. package/schema/fixtures/event/valid/gate-organ-attested.json +14 -0
  619. package/schema/fixtures/event/valid/genesis-null-prev.json +14 -0
  620. package/schema/fixtures/event/valid/log-checkpoint.json +17 -0
  621. package/schema/fixtures/event/valid/payload-pruned-orphan.json +13 -0
  622. package/schema/fixtures/event/valid/payload-pruned.json +17 -0
  623. package/schema/fixtures/event/valid/policy-declined.json +16 -0
  624. package/schema/fixtures/event/valid/policy-proposed.json +35 -0
  625. package/schema/fixtures/event/valid/policy-updated.json +14 -0
  626. package/schema/fixtures/event/valid/reconciliation-required.json +18 -0
  627. package/schema/fixtures/event/valid/reconciliation-satisfied.json +17 -0
  628. package/schema/fixtures/event/valid/route-accepted.json +15 -0
  629. package/schema/fixtures/event/valid/route-proposed.json +16 -0
  630. package/schema/fixtures/event/valid/spec-example.json +15 -0
  631. package/schema/fixtures/event/valid/task-registered-harness-version.json +23 -0
  632. package/schema/fixtures/event/valid/task-registered.json +14 -0
  633. package/schema/fixtures/hash/known-answer-pre-121.json +74 -0
  634. package/schema/fixtures/hash/known-answer.json +74 -0
  635. package/schema/fixtures/policy/invalid/bad-approval-ttl.json +7 -0
  636. package/schema/fixtures/policy/invalid/bad-web-port.json +4 -0
  637. package/schema/fixtures/policy/invalid/checkpoint-key-not-base64.json +6 -0
  638. package/schema/fixtures/policy/invalid/class-rule-missing-autonomy.json +9 -0
  639. package/schema/fixtures/policy/invalid/empty-class-key.json +6 -0
  640. package/schema/fixtures/policy/invalid/live-rate-on-human-only.json +7 -0
  641. package/schema/fixtures/policy/invalid/malformed-class-key.json +6 -0
  642. package/schema/fixtures/policy/invalid/missing-version.json +8 -0
  643. package/schema/fixtures/policy/invalid/negative-limit.json +9 -0
  644. package/schema/fixtures/policy/invalid/non-numeric-limit.json +9 -0
  645. package/schema/fixtures/policy/invalid/non-positive-max-pending.json +9 -0
  646. package/schema/fixtures/policy/invalid/on-expiry-grant.json +8 -0
  647. package/schema/fixtures/policy/invalid/payload-retention-bare-number.json +4 -0
  648. package/schema/fixtures/policy/invalid/payload-retention-compound.json +4 -0
  649. package/schema/fixtures/policy/invalid/payload-retention-fractional.json +4 -0
  650. package/schema/fixtures/policy/invalid/payload-retention-zero.json +4 -0
  651. package/schema/fixtures/policy/invalid/protected-paths-escape.json +4 -0
  652. package/schema/fixtures/policy/invalid/protected-paths-glob.json +4 -0
  653. package/schema/fixtures/policy/invalid/retro-rate-on-human-only.json +7 -0
  654. package/schema/fixtures/policy/invalid/retro-rate-on-manual.json +7 -0
  655. package/schema/fixtures/policy/invalid/retro-rate-zero.json +7 -0
  656. package/schema/fixtures/policy/invalid/sample-rate-too-high.json +5 -0
  657. package/schema/fixtures/policy/invalid/sampling-secret-env-empty.json +7 -0
  658. package/schema/fixtures/policy/invalid/sampling-secret-env-not-string.json +6 -0
  659. package/schema/fixtures/policy/invalid/skew-tolerance-compound.json +6 -0
  660. package/schema/fixtures/policy/invalid/unknown-autonomy.json +7 -0
  661. package/schema/fixtures/policy/invalid/unknown-class-rule-key.json +6 -0
  662. package/schema/fixtures/policy/invalid/unknown-top-level-key.json +7 -0
  663. package/schema/fixtures/policy/invalid/vault-passphrase-env-empty.json +6 -0
  664. package/schema/fixtures/policy/invalid/vault-passphrase-literal.json +6 -0
  665. package/schema/fixtures/policy/invalid/version-not-string.json +4 -0
  666. package/schema/fixtures/policy/valid/canonical.json +47 -0
  667. package/schema/fixtures/policy/valid/checkpoint-keys.json +18 -0
  668. package/schema/fixtures/policy/valid/class-approvers-limits.json +25 -0
  669. package/schema/fixtures/policy/valid/class-retro-rate.json +17 -0
  670. package/schema/fixtures/policy/valid/global-budgets.json +19 -0
  671. package/schema/fixtures/policy/valid/human-only.json +9 -0
  672. package/schema/fixtures/policy/valid/minimal.json +6 -0
  673. package/schema/fixtures/policy/valid/protected-paths.json +10 -0
  674. package/schema/fixtures/policy/valid/record-namespace.json +13 -0
  675. package/schema/fixtures/policy/valid/request-volume-limits.json +26 -0
  676. package/schema/fixtures/policy/valid/retention-and-sampling-secret.json +16 -0
  677. package/schema/fixtures/policy/valid/skew-tolerance.json +15 -0
  678. package/schema/fixtures/policy/valid/vault-passphrase-env.json +14 -0
  679. package/schema/fixtures/policy/valid/wildcards.json +15 -0
  680. package/schema/fixtures/policy-md/invalid/alias-bomb.md +15 -0
  681. package/schema/fixtures/policy-md/invalid/no-fence.md +7 -0
  682. package/schema/fixtures/policy-md/invalid/protected-route-not-a-subclass.md +16 -0
  683. package/schema/fixtures/policy-md/invalid/schema-invalid-autonomy.md +16 -0
  684. package/schema/fixtures/policy-md/invalid/schema-invalid-read-proof.md +17 -0
  685. package/schema/fixtures/policy-md/invalid/two-fences.md +19 -0
  686. package/schema/fixtures/policy-md/invalid/unclosed-fence.md +11 -0
  687. package/schema/fixtures/policy-md/invalid/wrong-info-string.md +11 -0
  688. package/schema/fixtures/policy-md/invalid/yaml-syntax-error.md +13 -0
  689. package/schema/fixtures/policy-md/precedence/both/APPROVAL.md +7 -0
  690. package/schema/fixtures/policy-md/precedence/both/APPROVALS.md +7 -0
  691. package/schema/fixtures/policy-md/precedence/fallback-only/APPROVALS.md +7 -0
  692. package/schema/fixtures/policy-md/valid/canonical.md +50 -0
  693. package/schema/fixtures/policy-md/valid/daemon-read-proof.md +18 -0
  694. package/schema/fixtures/policy-md/valid/minimal.md +3 -0
  695. package/schema/fixtures/policy-md/valid/prose-lookalikes.md +54 -0
  696. package/schema/fixtures/policy-md/valid/routed-protected-paths.md +49 -0
  697. package/schema/fixtures/policy-md/valid/with-values.md +79 -0
  698. package/schema/fixtures/sample-record/invalid/bad-date-time.json +4 -0
  699. package/schema/fixtures/sample-record/invalid/missing-required-field.json +3 -0
  700. package/schema/fixtures/sample-record/invalid/unknown-top-level-field.json +5 -0
  701. package/schema/fixtures/sample-record/invalid/wrong-type.json +4 -0
  702. package/schema/fixtures/sample-record/valid/minimal.json +4 -0
  703. package/schema/fixtures/sample-record/valid/with-note.json +5 -0
  704. package/schema/fixtures/values/invalid/class-shaped.json +9 -0
  705. package/schema/fixtures/values/invalid/duplicate-entry.json +4 -0
  706. package/schema/fixtures/values/invalid/non-string-item.json +4 -0
  707. package/schema/fixtures/values/invalid/over-cap.json +26 -0
  708. package/schema/fixtures/values/invalid/unknown-key.json +5 -0
  709. package/schema/fixtures/values/invalid/version-string.json +1 -0
  710. package/schema/fixtures/values/valid/empty-lists.json +7 -0
  711. package/schema/fixtures/values/valid/full.json +20 -0
  712. package/schema/fixtures/values/valid/minimal.json +1 -0
  713. package/schema/fixtures/values-md/invalid/schema-invalid.md +62 -0
  714. package/schema/fixtures/values-md/invalid/two-blocks.md +69 -0
  715. package/schema/fixtures/values-md/invalid/unterminated.md +61 -0
  716. package/schema/fixtures/values-md/invalid/yaml-error.md +63 -0
  717. package/schema/fixtures/values-md/valid/absent.md +50 -0
  718. package/schema/fixtures/values-md/valid/with-values.md +79 -0
  719. package/schema/policy.schema.json +501 -0
  720. package/schema/sample-record.schema.json +26 -0
  721. package/schema/values.schema.json +55 -0
  722. package/templates/codex/README.md +9 -0
@@ -0,0 +1,806 @@
1
+ /**
2
+ * `approval channel telegram listen | health` — the runtime half of the
3
+ * Telegram channel (SPEC.md §10.3, APRV-26).
4
+ *
5
+ * As everywhere else in this CLI, **no logic lives here**. The rendering and
6
+ * the Bot API are `channels/telegram.ts`; turning a button press into an event
7
+ * is `channels/contract.ts`'s `recordChannelDecision`, which calls the
8
+ * human-only `decide()` in `core/gate.ts`. This file resolves configuration,
9
+ * builds the pending queue, wires the two together, and chooses an exit code.
10
+ *
11
+ * Three things it does that the channel deliberately cannot:
12
+ *
13
+ * 1. **It reads the environment.** `APPROVAL_TG_TOKEN` and `APPROVAL_TG_CHAT`
14
+ * are read here and passed to the channel as values (SPEC.md §5.1: policy
15
+ * carries the env-var *names*, never the secrets). Nothing in `channels/`
16
+ * touches `process.env`.
17
+ * 2. **It declares who is approving.** The decision is recorded against the
18
+ * human actor from `--as` / `APPROVAL_HUMAN`, never against anything the
19
+ * callback carried. SPEC.md §11: identity in v0.1 is config-declared, the
20
+ * trust boundary is the local machine, and everyone who can reach the
21
+ * configured chat can approve as that actor. This is stated in `--help`
22
+ * because an operator has to be able to see it without reading the source.
23
+ * 3. **It holds the token.** A grant mints a single-use execution token;
24
+ * `recordChannelDecision` returns it to *this* handler, which prints it on
25
+ * **stdout** and never hands it back to the channel. It is never sent to
26
+ * Telegram — see the module doc of `channels/telegram.ts` for why a chat
27
+ * transcript is not a credential store, and for the flag on that decision.
28
+ *
29
+ * ## Payload material — the store, and why `--payloads` still exists
30
+ *
31
+ * SPEC.md §6.2 records a `payload_hash` in the log and never the bytes, and
32
+ * §10.4 requires a channel to present the full payload for a manual action. So
33
+ * the bytes must come from somewhere the runtime can reach. Since APRV-28 that
34
+ * somewhere is the payload store beside the log (`.approval/payloads/`, written
35
+ * by `approval request --payload`), and a listener ordinarily needs no payload
36
+ * flag at all. `--payloads` remains an override for bytes an operator holds
37
+ * elsewhere: a JSON file mapping action key to that action's payload value,
38
+ * consulted before the store. The tagger
39
+ * (`channels/tagging.ts`) re-hashes whatever it is given and refuses anything
40
+ * that does not match the recorded binding, so a wrong or stale file cannot put
41
+ * different bytes in front of an approver than the token will execute — it
42
+ * produces a visible skip instead. Requests whose material is missing are
43
+ * reported on stderr and NOT delivered: a manual request rendered without its
44
+ * payload would be exactly the §10.4 violation the contract refuses.
45
+ *
46
+ * ## Dispatch: where it lives, and why it lives here (APRV-55) — flagged
47
+ *
48
+ * SPEC.md §10.2 lists "dispatches channel notifications" among the daemon's
49
+ * jobs. At v0.1 the reference runtime performs that dispatch **in this
50
+ * listener**, on every poll cycle, and the placement is deliberate:
51
+ *
52
+ * 1. The listener already holds the channel connection (the bot token, the
53
+ * chat id) and the approver identity. The daemon holds neither, and giving
54
+ * it either would put a credential and a human identity into a process
55
+ * whose job is to read files and append events.
56
+ * 2. The daemon is the sole writer of the log; dispatch appends nothing. Moving
57
+ * a read-and-send out of the daemon costs the single-writer stance nothing,
58
+ * because dispatch was never a write.
59
+ * 3. A network round-trip inside the daemon's tick couples the projection loop
60
+ * to Telegram's availability. A slow Bot API would delay TTL expiry and
61
+ * write-back, which are the daemon's actual obligations.
62
+ *
63
+ * So this is an implementation placement, not a change to the daemon's stated
64
+ * role: a later build MAY move dispatch into the daemon (or a supervisor) with
65
+ * no change to the log or to any event shape. SPEC.md §10.3 records the same.
66
+ *
67
+ * ### The cycle
68
+ *
69
+ * {@link dispatchPending} runs before every `getUpdates` — the startup send and
70
+ * every later cycle are the same call with the same state, the startup one
71
+ * merely finding an empty delivered set. Each call **re-derives** the pending
72
+ * queue from the verified log ({@link buildPendingQueue}), so which requests
73
+ * are pending is always the log's answer and never this process's memory. A
74
+ * request appended while the listener is running is therefore delivered on the
75
+ * next cycle, without a restart; a request that was decided or whose TTL lapsed
76
+ * simply stops appearing in the derivation and is never sent.
77
+ *
78
+ * What *is* remembered, and only in {@link DispatchState} for this process's
79
+ * lifetime, is which action keys this listener has already put on the phone.
80
+ * Losing that memory (a restart, a crash) re-sends everything still pending:
81
+ * a duplicate on the phone, never silence. That direction is the whole design
82
+ * (SPEC.md §10.3: channels hold no state that is a source of truth).
83
+ *
84
+ * APRV-196 made that re-send legible rather than rarer. The first batch a
85
+ * process sends is preceded by one banner naming how many are coming, the
86
+ * copies already in the chat keep working (`actionRefOf` in
87
+ * `channels/telegram.ts` resolves their buttons to the same request), and the
88
+ * bookkeeping above is pruned as requests settle and age out instead of growing
89
+ * for the life of a listener that `approval up` keeps running for weeks.
90
+ *
91
+ * ### Send failures
92
+ *
93
+ * A key that fails to send stays undelivered, so the next cycle retries it.
94
+ * There is **no attempt limit**: giving up would turn a transient outage into a
95
+ * pending request no human ever sees, which is the one failure this project
96
+ * exists to prevent. The retry rate is bounded by the poll cycle itself (the
97
+ * long-poll timeout, or the channel's doubling backoff after a poll error), and
98
+ * the stderr warnings are throttled after {@link DISPATCH_LOUD_ATTEMPTS}
99
+ * consecutive failures for one key so a long outage cannot bury the terminal.
100
+ * The one exception is the **startup** dispatch, which still exits non-zero on
101
+ * a send failure: an operator who has just mistyped a chat id or a token should
102
+ * learn it immediately rather than watch a listener retry forever.
103
+ */
104
+ import type { DecideOptions } from "../core/gate.js";
105
+ import { type ChannelRequest, type DeliveryId } from "../channels/contract.js";
106
+ import { type ChannelTagRefusalCode, type TagOptions } from "../channels/tagging.js";
107
+ import { type CheckpointTap } from "./checkpoint-tap.js";
108
+ import { TelegramChannel, type CheckpointTapResponse, type ReviewCard, type ReviewTapResponse, type TelegramCommand, type TelegramTerminalState } from "../channels/telegram.js";
109
+ import { type TelegramDelivery } from "../core/telegram-config.js";
110
+ import { type ParsedFlags } from "./args.js";
111
+ import { type GlossRunner } from "./gloss.js";
112
+ import { type GlossRunnerFactoryOptions } from "./gloss-options.js";
113
+ import type { Streams } from "./main.js";
114
+ /**
115
+ * The gloss runner this listener will use, as a spreadable fragment (APRV-197).
116
+ *
117
+ * ON unless `--no-gloss`. Two flags rather than one because the pair reads
118
+ * honestly next to `channel cli`, where the default is the other way round:
119
+ * `--gloss` is accepted here (and is simply the default restated) so that one
120
+ * command line works on both verbs, and `--no-gloss` wins a tie, because the
121
+ * flag that removes a language model from the path should never lose one.
122
+ *
123
+ * A fragment rather than a value so that "no runner" is the ABSENCE of the
124
+ * key. {@link ListenSetup.gloss} being optional is what lets every
125
+ * programmatic caller of `dispatchPending` spawn nothing without saying so.
126
+ *
127
+ * `passphraseEnv` is the name this policy's `vault.passphrase_env` gives, and
128
+ * the only thing the APRV-207 scrub needs from a policy: the subprocess is
129
+ * spawned starved either way, and naming the variable covers the deployment
130
+ * that renamed it out from under the credential prefixes.
131
+ */
132
+ export declare function glossWiring(flags: ParsedFlags, passphraseEnv?: string | null, factories?: Omit<GlossRunnerFactoryOptions, "passphraseEnv">): {
133
+ gloss?: GlossRunner;
134
+ };
135
+ export interface ListenSetup {
136
+ channel: TelegramChannel;
137
+ logPath: string;
138
+ actor: string;
139
+ json: boolean;
140
+ once: boolean;
141
+ gateOptions: DecideOptions;
142
+ tagOptions: TagOptions;
143
+ /**
144
+ * How this listener puts the pending set in front of the approver (APRV-216):
145
+ * `paced`, one question at a time, or `burst`, everything not yet sent on
146
+ * every cycle.
147
+ *
148
+ * REQUIRED rather than defaulted, so that every construction site states
149
+ * which of the two it means. The policy's answer is resolved once, in
150
+ * {@link prepareListen}, and the default that answer falls back to lives in
151
+ * `core/telegram-config.ts` beside the other Telegram policy readings.
152
+ */
153
+ delivery: TelegramDelivery;
154
+ /**
155
+ * How the one-sentence model gloss is obtained (APRV-144).
156
+ *
157
+ * OPT-IN, and absent by default. The verb wires in the production runner
158
+ * (`claude -p --model haiku`, hard timeout, failing toward absence); every
159
+ * other caller — the test suite above all — gets no gloss unless it hands
160
+ * over a runner. A default that spawned would make a subprocess an implicit
161
+ * dependency of anything that drives a dispatch cycle, and would put a model
162
+ * inside a test suite that must never invoke one.
163
+ *
164
+ * Injectable so the tests drive both branches, answered and absent, against
165
+ * a stub.
166
+ */
167
+ gloss?: GlossRunner;
168
+ /**
169
+ * Where a checkpoint key may come from, and where the cadence is read
170
+ * (APRV-257).
171
+ *
172
+ * Present at every construction site, because every one of them knows a log
173
+ * path and a policy. Whether a checkpoint is ever OFFERED is the policy's
174
+ * answer — `audit.checkpoint_every` plus `audit.checkpoint_keys` — and
175
+ * {@link checkpointOfferFor} gives up before it walks a log when the policy
176
+ * names neither, so a gate that has not turned checkpoints on pays a policy
177
+ * load per cycle and nothing else.
178
+ */
179
+ checkpoint: CheckpointTap;
180
+ }
181
+ /**
182
+ * Why a listener could not be built. A closed union, because more than one
183
+ * caller now branches on it: the verb turns each into an exit code, and
184
+ * `approval up` turns each into a part it will not start (SPEC.md §11.1
185
+ * invariant 6 — a refusal is machine-readable and distinct).
186
+ */
187
+ export declare const LISTEN_REFUSAL_CODES: readonly [
188
+ /** A credential variable the policy names is unset or empty. */
189
+ "not-configured",
190
+ /** No `human:<id>` was declared, so nothing could be recorded against one. */
191
+ "no-identity",
192
+ /** `--poll-timeout` was not a whole number of seconds. */
193
+ "poll-timeout",
194
+ /** The log could not be read (or its directory does not exist). */
195
+ "log-unreadable",
196
+ /** `--payloads` did not hold a JSON object of action key -> payload. */
197
+ "payloads-unreadable"];
198
+ export type ListenRefusalCode = (typeof LISTEN_REFUSAL_CODES)[number];
199
+ /** Everything {@link prepareListen} needs, already resolved to absolute paths. */
200
+ export interface ListenRequest {
201
+ /** The log to derive the queue from and append decisions to. */
202
+ logPath: string;
203
+ /** Policy location, with `loadPolicy`'s semantics. */
204
+ policy: {
205
+ dir?: string;
206
+ file?: string;
207
+ };
208
+ /** `--as` as typed, or `null` to fall back to `APPROVAL_HUMAN`. */
209
+ as: string | null;
210
+ /** `--payloads`, already absolute, or `null` for the payload store alone. */
211
+ payloads: string | null;
212
+ /** `--api-base`, or `null` for the Bot API. */
213
+ apiBase: string | null;
214
+ /** `--poll-timeout` as typed, or `null` for the channel's own default. */
215
+ pollTimeout: string | null;
216
+ once: boolean;
217
+ json: boolean;
218
+ /** Where the channel's operational complaints go. Ordinarily stderr. */
219
+ log(message: string): void;
220
+ /** The gloss runner, if the caller wants one. See {@link ListenSetup.gloss}. */
221
+ gloss?: GlossRunner;
222
+ }
223
+ export type ListenPreparation = {
224
+ ok: true;
225
+ setup: ListenSetup;
226
+ } | {
227
+ ok: false;
228
+ code: ListenRefusalCode;
229
+ message: string;
230
+ };
231
+ /**
232
+ * Everything that can fail without touching the network, in order.
233
+ *
234
+ * Deliberately sequential and deliberately synchronous: an operator who typed
235
+ * the wrong thing learns it before a bot message is sent, and the async half
236
+ * below can then assume its configuration is whole.
237
+ *
238
+ * It PRINTS NOTHING and CHOOSES NO EXIT CODE (APRV-110). The verb below turns
239
+ * each refusal into the usage or I/O error it always was; `approval up` turns
240
+ * the same refusal into a channel it declines to start, reported in doctor's
241
+ * vocabulary while the other parts carry on. Two callers, one set of checks,
242
+ * one set of sentences — which is the only way the two surfaces can agree about
243
+ * what "telegram is not configured" means.
244
+ */
245
+ export declare function prepareListen(request: ListenRequest): ListenPreparation;
246
+ /**
247
+ * What to tell a human who tapped a button for an action this listener is not
248
+ * holding open (APRV-196).
249
+ *
250
+ * The one place a stale tap gets a real answer instead of a shrug. It reads the
251
+ * VERIFIED log (SPEC.md §11.1(1): a sentence a human reads about what the log
252
+ * says is derived from a log that verified, or it is not derived at all) and
253
+ * answers from `requestState`, the same derivation the gate and the pending
254
+ * queue use. Nothing here decides anything, nothing is appended, and nothing is
255
+ * remembered between calls: an unreadable log answers `null`, which the channel
256
+ * renders as its "not open here" toast.
257
+ *
258
+ * The argument is an action REFERENCE and never a key. The string came off the
259
+ * network, so this hashes the keys the log actually carries and looks for a
260
+ * match; a caller cannot make it describe a request by naming one, and a ref
261
+ * matching nothing simply answers `null`.
262
+ *
263
+ * The walk is over `approval.requested` records, which is the set of things
264
+ * that could ever have had a button. Run only on a stale tap, which is rare by
265
+ * construction.
266
+ */
267
+ export declare function describeActionFor(logPath: string): (actionRef: string) => string | null;
268
+ /**
269
+ * Consecutive failures for one action key after which stderr warnings thin out.
270
+ *
271
+ * Not an attempt limit: the send is retried on every cycle forever (see the
272
+ * module doc). Only the complaining is throttled, to every tenth attempt.
273
+ */
274
+ export declare const DISPATCH_LOUD_ATTEMPTS = 3;
275
+ /**
276
+ * How long an unannotated delivery stays in the bookkeeping before it is
277
+ * dropped (APRV-196). Twenty-four hours, matching the channel's own
278
+ * `TELEGRAM_DEFAULT_RETENTION_MS`.
279
+ *
280
+ * It is a floor on forgetting and not a deadline for anything: a request that
281
+ * is still pending is never dropped however old it is, because the pending
282
+ * queue is checked first. What this bounds is the memory a long-lived listener
283
+ * holds for questions the log has finished with.
284
+ */
285
+ export declare const DISPATCH_RETENTION_MS: number;
286
+ /**
287
+ * The line that introduces the first batch a listener process sends (APRV-196).
288
+ *
289
+ * **Why a banner and not an edit of the earlier copies.** The incident was a
290
+ * restart re-sending five pending requests with no warning, on top of five
291
+ * copies whose buttons had quietly stopped working. Editing those earlier
292
+ * copies to say "superseded" would read better — and it is not a design that
293
+ * can be relied on, because it requires this process to know their message ids,
294
+ * which a restart by definition does not: SPEC.md §10.3 forbids channel state
295
+ * that is a source of truth, and a crash loses a cache whether or not one is
296
+ * allowed. A design that only works when the crash was gentle is a design that
297
+ * fails on the day it is needed. So the banner is unconditional, and the
298
+ * earlier copies are made harmless instead of tidy: their buttons resolve by
299
+ * action reference to the request this process has just re-delivered
300
+ * (`actionRefOf` in `channels/telegram.ts`), so a human who taps the copy they
301
+ * can see decides the request they meant.
302
+ *
303
+ * It says "started" rather than "restarted" because a listener cannot tell the
304
+ * two apart, having deliberately kept nothing that would let it, and a first
305
+ * start that claimed to be a restart would be this channel's own text lying
306
+ * about the system's history.
307
+ */
308
+ export declare function bannerLines(pending: number): string[];
309
+ /**
310
+ * The summary line that precedes a paced send, and the body of `/queue`.
311
+ *
312
+ * One message, and everything in it is arithmetic on the verified log at the
313
+ * instant it is written: how many requests are pending, how long the oldest has
314
+ * waited, and which classes they are. Nothing is remembered between calls, so
315
+ * two summaries a minute apart can disagree only because the log moved.
316
+ *
317
+ * The class tally is the part worth the space. The count alone says how much
318
+ * work is waiting; the classes say what KIND of work, which is what tells an
319
+ * approver whether the queue is six identical `network.call`s they can walk
320
+ * through or one `policy.edit` they should read carefully.
321
+ */
322
+ export declare function summaryLines(requests: ChannelRequest[], now: string): string[];
323
+ /**
324
+ * `/queue`'s reply: the summary, then one numbered line per pending request.
325
+ *
326
+ * Derived, like the summary, from the verified log at reply time and not from
327
+ * anything this process is holding: the numbering is positional and names no
328
+ * button, so a stale copy of this list cannot be used to decide anything. The
329
+ * marker says which one this listener has selected and once delivered, because
330
+ * the question `/queue` is usually asked to answer is "what else is there
331
+ * besides the one I am looking at" — and, since APRV-256, its unhappy twin,
332
+ * "where is the one I am supposed to be looking at".
333
+ *
334
+ * The footer answers that second question the only honest way available to a
335
+ * process whose knowledge of the chat ends at "a send returned success": it
336
+ * says what was sent, says it cannot tell whether the card survived, and then
337
+ * spends its remaining words on recovery rather than reassurance.
338
+ */
339
+ export declare function queueLines(requests: ChannelRequest[], now: string, shown: readonly string[]): string[];
340
+ /**
341
+ * What this process is showing, and in what order (APRV-216). **In memory
342
+ * only**, like every other field of {@link DispatchState} and for the same
343
+ * reason (SPEC.md §10.3).
344
+ *
345
+ * None of this is truth, and the check that proves it is what happens when it
346
+ * is lost: a restarted listener re-derives the pending set from the verified
347
+ * log, rebuilds the order from log order, and shows the oldest — which is
348
+ * exactly what a fresh start does anyway. What a crash costs is the human's
349
+ * place in a walkthrough, never a request that stays pending in the log and is
350
+ * never shown.
351
+ */
352
+ export interface PacedState {
353
+ /**
354
+ * Every pending action key, in the order this process will show them.
355
+ *
356
+ * Seeded from log order (oldest first, which is what `buildPendingQueue`
357
+ * returns) and rearranged by `/skip` alone. Keys the log no longer calls
358
+ * pending are dropped on every cycle, and newly pending ones join the back.
359
+ */
360
+ order: string[];
361
+ /**
362
+ * The action keys of the unit in front of the approver, or `null` when
363
+ * nothing is.
364
+ *
365
+ * A unit rather than a key because a digest (APRV-115) is one thing to read
366
+ * and several things to decide. It is released when the log says none of its
367
+ * members is pending any more, which is what makes a decision — at any
368
+ * surface, on any copy — advance the walkthrough.
369
+ */
370
+ current: string[] | null;
371
+ /** Whether any summary has been sent yet, i.e. whether this is the start. */
372
+ summarySent: boolean;
373
+ /** The pending count the last summary named, so growth can be recognised. */
374
+ announced: number;
375
+ }
376
+ /**
377
+ * The retrospective walkthrough this process is running (APRV-299). **In memory
378
+ * only**, exactly like {@link PacedState} and under the same rule (SPEC.md
379
+ * §10.3).
380
+ *
381
+ * Its loss is the check that it is not truth: a restarted listener re-derives
382
+ * the open samples from the verified log, rebuilds the order from log order,
383
+ * and offers the oldest — which is what a fresh start does anyway. A card that
384
+ * never arrives, or that a human scrolls past, leaves the sample OPEN: it stays
385
+ * in `approval audit list`, in `.approval/QUEUE.md`, and reviewable with
386
+ * `approval audit review <seq>`. Nothing here can empty the backlog, which is
387
+ * the property a sampled-audit backlog exists to have.
388
+ */
389
+ export interface ReviewWalkthrough {
390
+ /** Every open sample's seq, in the order this process will show them. */
391
+ order: number[];
392
+ /** The sample whose card is in front of the approver, or `null`. */
393
+ current: number | null;
394
+ /** Sample seq -> the message this process sent the card as. */
395
+ readonly delivered: Map<number, DeliveryId>;
396
+ /** Whether any review summary has been sent yet. */
397
+ summarySent: boolean;
398
+ /** The open count the last summary named, so growth can be recognised. */
399
+ announced: number;
400
+ /**
401
+ * The log's size in bytes when this pass last derived the backlog, or `null`
402
+ * before the first one.
403
+ *
404
+ * A cost guard and nothing else, and it is sound for exactly one reason: the
405
+ * log is APPEND-ONLY, so a size that has not changed is a record set that has
406
+ * not changed. It is read only to skip a full verified walk on the cycle
407
+ * where a card is already in front of the approver and nothing has been
408
+ * written — which, with a 25-second poll and a human who answers in minutes,
409
+ * is most cycles. Every other cycle re-derives from the log as usual, and a
410
+ * lost or stale value costs one extra read rather than a wrong answer.
411
+ */
412
+ logSize: number | null;
413
+ }
414
+ /**
415
+ * The summary line that precedes a review card, and `/queue`'s review footer.
416
+ *
417
+ * Arithmetic on the verified log at the instant it is written, exactly as
418
+ * {@link summaryLines} is: how many samples are awaiting review, how old the
419
+ * oldest is, and which classes they are. The last clause is the one that stops
420
+ * a reader treating this like the pending queue: nothing here is waiting on
421
+ * them, because all of it has already happened.
422
+ */
423
+ export declare function reviewSummaryLines(cards: ReviewCard[], now: string): string[];
424
+ /**
425
+ * What one listener process remembers between cycles. **In memory only.**
426
+ *
427
+ * SPEC.md §10.3: channels hold no state that is a source of truth. Nothing here
428
+ * is truth — the pending set is re-derived from the verified log every cycle,
429
+ * and this only prevents a second copy of a message this process already sent.
430
+ * Its loss (restart, crash) degrades to a re-send, never to a request that is
431
+ * pending in the log and absent from the approver's phone.
432
+ */
433
+ export interface DispatchState {
434
+ /**
435
+ * action key -> the delivery id this process sent it under.
436
+ *
437
+ * Pruned (APRV-196): an entry goes when the request reaches a terminal state
438
+ * and its message has been annotated, and a straggler goes when it is older
439
+ * than {@link DISPATCH_RETENTION_MS} and the pending queue no longer carries
440
+ * it. Neither prune can cost a re-send, because `buildPendingQueue` only ever
441
+ * returns requests the verified log says are pending — the same reason losing
442
+ * the whole map to a restart is safe.
443
+ */
444
+ readonly delivered: Map<string, DeliveryId>;
445
+ /** action key -> when this process sent it, ms since epoch (APRV-196). */
446
+ readonly sentAtMs: Map<string, number>;
447
+ /**
448
+ * Whether the re-delivery banner has been sent (APRV-196).
449
+ *
450
+ * A box rather than a field because {@link DispatchState} is `readonly`
451
+ * everywhere else, and for the same reason: a cycle may write what it did,
452
+ * and nothing may swap the state out from under one.
453
+ */
454
+ readonly banner: {
455
+ sent: boolean;
456
+ };
457
+ /** action key -> consecutive failed send attempts. Cleared on success. */
458
+ readonly attempts: Map<string, number>;
459
+ /** `<action key>:<code>` skips already reported, so cycles do not repeat them. */
460
+ readonly warned: Set<string>;
461
+ /**
462
+ * Keys this process has already annotated on the approver's phone (APRV-106
463
+ * for withdrawal, APRV-113 for every other terminal state). In memory, like
464
+ * `delivered`, and for the same reason: it stops a second edit of the same
465
+ * message, and its loss costs a duplicate edit at worst.
466
+ *
467
+ * The memory that matters here is `delivered`, and losing it degrades to
468
+ * un-annotated messages, NEVER to wrong annotations: a process that does not
469
+ * remember sending a message cannot edit it, and one that does re-reads the
470
+ * outcome from the verified log every cycle. A fresh listener also never
471
+ * sends a settled request in the first place — `buildPendingQueue` re-derives
472
+ * from the verified log and only `requested` is pending — so a restart leaves
473
+ * stale text on old messages whose buttons the gate refuses anyway, and
474
+ * nothing worse.
475
+ */
476
+ readonly annotated: Set<string>;
477
+ /**
478
+ * The walkthrough this process is running under `delivery: paced`
479
+ * (APRV-216). Present under `burst` too and simply never read there, so that
480
+ * one state shape serves both modes and a policy change between two runs
481
+ * needs no different bookkeeping.
482
+ */
483
+ readonly paced: PacedState;
484
+ /**
485
+ * The checkpoint prompt this process has outstanding (APRV-257). **In memory
486
+ * only**, like everything else here.
487
+ *
488
+ * `offeredSince` is the newest checkpoint's seq at the moment a prompt went
489
+ * out (`null` for a log that had never been checkpointed), and it is what
490
+ * makes "at most one outstanding, and never a nag" a single condition: a
491
+ * cadence that has lapsed keeps producing an offer on every cycle, and this
492
+ * process asks once per lapse. The value changes only when a checkpoint
493
+ * actually lands, which is also the moment due-ness goes false — so the next
494
+ * prompt comes from the next lapse and never from this one repeating.
495
+ *
496
+ * `offered: false` means nothing is outstanding. Losing the box to a restart
497
+ * costs one duplicate prompt for a checkpoint that is genuinely owed, which
498
+ * is the same direction every other piece of this bookkeeping degrades in.
499
+ */
500
+ readonly checkpoint: {
501
+ offered: boolean;
502
+ offeredSince: number | null;
503
+ };
504
+ /**
505
+ * The retrospective walkthrough (APRV-299), paced in both delivery modes.
506
+ *
507
+ * Always paced, and deliberately so even under `burst`: a review is never
508
+ * urgent, nobody is blocked on one, and a restart that put sixty of them on a
509
+ * phone at once would be the flood APRV-287 collapsed in the other direction.
510
+ * One card at a time, behind a summary, is the whole of the design.
511
+ */
512
+ readonly review: ReviewWalkthrough;
513
+ }
514
+ export declare function newDispatchState(): DispatchState;
515
+ /** What one {@link dispatchPending} call did. Total: it never throws. */
516
+ export interface DispatchResult {
517
+ /** Requests put in front of the approver by this cycle. */
518
+ delivered: {
519
+ action_key: string;
520
+ delivery_id: DeliveryId;
521
+ }[];
522
+ /** Sends that failed and will be retried on the next cycle. */
523
+ failed: {
524
+ action_key: string;
525
+ attempts: number;
526
+ message: string;
527
+ }[];
528
+ /**
529
+ * The queue could not be derived at all: the log is unreadable or does not
530
+ * verify. Nothing was sent. Fatal at startup, retried on later cycles.
531
+ */
532
+ queueError?: {
533
+ code: ChannelTagRefusalCode;
534
+ message: string;
535
+ };
536
+ /**
537
+ * Deliveries annotated with their terminal outcome and disarmed this cycle
538
+ * (APRV-106 for `withdrawn`, APRV-113 for the rest).
539
+ */
540
+ annotated: {
541
+ action_key: string;
542
+ delivery_id: DeliveryId;
543
+ outcome: TelegramTerminalState;
544
+ }[];
545
+ /**
546
+ * Digests sent this cycle (APRV-115): the message that carries the buttons,
547
+ * the batch delivery id every member's event will carry, and the members.
548
+ * A group that fell back to one message per member produces no entry here.
549
+ */
550
+ digests: {
551
+ delivery_id: DeliveryId;
552
+ batch_delivery_id: DeliveryId;
553
+ action_keys: string[];
554
+ }[];
555
+ /**
556
+ * The re-delivery banner, when this cycle sent one (APRV-196): the message
557
+ * that precedes a startup batch and says how many requests are coming.
558
+ */
559
+ banner?: {
560
+ delivery_id: DeliveryId;
561
+ pending: number;
562
+ };
563
+ /**
564
+ * The paced summary this cycle sent, when it sent one (APRV-216): the line
565
+ * that precedes the request being shown and says how many are waiting behind
566
+ * it. Sent by the first paced cycle that has something to show, and again
567
+ * whenever the pending set has grown while nothing was in front of the
568
+ * approver. Never both this and {@link banner}: they are the two modes'
569
+ * openings, and a process runs one mode.
570
+ */
571
+ summary?: {
572
+ delivery_id: DeliveryId;
573
+ pending: number;
574
+ };
575
+ /**
576
+ * Action keys dropped from the delivery bookkeeping this cycle (APRV-196),
577
+ * with why. Neither kind can cost a re-send: the pending queue is the log's
578
+ * answer, and a dropped key that is still pending is simply re-delivered.
579
+ */
580
+ pruned: {
581
+ action_key: string;
582
+ reason: "settled" | "stale";
583
+ }[];
584
+ /**
585
+ * The collapsed re-delivery this cycle sent, when it sent one (APRV-287):
586
+ * the one message that stood in for a batch of requests nobody is waiting on
587
+ * any more, and the keys it covers. At most one, on a process's first cycle.
588
+ */
589
+ collapsed?: {
590
+ delivery_id: DeliveryId;
591
+ action_keys: string[];
592
+ oldest_ms: number;
593
+ };
594
+ /**
595
+ * The `CHECKPOINT DUE` prompt this cycle sent, when it sent one (APRV-257):
596
+ * the message it is on and the head it asks about. At most one per lapse.
597
+ */
598
+ checkpoint?: {
599
+ delivery_id: DeliveryId;
600
+ seq: number;
601
+ hash: string;
602
+ };
603
+ /**
604
+ * The review card this cycle sent, when it sent one (APRV-299): the message
605
+ * it is on, the `audit.sampled` seq it is drawn for, and the action it is
606
+ * about. At most one per cycle, and none while a request is in front of the
607
+ * approver.
608
+ */
609
+ reviewCard?: {
610
+ delivery_id: DeliveryId;
611
+ sample_seq: number;
612
+ action_key: string;
613
+ };
614
+ /**
615
+ * The review summary this cycle sent, when it sent one (APRV-299): the line
616
+ * saying how many samples are awaiting review and how old the oldest is.
617
+ */
618
+ reviewSummary?: {
619
+ delivery_id: DeliveryId;
620
+ open: number;
621
+ };
622
+ /**
623
+ * The review backlog could not be derived: the log is unreadable or does not
624
+ * verify. No card was sent. Never fatal — a review is not a decision anyone
625
+ * is blocked on — and retried on the next cycle.
626
+ */
627
+ reviewError?: {
628
+ code: string;
629
+ message: string;
630
+ };
631
+ }
632
+ /**
633
+ * One dispatch cycle: re-derive the pending queue from the verified log, send
634
+ * whatever this process has not already sent.
635
+ *
636
+ * `now` is a parameter, not a clock read: TTL judgment inside
637
+ * {@link buildPendingQueue} is deterministic and the tests drive it at chosen
638
+ * instants. Requests that are decided, expired, or not yet requested are absent
639
+ * from the derivation and so are never sent.
640
+ */
641
+ export declare function dispatchPending(setup: ListenSetup, streams: Streams, state: DispatchState, now: string): Promise<DispatchResult>;
642
+ /**
643
+ * How old a pending request must be, on a listener's first cycle, to be one
644
+ * nobody is waiting on (APRV-287).
645
+ *
646
+ * The hook's own wait PLUS its retry grace, read from the same module the hook
647
+ * reads (`core/harness-wait.ts`), because two numbers would be two answers to
648
+ * "is anybody still holding this". Past the wait alone a hook process has
649
+ * stopped blocking and a retry can still adopt the question, so those are
650
+ * ordinary pending requests. Past the wait and the grace together nothing will
651
+ * adopt it: that is the moment the hook itself takes such a request back, and a
652
+ * request still pending here is one whose session never came back at all —
653
+ * exactly the dozen that arrived on a phone behind a dead daemon on
654
+ * 2026-09-06.
655
+ *
656
+ * Collapsing is not deciding. These stay pending, listable by `/queue`, and
657
+ * decidable from any copy already delivered; what changes is how many messages
658
+ * it takes to say they are there.
659
+ */
660
+ export declare const COLLAPSE_STALE_AFTER_MS: number;
661
+ /** The computed lines a collapsed re-delivery leads with (APRV-287). */
662
+ export declare function staleLines(requests: ChannelRequest[], now: string): string[];
663
+ /**
664
+ * What a checkpoint tap does, on the machine the listener runs on (APRV-257).
665
+ *
666
+ * The signing happens HERE, in the listener's process, and that is the whole
667
+ * point of the tap: this process holds the vault passphrase because a HUMAN
668
+ * exported it into the shell they started it from, and `core/child-env.ts`
669
+ * strips that variable from every child an agent's session spawns. No agent can
670
+ * arrange for a process that reaches this function with a key.
671
+ *
672
+ * Nothing about the head is re-derived. The `(seq, hash)` comes back from the
673
+ * channel exactly as it was put on the screen, and
674
+ * {@link ../core/checkpoint.js appendCheckpointAt} signs that and checks the
675
+ * log still carries it. A handler that quietly re-read the head would be
676
+ * putting a human's key over bytes nobody looked at.
677
+ *
678
+ * `Not now` appends nothing and says so. It is not a rejection: there is no
679
+ * request here to reject, and a checkpoint that is owed is a warning at every
680
+ * layer and a refusal at none.
681
+ */
682
+ export declare function checkpointHandlerFor(setup: ListenSetup, streams: Streams): (tap: {
683
+ sign: boolean;
684
+ head: {
685
+ seq: number;
686
+ hash: string;
687
+ };
688
+ }) => CheckpointTapResponse;
689
+ /**
690
+ * What a review tap does: the human-only `reviewSample`, and nothing else
691
+ * (APRV-299).
692
+ *
693
+ * The one path from a button on a phone to an `audit.reviewed`, and it is the
694
+ * SAME path `approval audit review` takes — same function, same refusals, same
695
+ * record shape — so a reaction given on a card and one given at a terminal are
696
+ * indistinguishable to `approval feedback`, which is the whole of AC3.
697
+ *
698
+ * The actor is `setup.actor`, the human identity this listener was configured
699
+ * with (`--as` / `APPROVAL_HUMAN`), exactly as a grant's is. It is never read
700
+ * off the tap, never off the callback, and never out of a payload field: this
701
+ * channel does not authenticate the person who pressed the button, and SPEC.md
702
+ * §11's config-declared identity is what a review is recorded against. Anyone
703
+ * who can reach the configured chat reviews as that actor, which is the same
704
+ * trust boundary a tapped grant already stands on.
705
+ *
706
+ * The reaction is passed through untouched and NOTHING here reads it (SPEC.md
707
+ * §11.1 invariant 10): it is a field on a record, chosen by a human, on its way
708
+ * to the log.
709
+ */
710
+ export declare function reviewHandlerFor(setup: ListenSetup, streams: Streams): (tap: {
711
+ sampleSeq: number;
712
+ verdict: "ok" | "denied";
713
+ reaction?: "disliked" | "indifferent" | "liked" | "loved";
714
+ note?: string;
715
+ }) => ReviewTapResponse;
716
+ /**
717
+ * `/queue`, `/skip`, `/next` — the paced walkthrough's three verbs (APRV-216).
718
+ *
719
+ * **None of them appends anything**, and the reason is structural rather than
720
+ * careful: this function never touches `recordChannelDecision`, so there is no
721
+ * path from a typed word to the log. A decision is a button, always, because a
722
+ * button carries the nonce and the action reference that bind an answer to the
723
+ * bytes an approver was shown, and a word typed into a chat carries neither.
724
+ *
725
+ * What they do move is process memory:
726
+ *
727
+ * - `/queue` reads the verified log and replies with the summary and a numbered
728
+ * list. It changes nothing, and it works while a request is selected, because
729
+ * the list is derived and not held. The reply says outright that it carries no
730
+ * buttons and that it cannot vouch for a card it once sent (APRV-256).
731
+ * - `/skip` sends the shown unit to the BACK of this process's order and
732
+ * forgets having delivered it, so the next cycle shows the next question and
733
+ * this one comes round again after the rest. The copy already in the chat
734
+ * keeps its buttons, and they still decide the same request by action
735
+ * reference (APRV-196), so a skip is "later", never "gone".
736
+ * - `/next` releases the shown unit without reordering, so this process moves
737
+ * past it and does not show it again. The same copy stays live in the chat:
738
+ * the approver has kept the question and given up their place in the queue,
739
+ * which is the opposite trade from `/skip`.
740
+ *
741
+ * A command that finds nothing to do says so, because silence in a chat window
742
+ * is indistinguishable from a listener that has died.
743
+ */
744
+ export declare function commandHandlerFor(setup: ListenSetup, streams: Streams, state: DispatchState,
745
+ /**
746
+ * When the command arrived. A clock read in production, because a command is
747
+ * answered when a human types it; injectable for the same reason
748
+ * {@link dispatchPending} takes `now` as a parameter, since the ages a reply
749
+ * states are arithmetic against it and a suite must be able to choose them.
750
+ */
751
+ clock?: () => string): (command: TelegramCommand) => Promise<void>;
752
+ /**
753
+ * How one run of the listen loop ended (APRV-110).
754
+ *
755
+ * `stopped` is the ordinary ending: a signal, or `--once` completing. The two
756
+ * failures are the ones the startup cycle has always treated as fatal, hoisted
757
+ * out of the verb so that a supervisor can treat them as a part that fell over
758
+ * rather than as a process that must exit.
759
+ */
760
+ export type ListenerOutcome = {
761
+ kind: "stopped";
762
+ } | {
763
+ kind: "queue-error";
764
+ code: ChannelTagRefusalCode;
765
+ message: string;
766
+ } | {
767
+ kind: "send-failed";
768
+ message: string;
769
+ };
770
+ /** A listen loop that is already running. {@link stop} ends it cleanly. */
771
+ export interface RunningListener {
772
+ /** Settles when the loop ends. Never rejects for a listener-shaped failure. */
773
+ readonly done: Promise<ListenerOutcome>;
774
+ /** Stop the loop, now or as soon as it reaches its first poll. */
775
+ stop(): void;
776
+ }
777
+ /**
778
+ * Start the dispatch-and-poll loop. **Installs no signal handler** and chooses
779
+ * no exit code (APRV-110): both are the caller's, because `approval up` runs
780
+ * this beside a daemon loop and a web server under one set of handlers.
781
+ *
782
+ * A FRESH {@link DispatchState} per call, which is the whole of the restart
783
+ * story: a supervisor that restarts a fallen listener re-derives the pending
784
+ * queue from the verified log and re-sends everything still pending, exactly as
785
+ * a restarted process would. A duplicate on the phone, never a silence.
786
+ */
787
+ export declare function startListener(setup: ListenSetup, streams: Streams): RunningListener;
788
+ /**
789
+ * The listener verb. Returns a promise, which is why `main` treats `channel`
790
+ * specially: it is the only long-lived command in the CLI.
791
+ */
792
+ export declare function commandTelegramListen(argv: string[], streams: Streams, cwd: string): number | Promise<number>;
793
+ /**
794
+ * Configuration health, offline.
795
+ *
796
+ * It answers one question — "is this runtime configured to talk to Telegram?"
797
+ * — and deliberately makes no network call: a health check that contacted the
798
+ * Bot API would leak the existence of the bot from any shell, and would fail
799
+ * for reasons (a captive portal, a rate limit) that say nothing about whether
800
+ * the operator's configuration is right. The *live* counters (deliveries,
801
+ * decisions, ignored callbacks, recovered poll errors) belong to a running
802
+ * listener and are surfaced by `TelegramChannel.health()` / `stats()` in
803
+ * process, and on the listener's stderr as they happen.
804
+ */
805
+ export declare function commandTelegramHealth(argv: string[], streams: Streams, cwd: string): number;
806
+ export declare function commandTelegram(argv: string[], streams: Streams, cwd: string): number | Promise<number>;