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,1035 @@
1
+ /**
2
+ * The adapter contract (SPEC.md §4, §6.2, §10.4, §11).
3
+ *
4
+ * An **adapter** is a side-effect executor: the thing that actually sends the
5
+ * email, writes the calendar entry, moves the file. SPEC.md §10.4 makes it the
6
+ * hard boundary of the whole system: credentials reach an adapter only inside
7
+ * a runtime-authorized execution window.
8
+ *
9
+ * That boundary describes a *sequence*, not a property of any one function:
10
+ * recompute the payload hash, verify the applicable authority and consume a
11
+ * token where required, record that the execution started, act, record how it
12
+ * ended. An adapter that owned that
13
+ * sequence could skip a step — and the step it would skip is whichever one was
14
+ * inconvenient the week the adapter was written. So the sequence lives here,
15
+ * once, and an adapter implements exactly one method:
16
+ *
17
+ * ```ts
18
+ * act(input: ActInput): Promise<ActOutcome> | ActOutcome
19
+ * ```
20
+ *
21
+ * {@link executeThroughAdapter} owns everything around that call. It is not a
22
+ * helper an adapter may choose; it is the only door, in the same sense that
23
+ * `core/token.ts`'s `consumeToken` is the only sanctioned way to append a
24
+ * manual `execution.started`.
25
+ *
26
+ * ## The five things the contract does that an adapter therefore cannot skip
27
+ *
28
+ * 1. **Recompute the hash.** Amended §10.4: "Adapters and `approval run` MUST
29
+ * recompute the hash of the payload they are about to execute and MUST
30
+ * refuse, with a distinct machine-readable reason (`payload-mismatch`), when
31
+ * it differs from the hash the grant recorded." The contract hashes
32
+ * `request.payload` with `core/payload.ts` — the same canonicalizer the log
33
+ * uses — and hands the digest to the token spend. An adapter is never asked
34
+ * what its payload hashes to, because an executor that could *state* its
35
+ * hash could state the approved one while holding different bytes.
36
+ * 2. **Check the class before touching the log.** An adapter declares the
37
+ * classes it serves. An adapter asked to execute an action declared under
38
+ * some other class is refused `adapter-class-mismatch` with the log
39
+ * untouched: the declaration is read from `task.registered` (the log, not the
40
+ * caller's claim), and nothing is appended, because nothing happened.
41
+ * 3. **Start before acting.** {@link startExecution} appends `execution.started`
42
+ * *before* `act` is called, and a refusal there means `act` is never called
43
+ * at all. A log that recorded an execution only once it succeeded could not
44
+ * tell you about the one that did not.
45
+ * 3b. **Resolve declared credentials before spending the token** (APRV-169). An
46
+ * adapter names the credentials it cannot act without, and the contract
47
+ * resolves them before `startExecution`. A missing one refuses
48
+ * `credential-unavailable` with the log untouched and the grant intact,
49
+ * because a configuration fault must not consume a human's single-use
50
+ * authority. The side effect's own ordering is unchanged: the token is still
51
+ * consumed and `execution.started` still appended before `act` runs.
52
+ * 3c. **Ask the adapter what it can learn before the spend** (APRV-276). An
53
+ * adapter MAY implement {@link Adapter.precheck}, and the contract calls it
54
+ * after the credentials resolve and before the token is consumed. It is the
55
+ * home of one specific refusal: the condition that makes the side effect
56
+ * impossible, that this runtime can learn without attempting it, and that
57
+ * would otherwise cost a human's single-use grant to discover. AgentMail's
58
+ * drift check is the worked case. A refusal appends nothing, spends nothing,
59
+ * and returns `adapter-precheck-refused`. It does not replace the same check
60
+ * inside `act`: the far side can move in between, and the check that binds
61
+ * the bytes actually sent is the later one.
62
+ * 4. **Scope the credentials.** The provider handed to `act` is a wrapper that
63
+ * closes when `act` returns. Inside the verified execution window it answers;
64
+ * outside it, every `get` refuses `credential-window-closed`. An adapter that
65
+ * stashes the provider and reads it later gets a refusal rather than a
66
+ * secret, so the execution window is a mechanism instead of an intention.
67
+ * 5. **Redact.** Every string the contract is about to return is scanned for
68
+ * each credential value the provider handed out during the window, and hits
69
+ * are replaced with {@link REDACTION_PLACEHOLDER} and counted. SPEC.md §11.1
70
+ * invariant 3 ("raw secrets never appear in the log") is the reason adapters
71
+ * exist; here it is a mechanical check rather than a convention. Note what
72
+ * reaches the log from an adapter: one bounded field. Since APRV-251 a
73
+ * completion may carry `provider_ref`, the identifier the provider files the
74
+ * effect under, and the sweep runs BEFORE that record is appended so the id
75
+ * is scanned exactly as the rest of the detail is. Everything else in the
76
+ * adapter's own vocabulary rides in the returned result, which is scanned
77
+ * before it is handed back.
78
+ *
79
+ * ## What is deliberately not here
80
+ *
81
+ * No vault. {@link CredentialProvider} is the seam a real vault implements
82
+ * (APRV-68); this module ships {@link inMemoryCredentials} for tests and
83
+ * {@link NO_CREDENTIALS}, which refuses everything, as the default. A runtime
84
+ * that wires no provider therefore fails closed: an adapter that needs a secret
85
+ * to act cannot act.
86
+ *
87
+ * No token verification, consumption, or append logic. Those are
88
+ * `core/token.ts` and `core/execute.ts`, called here and reimplemented nowhere.
89
+ *
90
+ * ## Two callers, one core path
91
+ *
92
+ * `approval run` (`src/cli/execute.ts`) is the other caller of the same core
93
+ * path: a command is an adapter whose `act` is `spawnSync`, whose payload is
94
+ * §6.2's `{argv, cwd}`, and whose credentials are the ambient environment. It
95
+ * calls `startExecution` and `finishExecution` directly rather than through this
96
+ * module, because its stdio, exit-code transparency, and `--` argv split are CLI
97
+ * concerns with nothing to do with adapters. The two callers share the core
98
+ * verbs, not this wrapper; anything that must hold for both belongs in
99
+ * `core/execute.ts`, and a rule added here alone protects adapters only.
100
+ *
101
+ * Deterministic and total: no clock of its own (it forwards
102
+ * {@link ExecuteOptions.clock}), no randomness, and nothing here throws — an
103
+ * adapter that throws is caught and recorded as a failed execution.
104
+ */
105
+ import { EXECUTE_REFUSAL_CODES, checkExecutionEligibility, declaringTasks, finishExecution, findDeclaration, indeterminateExecution, providerRefRecordable, startExecution, hasApprovalCycle, } from "../core/execute.js";
106
+ import { request as requestApproval } from "../core/gate.js";
107
+ import { payloadHash } from "../core/payload.js";
108
+ import { loadPolicy } from "../core/policy-load.js";
109
+ import { resolve } from "../core/policy-match.js";
110
+ import { payloadOf, readVerifiedRecords } from "../core/state.js";
111
+ import { PAYLOAD_HASH_FIELD, TOKEN_HASH_FIELD, digestsEqual, tokenHash } from "../core/token.js";
112
+ // ---------------------------------------------------------------------------
113
+ // Credentials
114
+ // ---------------------------------------------------------------------------
115
+ /**
116
+ * Why a credential was not handed over. Frozen union, per SPEC.md §11.1(6).
117
+ *
118
+ * The three are distinguished because they call for three different responses:
119
+ * fix the configuration, ask a human, or fix the adapter.
120
+ */
121
+ export const CREDENTIAL_REFUSAL_CODES = [
122
+ /** No such credential is configured. The repair is configuration. */
123
+ "credential-unavailable",
124
+ /** The provider knows it and declined: policy, a locked vault, a human's no. */
125
+ "credential-refused",
126
+ /**
127
+ * The verified execution window has closed: `act` has already returned, and the
128
+ * provider it was handed is no longer live. Distinct from the two above
129
+ * because nothing is wrong with the credential or the configuration — the
130
+ * adapter asked at the wrong time, which is a defect in the adapter and is
131
+ * reported as one.
132
+ */
133
+ "credential-window-closed",
134
+ ];
135
+ /** The default: no vault is wired, so nothing is handed out. Fails closed. */
136
+ export const NO_CREDENTIALS = {
137
+ get(name) {
138
+ return {
139
+ ok: false,
140
+ code: "credential-unavailable",
141
+ message: `no credential provider is configured, so ${JSON.stringify(name)} cannot be supplied. SPEC.md §10.4 puts the credentials behind the adapter boundary; wire a provider explicitly rather than reading the environment from inside an adapter.`,
142
+ };
143
+ },
144
+ };
145
+ /**
146
+ * A provider over a literal map. **Tests and fixtures only** — it holds secrets
147
+ * in process memory in the clear, which is precisely what the vault (APRV-68)
148
+ * exists to stop doing.
149
+ */
150
+ export function inMemoryCredentials(entries) {
151
+ return {
152
+ get(name) {
153
+ const value = Object.prototype.hasOwnProperty.call(entries, name)
154
+ ? entries[name]
155
+ : undefined;
156
+ if (typeof value !== "string") {
157
+ return {
158
+ ok: false,
159
+ code: "credential-unavailable",
160
+ message: `no credential named ${JSON.stringify(name)} is configured`,
161
+ };
162
+ }
163
+ return { ok: true, value };
164
+ },
165
+ };
166
+ }
167
+ /**
168
+ * Wrap `inner` in a window that closes.
169
+ *
170
+ * The mechanism is a closure over a boolean, not a revoked reference: the
171
+ * adapter may keep the object it was handed for as long as it likes, and the
172
+ * object will refuse. Values handed out are remembered so the contract can scan
173
+ * its own output for them; the *names* are not interesting and the values never
174
+ * leave this set.
175
+ */
176
+ function scopeCredentials(inner) {
177
+ let open = true;
178
+ const issued = new Set();
179
+ return {
180
+ provider: {
181
+ get(name) {
182
+ if (!open) {
183
+ return {
184
+ ok: false,
185
+ code: "credential-window-closed",
186
+ message: `credential ${JSON.stringify(name)} was requested after act() returned. Credentials are reachable only inside the verified execution window: the execution has already been recorded, so a secret handed over now would be outside the authority that opened the call.`,
187
+ };
188
+ }
189
+ const result = inner.get(name);
190
+ if (result.ok && result.value.length > 0)
191
+ issued.add(result.value);
192
+ return result;
193
+ },
194
+ },
195
+ issued,
196
+ close() {
197
+ open = false;
198
+ },
199
+ };
200
+ }
201
+ // ---------------------------------------------------------------------------
202
+ // Redaction (SPEC.md §11.1 invariant 3, mechanically)
203
+ // ---------------------------------------------------------------------------
204
+ /** What a redacted credential value is replaced with. */
205
+ export const REDACTION_PLACEHOLDER = "[redacted]";
206
+ /**
207
+ * Replace every occurrence of every secret in `text`.
208
+ *
209
+ * Empty secrets are skipped, because "replace every occurrence of the empty
210
+ * string" redacts a document into nothing and would hide the very message a
211
+ * reader needs. Everything else is replaced literally (no regex, no escaping
212
+ * question), including a secret that appears as a substring of a longer word:
213
+ * over-redaction is the safe direction, and a credential that happens to be a
214
+ * common word is a credential problem, not a scanner problem.
215
+ */
216
+ export function redactSecrets(text, secrets) {
217
+ let out = text;
218
+ let hits = 0;
219
+ for (const secret of secrets) {
220
+ if (secret.length === 0)
221
+ continue;
222
+ let index = out.indexOf(secret);
223
+ while (index !== -1) {
224
+ hits += 1;
225
+ out = out.slice(0, index) + REDACTION_PLACEHOLDER + out.slice(index + secret.length);
226
+ index = out.indexOf(secret, index + REDACTION_PLACEHOLDER.length);
227
+ }
228
+ }
229
+ return { text: out, hits };
230
+ }
231
+ /** Does `text` contain any of `secrets`? The assertion form of the guard. */
232
+ export function containsSecret(text, secrets) {
233
+ for (const secret of secrets) {
234
+ if (secret.length === 0)
235
+ continue;
236
+ if (text.includes(secret))
237
+ return true;
238
+ }
239
+ return false;
240
+ }
241
+ /**
242
+ * Walk `value` and redact every string in it, keys included.
243
+ *
244
+ * Keys are scanned as well as values because a leak does not care which side of
245
+ * the colon it lands on: `{"sk-live-…": "used"}` publishes the secret exactly as
246
+ * effectively as the other arrangement.
247
+ */
248
+ export function redactJson(value, secrets) {
249
+ const list = [...secrets].filter((secret) => secret.length > 0);
250
+ if (list.length === 0)
251
+ return { value, hits: 0 };
252
+ let hits = 0;
253
+ const walk = (node) => {
254
+ if (typeof node === "string") {
255
+ const redacted = redactSecrets(node, list);
256
+ hits += redacted.hits;
257
+ return redacted.text;
258
+ }
259
+ if (Array.isArray(node))
260
+ return node.map(walk);
261
+ if (typeof node === "object" && node !== null) {
262
+ const out = {};
263
+ for (const [key, member] of Object.entries(node)) {
264
+ const redactedKey = redactSecrets(key, list);
265
+ hits += redactedKey.hits;
266
+ out[redactedKey.text] = walk(member);
267
+ }
268
+ return out;
269
+ }
270
+ return node;
271
+ };
272
+ return { value: walk(value), hits };
273
+ }
274
+ /**
275
+ * The one key by which a success `detail` NAMES the provider's own identifier
276
+ * for the effect (APRV-251, SPEC.md §8).
277
+ *
278
+ * An adapter that wants its effect joinable by id puts a short printable string
279
+ * at the top level of its detail under this key, beside whatever else its
280
+ * receipt says. Everything after that is the contract's: the value passes the
281
+ * redaction sweep with the rest of the detail, the adapter half of the record
282
+ * is this runtime's own knowledge of which adapter it called, and the record is
283
+ * written by {@link finishExecution}.
284
+ *
285
+ * ONE conventional key rather than a guess across `message_id`, `sid`, `id` and
286
+ * whatever the next provider calls it. A contract that guessed would sooner or
287
+ * later lift the wrong field of some receipt onto a permanent log, and an
288
+ * adapter that says nothing under this key is treated as naming no reference,
289
+ * which is the pre-amendment behaviour and always valid.
290
+ */
291
+ export const PROVIDER_REF_DETAIL_KEY = "provider_ref";
292
+ /**
293
+ * The reference to record for this call, or `null` for none.
294
+ *
295
+ * Given BOTH the raw detail the adapter returned and the redacted copy about to
296
+ * be handed back, because the interesting case is the one where they differ. A
297
+ * lifted id whose bytes the redaction sweep touched is dropped rather than
298
+ * recorded: `[redacted]` matches no provider's record, and writing it would put
299
+ * a value in the join column that reads exactly like one that means something.
300
+ * The credential itself never reaches the log either way, since what would be
301
+ * written is the redacted copy.
302
+ *
303
+ * Everything else it declines is declined for the same reason the schema would
304
+ * reject it (an absent key, a value that is not a string, a string that is
305
+ * empty, too long, or carries a space or a control character). Declining here
306
+ * rather than at the append is deliberate: a record the write boundary rejects
307
+ * would leave a side effect that already happened with no outcome in the log,
308
+ * and a completion carrying no reference is the better failure.
309
+ */
310
+ export function providerRefFor(adapterName, rawDetail, redactedDetail) {
311
+ const read = (node) => {
312
+ if (typeof node !== "object" || node === null || Array.isArray(node))
313
+ return null;
314
+ const named = node[PROVIDER_REF_DETAIL_KEY];
315
+ return typeof named === "string" ? named : null;
316
+ };
317
+ const raw = read(rawDetail);
318
+ if (raw === null)
319
+ return null;
320
+ // The redacted copy is what a reader would get, so it is what is compared.
321
+ if (read(redactedDetail) !== raw)
322
+ return null;
323
+ const ref = { adapter: adapterName, id: raw };
324
+ return providerRefRecordable(ref) ? ref : null;
325
+ }
326
+ // ---------------------------------------------------------------------------
327
+ // Refusals
328
+ // ---------------------------------------------------------------------------
329
+ /**
330
+ * Everything {@link executeThroughAdapter} can refuse. Frozen public API, per
331
+ * SPEC.md §11.1(6), and a strict superset of {@link EXECUTE_REFUSAL_CODES}:
332
+ * every core refusal surfaces verbatim rather than being collapsed into an
333
+ * adapter-flavoured one, because `token-consumed`, `payload-mismatch` and
334
+ * `budget-exceeded` call for three different responses whether the caller is an
335
+ * adapter or `approval run`.
336
+ */
337
+ export const ADAPTER_REFUSAL_CODES = [
338
+ ...EXECUTE_REFUSAL_CODES,
339
+ /** Request intake could not find the task registration. */
340
+ "not-registered",
341
+ /** A concurrent caller opened the live-selected request first. */
342
+ "duplicate-request",
343
+ /** Live-selected intake reached the approver queue ceiling. */
344
+ "queue-full",
345
+ /** Live-selected intake reached the origin's request rate limit. */
346
+ "rate-limited",
347
+ /** A selected live action had no declaration hash to bind. */
348
+ "payload-hash-required",
349
+ /** A selected live self-delivery address could not be created. */
350
+ "token-delivery-unavailable",
351
+ /** Live intake could not retain the exact payload for human display or audit. */
352
+ "payload-store-failed",
353
+ /**
354
+ * The adapter does not serve the class this action was declared under.
355
+ * Refused before anything is appended: routing an action to the wrong
356
+ * executor is a wiring mistake, and a wiring mistake must not consume a
357
+ * single-use token or leave a dangling execution behind.
358
+ */
359
+ "adapter-class-mismatch",
360
+ /**
361
+ * The payload has no RFC 8785 canonical form, so there is no hash to check
362
+ * against the grant. Nothing is appended and no token is spent.
363
+ */
364
+ "payload-unhashable",
365
+ /**
366
+ * `act` ran and reported failure. `execution.failed` WAS appended: the side
367
+ * effect was attempted, and the log says so. `adapter_code` carries the
368
+ * adapter's own reason.
369
+ */
370
+ "adapter-failed",
371
+ /**
372
+ * A throw on the way to `act`, before it was entered: assembling the
373
+ * credential window, or reading the adapter's own method. Nothing was
374
+ * attempted, so `execution.failed` is the honest record and the caller may
375
+ * fix its wiring and try again.
376
+ *
377
+ * A throw from INSIDE `act` is a different code (`execution-indeterminate`)
378
+ * and a different event, because the outcome is then unknown (APRV-120).
379
+ *
380
+ * Only the error's `message` is kept — never the stack, which routinely
381
+ * quotes arguments and would be a credential-shaped leak with a plausible
382
+ * excuse — and even that message passes the redaction guard.
383
+ */
384
+ "adapter-act-threw",
385
+ /**
386
+ * A credential the adapter declared in {@link Adapter.requiredCredentials}
387
+ * could not be resolved (APRV-169). Refused BEFORE the token is consumed and
388
+ * before `execution.started` is appended, so the grant survives: the log is
389
+ * left exactly as it was found and the same token is spendable once the
390
+ * credential appears.
391
+ *
392
+ * The provider's own reason (`credential-unavailable`, `credential-refused`)
393
+ * rides in `adapter_code`, because "nobody stored an SMTP password" and "the
394
+ * vault would not open" are two different repairs.
395
+ */
396
+ "credential-unavailable",
397
+ /**
398
+ * The adapter's own {@link Adapter.precheck} answered no (APRV-276). Refused
399
+ * BEFORE the token is consumed and before `execution.started` is appended, so
400
+ * the grant survives exactly as it does for `credential-unavailable`: the log
401
+ * is left as it was found and the same token is spendable once the condition
402
+ * the precheck named is repaired.
403
+ *
404
+ * The adapter's own reason rides in `adapter_code`
405
+ * (`agentmail-draft-drifted`, say), because the repair belongs to the far
406
+ * side's vocabulary and this union cannot enumerate it.
407
+ *
408
+ * A precheck that throws lands here too, under `adapter_code`
409
+ * `precheck-threw`: a check that could not be performed is not a check that
410
+ * passed, and the fail-closed answer costs nothing, since nothing was
411
+ * attempted.
412
+ */
413
+ "adapter-precheck-refused",
414
+ ];
415
+ /** The exit code recorded for an execution the adapter did not complete. */
416
+ const ADAPTER_FAILURE_EXIT_CODE = 1;
417
+ /**
418
+ * Does `token` match the digest the log's grant for `actionKey` recorded?
419
+ *
420
+ * A pure comparison over records this path has already read and verified, and
421
+ * deliberately NOT a second opinion about whether the token may be spent:
422
+ * `core/token.ts` owns TTL, revocation and the single-use check, and
423
+ * `startExecution` runs all three before anything is appended. What this answers
424
+ * is the narrower question the pre-token phase needs: does the caller hold the
425
+ * token a human's grant minted for this action?
426
+ *
427
+ * Constant-time, through `digestsEqual`. `false` for everything else: no grant,
428
+ * no recorded digest, no token.
429
+ */
430
+ function tokenMatchesGrant(records, actionKey, token) {
431
+ if (token === undefined || token.length === 0)
432
+ return false;
433
+ let recorded;
434
+ for (const record of records) {
435
+ if (record.event !== "approval.granted")
436
+ continue;
437
+ if (record.action_key !== actionKey)
438
+ continue;
439
+ recorded = payloadOf(record)[TOKEN_HASH_FIELD];
440
+ }
441
+ if (typeof recorded !== "string" || recorded.length === 0)
442
+ return false;
443
+ return digestsEqual(tokenHash(token), recorded);
444
+ }
445
+ /**
446
+ * Does the log bind this action to exactly the bytes the caller presented?
447
+ *
448
+ * Read for one purpose (APRV-276): deciding whether {@link Adapter.precheck}
449
+ * may run at all. A precheck is handed the payload, and every word of its
450
+ * contract assumes those bytes are the approved ones — AgentMail compares the
451
+ * live draft against them and calls a difference drift. Handed bytes no human
452
+ * approved, the same comparison is a question about the wrong snapshot, and its
453
+ * answer is noise at best: a refusal naming the caller's own edit as the far
454
+ * side's drift, or a pass that says a tampered payload matches the draft.
455
+ *
456
+ * So this is a precondition and never a verdict. It answers no and the precheck
457
+ * is SKIPPED, not refused: `startExecution` is the authority on content binding
458
+ * and refuses `payload-mismatch` in its own words a few lines later, with
459
+ * nothing appended and the token still live. Two modules refusing the same fact
460
+ * is two places for the reason to drift.
461
+ *
462
+ * The binding it compares against is the one that path's authorization actually
463
+ * uses, which is why both are read here: the grant's recorded `payload_hash` on
464
+ * the manual path (`core/token.ts`), and the registered declaration's off it
465
+ * (`core/execute.ts`), with the declaration standing in for a grant that
466
+ * recorded none, exactly as `verifyToken` lets it. A binding that exists
467
+ * nowhere answers no, so the strict path is the default: an action whose bytes
468
+ * nothing in the log states is one no precheck may reason about.
469
+ */
470
+ function logBindsPayload(records, actionKey, declared, hash) {
471
+ let bound = declared.payload_hash;
472
+ for (const record of records) {
473
+ if (record.event !== "approval.granted")
474
+ continue;
475
+ if (record.action_key !== actionKey)
476
+ continue;
477
+ const recorded = payloadOf(record)[PAYLOAD_HASH_FIELD];
478
+ bound = typeof recorded === "string" && recorded.length > 0 ? recorded : declared.payload_hash;
479
+ }
480
+ if (bound === null)
481
+ return false;
482
+ return digestsEqual(bound, hash);
483
+ }
484
+ /**
485
+ * Hand `grant` to a provider that asked to be told, and swallow whatever it does
486
+ * about it.
487
+ *
488
+ * A provider is not required to implement `grant`, and one that implements it
489
+ * badly must not be able to fail an execution: this call carries no secret, no
490
+ * decision, and nothing the contract needs back. Every path that leaves the
491
+ * execution passes `null` through here, so a capability opened for a window is
492
+ * closed on every exit, refusals included.
493
+ */
494
+ function tell(provider, grant) {
495
+ try {
496
+ provider.grant?.(grant);
497
+ }
498
+ catch {
499
+ // Nothing to report and nothing to repair: the contract asked, not asked for.
500
+ }
501
+ }
502
+ /**
503
+ * Resolve every credential the adapter declared it cannot act without, before
504
+ * the token is consumed (APRV-169).
505
+ *
506
+ * The ordering this exists to establish, stated once: a credential the runtime
507
+ * cannot reach is a configuration fault, and a configuration fault must not
508
+ * spend a human's single-use grant. Resolving here means a
509
+ * `credential-unavailable` refusal costs no authority: nothing is appended, the
510
+ * token stays spendable, and the same token executes once the credential
511
+ * appears.
512
+ *
513
+ * What this does NOT reorder is the consume-then-execute sequence for the side
514
+ * effect itself. `startExecution` still consumes the token and appends
515
+ * `execution.started` before `act` is called, because that ordering is what
516
+ * makes a crash between the two an ambiguity the log can SEE rather than one it
517
+ * is silent about (APRV-120). Credentials move ahead of the token; the side
518
+ * effect does not.
519
+ *
520
+ * The reads happen in a window of their own that closes immediately, so a
521
+ * provider handed here is never left live outside a scope, and every value it
522
+ * hands over joins the redaction corpus of the refusal this may return. Nothing
523
+ * read here is kept or returned: what comes back is whether the name resolved,
524
+ * and `act` asks for the values itself inside the verified execution window.
525
+ *
526
+ * Note what an unauthorized caller learns by invoking this path: whether the
527
+ * names THIS ADAPTER statically declared are present in a provider the caller
528
+ * supplied in the first place. It is not a channel for asking about arbitrary
529
+ * names, and a caller holding the provider could ask it directly anyway.
530
+ */
531
+ function resolveRequiredCredentials(adapter, actionKey, inner) {
532
+ const names = adapter.requiredCredentials ?? [];
533
+ if (names.length === 0)
534
+ return { ok: true, issued: new Set() };
535
+ const scope = scopeCredentials(inner);
536
+ try {
537
+ for (const name of names) {
538
+ let got;
539
+ try {
540
+ got = scope.provider.get(name);
541
+ }
542
+ catch (error) {
543
+ // A provider is required to be total. One that throws anyway is a
544
+ // configuration this runtime cannot use, and it is reported as one
545
+ // rather than allowed to escape: nothing here throws.
546
+ got = {
547
+ ok: false,
548
+ code: "credential-unavailable",
549
+ message: `the credential provider raised instead of answering: ${error instanceof Error ? error.message : String(error)}`,
550
+ };
551
+ }
552
+ if (got.ok)
553
+ continue;
554
+ const redacted = redactSecrets(`the ${adapter.name} adapter declares that it cannot act without the credential ${JSON.stringify(name)}, and it did not resolve (${got.code}): ${got.message}. Nothing was appended and no token was spent: credentials resolve before the token is consumed (SPEC.md §10.4, APRV-169), so this refusal costs no authority and the same token executes once the credential is reachable.`, scope.issued);
555
+ return {
556
+ ok: false,
557
+ credentialCode: got.code,
558
+ message: redacted.text,
559
+ redactions: redacted.hits,
560
+ };
561
+ }
562
+ return { ok: true, issued: scope.issued };
563
+ }
564
+ finally {
565
+ scope.close();
566
+ }
567
+ }
568
+ /**
569
+ * Ask the adapter what it can find out before the token is spent (APRV-276).
570
+ *
571
+ * The ordering this exists to establish, stated once and alongside
572
+ * {@link resolveRequiredCredentials}'s: a condition that makes the side effect
573
+ * impossible, and that this runtime can learn without attempting it, must not
574
+ * cost a human's single-use grant. A credential nobody stored was the first
575
+ * such condition (APRV-169); a draft the agent edited after the human read it
576
+ * is the second, and the difference between them is only whose fault it is.
577
+ * Both refuse with the log untouched and the token spendable.
578
+ *
579
+ * What this does NOT reorder is the consume-then-execute sequence for the side
580
+ * effect itself, for the reason APRV-120 gives: `startExecution` still consumes
581
+ * the token and appends `execution.started` before `act` is called, so a crash
582
+ * between the two is an ambiguity the log can SEE. Nor does it move a check OUT
583
+ * of `act`: an adapter that prechecks a condition checks it again inside the
584
+ * window, because the far side can move in between and the check that binds the
585
+ * bytes actually sent is the later one.
586
+ *
587
+ * The window is its own and closes immediately, exactly as the credential
588
+ * resolution's does, and every value the provider handed over joins the
589
+ * redaction corpus of whatever this returns. So does `inherited`, everything
590
+ * the resolution above already handed this adapter, and it has to: a precheck
591
+ * that throws typically throws holding a secret it was given a step earlier and
592
+ * never asked this window for, so scanning only what THIS window issued would
593
+ * scan an empty set and print the credential. An adapter that implements no
594
+ * precheck pays nothing: the function returns at its first line.
595
+ *
596
+ * Total: a precheck that throws is reported as a refusal rather than allowed to
597
+ * escape. A check that could not be performed is not a check that passed, and
598
+ * failing closed here is free, since nothing has been attempted.
599
+ */
600
+ async function runPrecheck(adapter, actionKey, payload, inner, inherited, signal) {
601
+ const precheck = adapter.precheck;
602
+ if (precheck === undefined)
603
+ return { ok: true, issued: new Set() };
604
+ const scope = scopeCredentials(inner);
605
+ try {
606
+ let outcome;
607
+ try {
608
+ const input = {
609
+ actionKey,
610
+ payload,
611
+ credentials: scope.provider,
612
+ ...(signal === undefined ? {} : { signal }),
613
+ };
614
+ outcome = await precheck.call(adapter, input);
615
+ }
616
+ catch (error) {
617
+ // The message and nothing else, for `act`'s reason: a stack trace quotes
618
+ // call arguments, and a credential passed as one would ride out inside an
619
+ // error report.
620
+ outcome = {
621
+ ok: false,
622
+ code: "precheck-threw",
623
+ message: `the ${adapter.name} adapter's pre-token check raised instead of answering: ${error instanceof Error ? error.message : String(error)}`,
624
+ };
625
+ }
626
+ if (outcome.ok)
627
+ return { ok: true, issued: scope.issued };
628
+ // Everything this window issued, plus everything the resolution above
629
+ // already handed over. A refusal is printed, and both sets are secrets it
630
+ // could be printing.
631
+ const secrets = new Set(inherited);
632
+ for (const secret of scope.issued)
633
+ secrets.add(secret);
634
+ const code = redactSecrets(outcome.code, secrets);
635
+ const message = redactSecrets(`${adapter.name} refused action ${actionKey} before the token was spent (${outcome.code}): ${outcome.message}. Nothing was appended and no token was spent: an adapter's pre-token check runs before the token is consumed (SPEC.md §10.4, APRV-276), so this refusal costs no authority and the same token executes once the condition it names is repaired.`, secrets);
636
+ return {
637
+ ok: false,
638
+ adapterCode: code.text,
639
+ message: message.text,
640
+ redactions: code.hits + message.hits,
641
+ };
642
+ }
643
+ finally {
644
+ scope.close();
645
+ }
646
+ }
647
+ /**
648
+ * Copy the core-relevant options across, and bind the hash the contract
649
+ * computed. Built explicitly rather than spread so that a future field added to
650
+ * {@link AdapterExecuteOptions} (a credential provider, a transport handle) is
651
+ * not silently forwarded into core.
652
+ */
653
+ function executeOptionsFrom(options, presentedPayloadHash) {
654
+ return {
655
+ ...(options.token === undefined ? {} : { token: options.token }),
656
+ ...(options.policy === undefined ? {} : { policy: options.policy }),
657
+ ...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
658
+ ...(options.append === undefined ? {} : { append: options.append }),
659
+ ...(options.clock === undefined ? {} : { clock: options.clock }),
660
+ ...(options.keyStoreDir === undefined ? {} : { keyStoreDir: options.keyStoreDir }),
661
+ ...(options.retryOnHeadMoved === undefined
662
+ ? {}
663
+ : { retryOnHeadMoved: options.retryOnHeadMoved }),
664
+ presentedPayloadHash,
665
+ };
666
+ }
667
+ function liveIntakeOptionsFrom(options) {
668
+ return {
669
+ ...(options.policy === undefined ? {} : { policy: options.policy }),
670
+ ...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
671
+ ...(options.append === undefined ? {} : { append: options.append }),
672
+ ...(options.clock === undefined ? {} : { clock: options.clock }),
673
+ ...(options.keyStoreDir === undefined ? {} : { keyStoreDir: options.keyStoreDir }),
674
+ ...(options.retryOnHeadMoved === undefined
675
+ ? {}
676
+ : { retryOnHeadMoved: options.retryOnHeadMoved }),
677
+ ...(options.liveIntake?.env === undefined ? {} : { env: options.liveIntake.env }),
678
+ ...(options.liveIntake?.drawAsk === undefined
679
+ ? {}
680
+ : { drawAsk: options.liveIntake.drawAsk }),
681
+ };
682
+ }
683
+ function refuse(adapter, actionKey, code, message, extra = {}) {
684
+ return {
685
+ ok: false,
686
+ code,
687
+ message,
688
+ adapter: adapter.name,
689
+ action_key: actionKey,
690
+ acted: false,
691
+ redactions: 0,
692
+ ...extra,
693
+ };
694
+ }
695
+ /**
696
+ * Execute one approved action through `adapter`, and own every step around the
697
+ * adapter's own.
698
+ *
699
+ * The order, and why it is this order:
700
+ *
701
+ * 1. **Hash the payload.** Before any log read, because a payload with no
702
+ * canonical form has nothing to check and nothing to execute.
703
+ * 2. **Read the declaration** from the verified log and check the class. Both
704
+ * before `startExecution`, so a misrouted action leaves the log exactly as it
705
+ * found it. (The log is read twice on this path — once here, once inside
706
+ * `startExecution`, which reads for itself and compare-and-appends against
707
+ * the head it read. That is not redundancy to remove: a routing check that
708
+ * handed its records to core would be core trusting a caller's snapshot.)
709
+ * 3. **Resolve the declared credentials** (APRV-169), in a window of their own
710
+ * that closes at once. A name the provider cannot answer refuses
711
+ * `credential-unavailable` here, with the log untouched and the token
712
+ * unspent, so a missing secret costs no authority and the same token works
713
+ * once the secret appears. An adapter declaring none skips this entirely.
714
+ * 3b. **The adapter's own pre-token check** (APRV-276), in a window of its own,
715
+ * on the same presented-phase grant. Whatever it refuses is refused with the
716
+ * log untouched and the token unspent, so a condition the runtime could
717
+ * learn without attempting the side effect costs no authority to discover.
718
+ * An adapter implementing none skips this entirely, and so does a payload
719
+ * the log does not bind this action to: step 4 owns that refusal.
720
+ * 4. **`startExecution`**, which on the manual path verifies and consumes the
721
+ * token, refuses `payload-mismatch` against the digest from step 1, and
722
+ * appends `execution.started`. Any refusal here returns with `acted: false`;
723
+ * `act` is not called, so no side effect was attempted.
724
+ * 5. **`act`**, inside a credential window that closes the moment it returns.
725
+ * 6. **The outcome event**, and WHICH one depends on where things went wrong
726
+ * (APRV-120). `act` returning success is `execution.completed`; `act`
727
+ * returning a failure is `execution.failed`, because the provider answered
728
+ * and the answer was no; a throw on the way INTO `act` is `execution.failed`
729
+ * too, because nothing was attempted; and a throw from inside `act` is
730
+ * `execution.indeterminate`, because the provider may or may not have
731
+ * committed and this runtime cannot tell. The boundary is the invocation
732
+ * itself, not a judgment about the error.
733
+ *
734
+ * A refusal from step 6 is returned with `started_seq` set and the log left
735
+ * holding a dangling execution — which is the honest state, since the side
736
+ * effect did happen and its outcome could not be recorded. `approval status`
737
+ * reports it and `approval execution resolve` is how a human closes it. An
738
+ * indeterminate outcome is not that: it IS recorded, the consumption stays
739
+ * burned, a retry is refused, and `approval execution reconcile` is how a
740
+ * person resolves it from the relying party's own evidence.
741
+ */
742
+ export async function executeThroughAdapter(adapter, request, options = {}) {
743
+ const { logPath, actionKey, payload, actor } = request;
744
+ // (a) The hash, computed here from the bytes, never accepted from a caller.
745
+ let hash;
746
+ try {
747
+ hash = payloadHash(payload);
748
+ }
749
+ catch (error) {
750
+ return refuse(adapter, actionKey, "payload-unhashable", `the payload for ${actionKey} has no RFC 8785 canonical serialization (${error instanceof Error ? error.message : String(error)}), so it cannot be hashed and cannot be shown to be the bytes the grant or registered declaration bound. Nothing was appended.`);
751
+ }
752
+ // (b) The declared class, from the verified log.
753
+ const read = readVerifiedRecords(logPath, options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir });
754
+ if (!read.ok)
755
+ return refuse(adapter, actionKey, read.code, read.message);
756
+ const declaring = declaringTasks(read.records, actionKey);
757
+ if (declaring.length > 1) {
758
+ return refuse(adapter, actionKey, "action-not-registered", `action key ${JSON.stringify(actionKey)} is declared by more than one task (${declaring.join(", ")}); the runtime refuses an ambiguous declaration rather than route the later one. Registration refuses such collisions (APRV-138).`);
759
+ }
760
+ const declared = findDeclaration(read.records, actionKey);
761
+ if (declared === null) {
762
+ return refuse(adapter, actionKey, "action-not-registered", `no task.registered record declares an action with idempotency_key ${JSON.stringify(actionKey)}; SPEC.md §7 requires a class to be declared before the action can execute, and an adapter cannot supply the declaration on the action's behalf.`);
763
+ }
764
+ if (!adapter.classes.includes(declared.class)) {
765
+ return refuse(adapter, actionKey, "adapter-class-mismatch", `adapter ${JSON.stringify(adapter.name)} serves ${adapter.classes.length === 0 ? "no classes" : adapter.classes.map((cls) => JSON.stringify(cls)).join(", ")}, and action ${actionKey} is declared under class ${JSON.stringify(declared.class)}. The action was routed to the wrong executor; nothing was appended and no token was spent.`);
766
+ }
767
+ // Supervised-live selection belongs to gate intake. Its unselected result is
768
+ // intentionally absent from the log, so an adapter cannot infer that intake
769
+ // happened merely because no approval.requested exists. On a genuinely
770
+ // no-token, no-cycle call, invoke the existing request path from fields read
771
+ // exclusively from the verified declaration. Selected or unavailable draws
772
+ // create the ordinary pending cycle; an unselected draw appends no approval
773
+ // event and continues. A prior cycle, including a rejected or expired one,
774
+ // is never redrawn here.
775
+ const policyOptions = options.policy ?? {};
776
+ const load = loadPolicy({
777
+ ...(policyOptions.file === undefined
778
+ ? { dir: policyOptions.dir ?? process.cwd() }
779
+ : { file: policyOptions.file }),
780
+ ...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
781
+ });
782
+ const initialResolution = resolve(load, declared.class, declared.reversible === null ? {} : { reversible: declared.reversible });
783
+ let livePolicySha256;
784
+ if ((options.token === undefined || options.token.length === 0) &&
785
+ initialResolution.supervision === "live" &&
786
+ !hasApprovalCycle(read.records, actionKey)) {
787
+ const intake = requestApproval(logPath, {
788
+ task: declared.task,
789
+ actionKey,
790
+ cls: declared.class,
791
+ est_cost_usd: declared.est_cost_usd,
792
+ ...(declared.reversible === null ? {} : { reversible: declared.reversible }),
793
+ ...(declared.summary === null ? {} : { summary: declared.summary }),
794
+ ...(declared.payload_hash === null ? {} : { payload_hash: declared.payload_hash }),
795
+ payload: { value: payload },
796
+ delivery: "self",
797
+ }, actor, liveIntakeOptionsFrom(options));
798
+ if (!intake.ok) {
799
+ return refuse(adapter, actionKey, intake.code, intake.message);
800
+ }
801
+ if (intake.proceed && intake.live !== undefined) {
802
+ livePolicySha256 = intake.policySha256;
803
+ }
804
+ }
805
+ // A no-token path must prove that core would admit this exact execution
806
+ // before credentials or a provider-backed precheck are touched. This result
807
+ // is only a preflight: startExecution repeats every check after precheck and
808
+ // remains the sole writer of execution.started.
809
+ const eligibilityOptions = {
810
+ ...executeOptionsFrom(options, hash),
811
+ ...(livePolicySha256 === undefined
812
+ ? {}
813
+ : { expectedPolicySha256: livePolicySha256 }),
814
+ };
815
+ const eligibility = checkExecutionEligibility(logPath, actionKey, eligibilityOptions, actor);
816
+ if (!eligibility.ok) {
817
+ return refuse(adapter, actionKey, eligibility.code, eligibility.message, {
818
+ execute: eligibility,
819
+ });
820
+ }
821
+ const effectiveToken = eligibility.mode === "token" ? eligibility.token : undefined;
822
+ // (c) The credentials the adapter declared it cannot act without, resolved
823
+ // BEFORE the token is consumed (APRV-169). See
824
+ // {@link resolveRequiredCredentials} for why this sits here and why the
825
+ // consume-then-execute ordering below is untouched.
826
+ const provider = options.credentials ?? NO_CREDENTIALS;
827
+ // The presented-phase grant (APRV-168). Minted only when the caller's token
828
+ // matches the digest a human's grant recorded for this action, so a provider
829
+ // may offer a capability here on the strength of that decision. Everything
830
+ // that decides whether the token may actually be SPENT still happens below,
831
+ // in `startExecution`, and nothing here appends or consumes.
832
+ const presented = tokenMatchesGrant(read.records, actionKey, effectiveToken)
833
+ ? { phase: "presented", actionKey, startedSeq: null, autonomy: null }
834
+ : null;
835
+ tell(provider, presented);
836
+ const resolved = resolveRequiredCredentials(adapter, actionKey, provider);
837
+ if (!resolved.ok) {
838
+ tell(provider, null);
839
+ return refuse(adapter, actionKey, "credential-unavailable", resolved.message, {
840
+ adapter_code: resolved.credentialCode,
841
+ redactions: resolved.redactions,
842
+ });
843
+ }
844
+ // (c2) The adapter's own pre-token check (APRV-276), in a window of its own,
845
+ // still on the presented-phase grant. A refusal here appends nothing and
846
+ // spends nothing, for the same reason (c) does.
847
+ //
848
+ // Skipped outright unless the log binds this action to the bytes in
849
+ // hand: a precheck asked about a payload no human approved is being
850
+ // asked the wrong question, and answering it would let an adapter's own
851
+ // vocabulary describe what is really a `payload-mismatch`. Those bytes
852
+ // get no precheck and no far-side request; `startExecution` refuses them
853
+ // below, in core's words, with the log untouched and the token live.
854
+ const prechecked = logBindsPayload(read.records, actionKey, declared, hash)
855
+ ? await runPrecheck(adapter, actionKey, payload, provider, resolved.issued, options.signal)
856
+ : { ok: true, issued: new Set() };
857
+ if (!prechecked.ok) {
858
+ tell(provider, null);
859
+ return refuse(adapter, actionKey, "adapter-precheck-refused", prechecked.message, {
860
+ adapter_code: prechecked.adapterCode,
861
+ redactions: prechecked.redactions,
862
+ });
863
+ }
864
+ // (d) Authorization and the start event. Refused here means act never runs.
865
+ const executeOptions = {
866
+ ...eligibilityOptions,
867
+ ...(effectiveToken === undefined ? {} : { token: effectiveToken }),
868
+ };
869
+ const started = startExecution(logPath, actionKey, executeOptions, actor);
870
+ if (!started.ok) {
871
+ tell(provider, null);
872
+ return refuse(adapter, actionKey, started.code, started.message, { execute: started });
873
+ }
874
+ const startedSeq = started.record.seq;
875
+ // (e) The adapter's own step, inside the credential window.
876
+ //
877
+ // `entered` is the custody boundary of APRV-120, and it is positional rather
878
+ // than a judgment: everything up to and including the read of `adapter.act`
879
+ // is preparation this runtime performed and can speak for, and the instant
880
+ // after it the call is the far side's. A throw on the near side is
881
+ // `execution.failed` — nothing was attempted. A throw on the far side is
882
+ // `execution.indeterminate` — the provider may or may not have committed, and
883
+ // saying "failed" about it is the assertion that produces double sends.
884
+ const scope = scopeCredentials(provider);
885
+ // Everything the pre-token resolution was handed is already a secret this
886
+ // path may be about to print, so it joins the corpus before `act` runs rather
887
+ // than only if `act` happens to ask for the same names again. The precheck's
888
+ // window is closed by now and its values join for the same reason.
889
+ for (const secret of resolved.issued)
890
+ scope.issued.add(secret);
891
+ for (const secret of prechecked.issued)
892
+ scope.issued.add(secret);
893
+ // The window is now a GRANTED one, and the provider is told so (APRV-168).
894
+ // Minted here because this is the only place that can: the brand on
895
+ // `ExecutionGrant` is a symbol no other module can name. It is dropped in the
896
+ // same `finally` that closes the window, so the capability it carries lives
897
+ // exactly as long as `act` does.
898
+ // The brand is a type-level marker with no runtime member (a `declare const
899
+ // unique symbol` emits nothing), so the cast is what mints it. That is the
900
+ // point: the cast compiles here and refuses to compile anywhere the brand
901
+ // cannot be named, which is everywhere else.
902
+ tell(provider, {
903
+ phase: "consumed",
904
+ actionKey,
905
+ startedSeq,
906
+ autonomy: started.autonomy,
907
+ ...(started.tokenSha256 === undefined ? {} : { tokenSha256: started.tokenSha256 }),
908
+ });
909
+ let entered = false;
910
+ let outcome;
911
+ let threw = null;
912
+ try {
913
+ const input = {
914
+ actionKey,
915
+ payload,
916
+ credentials: scope.provider,
917
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
918
+ };
919
+ const act = adapter.act.bind(adapter);
920
+ entered = true;
921
+ outcome = await act(input);
922
+ }
923
+ catch (error) {
924
+ // The message and nothing else: a stack trace quotes call arguments, and a
925
+ // credential passed as one would ride out of here inside an error report.
926
+ threw = error instanceof Error ? error.message : String(error);
927
+ outcome = { ok: false, code: "adapter-act-threw", message: threw };
928
+ }
929
+ finally {
930
+ scope.close();
931
+ // The window and the grant end together. A provider that kept the grant is
932
+ // holding a value the contract no longer honours, and it was told so.
933
+ tell(provider, null);
934
+ }
935
+ // (f) The redaction sweep, THEN the outcome event, then the redacted result.
936
+ //
937
+ // The sweep runs first because one thing it produces now goes into the record
938
+ // rather than only into the result: the provider reference of APRV-251, which
939
+ // the adapter names inside its own detail and which therefore passes exactly
940
+ // the scan every other returned string passes before anything writes it down.
941
+ // Nothing else about the ordering matters — the sweep reads the outcome and
942
+ // the issued secrets, both settled the moment `act` returned.
943
+ const secrets = scope.issued;
944
+ const unknown = threw !== null && entered;
945
+ const exitCode = outcome.ok ? 0 : ADAPTER_FAILURE_EXIT_CODE;
946
+ const failureCode = threw === null ? "adapter-failed" : "adapter-act-threw";
947
+ const rawMessage = outcome.ok ? "" : outcome.message;
948
+ const message = redactSecrets(rawMessage, secrets);
949
+ const adapterCode = redactSecrets(outcome.ok ? "" : outcome.code, secrets);
950
+ const detail = outcome.ok && outcome.detail !== undefined
951
+ ? redactJson(outcome.detail, secrets)
952
+ : { value: null, hits: 0 };
953
+ const redactions = message.hits + adapterCode.hits + detail.hits;
954
+ // Only a completion has an effect for a provider to have filed, and only the
955
+ // adapter can say what its receipt called it. The `adapter` half is this
956
+ // runtime's own knowledge of which adapter it called, never a claim the
957
+ // detail makes about itself.
958
+ const providerRef = outcome.ok
959
+ ? providerRefFor(adapter.name, outcome.detail, detail.value)
960
+ : null;
961
+ const finished = unknown
962
+ ? indeterminateExecution(logPath, actionKey, "act-threw", actor, executeOptions)
963
+ : finishExecution(logPath, actionKey, exitCode, actor, {
964
+ ...executeOptions,
965
+ ...(providerRef === null ? {} : { providerRef }),
966
+ });
967
+ if (!finished.ok) {
968
+ return {
969
+ ok: false,
970
+ code: finished.code,
971
+ message: `${adapter.name} ${outcome.ok ? "completed" : "did not complete"} action ${actionKey}, and the outcome could not be recorded: ${finished.message}. The side effect was attempted and the log now holds a dangling execution; close it with \`approval execution resolve\`.`,
972
+ adapter: adapter.name,
973
+ action_key: actionKey,
974
+ acted: entered,
975
+ started_seq: startedSeq,
976
+ execute: finished,
977
+ redactions,
978
+ };
979
+ }
980
+ if (unknown) {
981
+ // The message is the adapter's, redacted, and it reaches the CALLER only:
982
+ // the record carries the closed reason and nothing else (APRV-120 #3).
983
+ return {
984
+ ok: false,
985
+ code: "execution-indeterminate",
986
+ message: `${adapter.name} entered act for ${actionKey} and raised, so the log records execution.indeterminate at seq ${finished.record.seq}: the side effect was attempted and nobody knows whether it committed. The token is spent and the idempotency key is burned; a retry is refused. Establish what happened and record it with \`approval execution reconcile\`. The adapter reported: ${message.text}`,
987
+ adapter: adapter.name,
988
+ action_key: actionKey,
989
+ acted: true,
990
+ started_seq: startedSeq,
991
+ outcome: "execution.indeterminate",
992
+ outcome_seq: finished.record.seq,
993
+ adapter_code: adapterCode.text,
994
+ redactions,
995
+ };
996
+ }
997
+ if (!outcome.ok) {
998
+ return {
999
+ ok: false,
1000
+ code: failureCode,
1001
+ message: message.text,
1002
+ adapter: adapter.name,
1003
+ action_key: actionKey,
1004
+ // A throw BEFORE act was entered attempted nothing: the credential window
1005
+ // or the adapter's own method raised, and no side effect was reached.
1006
+ acted: entered,
1007
+ started_seq: startedSeq,
1008
+ outcome: "execution.failed",
1009
+ outcome_seq: finished.record.seq,
1010
+ exit_code: exitCode,
1011
+ adapter_code: adapterCode.text,
1012
+ redactions,
1013
+ };
1014
+ }
1015
+ return {
1016
+ ok: true,
1017
+ adapter: adapter.name,
1018
+ action_key: actionKey,
1019
+ task: started.task,
1020
+ class: started.class,
1021
+ autonomy: started.autonomy,
1022
+ payload_hash: hash,
1023
+ started_seq: startedSeq,
1024
+ outcome: "execution.completed",
1025
+ outcome_seq: finished.record.seq,
1026
+ exit_code: 0,
1027
+ ...(outcome.detail === undefined ? {} : { detail: detail.value }),
1028
+ // What the log now says this effect is called on the provider's side, so a
1029
+ // caller reads the recorded reference rather than re-deriving it from the
1030
+ // detail and reaching a different answer (APRV-251).
1031
+ ...(providerRef === null ? {} : { provider_ref: providerRef }),
1032
+ redactions,
1033
+ };
1034
+ }
1035
+ //# sourceMappingURL=contract.js.map