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,723 @@
1
+ /**
2
+ * The runtime-side tagger: log + policy in, render-ready request out
3
+ * (SPEC.md §9, §10.3, §10.4).
4
+ *
5
+ * This is the only place a {@link ChannelRequest} is built, and it is on the
6
+ * runtime side of the boundary on purpose. Every `computed` field here is
7
+ * derived by the same modules the gate itself uses — `core/state.ts` for the
8
+ * verified read and the approval derivation, `core/policy-match.ts` /
9
+ * `policy-explain.ts` for autonomy, `core/budgets.ts` for the verdicts,
10
+ * `core/attest.ts` for the attestation status, `core/payload.ts` for the
11
+ * content binding — so what a channel displays as "computed" is the same answer
12
+ * the gate would give, not a second implementation that could disagree with it.
13
+ * Every `claimed` field is copied out of a log record and stamped with the actor
14
+ * who authored that record.
15
+ *
16
+ * ## Why this takes a log *path*, not records
17
+ *
18
+ * SPEC.md §11.1(1): enforcement paths read only verified records. A channel
19
+ * request is what a human's decision is made from, so it is an enforcement
20
+ * surface in the sense that matters — a request built from a spliced log would
21
+ * put a fabricated action in front of an approver. Accepting an
22
+ * `EventRecord[]` would let a caller hand over anything; taking the path and
23
+ * calling {@link readVerifiedRecords} here means the chain is walked, the hashes
24
+ * recomputed and the schemas checked before a single field is tagged, and a log
25
+ * that does not verify produces a refusal rather than a queue entry.
26
+ *
27
+ * ## Where the full payload comes from — flagged for human review
28
+ *
29
+ * v0.1's log records a `payload_hash`, never the payload bytes: the binding is
30
+ * a commitment, and putting the bytes in an append-only log would make every
31
+ * approved payload permanent and world-readable to anyone with the log. So the
32
+ * material to render comes from the payload store beside the log
33
+ * (`core/payload-store.ts`, APRV-28), or from a caller-supplied override
34
+ * ({@link TagOptions.payload}) where an operator holds the bytes somewhere else,
35
+ * and this module **verifies it against the recorded hash** before tagging it
36
+ * `computed` — material that does not hash to the bound value is refused
37
+ * `payload-mismatch` and never reaches a channel. That verification is what
38
+ * makes `fullPayload` a computed field rather than one more agent claim, and it
39
+ * is the same check `core/token.ts` makes at spend time.
40
+ *
41
+ * Determinism: no clock. `now` is a parameter, so a queue rendering is
42
+ * replayable exactly as it was rendered.
43
+ */
44
+ import { createHash } from "node:crypto";
45
+ import { existsSync } from "node:fs";
46
+ import { join } from "node:path";
47
+ import { checkAttestation, policyFileHash, } from "../core/attest.js";
48
+ import { evaluateBudgetsWithTask, } from "../core/budgets.js";
49
+ import { usdNumber } from "../core/money.js";
50
+ import { payloadHash } from "../core/payload.js";
51
+ import { loadPayload, payloadStoreDirFor } from "../core/payload-store.js";
52
+ import { explain } from "../core/policy-explain.js";
53
+ import { loadPolicy, POLICY_FILENAMES, } from "../core/policy-load.js";
54
+ import { resolve } from "../core/policy-match.js";
55
+ import { ATTESTATION_CLASS, isAttestationActionKey, openProposals, } from "../core/policy-proposal.js";
56
+ import { isRecipientKey, RECIPIENT_KEY_FIELD } from "../core/seal.js";
57
+ import { payloadOf, readVerifiedRecords, requestState, } from "../core/state.js";
58
+ import { claimed, computed, createChannelRequest, } from "./contract.js";
59
+ import { commandBreakdown, commandPayloadView, protectedPathView } from "./payload-view.js";
60
+ /** Why the tagger refused. Frozen per SPEC.md §11.1(6). */
61
+ export const CHANNEL_TAG_REFUSAL_CODES = [
62
+ /** The log could not be opened. */
63
+ "log-unreadable",
64
+ /** The log's final line is unterminated (a crashed write). */
65
+ "log-torn-tail",
66
+ /** The chain does not verify; nothing may be rendered from it. */
67
+ "log-corrupt",
68
+ /** No `approval.requested` record for this action key. */
69
+ "not-requested",
70
+ /** There is a request, but it is decided or expired — nothing to approve. */
71
+ "not-awaiting",
72
+ /** The request carries no usable `payload.class`; policy cannot be resolved. */
73
+ "class-missing",
74
+ /** The request carries no `payload_hash`; there is no binding to display. */
75
+ "payload-hash-missing",
76
+ /** No payload material was supplied for a manual request (§10.4). */
77
+ "payload-unavailable",
78
+ /** The supplied material does not hash to the bound `payload_hash`. */
79
+ "payload-mismatch",
80
+ /** The supplied material cannot be canonicalized (a cycle, a NaN, …). */
81
+ "payload-unrenderable",
82
+ /** {@link createChannelRequest} refused the assembled request. */
83
+ "request-invalid",
84
+ /**
85
+ * An attestation prompt's policy bytes are no longer the bytes on disk
86
+ * (APRV-109).
87
+ *
88
+ * Skipped rather than rendered: the hash, the diff and the advisory the
89
+ * proposal recorded all describe a file that has since changed, and a prompt
90
+ * showing them would ask a human to sign for bytes nobody is holding. The
91
+ * repair is to propose the amendment again, which re-derives all three from
92
+ * the file as it now stands.
93
+ */
94
+ "proposal-stale",
95
+ ];
96
+ function refuse(code, message) {
97
+ return { ok: false, code, message };
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Policy plumbing (mirrors `core/gate.ts`, deliberately)
101
+ // ---------------------------------------------------------------------------
102
+ /**
103
+ * The policy file that will be hashed for attestation.
104
+ *
105
+ * Same discovery order as `core/gate.ts` and `loadPolicy`, so the file the
106
+ * channel reports as attested is the file the gate will enforce. Duplicated
107
+ * rather than imported because the gate's copy is private; the alternative —
108
+ * widening the gate's API for a display path — trades a nine-line function for
109
+ * a new public surface on the module that decides things.
110
+ */
111
+ function policyPathOf(options) {
112
+ const policy = options.policy ?? {};
113
+ if (policy.file !== undefined)
114
+ return policy.file;
115
+ const dir = policy.dir ?? process.cwd();
116
+ for (const filename of POLICY_FILENAMES) {
117
+ const candidate = join(dir, filename);
118
+ if (existsSync(candidate))
119
+ return candidate;
120
+ }
121
+ return join(dir, POLICY_FILENAMES[0] ?? "APPROVAL.md");
122
+ }
123
+ function loadOptionsOf(options) {
124
+ const policy = options.policy ?? {};
125
+ const load = {};
126
+ if (policy.file !== undefined)
127
+ load.file = policy.file;
128
+ else
129
+ load.dir = policy.dir ?? process.cwd();
130
+ if (options.schemaDir !== undefined)
131
+ load.schemaDir = options.schemaDir;
132
+ return load;
133
+ }
134
+ function budgetScopeOf(load, resolution) {
135
+ return {
136
+ classLimits: resolution.limits,
137
+ classPattern: resolution.matched === null ? null : resolution.matched.pattern,
138
+ globalBudgets: load.ok ? load.policy.budgets ?? null : null,
139
+ };
140
+ }
141
+ function ttlOf(load) {
142
+ return load.ok ? load.durations.approvalTtlMs : null;
143
+ }
144
+ // ---------------------------------------------------------------------------
145
+ // Log lookups
146
+ // ---------------------------------------------------------------------------
147
+ /** The `approval.requested` record at `seq`, or `null`. */
148
+ function recordAt(records, seq) {
149
+ if (seq === null)
150
+ return null;
151
+ for (const record of records) {
152
+ if (record.seq === seq)
153
+ return record;
154
+ }
155
+ return null;
156
+ }
157
+ /**
158
+ * The latest `task.registered` payload for `task`, or `{}`.
159
+ *
160
+ * Read for `route.rationale` / `route.confidence` only. v0.1's `register`
161
+ * copies `actions`, `state` and `budget` onto the record and *not* `route`, so
162
+ * these are usually absent — the fields are wired anyway, tagged claimed with
163
+ * the registering actor, so a log that carries them (a later register, an
164
+ * imported log) renders them on the correct side of the boundary rather than
165
+ * being quietly dropped or, worse, shown as fact.
166
+ */
167
+ function registrationOf(records, task) {
168
+ if (task === null)
169
+ return null;
170
+ let found = null;
171
+ for (const record of records) {
172
+ if (record.event === "task.registered" && record.task === task)
173
+ found = record;
174
+ }
175
+ return found;
176
+ }
177
+ function routeOf(registration) {
178
+ if (registration === null)
179
+ return {};
180
+ const route = payloadOf(registration)["route"];
181
+ return typeof route === "object" && route !== null && !Array.isArray(route)
182
+ ? route
183
+ : {};
184
+ }
185
+ // ---------------------------------------------------------------------------
186
+ // Payload rendering
187
+ // ---------------------------------------------------------------------------
188
+ /**
189
+ * Render the payload material and check it against the recorded binding.
190
+ *
191
+ * The hash is recomputed here, never taken on trust: `payload-mismatch` is the
192
+ * same refusal `core/token.ts` raises at spend time, raised earlier, so a human
193
+ * is never shown bytes that the token would later refuse to execute.
194
+ */
195
+ function renderPayload(material, boundHash, maxChars) {
196
+ let hash;
197
+ let text;
198
+ try {
199
+ hash = payloadHash(material);
200
+ text = JSON.stringify(material, null, 2) ?? String(material);
201
+ }
202
+ catch (cause) {
203
+ return refuse("payload-unrenderable", `the payload material could not be canonicalized: ${cause instanceof Error ? cause.message : String(cause)}. A payload that cannot be serialized cannot be bound to, so it cannot be approved.`);
204
+ }
205
+ if (hash !== boundHash) {
206
+ return refuse("payload-mismatch", `the supplied payload material hashes to ${hash} but the request is bound to ${boundHash} (amended SPEC.md §6.2/§10). A grant approves specific bytes; showing a human different bytes than the token will execute is the exact failure the binding exists to prevent.`);
207
+ }
208
+ const truncated = maxChars !== undefined && text.length > maxChars;
209
+ return {
210
+ ok: true,
211
+ rendering: {
212
+ value: material,
213
+ text: truncated ? text.slice(0, maxChars) : text,
214
+ hash,
215
+ truncated,
216
+ },
217
+ };
218
+ }
219
+ /**
220
+ * The material for one action: the caller's override, else the payload store.
221
+ *
222
+ * Three outcomes, and the middle one is the point of the whole store. `none`
223
+ * means nobody holds the bytes — the caller passed no source (or it returned
224
+ * nothing) and the store has no file — which is `payload-unavailable` for a
225
+ * manual request. `refusal` means the store *does* hold a file and it does not
226
+ * verify: a tampered `<hash>.json` is reported as `payload-mismatch` and its
227
+ * contents are never returned, let alone rendered. `material` is the ordinary
228
+ * case, and it is still hash-checked downstream by {@link renderPayload}, so the
229
+ * store is verified twice on the path to a human and trusted at neither step.
230
+ *
231
+ * A stored external reference is `none` with a reason: the pointer is reported
232
+ * in the refusal message, and no bytes are invented for it.
233
+ */
234
+ function materialFor(options, actionKey, boundHash) {
235
+ const supplied = options.payload === undefined ? undefined : options.payload(actionKey, boundHash);
236
+ if (supplied !== undefined)
237
+ return { kind: "material", value: supplied };
238
+ const storeDir = options.payloadStoreDir;
239
+ if (storeDir === undefined || storeDir === null)
240
+ return { kind: "none", reason: null };
241
+ const loaded = loadPayload(storeDir, boundHash);
242
+ if (loaded.ok)
243
+ return { kind: "material", value: loaded.value };
244
+ if (loaded.code === "hash-mismatch") {
245
+ return { kind: "refusal", refusal: refuse("payload-mismatch", loaded.message) };
246
+ }
247
+ return { kind: "none", reason: loaded.code === "absent" ? null : loaded.message };
248
+ }
249
+ // ---------------------------------------------------------------------------
250
+ // buildChannelRequest
251
+ // ---------------------------------------------------------------------------
252
+ /**
253
+ * The options a build runs with: the caller's, plus the store convention.
254
+ *
255
+ * Resolved from the log path the caller already passes, so every surface —
256
+ * `approval render`, the CLI channel, web, Telegram — reads the same store
257
+ * without a flag, and a caller that wants no store at all says
258
+ * `payloadStoreDir: null` rather than being unable to say it.
259
+ */
260
+ function withStore(options, logPath) {
261
+ return options.payloadStoreDir === undefined
262
+ ? { ...options, payloadStoreDir: payloadStoreDirFor(logPath) }
263
+ : options;
264
+ }
265
+ /**
266
+ * Build the render-ready request for one action key.
267
+ *
268
+ * Computed, and what derives each:
269
+ *
270
+ * | field | derivation | `source` |
271
+ * | --- | --- | --- |
272
+ * | `class`, `task`, `payload_hash`, `requested_ts`, `chain`, `state` | the verified log | `log` |
273
+ * | `autonomy`, `provenance` | `explain()` over the attested policy | `policy-match` |
274
+ * | `budgets` | `evaluateBudgetsWithTask()` at `now` | `budgets` |
275
+ * | `attestation` | `checkAttestation()` against the live policy file | `attestation` |
276
+ * | `fullPayload` | supplied material, hash-checked | `payload-binding` |
277
+ * | `command_breakdown`, `protected_path` | the classifier, re-run over the hash-checked material | `classifier` |
278
+ * | `ttl_remaining_ms`, `waiting` | arithmetic on `now` | `clock` |
279
+ *
280
+ * Claimed, and who authored each: `summary` and `est_cost_usd` carry the actor
281
+ * of the `approval.requested` record — the party that submitted the declaration
282
+ * — and `rationale` / `confidence` carry the registering actor.
283
+ *
284
+ * Refuses an unknown or undecidable key rather than rendering a partial one:
285
+ * `not-requested` (no such request), `not-awaiting` (already granted, rejected,
286
+ * revoked or expired), and the payload codes above. An unverifiable log refuses
287
+ * `log-corrupt` before anything is derived.
288
+ */
289
+ export function buildChannelRequest(logPath, actionKey, options, now) {
290
+ const read = readVerifiedRecords(logPath, options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir });
291
+ if (!read.ok)
292
+ return refuse(read.code, read.message);
293
+ const load = loadPolicy(loadOptionsOf(options));
294
+ // APRV-109. An attestation prompt has no `approval.requested` to derive from,
295
+ // so it is resolved from its own open proposal before the approval path runs.
296
+ if (isAttestationActionKey(actionKey)) {
297
+ const proposal = openProposals(read.records, now).find((entry) => entry.actionKey === actionKey);
298
+ if (proposal === undefined) {
299
+ return refuse("not-awaiting", `${actionKey} has no open policy.proposed record; the attestation prompt was answered, superseded, or its proposer's deadline passed, and a channel may only collect a gesture on a live question`);
300
+ }
301
+ return tagProposal(read.records, read.head?.seq ?? 0, proposal, load, withStore(options, logPath), now);
302
+ }
303
+ const derivation = requestState(read.records, actionKey, now, ttlOf(load));
304
+ return tagDerivation(read.records, read.head?.seq ?? 0, derivation, load, withStore(options, logPath), now);
305
+ }
306
+ /** Month names for the dated form of {@link clockText}. UTC, like everything here. */
307
+ const MONTHS = [
308
+ "Jan",
309
+ "Feb",
310
+ "Mar",
311
+ "Apr",
312
+ "May",
313
+ "Jun",
314
+ "Jul",
315
+ "Aug",
316
+ "Sep",
317
+ "Oct",
318
+ "Nov",
319
+ "Dec",
320
+ ];
321
+ /** Whole UTC days since the epoch. The day boundary is the displayed zone's. */
322
+ function utcDay(ms) {
323
+ return Math.floor(ms / 86_400_000);
324
+ }
325
+ /**
326
+ * A deadline, said the way a reader on a phone can act on it (APRV-143).
327
+ *
328
+ * ```
329
+ * 13:09 UTC the deadline is later today
330
+ * tomorrow 13:09 UTC the deadline is the next UTC day
331
+ * 27 Aug 13:09 UTC anything further out, and anything already past
332
+ * ```
333
+ *
334
+ * The observed failure is a 24h TTL rendering as `expires 13:09 UTC` beside
335
+ * `requested 1 min ago`: a reader does the arithmetic, gets "nine minutes ago",
336
+ * and concludes the question is dead. Time of day alone can only be read
337
+ * against a day the line never states.
338
+ *
339
+ * Day boundaries are computed in UTC because the clock is printed in UTC, and a
340
+ * "tomorrow" measured in one zone against a time printed in another is worse
341
+ * than no word at all. `now` unreadable degrades to the time-only form: a
342
+ * renderer that cannot place today must not name a relative day.
343
+ */
344
+ function clockText(ms, nowMs) {
345
+ const at = new Date(ms);
346
+ const hh = String(at.getUTCHours()).padStart(2, "0");
347
+ const mm = String(at.getUTCMinutes()).padStart(2, "0");
348
+ const clock = `${hh}:${mm} UTC`;
349
+ if (Number.isNaN(nowMs))
350
+ return clock;
351
+ const days = utcDay(ms) - utcDay(nowMs);
352
+ if (days === 0)
353
+ return clock;
354
+ if (days === 1)
355
+ return `tomorrow ${clock}`;
356
+ return `${String(at.getUTCDate())} ${MONTHS[at.getUTCMonth()] ?? "?"} ${clock}`;
357
+ }
358
+ /**
359
+ * `just now`, `4 min ago`, `2h 05m ago` — how long the question has waited.
360
+ *
361
+ * Exported since APRV-216 so the Telegram queue summary states a request's age
362
+ * in the same words the request's own prompt does. One phrasing and one
363
+ * rounding: a summary calling a question `2h 05m` old beside a prompt that
364
+ * calls it something else leaves a reader deciding which of the two the
365
+ * runtime meant.
366
+ */
367
+ export function ageText(ms) {
368
+ const minutes = Math.floor(ms / 60_000);
369
+ if (minutes < 1)
370
+ return "just now";
371
+ if (minutes < 60)
372
+ return `${String(minutes)} min ago`;
373
+ return `${String(Math.floor(minutes / 60))}h ${String(minutes % 60).padStart(2, "0")}m ago`;
374
+ }
375
+ /**
376
+ * The age/deadline line of APRV-106. See `ChannelRequest.waiting` for why it is
377
+ * computed and why the requester's own `wait_until` cannot lower scrutiny.
378
+ *
379
+ * Determinism: `now` is the parameter every other field here is derived
380
+ * against, so a queue rendered twice at the same instant produces the same
381
+ * line. Unparseable instants degrade to the honest half rather than to a
382
+ * guess — a channel that cannot say when a request was made must not imply it
383
+ * was made recently.
384
+ */
385
+ function waitingLine(requestTs, waitUntil, ttlRemainingMs, now) {
386
+ const requestedAt = Date.parse(requestTs);
387
+ const nowMs = Date.parse(now);
388
+ const age = Number.isNaN(requestedAt) || Number.isNaN(nowMs)
389
+ ? `requested at ${requestTs}`
390
+ : `requested ${ageText(Math.max(0, nowMs - requestedAt))}`;
391
+ const waitMs = waitUntil === null ? Number.NaN : Date.parse(waitUntil);
392
+ if (!Number.isNaN(waitMs)) {
393
+ return `${age} · requester waits until ${clockText(waitMs, nowMs)}`;
394
+ }
395
+ if (ttlRemainingMs !== null && !Number.isNaN(nowMs)) {
396
+ return `${age} · expires ${clockText(nowMs + ttlRemainingMs, nowMs)}`;
397
+ }
398
+ // No TTL and no declared wait: the policy bounded nothing, and inventing a
399
+ // deadline here would be the renderer stating a fact the log does not carry.
400
+ return `${age} · no deadline (the policy declares no approval_ttl)`;
401
+ }
402
+ /**
403
+ * `policy.protected_paths`, or nothing when the policy did not load.
404
+ *
405
+ * Narrower on a failed load, never wider: an unreadable policy under-reports
406
+ * which paths are protected rather than inventing a protection, and autonomy
407
+ * has already failed closed to `manual` by the time this is read.
408
+ */
409
+ function protectedPathsOf(load) {
410
+ return load.ok ? (load.policy.protected_paths ?? []) : [];
411
+ }
412
+ /**
413
+ * The two payload-derived computed lines: what the command does (APRV-144 #1)
414
+ * and which protected path selected the class (APRV-143 #3).
415
+ *
416
+ * Both are derived from the payload material this function was already handed —
417
+ * material that {@link renderPayload} has hash-checked against the recorded
418
+ * binding — and both go through `core/command-class.ts` rather than reading a
419
+ * claim off the bytes. A payload nobody holds, or one of a shape neither
420
+ * derivation recognises, produces neither line: an aid that cannot be derived
421
+ * is absent, never guessed.
422
+ */
423
+ /**
424
+ * The `token_delivery` line, for a request that published a delivery address
425
+ * (APRV-105), and nothing at all for one that did not.
426
+ *
427
+ * Computed from `log`: the key comes off the verified `approval.requested`
428
+ * record and is digested here. A malformed value produces no line rather than a
429
+ * line saying something is wrong — the delivery address is a convenience, and a
430
+ * broken one costs the requester its own convenience and costs the approver
431
+ * nothing they need for the decision.
432
+ */
433
+ function deliveryDerivation(recipientKey) {
434
+ if (!isRecipientKey(recipientKey))
435
+ return {};
436
+ const digest = createHash("sha256").update(recipientKey, "utf8").digest("hex").slice(0, 16);
437
+ return {
438
+ token_delivery: computed(`sealed to x25519:${digest} — granting delivers the token to the requesting process, not only to this screen`, "log"),
439
+ };
440
+ }
441
+ function payloadDerivations(rendering, load) {
442
+ if (rendering === null)
443
+ return {};
444
+ const fields = {};
445
+ const command = commandPayloadView(rendering.value);
446
+ if (command !== null) {
447
+ const breakdown = commandBreakdown(command.command);
448
+ if (breakdown !== null)
449
+ fields.command_breakdown = computed(breakdown, "classifier");
450
+ }
451
+ const guarded = protectedPathView(rendering.value, protectedPathsOf(load));
452
+ if (guarded !== null) {
453
+ fields.protected_path = computed(`${guarded.path} (rule ${guarded.rule})`, "classifier");
454
+ }
455
+ return fields;
456
+ }
457
+ /** The shared body of {@link buildChannelRequest} and {@link buildPendingQueue}. */
458
+ function tagDerivation(records, headSeq, derivation, load, options, now) {
459
+ const actionKey = derivation.actionKey;
460
+ if (derivation.state === "none") {
461
+ return refuse("not-requested", `action ${actionKey} has no approval.requested record; there is nothing pending to render`);
462
+ }
463
+ if (derivation.state !== "requested") {
464
+ return refuse("not-awaiting", `action ${actionKey} is ${derivation.state}, not awaiting a decision; a channel may only collect a gesture on a live request`);
465
+ }
466
+ const cls = derivation.declared.class;
467
+ if (cls === null || cls.length === 0) {
468
+ return refuse("class-missing", `the approval.requested record for ${actionKey} carries no usable payload.class; autonomy and every class-scoped budget are resolved from it, so nothing can be shown as computed`);
469
+ }
470
+ const boundHash = derivation.declared.payload_hash;
471
+ if (boundHash === null) {
472
+ return refuse("payload-hash-missing", `the approval.requested record for ${actionKey} carries no payload_hash; amended SPEC.md §6.2 makes the binding mandatory for manual actions, so a request without one cannot be presented for decision`);
473
+ }
474
+ const requestRecord = recordAt(records, derivation.requestSeq);
475
+ if (requestRecord === null || derivation.requestTs === null) {
476
+ return refuse("not-requested", `the approval.requested record for ${actionKey} could not be located in the verified log`);
477
+ }
478
+ const reversible = derivation.declared.reversible;
479
+ const explanation = explain(load, cls, reversible === null ? {} : { reversible });
480
+ const resolution = resolve(load, cls, reversible === null ? {} : { reversible });
481
+ // The declared amount in its canonical decimal form (APRV-121) for the
482
+ // budget evaluation, and as a number for the card. A channel card is a
483
+ // display surface: nothing it renders is hashed, so the float lives here and
484
+ // goes no further.
485
+ const cost = derivation.declared.est_cost_usd ?? "0";
486
+ const budgets = evaluateBudgetsWithTask(records, budgetScopeOf(load, resolution), { class: cls, est_cost_usd: cost }, now, derivation.task).verdicts;
487
+ const attestation = checkAttestation(records, policyPathOf(options));
488
+ const material = materialFor(options, actionKey, boundHash);
489
+ if (material.kind === "refusal")
490
+ return material.refusal;
491
+ let rendering = null;
492
+ if (material.kind === "material") {
493
+ const rendered = renderPayload(material.value, boundHash, options.maxPayloadChars);
494
+ if (!rendered.ok)
495
+ return rendered;
496
+ rendering = rendered.rendering;
497
+ }
498
+ else if (explanation.outcome.autonomy === "manual") {
499
+ return refuse("payload-unavailable", `no payload material is held for manual action ${actionKey}: the caller supplied none and the payload store has none${material.reason === null ? "" : ` (${material.reason})`}. SPEC.md §10.4 requires a channel to present the full payload or a faithful rendering of it before collecting a decision, so the request is refused here rather than delivered as a summary alone.`);
500
+ }
501
+ const ttlMs = ttlOf(load);
502
+ const requestedAt = Date.parse(derivation.requestTs);
503
+ const nowMs = Date.parse(now);
504
+ const ttlRemaining = ttlMs === null || Number.isNaN(requestedAt) || Number.isNaN(nowMs)
505
+ ? null
506
+ : Math.max(0, requestedAt + ttlMs - nowMs);
507
+ const route = routeOf(registrationOf(records, derivation.task));
508
+ const registrationActor = registrationOf(records, derivation.task)?.actor ?? requestRecord.actor;
509
+ const fields = {
510
+ action_key: computed(actionKey, "log"),
511
+ task: computed(derivation.task, "log"),
512
+ class: computed(cls, "log"),
513
+ autonomy: computed(explanation.outcome.autonomy, "policy-match"),
514
+ provenance: computed(explanation.provenance, "policy-match"),
515
+ est_cost_usd: claimed(usdNumber(cost), requestRecord.actor),
516
+ summary: claimed(derivation.declared.summary, requestRecord.actor),
517
+ ...payloadDerivations(rendering, load),
518
+ payload_hash: computed(boundHash, "log"),
519
+ // APRV-105. Present only when the request published a delivery address, so
520
+ // an approver is told when granting will hand a readable token to the
521
+ // requesting process rather than only to this screen. Digested rather than
522
+ // printed whole: the key is public and harmless, but several hundred
523
+ // characters of base64 in a prompt is several hundred characters nobody
524
+ // reads, and a digest is enough to tell two requests' addresses apart.
525
+ ...deliveryDerivation(payloadOf(requestRecord)[RECIPIENT_KEY_FIELD]),
526
+ fullPayload: computed(rendering, "payload-binding"),
527
+ budgets: computed(budgets, "budgets"),
528
+ attestation: computed(attestation, "attestation"),
529
+ requested_ts: computed(derivation.requestTs, "log"),
530
+ ttl_remaining_ms: computed(ttlRemaining, "clock"),
531
+ waiting: computed(waitingLine(derivation.requestTs, derivation.declared.wait_until, ttlRemaining, now), "clock"),
532
+ chain: computed({ seq: requestRecord.seq, hash: requestRecord.hash, head_seq: headSeq }, "log"),
533
+ state: computed(derivation.state, "log"),
534
+ ...(typeof route["rationale"] === "string"
535
+ ? { rationale: claimed(route["rationale"], registrationActor) }
536
+ : {}),
537
+ ...(typeof route["confidence"] === "number"
538
+ ? { confidence: claimed(route["confidence"], registrationActor) }
539
+ : {}),
540
+ };
541
+ const created = createChannelRequest(fields);
542
+ if (!created.ok)
543
+ return refuse("request-invalid", created.message);
544
+ return { ok: true, request: created.request };
545
+ }
546
+ // ---------------------------------------------------------------------------
547
+ // Attestation prompts (APRV-109)
548
+ // ---------------------------------------------------------------------------
549
+ /** The diff summary a proposal recorded, or `null` when it recorded none. */
550
+ function diffSummaryOf(record) {
551
+ const value = payloadOf(record)["diff"];
552
+ if (typeof value !== "object" || value === null)
553
+ return null;
554
+ const summary = value;
555
+ const lines = Array.isArray(summary["lines"])
556
+ ? summary["lines"].filter((line) => typeof line === "string")
557
+ : [];
558
+ return {
559
+ available: summary["available"] === true,
560
+ reason: typeof summary["reason"] === "string" ? summary["reason"] : null,
561
+ lines,
562
+ headline: typeof summary["headline"] === "string" ? summary["headline"] : "",
563
+ baseline_sha256: typeof summary["baseline_sha256"] === "string" ? summary["baseline_sha256"] : null,
564
+ };
565
+ }
566
+ /** The diff, as the one block of text every channel prints. */
567
+ function diffText(summary) {
568
+ if (!summary.available) {
569
+ return `HASH-ONLY: no semantic diff. ${summary.reason ?? "no verifiable baseline"}. What changed in MEANING is not shown, so read the file diff at a terminal before deciding.`;
570
+ }
571
+ return [`${summary.headline}:`, ...summary.lines].join("\n");
572
+ }
573
+ /** The load advisory, recomputed here from the live bytes at display time. */
574
+ function loadText(load) {
575
+ return load.ok
576
+ ? "loads clean"
577
+ : `DOES NOT LOAD (${load.code}): ${load.message}. Attesting it is allowed — an attestation records bytes, not correctness — but every class will FAIL CLOSED to manual.`;
578
+ }
579
+ /**
580
+ * Tag one open `policy.proposed` as a manual prompt (APRV-109).
581
+ *
582
+ * The prompt is an ordinary {@link ChannelRequest} and that is the whole design:
583
+ * telegram, web and cli render it through the paths they already have, the
584
+ * computed/claimed split applies unchanged, and `channels/conformance.ts` checks
585
+ * it like any other request. Two additive computed members carry what an
586
+ * attestation needs and an approval does not — the semantic diff and the load
587
+ * advisory — and everything else lines up with a field that already existed.
588
+ *
589
+ * Three of those alignments are worth stating, because a reader will ask:
590
+ *
591
+ * - **`autonomy` is `manual` with provenance `floor`.** No `classes` rule
592
+ * decides this and none could: attestation is human-only in code (SPEC.md
593
+ * §11) and the act is irreversible, since the log is append-only and attested
594
+ * bytes are operative from that record onward. The prompt reports a floor the
595
+ * policy cannot lower rather than a rule it does not have.
596
+ * - **`est_cost_usd` is COMPUTED zero, not a claim.** An attestation buys
597
+ * nothing and spends nothing; there is no estimate for a proposer to author,
598
+ * so there is nothing here to label claimed.
599
+ * - **`attestation` is the LIVE status**, which on an open prompt is
600
+ * `hash-mismatch` or `not-attested`. That is the fact the approver is being
601
+ * asked to change, so it belongs on the screen exactly as it belongs on every
602
+ * other prompt.
603
+ *
604
+ * The live file is re-hashed here and a prompt whose bytes have moved is refused
605
+ * `proposal-stale` rather than rendered: `core/policy-proposal.ts` would refuse
606
+ * the tap for the same reason, and a queue that showed the question anyway would
607
+ * be inviting a gesture the gate has already decided to reject.
608
+ */
609
+ function tagProposal(records, headSeq, proposal, load, options, now) {
610
+ const record = proposal.record;
611
+ const payload = payloadOf(record);
612
+ const policyPath = policyPathOf(options);
613
+ let liveSha256;
614
+ try {
615
+ liveSha256 = policyFileHash(policyPath);
616
+ }
617
+ catch (cause) {
618
+ return refuse("proposal-stale", `the attestation prompt at seq ${String(record.seq)} proposes ${proposal.sha256} and ${policyPath} could not be read to confirm it (${cause instanceof Error ? cause.message : String(cause)}); a prompt whose bytes nobody can read is not a prompt anybody can answer`);
619
+ }
620
+ if (liveSha256 !== proposal.sha256) {
621
+ return refuse("proposal-stale", `the attestation prompt at seq ${String(record.seq)} proposes ${proposal.sha256} and ${policyPath} now hashes ${liveSha256}; the file changed after the question was asked, so the hash, the diff and the advisory on this prompt all describe bytes that are no longer there. Propose the amendment again.`);
622
+ }
623
+ const boundHash = payload["payload_hash"];
624
+ if (typeof boundHash !== "string" || boundHash.length === 0) {
625
+ return refuse("payload-hash-missing", `the policy.proposed record at seq ${String(record.seq)} carries no payload_hash, so the full policy text it binds cannot be located; SPEC.md §10.4 requires the bytes to be presentable before a decision is collected`);
626
+ }
627
+ const material = materialFor(options, proposal.actionKey, boundHash);
628
+ if (material.kind === "refusal")
629
+ return material.refusal;
630
+ if (material.kind !== "material") {
631
+ return refuse("payload-unavailable", `no policy text is held for the attestation prompt at seq ${String(record.seq)}: the caller supplied none and the payload store has none${material.reason === null ? "" : ` (${material.reason})`}. SPEC.md §10.4 requires a channel to present the full payload before collecting a decision, and for an attestation that payload is the policy file itself.`);
632
+ }
633
+ const rendered = renderPayload(material.value, boundHash, options.maxPayloadChars);
634
+ if (!rendered.ok)
635
+ return rendered;
636
+ const summary = diffSummaryOf(record);
637
+ if (summary === null) {
638
+ return refuse("request-invalid", `the policy.proposed record at seq ${String(record.seq)} carries no diff summary; a prompt that showed only a hash would ask a human to sign for sixty-four characters, which is the failure APRV-109 exists to prevent`);
639
+ }
640
+ const waitUntil = typeof payload["wait_until"] === "string" ? payload["wait_until"] : null;
641
+ const nowMs = Date.parse(now);
642
+ const waitMs = waitUntil === null ? Number.NaN : Date.parse(waitUntil);
643
+ const remaining = Number.isNaN(waitMs) || Number.isNaN(nowMs) ? null : Math.max(0, waitMs - nowMs);
644
+ const fields = {
645
+ action_key: computed(proposal.actionKey, "log"),
646
+ task: computed(null, "log"),
647
+ class: computed(ATTESTATION_CLASS, "log"),
648
+ autonomy: computed("manual", "attestation"),
649
+ provenance: computed("floor", "attestation"),
650
+ est_cost_usd: computed(0, "attestation"),
651
+ summary: claimed(typeof payload["note"] === "string" ? payload["note"] : null, record.actor),
652
+ policy_diff: computed(diffText(summary), "log"),
653
+ policy_load: computed(loadText(load), "policy-load"),
654
+ payload_hash: computed(boundHash, "log"),
655
+ fullPayload: computed(rendered.rendering, "payload-binding"),
656
+ budgets: computed([], "budgets"),
657
+ attestation: computed(checkAttestation(records, policyPath), "attestation"),
658
+ requested_ts: computed(record.ts, "log"),
659
+ ttl_remaining_ms: computed(remaining, "clock"),
660
+ waiting: computed(waitingLine(record.ts, waitUntil, remaining, now), "clock"),
661
+ chain: computed({ seq: record.seq, hash: record.hash, head_seq: headSeq }, "log"),
662
+ state: computed("requested", "log"),
663
+ };
664
+ const created = createChannelRequest(fields);
665
+ if (!created.ok)
666
+ return refuse("request-invalid", created.message);
667
+ return { ok: true, request: created.request };
668
+ }
669
+ /**
670
+ * Build the pending queue: every action key with a live `approval.requested`.
671
+ *
672
+ * Order is log order (oldest request first), which is the order SPEC.md §9's
673
+ * queue projection asks for. One verified read serves the whole queue, and one
674
+ * policy load serves every entry, so an entry cannot disagree with its
675
+ * neighbour about what the policy says.
676
+ */
677
+ export function buildPendingQueue(logPath, options, now) {
678
+ const read = readVerifiedRecords(logPath, options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir });
679
+ if (!read.ok)
680
+ return refuse(read.code, read.message);
681
+ const load = loadPolicy(loadOptionsOf(options));
682
+ const ttlMs = ttlOf(load);
683
+ const headSeq = read.head?.seq ?? 0;
684
+ const withStoreOptions = withStore(options, logPath);
685
+ const keys = [];
686
+ for (const record of read.records) {
687
+ if (record.event !== "approval.requested")
688
+ continue;
689
+ const key = record.action_key;
690
+ if (key === undefined || keys.includes(key))
691
+ continue;
692
+ keys.push(key);
693
+ }
694
+ const requests = [];
695
+ const skipped = [];
696
+ for (const key of keys) {
697
+ const derivation = requestState(read.records, key, now, ttlMs);
698
+ if (derivation.state !== "requested")
699
+ continue;
700
+ const built = tagDerivation(read.records, headSeq, derivation, load, withStoreOptions, now);
701
+ if (built.ok)
702
+ requests.push(built.request);
703
+ else
704
+ skipped.push({ action_key: key, code: built.code, message: built.message });
705
+ }
706
+ // APRV-109. Attestation prompts join the same queue, so every channel that
707
+ // already dispatches pending approvals dispatches these too — no channel
708
+ // learns a second verb, and the one that cannot render a prompt reports it in
709
+ // `skipped` exactly as it reports an approval it cannot render. They come
710
+ // AFTER the approvals: a policy amendment changes the rules the entries above
711
+ // it were routed by, and an approver reading top to bottom should answer the
712
+ // questions asked under the current policy before changing what the current
713
+ // policy is.
714
+ for (const proposal of openProposals(read.records, now)) {
715
+ const built = tagProposal(read.records, headSeq, proposal, load, withStoreOptions, now);
716
+ if (built.ok)
717
+ requests.push(built.request);
718
+ else
719
+ skipped.push({ action_key: proposal.actionKey, code: built.code, message: built.message });
720
+ }
721
+ return { ok: true, requests, skipped };
722
+ }
723
+ //# sourceMappingURL=tagging.js.map