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,849 @@
1
+ /**
2
+ * `approval up` — the ambient runtime: one process for the daemon and every
3
+ * channel the policy configures (SPEC.md §10.2/§10.3, APRV-110).
4
+ *
5
+ * Until now a working gate was two foreground processes an operator had to
6
+ * remember: `approval daemon run` to watch the files and expire what lapsed, and
7
+ * `approval channel telegram listen` to put requests in front of a human and
8
+ * collect the answer. Two terminals, two lifetimes, and a system that is half up
9
+ * whenever one of them is not. This verb runs both, plus the local queue page,
10
+ * under one supervisor, one set of signal handlers, and one event stream.
11
+ *
12
+ * **No logic lives here either.** The loop is still `daemon/daemon.ts`, the
13
+ * dispatch cycle is still `cli/channel-telegram.ts`'s `dispatchPending`, and the
14
+ * queue page is still `channel-web.ts`'s `startWebChannel` — which has said
15
+ * "exported for the tests and for the M5 daemon" since APRV-25. What this file
16
+ * adds is supervision: which parts to start, what to do when one falls over, and
17
+ * how to stop them all at once.
18
+ *
19
+ * ## Per-part crash isolation
20
+ *
21
+ * A channel is a network client and the daemon is not. A Bot API that starts
22
+ * refusing sends must not stop TTL expiry, write-back or the queue projection —
23
+ * that inversion is exactly what the split into two processes bought, and it is
24
+ * what this file has to buy back. So:
25
+ *
26
+ * - the DAEMON settles the verb. Its outcome chooses the exit code, exactly as
27
+ * `approval daemon run` maps it, and its failure stops everything;
28
+ * - a CHANNEL that falls over is reported and restarted after a doubling
29
+ * backoff, forever. There is no attempt limit for the same reason
30
+ * `dispatchPending` has no send limit: giving up would turn an outage into a
31
+ * pending request no human ever sees;
32
+ * - a channel that cannot start AT ALL — a credential the policy names is unset,
33
+ * no declared human identity — is not started, and the refusal is reported in
34
+ * `approval doctor`'s vocabulary (a `skip`, a detail, a fix). Fail closed, and
35
+ * then carry on with the parts that can run: a half-armed runtime that says
36
+ * nothing is the failure this project exists to prevent, and a runtime that
37
+ * refused to start the daemon because Telegram was unconfigured would be
38
+ * withholding the projection over a channel nobody asked for.
39
+ *
40
+ * ## The credentials come from the launch environment, and only from there
41
+ *
42
+ * SPEC.md §11.1 invariant 7: no verb loads `.approval/env` implicitly. This one
43
+ * does not either. The bot token, the chat id and the approver identity are read
44
+ * from `process.env` — the environment the operator launched this process with —
45
+ * through exactly the same resolvers the separate listener uses. `approval setup
46
+ * service` writes a unit that names those variables, or runs a wrapper that
47
+ * evaluates `approval env`, and either way a human wrote the line that does it.
48
+ *
49
+ * ## The event stream is an additive union
50
+ *
51
+ * `--json` prints one object per line, and every object is one of three kinds:
52
+ * a `DaemonEvent` verbatim, a listener line verbatim (`notified`, `decision`,
53
+ * `annotated`, `listening`, `stopped`), or one of this file's own supervision
54
+ * lines ({@link UpEvent}). Nothing is rewritten and no field is added to a shape
55
+ * that already existed: the decision object is byte-identical to the one
56
+ * `channel telegram listen` prints, because it is printed by the same function.
57
+ * That is what makes the composed test suite an assertion about equivalence
58
+ * rather than about a new format.
59
+ *
60
+ * The one shape that appears twice is `stopped`: the daemon's carries its tick
61
+ * counters and a channel's carries its delivery counters, and a supervisor that
62
+ * branches on `event` alone can tell them apart by their fields. Renaming either
63
+ * would have broken a stream an operator already parses.
64
+ *
65
+ * ## What it does not do
66
+ *
67
+ * It does not fork, write a pidfile, or manage its own lifecycle, for the reason
68
+ * `approval daemon run` gives: `launchd` and `systemd` do that better, and
69
+ * `approval setup service` is the verb that hands them the unit.
70
+ */
71
+ import { isAbsolute, resolve as resolvePathSegments } from "node:path";
72
+ import { HUMAN_ACTOR_ENV, resolveHumanActor } from "../core/attest.js";
73
+ import { instanceFindings } from "../core/instance.js";
74
+ import { loadPolicy } from "../core/policy-load.js";
75
+ import { passphraseEnvFor } from "../core/vault.js";
76
+ import { DEFAULT_DEBOUNCE_MS, DEFAULT_INTERVAL_MS, DEFAULT_TASKS_DIR, Daemon, isDirectory, } from "../daemon/daemon.js";
77
+ import { drawServerFor } from "../daemon/draw.js";
78
+ import { enableGitEvidence } from "../daemon/git-evidence.js";
79
+ import { boolFlag, parseFlags, stringFlag } from "./args.js";
80
+ import { prepareListen, startListener, } from "./channel-telegram.js";
81
+ import { payloadSource as webPayloadSource, policyWebPort, resolveWebPort, startWebChannel, } from "./channel-web.js";
82
+ import { advanceFlags, describeDaemonEvent, describeGitEvidence, durationFlag, exitForDaemonOutcome, readProofFlags, } from "./daemon.js";
83
+ import { DEFAULT_DARK_INTERVAL_MS, DEFAULT_DARK_WINDOW_MS, } from "../daemon/dark-session.js";
84
+ import { useReadProof } from "../core/state.js";
85
+ import { EXIT_INTEGRITY, EXIT_IO, EXIT_OK, EXIT_USAGE } from "./exit-codes.js";
86
+ import { glossRunnerFromOptions, parseGlossOptions } from "./gloss-options.js";
87
+ import { UP_HELP } from "./help.js";
88
+ import { DEFAULT_LOG_PATH, preflightLog, resolvePath } from "./paths.js";
89
+ import { describePreflightEvent, reexecFreshBuild, startupPreflight, } from "./preflight.js";
90
+ import { DEFAULT_QUEUE_PATH } from "./render.js";
91
+ import { skipNotice, style } from "./style.js";
92
+ import { usageErrorText } from "./usage.js";
93
+ /** The first backoff after a part falls over. Doubles to {@link UP_RESTART_MAX_MS}. */
94
+ export const UP_RESTART_BASE_MS = 1_000;
95
+ /** The ceiling the doubling stops at, so a long outage retries once a minute. */
96
+ export const UP_RESTART_MAX_MS = 60_000;
97
+ /**
98
+ * How long a part must have been running before a failure is treated as a fresh
99
+ * one rather than as the next step of a crash loop. A channel that ran for an
100
+ * hour and then hit a network blip should retry in a second, not in a minute.
101
+ */
102
+ export const UP_STABLE_MS = 60_000;
103
+ /**
104
+ * One supervision line as a human sentence, and where it belongs.
105
+ *
106
+ * `st` is injectable for the render tests, exactly as doctor's renderer takes
107
+ * one; the default asks the process, which is what the verb wants.
108
+ */
109
+ export function describeUpEvent(event, st = style()) {
110
+ switch (event.event) {
111
+ // Delegated, so `approval daemon run` and `approval up` cannot drift apart
112
+ // in the words they use for the same fact.
113
+ case "preflight":
114
+ case "preflight_warning":
115
+ return describePreflightEvent(event);
116
+ case "up_started":
117
+ return {
118
+ text: `up: ${event.parts.join(", ")} in one process against ${event.log}; ctrl-c stops all of them`,
119
+ stderr: false,
120
+ };
121
+ case "part_started":
122
+ return { text: `up: ${event.part} started — ${event.detail}`, stderr: false };
123
+ case "part_unavailable":
124
+ // Doctor's skip, not a refusal: the part is absent by configuration, and
125
+ // nothing failed (APRV-153). The JSON emit path is untouched.
126
+ return {
127
+ text: skipNotice(st, event.check, event.detail, event.fix ?? undefined),
128
+ stderr: true,
129
+ };
130
+ case "part_failed":
131
+ return {
132
+ text: `approval: the ${event.part} channel stopped (attempt ${String(event.attempt)}): ${event.message} — restarting in ${String(event.restart_in_ms)}ms; the daemon loop is unaffected`,
133
+ stderr: true,
134
+ };
135
+ case "part_restarted":
136
+ return {
137
+ text: `up: ${event.part} restarted (attempt ${String(event.attempt)}); everything still pending is re-sent`,
138
+ stderr: false,
139
+ };
140
+ case "part_stopped":
141
+ return { text: `up: ${event.part} stopped (${event.reason})`, stderr: false };
142
+ case "up_stopped":
143
+ return { text: `up: stopped (${event.reason})`, stderr: false };
144
+ }
145
+ }
146
+ // ---------------------------------------------------------------------------
147
+ // Flags
148
+ // ---------------------------------------------------------------------------
149
+ const UP_FLAGS = {
150
+ // The daemon's own, spelled identically.
151
+ "--log": "string",
152
+ "--tasks": "string",
153
+ "--out": "string",
154
+ "--policy": "string",
155
+ "--dir": "string",
156
+ "--interval": "string",
157
+ "--debounce": "string",
158
+ "--once": "boolean",
159
+ // The watcher trace (APRV-230), spelled identically to `daemon run`'s: the
160
+ // ambient runtime is the process an operator actually runs, so the diagnostic
161
+ // for what is waking it has to be reachable from this spelling too.
162
+ "--trace-watch": "boolean",
163
+ "--git-evidence": "boolean",
164
+ // The cadence advance (APRV-204), spelled identically to `daemon run`'s.
165
+ "--advance": "boolean",
166
+ "--advance-interval": "string",
167
+ "--advance-after": "string",
168
+ "--advance-remote": "string",
169
+ "--advance-base": "string",
170
+ "--no-advance-pr": "boolean",
171
+ "--no-advance-auto-merge": "boolean",
172
+ // The live draw (APRV-208), spelled identically to `daemon run`'s.
173
+ "--no-draw": "boolean",
174
+ // The dark-session sweep (APRV-192), spelled identically to `daemon run`'s.
175
+ "--dark-sessions": "boolean",
176
+ "--dark-window": "string",
177
+ "--dark-interval": "string",
178
+ // The prefix proof (APRV-217), spelled identically to `daemon run`'s.
179
+ "--read-proof": "string",
180
+ "--full-reproof-every": "string",
181
+ "--full-reproof-after": "string",
182
+ // The channels'.
183
+ "--as": "string",
184
+ "--payloads": "string",
185
+ "--payload-dir": "string",
186
+ "--api-base": "string",
187
+ "--poll-timeout": "string",
188
+ "--port": "string",
189
+ "--no-telegram": "boolean",
190
+ "--no-web": "boolean",
191
+ "--gloss": "boolean",
192
+ "--no-gloss": "boolean",
193
+ "--gloss-provider": "string",
194
+ "--gloss-model": "string",
195
+ // The supervisor's.
196
+ "--restart-backoff": "string",
197
+ // The startup preflight (APRV-215).
198
+ "--no-preflight": "boolean",
199
+ "--preflight-remote": "string",
200
+ "--preflight-base": "string",
201
+ // The rebuild half of it, alone (APRV-301): fetch and fast-forward as usual,
202
+ // but leave a stale `dist/` where it is. The preflight then says so on stderr
203
+ // and reports `"action":"build-skipped"`, because starting on a build older
204
+ // than the sources is a thing an operator may mean and must never be told is
205
+ // fine.
206
+ "--no-build": "boolean",
207
+ // Test-only, spelled exactly as doctor's: retarget the build-freshness half of
208
+ // the preflight at a fixture tree. It moves nothing else, and a wrong value
209
+ // can only make the rebuild decision wrong — never the fast-forward.
210
+ "--root": "string",
211
+ "--json": "boolean",
212
+ "--help": "boolean",
213
+ "-h": "boolean",
214
+ };
215
+ function absolute(value, cwd) {
216
+ return isAbsolute(value) ? value : resolvePathSegments(cwd, value);
217
+ }
218
+ function usageError(streams, json, message) {
219
+ if (json)
220
+ streams.err(`${JSON.stringify({ error: { code: "usage", message } })}\n`);
221
+ else
222
+ streams.err(usageErrorText(message, UP_HELP));
223
+ return EXIT_USAGE;
224
+ }
225
+ function ioError(streams, json, message) {
226
+ if (json)
227
+ streams.err(`${JSON.stringify({ error: { code: "io", message } })}\n`);
228
+ else
229
+ streams.err(`approval: ${message}\n`);
230
+ return EXIT_IO;
231
+ }
232
+ // ---------------------------------------------------------------------------
233
+ // A cancellable wait
234
+ // ---------------------------------------------------------------------------
235
+ /**
236
+ * A backoff that a shutdown can cut short.
237
+ *
238
+ * Without this, SIGTERM during a sixty-second restart wait would be a minute of
239
+ * a process that has been asked to stop still being alive, which is exactly the
240
+ * behaviour an operator reads as "it hung".
241
+ */
242
+ class Wait {
243
+ timer = null;
244
+ settle = null;
245
+ for(ms) {
246
+ return new Promise((resolve) => {
247
+ this.settle = resolve;
248
+ this.timer = setTimeout(() => {
249
+ this.timer = null;
250
+ this.settle = null;
251
+ resolve();
252
+ }, ms);
253
+ });
254
+ }
255
+ cancel() {
256
+ if (this.timer !== null)
257
+ clearTimeout(this.timer);
258
+ this.timer = null;
259
+ const settle = this.settle;
260
+ this.settle = null;
261
+ if (settle !== null)
262
+ settle();
263
+ }
264
+ }
265
+ // ---------------------------------------------------------------------------
266
+ // The verb
267
+ // ---------------------------------------------------------------------------
268
+ /**
269
+ * `approval up` (and `approval daemon run --with-channels`, which is the same
270
+ * function reached from the other spelling).
271
+ */
272
+ export function commandUp(argv, streams, cwd) {
273
+ const json = argv.includes("--json");
274
+ const parsed = parseFlags(argv, UP_FLAGS);
275
+ if (!parsed.ok)
276
+ return usageError(streams, json, parsed.message);
277
+ if (boolFlag(parsed.flags, "--help") || boolFlag(parsed.flags, "-h")) {
278
+ streams.out(`${UP_HELP}\n`);
279
+ return EXIT_OK;
280
+ }
281
+ const extra = parsed.positionals[0];
282
+ if (extra !== undefined) {
283
+ return usageError(streams, json, `unexpected argument ${JSON.stringify(extra)}`);
284
+ }
285
+ const flags = parsed.flags;
286
+ const selectedGloss = parseGlossOptions(flags, true);
287
+ if (!selectedGloss.ok)
288
+ return usageError(streams, json, selectedGloss.message);
289
+ const interval = durationFlag(flags, "--interval", DEFAULT_INTERVAL_MS);
290
+ if (!interval.ok)
291
+ return usageError(streams, json, interval.message);
292
+ const debounce = durationFlag(flags, "--debounce", DEFAULT_DEBOUNCE_MS);
293
+ if (!debounce.ok)
294
+ return usageError(streams, json, debounce.message);
295
+ const backoff = durationFlag(flags, "--restart-backoff", UP_RESTART_BASE_MS);
296
+ if (!backoff.ok)
297
+ return usageError(streams, json, backoff.message);
298
+ const logPath = resolvePath(stringFlag(flags, "--log"), DEFAULT_LOG_PATH, cwd);
299
+ const queuePath = resolvePath(stringFlag(flags, "--out"), DEFAULT_QUEUE_PATH, cwd);
300
+ const tasksFlag = stringFlag(flags, "--tasks");
301
+ const tasksDir = resolvePath(tasksFlag, DEFAULT_TASKS_DIR, cwd);
302
+ // -------------------------------------------------------------------------
303
+ // The startup preflight (APRV-215)
304
+ // -------------------------------------------------------------------------
305
+ //
306
+ // First, before the log is even opened, because its whole subject is which
307
+ // code and which log this process is about to run against. It reads git, and
308
+ // at most fast-forwards, rebuilds, and clears an untracked `backlog/tasks/`
309
+ // file the incoming commit already contains out of the merge's way
310
+ // (APRV-300); it never resets, never stashes, and never touches the working
311
+ // log. A refusal exits without starting anything.
312
+ //
313
+ // `--json` emission goes through the same `UpEvent` union as everything else,
314
+ // so the stream stays one union of additive shapes. The refusal does NOT: it
315
+ // is an error object on stderr like every other refusal in this file, plus
316
+ // the facts, so a machine caller can branch on the code without parsing a
317
+ // runbook.
318
+ if (!boolFlag(flags, "--no-preflight")) {
319
+ const rootFlag = stringFlag(flags, "--root");
320
+ const cleared = startupPreflight({
321
+ logPath,
322
+ queuePath,
323
+ root: rootFlag === null ? null : absolute(rootFlag, cwd),
324
+ remote: stringFlag(flags, "--preflight-remote"),
325
+ branch: stringFlag(flags, "--preflight-base"),
326
+ build: !boolFlag(flags, "--no-build"),
327
+ json,
328
+ emit: (event) => {
329
+ if (json) {
330
+ const line = `${JSON.stringify(event)}\n`;
331
+ if (event.event === "preflight_warning")
332
+ streams.err(line);
333
+ else
334
+ streams.out(line);
335
+ return;
336
+ }
337
+ const rendered = describePreflightEvent(event);
338
+ if (rendered.stderr)
339
+ streams.err(`${rendered.text}\n`);
340
+ else
341
+ streams.out(`${rendered.text}\n`);
342
+ },
343
+ refuse: (text) => streams.err(text),
344
+ });
345
+ // Exit 1, "the runtime decided", rather than 4: nothing failed to read or
346
+ // write, and a supervisor that read this as an I/O fault would retry a
347
+ // checkout state only a human can resolve.
348
+ if (!cleared.ok)
349
+ return EXIT_INTEGRITY;
350
+ // A rebuild happened, so THIS process is the stale build the preflight just
351
+ // replaced: Node loaded it at startup and no amount of new bytes on disk
352
+ // changes that. Carrying on here would start the writer on exactly the code
353
+ // the operator was trying to leave behind, which is the defect this
354
+ // preflight exists to remove. Become the fresh build, and exit as it exits.
355
+ if (cleared.reexec !== null)
356
+ return reexecFreshBuild(cleared.reexec, cwd);
357
+ }
358
+ const check = preflightLog(logPath);
359
+ if (!check.ok)
360
+ return ioError(streams, json, check.message);
361
+ // Same judgment `approval daemon run` makes: an explicitly named task folder
362
+ // that does not exist is a typo, and the default folder's absence is a
363
+ // legitimate log-only deployment that is warned about rather than refused.
364
+ if (!isDirectory(tasksDir)) {
365
+ if (tasksFlag !== null) {
366
+ return ioError(streams, json, `--tasks ${tasksDir} is not a directory; nothing would be watched for envelope drift`);
367
+ }
368
+ streams.err(`approval: task folder ${tasksDir} does not exist, so no envelope drift can be detected; the TTL sweep and the queue projection run anyway (pass --tasks <dir> if your task files live elsewhere)\n`);
369
+ }
370
+ const policyFlag = stringFlag(flags, "--policy");
371
+ const dirFlag = stringFlag(flags, "--dir");
372
+ const policy = policyFlag !== null
373
+ ? { file: absolute(policyFlag, cwd) }
374
+ : { dir: dirFlag === null ? cwd : absolute(dirFlag, cwd) };
375
+ const load = loadPolicy(policy);
376
+ const once = boolFlag(flags, "--once");
377
+ const emit = (event) => {
378
+ if (json) {
379
+ const line = `${JSON.stringify(event)}\n`;
380
+ if (event.event === "part_unavailable" || event.event === "part_failed")
381
+ streams.err(line);
382
+ else
383
+ streams.out(line);
384
+ return;
385
+ }
386
+ const rendered = describeUpEvent(event);
387
+ if (rendered.stderr)
388
+ streams.err(`${rendered.text}\n`);
389
+ else
390
+ streams.out(`${rendered.text}\n`);
391
+ };
392
+ // -------------------------------------------------------------------------
393
+ // Which parts can run
394
+ // -------------------------------------------------------------------------
395
+ const wantTelegram = !boolFlag(flags, "--no-telegram");
396
+ const wantWeb = !boolFlag(flags, "--no-web");
397
+ const portFlag = stringFlag(flags, "--port");
398
+ const payloadsFlag = stringFlag(flags, "--payloads");
399
+ const payloadDirFlag = stringFlag(flags, "--payload-dir");
400
+ const asFlag = stringFlag(flags, "--as");
401
+ /** Deferred so nothing is printed before the daemon's own `started` line. */
402
+ const unavailable = [];
403
+ const parts = ["daemon"];
404
+ let telegram = null;
405
+ if (wantTelegram) {
406
+ const gloss = glossRunnerFromOptions(selectedGloss.options, {
407
+ passphraseEnv: passphraseEnvFor(load),
408
+ diagnostic: (reason) => streams.err(`approval: Codex gloss unavailable (${reason}); continuing without it\n`),
409
+ });
410
+ const prepared = prepareListen({
411
+ logPath,
412
+ policy,
413
+ as: asFlag,
414
+ payloads: payloadsFlag === null ? null : absolute(payloadsFlag, cwd),
415
+ apiBase: stringFlag(flags, "--api-base"),
416
+ pollTimeout: stringFlag(flags, "--poll-timeout"),
417
+ once,
418
+ json,
419
+ log: (message) => streams.err(`${message}\n`),
420
+ // APRV-197: on by default, `--no-gloss` to turn it off, exactly as on
421
+ // `channel telegram listen` — this IS that listener, and a flag that
422
+ // meant different things on the two verbs that start it would be a trap.
423
+ // The reasoning is at `glossWiring` there.
424
+ //
425
+ // APRV-207: the subprocess is spawned starved, and the policy already
426
+ // loaded above names the passphrase variable the scrub must remove.
427
+ ...(gloss === undefined ? {} : { gloss }),
428
+ });
429
+ if (prepared.ok) {
430
+ telegram = prepared.setup;
431
+ parts.push("telegram");
432
+ // APRV-178. The channel's credentials come from the launch environment
433
+ // and only from there, which is invariant 7 and stays true — but an
434
+ // exported value that this instance's own `.approval/env` disagrees with
435
+ // is how a demo gate spent an evening sending through the production bot.
436
+ // Said once, on stderr, before anything starts: a long-running process
437
+ // that is quietly holding another instance's bot token should say so at
438
+ // the moment it picks it up, not in a postmortem. It is a warning and not
439
+ // a refusal, because an operator who feeds the primary daemon from a
440
+ // shell profile is doing something deliberate and supported.
441
+ for (const finding of instanceFindings(logPath, load)) {
442
+ streams.err(`approval: cross-instance: ${finding.detail}\n`);
443
+ }
444
+ }
445
+ else if (prepared.code === "poll-timeout" || prepared.code === "payloads-unreadable") {
446
+ // A mistyped command line, not an unconfigured machine. Refused here, the
447
+ // way every verb refuses one, rather than degraded into a missing channel
448
+ // an operator would have to notice in a log.
449
+ return prepared.code === "poll-timeout"
450
+ ? usageError(streams, json, prepared.message)
451
+ : ioError(streams, json, prepared.message);
452
+ }
453
+ else {
454
+ unavailable.push({
455
+ event: "part_unavailable",
456
+ part: "telegram",
457
+ check: "telegram",
458
+ status: "skip",
459
+ detail: prepared.message,
460
+ fix: prepared.code === "no-identity"
461
+ ? `approval setup identity — declare who the human is, then evaluate \`approval env\` in the environment this process is launched from (or export ${HUMAN_ACTOR_ENV} there yourself)`
462
+ : "approval setup channel telegram — store the bot token and discover the approver chat, then evaluate `approval env` in the environment this process is launched from",
463
+ });
464
+ }
465
+ }
466
+ const webPort = resolveWebPort(portFlag, policyWebPort(load));
467
+ if (!webPort.ok)
468
+ return usageError(streams, json, webPort.message);
469
+ const webActor = resolveHumanActor(asFlag === null ? {} : { actor: asFlag });
470
+ const webDeclared = portFlag !== null || policyWebPort(load) !== null;
471
+ let web = null;
472
+ if (wantWeb) {
473
+ if (once) {
474
+ // `--once` is one daemon tick and one poll cycle. A pull channel has no
475
+ // cycle: its page is fetched when a human chooses to look, which is why
476
+ // `approval channel web` has no `--once` either.
477
+ unavailable.push({
478
+ event: "part_unavailable",
479
+ part: "web",
480
+ check: "web-port",
481
+ status: "skip",
482
+ detail: "--once runs one daemon tick and one poll cycle, and the queue page is a pull channel with no cycle to run, so it is not served",
483
+ fix: null,
484
+ });
485
+ }
486
+ else if (!webDeclared) {
487
+ unavailable.push({
488
+ event: "part_unavailable",
489
+ part: "web",
490
+ check: "web-port",
491
+ status: "skip",
492
+ detail: "this policy declares no channels.web.port, so no queue page is served — which is a legitimate configuration and not a fault",
493
+ fix: "pass --port <n> to serve it for this run, or add channels.web.port to APPROVAL.md via approval policy amend (an edited policy is inoperative until it is re-attested)",
494
+ });
495
+ }
496
+ else if (webActor === null) {
497
+ unavailable.push({
498
+ event: "part_unavailable",
499
+ part: "web",
500
+ check: "web-port",
501
+ status: "skip",
502
+ detail: `no human identity: the queue page collects decisions and every one is recorded against ${HUMAN_ACTOR_ENV}, so a page whose buttons could record nothing is not served`,
503
+ fix: `approval setup identity — declare who the human is, then evaluate \`approval env\` in the environment this process is launched from (or export ${HUMAN_ACTOR_ENV} there yourself)`,
504
+ });
505
+ }
506
+ else {
507
+ web = { port: webPort.port, actor: webActor };
508
+ parts.push("web");
509
+ }
510
+ }
511
+ // -------------------------------------------------------------------------
512
+ // The daemon
513
+ // -------------------------------------------------------------------------
514
+ const options = {
515
+ logPath,
516
+ tasksDir,
517
+ queuePath,
518
+ policy,
519
+ cwd,
520
+ intervalMs: interval.ms,
521
+ debounceMs: debounce.ms,
522
+ once,
523
+ traceWatch: boolFlag(flags, "--trace-watch"),
524
+ sink: {
525
+ emit: (event) => {
526
+ if (json) {
527
+ const line = `${JSON.stringify(event)}\n`;
528
+ if (event.event === "warning")
529
+ streams.err(line);
530
+ else
531
+ streams.out(line);
532
+ return;
533
+ }
534
+ const rendered = describeDaemonEvent(event);
535
+ if (rendered.stderr)
536
+ streams.err(`${rendered.text}\n`);
537
+ else
538
+ streams.out(`${rendered.text}\n`);
539
+ },
540
+ },
541
+ };
542
+ // The cadence advance (APRV-204), parsed by `daemon run`'s own function so a
543
+ // typo is refused in the same words on both spellings of this verb.
544
+ const cadence = advanceFlags(flags);
545
+ if (!cadence.ok)
546
+ return usageError(streams, json, cadence.message);
547
+ if (cadence.cadence !== null)
548
+ options.advance = cadence.cadence;
549
+ // The dark-session sweep (APRV-192), parsed by the same duration function for
550
+ // the same reason: one typo, one sentence, on both spellings of this verb.
551
+ const darkWindow = durationFlag(flags, "--dark-window", DEFAULT_DARK_WINDOW_MS);
552
+ if (!darkWindow.ok)
553
+ return usageError(streams, json, darkWindow.message);
554
+ const darkInterval = durationFlag(flags, "--dark-interval", DEFAULT_DARK_INTERVAL_MS);
555
+ if (!darkInterval.ok)
556
+ return usageError(streams, json, darkInterval.message);
557
+ if (boolFlag(flags, "--dark-sessions")) {
558
+ options.darkSessions = { windowMs: darkWindow.ms, intervalMs: darkInterval.ms };
559
+ }
560
+ // The prefix proof (APRV-217), parsed by `daemon run`'s own function so the
561
+ // flag beats the policy identically on both spellings of this verb.
562
+ const proof = readProofFlags(flags, policy);
563
+ if (!proof.ok)
564
+ return usageError(streams, json, proof.message);
565
+ options.readProof = proof.readProof;
566
+ // Process-wide too, for the reason `daemon run` sets it: the channels and the
567
+ // queue renderer in this process read the same log through paths that thread
568
+ // no options of their own.
569
+ useReadProof(proof.readProof);
570
+ // SPEC.md §8's optional git hardening, judged before the first tick exactly as
571
+ // `daemon run` judges it: an operator who asked for a second evidence layer and
572
+ // silently did not get one is worse off than one who was refused at startup.
573
+ if (boolFlag(flags, "--git-evidence")) {
574
+ const enabled = enableGitEvidence(logPath, (event) => {
575
+ if (json) {
576
+ const line = `${JSON.stringify(event)}\n`;
577
+ if (event.event === "git_evidence_failed")
578
+ streams.err(line);
579
+ else
580
+ streams.out(line);
581
+ return;
582
+ }
583
+ const rendered = describeGitEvidence(event);
584
+ if (rendered.stderr)
585
+ streams.err(`${rendered.text}\n`);
586
+ else
587
+ streams.out(`${rendered.text}\n`);
588
+ });
589
+ if (!enabled.ok) {
590
+ if (json) {
591
+ streams.err(`${JSON.stringify({ error: { code: enabled.code, message: enabled.message } })}\n`);
592
+ }
593
+ else {
594
+ streams.err(`approval: ${enabled.message}\n`);
595
+ }
596
+ return enabled.code === "git-unavailable" || enabled.code === "log-dir-missing"
597
+ ? EXIT_IO
598
+ : EXIT_USAGE;
599
+ }
600
+ options.gitEvidence = enabled.recorder;
601
+ }
602
+ // APRV-208. `approval up` is the ambient runtime an operator actually leaves
603
+ // running, so in practice it is the process that serves live draws. Same rule
604
+ // as `approval daemon run`: attempted when the sampling secret resolves in
605
+ // this process's environment, skipped with a line when it does not.
606
+ if (!boolFlag(flags, "--no-draw")) {
607
+ const draw = drawServerFor({ logPath, policy });
608
+ if (draw.ok)
609
+ options.draw = draw.server;
610
+ // Silent on `no-live-class`, for the reason `approval daemon run` states:
611
+ // a policy that declares nothing live has nothing to be told about.
612
+ else if (draw.reason !== "no-live-class") {
613
+ streams.err(`approval: live draws will not be served (${draw.reason}): ${draw.message} Every supervised-live action gates to a human until the sampling secret resolves in this process's own environment.\n`);
614
+ }
615
+ }
616
+ emit({ event: "up_started", parts, log: logPath });
617
+ for (const event of unavailable)
618
+ emit(event);
619
+ const daemon = new Daemon(options);
620
+ // -------------------------------------------------------------------------
621
+ // Supervision
622
+ // -------------------------------------------------------------------------
623
+ let shuttingDown = false;
624
+ let stopReason = "once";
625
+ let listener = null;
626
+ /** Set while a web server is up: resolving it lets that part close and return. */
627
+ let stopWeb = null;
628
+ const waits = new Set();
629
+ /** Wait, unless a shutdown has already begun or begins while waiting. */
630
+ const pause = async (ms) => {
631
+ const wait = new Wait();
632
+ waits.add(wait);
633
+ try {
634
+ if (shuttingDown)
635
+ return;
636
+ await wait.for(ms);
637
+ }
638
+ finally {
639
+ waits.delete(wait);
640
+ }
641
+ };
642
+ const telegramPart = async (setup) => {
643
+ // `detail` is optional on the contract, and a health report that declines to
644
+ // elaborate is not a fault. The fallback keeps `part_started` a fixed shape.
645
+ emit({
646
+ event: "part_started",
647
+ part: "telegram",
648
+ detail: setup.channel.health().detail ?? "configured",
649
+ });
650
+ let attempts = 0;
651
+ for (;;) {
652
+ const startedAt = Date.now();
653
+ const running = startListener(setup, streams);
654
+ listener = running;
655
+ let message;
656
+ try {
657
+ const outcome = await running.done;
658
+ if (outcome.kind === "stopped") {
659
+ emit({
660
+ event: "part_stopped",
661
+ part: "telegram",
662
+ reason: shuttingDown ? stopReason : setup.once ? "once" : "listener stopped",
663
+ });
664
+ return;
665
+ }
666
+ message =
667
+ outcome.kind === "send-failed"
668
+ ? `telegram sendMessage failed: ${outcome.message}`
669
+ : `the pending queue could not be derived (${outcome.code}): ${outcome.message}`;
670
+ }
671
+ catch (cause) {
672
+ message = cause instanceof Error ? cause.message : String(cause);
673
+ }
674
+ finally {
675
+ listener = null;
676
+ }
677
+ if (shuttingDown || setup.once) {
678
+ emit({
679
+ event: "part_stopped",
680
+ part: "telegram",
681
+ reason: shuttingDown ? stopReason : "once",
682
+ });
683
+ return;
684
+ }
685
+ // A part that ran for a while and then fell over is a fresh failure, not
686
+ // the next rung of a crash loop.
687
+ attempts = Date.now() - startedAt >= UP_STABLE_MS ? 1 : attempts + 1;
688
+ const delay = Math.min(backoff.ms * 2 ** (attempts - 1), UP_RESTART_MAX_MS);
689
+ emit({
690
+ event: "part_failed",
691
+ part: "telegram",
692
+ attempt: attempts,
693
+ message,
694
+ restart_in_ms: delay,
695
+ });
696
+ await pause(delay);
697
+ if (shuttingDown) {
698
+ emit({ event: "part_stopped", part: "telegram", reason: stopReason });
699
+ return;
700
+ }
701
+ emit({ event: "part_restarted", part: "telegram", attempt: attempts });
702
+ }
703
+ };
704
+ const webPart = async (settings) => {
705
+ let attempts = 0;
706
+ for (;;) {
707
+ let running;
708
+ try {
709
+ running = await startWebChannel({
710
+ logPath,
711
+ actor: settings.actor,
712
+ policy,
713
+ port: settings.port,
714
+ ...(payloadDirFlag === null
715
+ ? {}
716
+ : {
717
+ payload: webPayloadSource(absolute(payloadDirFlag, cwd), (message) => streams.err(`${message}\n`)),
718
+ }),
719
+ log: (message) => streams.err(`${message}\n`),
720
+ });
721
+ }
722
+ catch (cause) {
723
+ if (shuttingDown)
724
+ return;
725
+ attempts += 1;
726
+ const delay = Math.min(backoff.ms * 2 ** (attempts - 1), UP_RESTART_MAX_MS);
727
+ emit({
728
+ event: "part_failed",
729
+ part: "web",
730
+ attempt: attempts,
731
+ message: `the web channel could not bind 127.0.0.1:${String(settings.port)}: ${cause instanceof Error ? cause.message : String(cause)}`,
732
+ restart_in_ms: delay,
733
+ });
734
+ await pause(delay);
735
+ if (shuttingDown) {
736
+ emit({ event: "part_stopped", part: "web", reason: stopReason });
737
+ return;
738
+ }
739
+ emit({ event: "part_restarted", part: "web", attempt: attempts });
740
+ continue;
741
+ }
742
+ const url = `http://127.0.0.1:${String(running.port)}/`;
743
+ emit({
744
+ event: "part_started",
745
+ part: "web",
746
+ detail: `the pending queue is at ${url} (loopback only, NO authentication: anyone with access to this machine can decide as ${settings.actor})`,
747
+ });
748
+ // `channel web`'s own startup line, verbatim, so a supervisor already
749
+ // parsing that stream reads the same object out of this one.
750
+ if (json) {
751
+ streams.out(`${JSON.stringify({
752
+ event: "listening",
753
+ channel: "web",
754
+ url,
755
+ host: "127.0.0.1",
756
+ port: running.port,
757
+ actor: settings.actor,
758
+ })}\n`);
759
+ }
760
+ // The server outlives this await only through a shutdown or its own
761
+ // error: an HTTP server that is listening does not stop on its own.
762
+ const failure = await new Promise((resolve) => {
763
+ const onError = (cause) => resolve(cause);
764
+ running.server.once("error", onError);
765
+ const settle = () => {
766
+ running.server.off("error", onError);
767
+ resolve(null);
768
+ };
769
+ if (shuttingDown)
770
+ settle();
771
+ else
772
+ stopWeb = settle;
773
+ });
774
+ stopWeb = null;
775
+ if (failure === null || shuttingDown) {
776
+ if (json)
777
+ streams.out(`${JSON.stringify({ event: "stopped", ...running.channel.stats() })}\n`);
778
+ emit({ event: "part_stopped", part: "web", reason: shuttingDown ? stopReason : "closed" });
779
+ await running.close().catch(() => undefined);
780
+ return;
781
+ }
782
+ await running.close().catch(() => undefined);
783
+ attempts += 1;
784
+ const delay = Math.min(backoff.ms * 2 ** (attempts - 1), UP_RESTART_MAX_MS);
785
+ emit({
786
+ event: "part_failed",
787
+ part: "web",
788
+ attempt: attempts,
789
+ message: failure.message,
790
+ restart_in_ms: delay,
791
+ });
792
+ await pause(delay);
793
+ if (shuttingDown) {
794
+ emit({ event: "part_stopped", part: "web", reason: stopReason });
795
+ return;
796
+ }
797
+ emit({ event: "part_restarted", part: "web", attempt: attempts });
798
+ }
799
+ };
800
+ const stopAll = (reason) => {
801
+ if (shuttingDown)
802
+ return;
803
+ shuttingDown = true;
804
+ stopReason = reason;
805
+ daemon.stop(reason);
806
+ listener?.stop();
807
+ stopWeb?.();
808
+ for (const wait of waits)
809
+ wait.cancel();
810
+ };
811
+ const onSignal = (signal) => stopAll(signal);
812
+ process.on("SIGINT", onSignal);
813
+ process.on("SIGTERM", onSignal);
814
+ const channelParts = [];
815
+ if (telegram !== null)
816
+ channelParts.push(telegramPart(telegram));
817
+ if (web !== null)
818
+ channelParts.push(webPart(web));
819
+ return daemon
820
+ .run()
821
+ .then(async (outcome) => {
822
+ // `--once` is one tick AND one poll cycle: the daemon's tick finishes in
823
+ // milliseconds and the channel's poll takes as long as the long poll does,
824
+ // so the fast part waits for the slow one rather than cutting it short.
825
+ if (once && outcome.kind === "stopped")
826
+ await Promise.all(channelParts);
827
+ // The daemon settles the verb. A failure of ITS OWN — an unreadable log, a
828
+ // torn tail, a chain that does not verify — stops the channels too: a
829
+ // queue page and a chat prompt derived from a log nobody could verify
830
+ // would be a statement to a human about facts the runtime disowns.
831
+ stopAll(outcome.kind === "stopped" ? outcome.reason : outcome.kind);
832
+ await Promise.all(channelParts);
833
+ emit({ event: "up_stopped", reason: stopReason });
834
+ if (outcome.kind !== "stopped") {
835
+ if (json) {
836
+ streams.err(`${JSON.stringify({ error: { code: outcome.kind, message: outcome.message } })}\n`);
837
+ }
838
+ else {
839
+ streams.err(`approval: ${outcome.message}\n`);
840
+ }
841
+ }
842
+ return exitForDaemonOutcome(outcome);
843
+ })
844
+ .finally(() => {
845
+ process.off("SIGINT", onSignal);
846
+ process.off("SIGTERM", onSignal);
847
+ });
848
+ }
849
+ //# sourceMappingURL=up.js.map