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.
- package/LICENSE +176 -0
- package/NOTICE +5 -0
- package/README.md +940 -4
- package/SPEC.md +476 -34
- package/cli.js +29 -3
- package/dist/src/adapters/agentmail.d.ts +426 -0
- package/dist/src/adapters/agentmail.js +1200 -0
- package/dist/src/adapters/agentmail.js.map +1 -0
- package/dist/src/adapters/conformance.d.ts +149 -0
- package/dist/src/adapters/conformance.js +461 -0
- package/dist/src/adapters/conformance.js.map +1 -0
- package/dist/src/adapters/contract.d.ts +628 -0
- package/dist/src/adapters/contract.js +1035 -0
- package/dist/src/adapters/contract.js.map +1 -0
- package/dist/src/adapters/email.d.ts +324 -0
- package/dist/src/adapters/email.js +749 -0
- package/dist/src/adapters/email.js.map +1 -0
- package/dist/src/adapters/env-passphrase.d.ts +93 -0
- package/dist/src/adapters/env-passphrase.js +132 -0
- package/dist/src/adapters/env-passphrase.js.map +1 -0
- package/dist/src/adapters/public.d.ts +11 -0
- package/dist/src/adapters/public.js +11 -0
- package/dist/src/adapters/public.js.map +1 -0
- package/dist/src/adapters/registry.d.ts +59 -0
- package/dist/src/adapters/registry.js +77 -0
- package/dist/src/adapters/registry.js.map +1 -0
- package/dist/src/adapters/smtp.d.ts +213 -0
- package/dist/src/adapters/smtp.js +499 -0
- package/dist/src/adapters/smtp.js.map +1 -0
- package/dist/src/adapters/vault-provider.d.ts +114 -0
- package/dist/src/adapters/vault-provider.js +161 -0
- package/dist/src/adapters/vault-provider.js.map +1 -0
- package/dist/src/adapters/zzz.d.ts +66 -0
- package/dist/src/adapters/zzz.js +299 -0
- package/dist/src/adapters/zzz.js.map +1 -0
- package/dist/src/channels/batch.d.ts +109 -0
- package/dist/src/channels/batch.js +121 -0
- package/dist/src/channels/batch.js.map +1 -0
- package/dist/src/channels/cli.d.ts +193 -0
- package/dist/src/channels/cli.js +468 -0
- package/dist/src/channels/cli.js.map +1 -0
- package/dist/src/channels/conformance.d.ts +92 -0
- package/dist/src/channels/conformance.js +445 -0
- package/dist/src/channels/conformance.js.map +1 -0
- package/dist/src/channels/contract.d.ts +623 -0
- package/dist/src/channels/contract.js +494 -0
- package/dist/src/channels/contract.js.map +1 -0
- package/dist/src/channels/payload-view.d.ts +35 -0
- package/dist/src/channels/payload-view.js +43 -0
- package/dist/src/channels/payload-view.js.map +1 -0
- package/dist/src/channels/render-queue.d.ts +149 -0
- package/dist/src/channels/render-queue.js +564 -0
- package/dist/src/channels/render-queue.js.map +1 -0
- package/dist/src/channels/tagging.d.ts +196 -0
- package/dist/src/channels/tagging.js +723 -0
- package/dist/src/channels/tagging.js.map +1 -0
- package/dist/src/channels/telegram.d.ts +1832 -0
- package/dist/src/channels/telegram.js +3190 -0
- package/dist/src/channels/telegram.js.map +1 -0
- package/dist/src/channels/web.d.ts +341 -0
- package/dist/src/channels/web.js +903 -0
- package/dist/src/channels/web.js.map +1 -0
- package/dist/src/cli/adapter.d.ts +90 -0
- package/dist/src/cli/adapter.js +288 -0
- package/dist/src/cli/adapter.js.map +1 -0
- package/dist/src/cli/amend.d.ts +59 -0
- package/dist/src/cli/amend.js +2171 -0
- package/dist/src/cli/amend.js.map +1 -0
- package/dist/src/cli/args.d.ts +43 -0
- package/dist/src/cli/args.js +86 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/attest.d.ts +41 -0
- package/dist/src/cli/attest.js +307 -0
- package/dist/src/cli/attest.js.map +1 -0
- package/dist/src/cli/audit-card.d.ts +62 -0
- package/dist/src/cli/audit-card.js +201 -0
- package/dist/src/cli/audit-card.js.map +1 -0
- package/dist/src/cli/audit.d.ts +59 -0
- package/dist/src/cli/audit.js +460 -0
- package/dist/src/cli/audit.js.map +1 -0
- package/dist/src/cli/channel-telegram.d.ts +806 -0
- package/dist/src/cli/channel-telegram.js +2063 -0
- package/dist/src/cli/channel-telegram.js.map +1 -0
- package/dist/src/cli/channel-web.d.ts +131 -0
- package/dist/src/cli/channel-web.js +357 -0
- package/dist/src/cli/channel-web.js.map +1 -0
- package/dist/src/cli/channel.d.ts +71 -0
- package/dist/src/cli/channel.js +438 -0
- package/dist/src/cli/channel.js.map +1 -0
- package/dist/src/cli/checkpoint-tap.d.ts +169 -0
- package/dist/src/cli/checkpoint-tap.js +238 -0
- package/dist/src/cli/checkpoint-tap.js.map +1 -0
- package/dist/src/cli/codex.d.ts +2 -0
- package/dist/src/cli/codex.js +172 -0
- package/dist/src/cli/codex.js.map +1 -0
- package/dist/src/cli/coverage.d.ts +61 -0
- package/dist/src/cli/coverage.js +343 -0
- package/dist/src/cli/coverage.js.map +1 -0
- package/dist/src/cli/daemon.d.ts +120 -0
- package/dist/src/cli/daemon.js +631 -0
- package/dist/src/cli/daemon.js.map +1 -0
- package/dist/src/cli/doctor.d.ts +129 -0
- package/dist/src/cli/doctor.js +2762 -0
- package/dist/src/cli/doctor.js.map +1 -0
- package/dist/src/cli/env.d.ts +65 -0
- package/dist/src/cli/env.js +302 -0
- package/dist/src/cli/env.js.map +1 -0
- package/dist/src/cli/execute.d.ts +202 -0
- package/dist/src/cli/execute.js +1682 -0
- package/dist/src/cli/execute.js.map +1 -0
- package/dist/src/cli/exit-codes.d.ts +73 -0
- package/dist/src/cli/exit-codes.js +82 -0
- package/dist/src/cli/exit-codes.js.map +1 -0
- package/dist/src/cli/feedback.d.ts +60 -0
- package/dist/src/cli/feedback.js +205 -0
- package/dist/src/cli/feedback.js.map +1 -0
- package/dist/src/cli/gate-window.d.ts +40 -0
- package/dist/src/cli/gate-window.js +294 -0
- package/dist/src/cli/gate-window.js.map +1 -0
- package/dist/src/cli/gate.d.ts +68 -0
- package/dist/src/cli/gate.js +557 -0
- package/dist/src/cli/gate.js.map +1 -0
- package/dist/src/cli/git-scope.d.ts +190 -0
- package/dist/src/cli/git-scope.js +295 -0
- package/dist/src/cli/git-scope.js.map +1 -0
- package/dist/src/cli/gloss-attach.d.ts +85 -0
- package/dist/src/cli/gloss-attach.js +107 -0
- package/dist/src/cli/gloss-attach.js.map +1 -0
- package/dist/src/cli/gloss-codex-child.d.ts +9 -0
- package/dist/src/cli/gloss-codex-child.js +149 -0
- package/dist/src/cli/gloss-codex-child.js.map +1 -0
- package/dist/src/cli/gloss-codex.d.ts +24 -0
- package/dist/src/cli/gloss-codex.js +255 -0
- package/dist/src/cli/gloss-codex.js.map +1 -0
- package/dist/src/cli/gloss-options.d.ts +42 -0
- package/dist/src/cli/gloss-options.js +79 -0
- package/dist/src/cli/gloss-options.js.map +1 -0
- package/dist/src/cli/gloss.d.ts +265 -0
- package/dist/src/cli/gloss.js +362 -0
- package/dist/src/cli/gloss.js.map +1 -0
- package/dist/src/cli/help.d.ts +103 -0
- package/dist/src/cli/help.js +2339 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/hook-codex.d.ts +78 -0
- package/dist/src/cli/hook-codex.js +167 -0
- package/dist/src/cli/hook-codex.js.map +1 -0
- package/dist/src/cli/hook.d.ts +331 -0
- package/dist/src/cli/hook.js +2849 -0
- package/dist/src/cli/hook.js.map +1 -0
- package/dist/src/cli/import.d.ts +35 -0
- package/dist/src/cli/import.js +175 -0
- package/dist/src/cli/import.js.map +1 -0
- package/dist/src/cli/init.d.ts +84 -0
- package/dist/src/cli/init.js +336 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/cli/instructions.d.ts +23 -0
- package/dist/src/cli/instructions.js +262 -0
- package/dist/src/cli/instructions.js.map +1 -0
- package/dist/src/cli/journal.d.ts +41 -0
- package/dist/src/cli/journal.js +238 -0
- package/dist/src/cli/journal.js.map +1 -0
- package/dist/src/cli/log-advance.d.ts +287 -0
- package/dist/src/cli/log-advance.js +840 -0
- package/dist/src/cli/log-advance.js.map +1 -0
- package/dist/src/cli/log-anchor.d.ts +176 -0
- package/dist/src/cli/log-anchor.js +387 -0
- package/dist/src/cli/log-anchor.js.map +1 -0
- package/dist/src/cli/log-checkpoint.d.ts +22 -0
- package/dist/src/cli/log-checkpoint.js +128 -0
- package/dist/src/cli/log-checkpoint.js.map +1 -0
- package/dist/src/cli/log-sync.d.ts +243 -0
- package/dist/src/cli/log-sync.js +849 -0
- package/dist/src/cli/log-sync.js.map +1 -0
- package/dist/src/cli/log-verbs.d.ts +16 -0
- package/dist/src/cli/log-verbs.js +360 -0
- package/dist/src/cli/log-verbs.js.map +1 -0
- package/dist/src/cli/long-help.d.ts +70 -0
- package/dist/src/cli/long-help.js +148 -0
- package/dist/src/cli/long-help.js.map +1 -0
- package/dist/src/cli/main.d.ts +77 -0
- package/dist/src/cli/main.js +1206 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/mcp.d.ts +52 -0
- package/dist/src/cli/mcp.js +306 -0
- package/dist/src/cli/mcp.js.map +1 -0
- package/dist/src/cli/paths.d.ts +56 -0
- package/dist/src/cli/paths.js +79 -0
- package/dist/src/cli/paths.js.map +1 -0
- package/dist/src/cli/payload.d.ts +58 -0
- package/dist/src/cli/payload.js +253 -0
- package/dist/src/cli/payload.js.map +1 -0
- package/dist/src/cli/policy.d.ts +43 -0
- package/dist/src/cli/policy.js +229 -0
- package/dist/src/cli/policy.js.map +1 -0
- package/dist/src/cli/preflight.d.ts +363 -0
- package/dist/src/cli/preflight.js +1175 -0
- package/dist/src/cli/preflight.js.map +1 -0
- package/dist/src/cli/progress.d.ts +78 -0
- package/dist/src/cli/progress.js +112 -0
- package/dist/src/cli/progress.js.map +1 -0
- package/dist/src/cli/prompt.d.ts +209 -0
- package/dist/src/cli/prompt.js +312 -0
- package/dist/src/cli/prompt.js.map +1 -0
- package/dist/src/cli/quickstart.d.ts +46 -0
- package/dist/src/cli/quickstart.js +297 -0
- package/dist/src/cli/quickstart.js.map +1 -0
- package/dist/src/cli/records.d.ts +34 -0
- package/dist/src/cli/records.js +66 -0
- package/dist/src/cli/records.js.map +1 -0
- package/dist/src/cli/render.d.ts +22 -0
- package/dist/src/cli/render.js +132 -0
- package/dist/src/cli/render.js.map +1 -0
- package/dist/src/cli/sandbox.d.ts +51 -0
- package/dist/src/cli/sandbox.js +150 -0
- package/dist/src/cli/sandbox.js.map +1 -0
- package/dist/src/cli/scaffold.d.ts +79 -0
- package/dist/src/cli/scaffold.js +137 -0
- package/dist/src/cli/scaffold.js.map +1 -0
- package/dist/src/cli/setup-adapter.d.ts +137 -0
- package/dist/src/cli/setup-adapter.js +509 -0
- package/dist/src/cli/setup-adapter.js.map +1 -0
- package/dist/src/cli/setup-channel.d.ts +117 -0
- package/dist/src/cli/setup-channel.js +635 -0
- package/dist/src/cli/setup-channel.js.map +1 -0
- package/dist/src/cli/setup-checkpoint.d.ts +57 -0
- package/dist/src/cli/setup-checkpoint.js +196 -0
- package/dist/src/cli/setup-checkpoint.js.map +1 -0
- package/dist/src/cli/setup-common.d.ts +275 -0
- package/dist/src/cli/setup-common.js +376 -0
- package/dist/src/cli/setup-common.js.map +1 -0
- package/dist/src/cli/setup-flow.d.ts +287 -0
- package/dist/src/cli/setup-flow.js +476 -0
- package/dist/src/cli/setup-flow.js.map +1 -0
- package/dist/src/cli/setup-service.d.ts +96 -0
- package/dist/src/cli/setup-service.js +308 -0
- package/dist/src/cli/setup-service.js.map +1 -0
- package/dist/src/cli/setup.d.ts +202 -0
- package/dist/src/cli/setup.js +473 -0
- package/dist/src/cli/setup.js.map +1 -0
- package/dist/src/cli/style.d.ts +320 -0
- package/dist/src/cli/style.js +469 -0
- package/dist/src/cli/style.js.map +1 -0
- package/dist/src/cli/token.d.ts +39 -0
- package/dist/src/cli/token.js +274 -0
- package/dist/src/cli/token.js.map +1 -0
- package/dist/src/cli/up.d.ts +155 -0
- package/dist/src/cli/up.js +849 -0
- package/dist/src/cli/up.js.map +1 -0
- package/dist/src/cli/usage.d.ts +37 -0
- package/dist/src/cli/usage.js +91 -0
- package/dist/src/cli/usage.js.map +1 -0
- package/dist/src/cli/values.d.ts +40 -0
- package/dist/src/cli/values.js +189 -0
- package/dist/src/cli/values.js.map +1 -0
- package/dist/src/cli/vault.d.ts +59 -0
- package/dist/src/cli/vault.js +362 -0
- package/dist/src/cli/vault.js.map +1 -0
- package/dist/src/cli/verb-registry.d.ts +76 -0
- package/dist/src/cli/verb-registry.js +2341 -0
- package/dist/src/cli/verb-registry.js.map +1 -0
- package/dist/src/cli/wordmark.d.ts +31 -0
- package/dist/src/cli/wordmark.js +52 -0
- package/dist/src/cli/wordmark.js.map +1 -0
- package/dist/src/codex/doctor.d.ts +13 -0
- package/dist/src/codex/doctor.js +41 -0
- package/dist/src/codex/doctor.js.map +1 -0
- package/dist/src/codex/manifest.d.ts +49 -0
- package/dist/src/codex/manifest.js +103 -0
- package/dist/src/codex/manifest.js.map +1 -0
- package/dist/src/codex/templates.d.ts +41 -0
- package/dist/src/codex/templates.js +319 -0
- package/dist/src/codex/templates.js.map +1 -0
- package/dist/src/codex/trust.d.ts +19 -0
- package/dist/src/codex/trust.js +183 -0
- package/dist/src/codex/trust.js.map +1 -0
- package/dist/src/codex/workspace-plan.d.ts +131 -0
- package/dist/src/codex/workspace-plan.js +561 -0
- package/dist/src/codex/workspace-plan.js.map +1 -0
- package/dist/src/core/actor.d.ts +2 -0
- package/dist/src/core/actor.js +5 -0
- package/dist/src/core/actor.js.map +1 -0
- package/dist/src/core/advance-cycle.d.ts +170 -0
- package/dist/src/core/advance-cycle.js +200 -0
- package/dist/src/core/advance-cycle.js.map +1 -0
- package/dist/src/core/agents-md.d.ts +276 -0
- package/dist/src/core/agents-md.js +747 -0
- package/dist/src/core/agents-md.js.map +1 -0
- package/dist/src/core/apply-patch.d.ts +49 -0
- package/dist/src/core/apply-patch.js +266 -0
- package/dist/src/core/apply-patch.js.map +1 -0
- package/dist/src/core/attest.d.ts +420 -0
- package/dist/src/core/attest.js +589 -0
- package/dist/src/core/attest.js.map +1 -0
- package/dist/src/core/audit.d.ts +492 -0
- package/dist/src/core/audit.js +882 -0
- package/dist/src/core/audit.js.map +1 -0
- package/dist/src/core/budgets.d.ts +238 -0
- package/dist/src/core/budgets.js +449 -0
- package/dist/src/core/budgets.js.map +1 -0
- package/dist/src/core/checkpoint.d.ts +500 -0
- package/dist/src/core/checkpoint.js +738 -0
- package/dist/src/core/checkpoint.js.map +1 -0
- package/dist/src/core/child-env.d.ts +88 -0
- package/dist/src/core/child-env.js +86 -0
- package/dist/src/core/child-env.js.map +1 -0
- package/dist/src/core/clock.d.ts +52 -0
- package/dist/src/core/clock.js +43 -0
- package/dist/src/core/clock.js.map +1 -0
- package/dist/src/core/command-class.d.ts +543 -0
- package/dist/src/core/command-class.js +2356 -0
- package/dist/src/core/command-class.js.map +1 -0
- package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
- package/dist/src/core/coverage-sources/adapter.js +71 -0
- package/dist/src/core/coverage-sources/adapter.js.map +1 -0
- package/dist/src/core/coverage-sources/gh.d.ts +48 -0
- package/dist/src/core/coverage-sources/gh.js +136 -0
- package/dist/src/core/coverage-sources/gh.js.map +1 -0
- package/dist/src/core/coverage-sources/git.d.ts +101 -0
- package/dist/src/core/coverage-sources/git.js +269 -0
- package/dist/src/core/coverage-sources/git.js.map +1 -0
- package/dist/src/core/coverage.d.ts +217 -0
- package/dist/src/core/coverage.js +337 -0
- package/dist/src/core/coverage.js.map +1 -0
- package/dist/src/core/credential-spec.d.ts +72 -0
- package/dist/src/core/credential-spec.js +23 -0
- package/dist/src/core/credential-spec.js.map +1 -0
- package/dist/src/core/dark-session.d.ts +331 -0
- package/dist/src/core/dark-session.js +714 -0
- package/dist/src/core/dark-session.js.map +1 -0
- package/dist/src/core/decision-refusal.d.ts +185 -0
- package/dist/src/core/decision-refusal.js +265 -0
- package/dist/src/core/decision-refusal.js.map +1 -0
- package/dist/src/core/env-file.d.ts +450 -0
- package/dist/src/core/env-file.js +837 -0
- package/dist/src/core/env-file.js.map +1 -0
- package/dist/src/core/execute.d.ts +858 -0
- package/dist/src/core/execute.js +1271 -0
- package/dist/src/core/execute.js.map +1 -0
- package/dist/src/core/frontmatter.d.ts +78 -0
- package/dist/src/core/frontmatter.js +100 -0
- package/dist/src/core/frontmatter.js.map +1 -0
- package/dist/src/core/gate-window.d.ts +312 -0
- package/dist/src/core/gate-window.js +506 -0
- package/dist/src/core/gate-window.js.map +1 -0
- package/dist/src/core/gate.d.ts +1364 -0
- package/dist/src/core/gate.js +3002 -0
- package/dist/src/core/gate.js.map +1 -0
- package/dist/src/core/git-run.d.ts +73 -0
- package/dist/src/core/git-run.js +93 -0
- package/dist/src/core/git-run.js.map +1 -0
- package/dist/src/core/harness-version.d.ts +157 -0
- package/dist/src/core/harness-version.js +211 -0
- package/dist/src/core/harness-version.js.map +1 -0
- package/dist/src/core/harness-wait.d.ts +55 -0
- package/dist/src/core/harness-wait.js +58 -0
- package/dist/src/core/harness-wait.js.map +1 -0
- package/dist/src/core/head-retry.d.ts +107 -0
- package/dist/src/core/head-retry.js +121 -0
- package/dist/src/core/head-retry.js.map +1 -0
- package/dist/src/core/instance.d.ts +253 -0
- package/dist/src/core/instance.js +319 -0
- package/dist/src/core/instance.js.map +1 -0
- package/dist/src/core/intake-limits.d.ts +247 -0
- package/dist/src/core/intake-limits.js +350 -0
- package/dist/src/core/intake-limits.js.map +1 -0
- package/dist/src/core/jcs.d.ts +52 -0
- package/dist/src/core/jcs.js +132 -0
- package/dist/src/core/jcs.js.map +1 -0
- package/dist/src/core/journal.d.ts +144 -0
- package/dist/src/core/journal.js +200 -0
- package/dist/src/core/journal.js.map +1 -0
- package/dist/src/core/live-draw.d.ts +436 -0
- package/dist/src/core/live-draw.js +703 -0
- package/dist/src/core/live-draw.js.map +1 -0
- package/dist/src/core/log-reconcile.d.ts +89 -0
- package/dist/src/core/log-reconcile.js +136 -0
- package/dist/src/core/log-reconcile.js.map +1 -0
- package/dist/src/core/log-subscribe.d.ts +36 -0
- package/dist/src/core/log-subscribe.js +162 -0
- package/dist/src/core/log-subscribe.js.map +1 -0
- package/dist/src/core/log.d.ts +278 -0
- package/dist/src/core/log.js +546 -0
- package/dist/src/core/log.js.map +1 -0
- package/dist/src/core/loop.d.ts +274 -0
- package/dist/src/core/loop.js +487 -0
- package/dist/src/core/loop.js.map +1 -0
- package/dist/src/core/md-fence.d.ts +41 -0
- package/dist/src/core/md-fence.js +74 -0
- package/dist/src/core/md-fence.js.map +1 -0
- package/dist/src/core/money.d.ts +147 -0
- package/dist/src/core/money.js +195 -0
- package/dist/src/core/money.js.map +1 -0
- package/dist/src/core/payload-census.d.ts +74 -0
- package/dist/src/core/payload-census.js +146 -0
- package/dist/src/core/payload-census.js.map +1 -0
- package/dist/src/core/payload-store.d.ts +175 -0
- package/dist/src/core/payload-store.js +340 -0
- package/dist/src/core/payload-store.js.map +1 -0
- package/dist/src/core/payload.d.ts +71 -0
- package/dist/src/core/payload.js +80 -0
- package/dist/src/core/payload.js.map +1 -0
- package/dist/src/core/policy-diff.d.ts +292 -0
- package/dist/src/core/policy-diff.js +588 -0
- package/dist/src/core/policy-diff.js.map +1 -0
- package/dist/src/core/policy-expectations.d.ts +199 -0
- package/dist/src/core/policy-expectations.js +394 -0
- package/dist/src/core/policy-expectations.js.map +1 -0
- package/dist/src/core/policy-explain.d.ts +150 -0
- package/dist/src/core/policy-explain.js +258 -0
- package/dist/src/core/policy-explain.js.map +1 -0
- package/dist/src/core/policy-load.d.ts +527 -0
- package/dist/src/core/policy-load.js +536 -0
- package/dist/src/core/policy-load.js.map +1 -0
- package/dist/src/core/policy-match.d.ts +281 -0
- package/dist/src/core/policy-match.js +478 -0
- package/dist/src/core/policy-match.js.map +1 -0
- package/dist/src/core/policy-proposal.d.ts +265 -0
- package/dist/src/core/policy-proposal.js +458 -0
- package/dist/src/core/policy-proposal.js.map +1 -0
- package/dist/src/core/prompt-layout.d.ts +221 -0
- package/dist/src/core/prompt-layout.js +422 -0
- package/dist/src/core/prompt-layout.js.map +1 -0
- package/dist/src/core/protected-path-guard.d.ts +453 -0
- package/dist/src/core/protected-path-guard.js +1566 -0
- package/dist/src/core/protected-path-guard.js.map +1 -0
- package/dist/src/core/registration.d.ts +25 -0
- package/dist/src/core/registration.js +39 -0
- package/dist/src/core/registration.js.map +1 -0
- package/dist/src/core/reindex.d.ts +99 -0
- package/dist/src/core/reindex.js +336 -0
- package/dist/src/core/reindex.js.map +1 -0
- package/dist/src/core/sampler.d.ts +313 -0
- package/dist/src/core/sampler.js +388 -0
- package/dist/src/core/sampler.js.map +1 -0
- package/dist/src/core/sandbox.d.ts +290 -0
- package/dist/src/core/sandbox.js +424 -0
- package/dist/src/core/sandbox.js.map +1 -0
- package/dist/src/core/seal.d.ts +165 -0
- package/dist/src/core/seal.js +290 -0
- package/dist/src/core/seal.js.map +1 -0
- package/dist/src/core/state.d.ts +505 -0
- package/dist/src/core/state.js +1009 -0
- package/dist/src/core/state.js.map +1 -0
- package/dist/src/core/task-file.d.ts +185 -0
- package/dist/src/core/task-file.js +464 -0
- package/dist/src/core/task-file.js.map +1 -0
- package/dist/src/core/telegram-config.d.ts +93 -0
- package/dist/src/core/telegram-config.js +114 -0
- package/dist/src/core/telegram-config.js.map +1 -0
- package/dist/src/core/token.d.ts +409 -0
- package/dist/src/core/token.js +561 -0
- package/dist/src/core/token.js.map +1 -0
- package/dist/src/core/validate.d.ts +138 -0
- package/dist/src/core/validate.js +0 -0
- package/dist/src/core/validate.js.map +1 -0
- package/dist/src/core/values.d.ts +137 -0
- package/dist/src/core/values.js +153 -0
- package/dist/src/core/values.js.map +1 -0
- package/dist/src/core/vault.d.ts +291 -0
- package/dist/src/core/vault.js +612 -0
- package/dist/src/core/vault.js.map +1 -0
- package/dist/src/core/verified-snapshot.d.ts +204 -0
- package/dist/src/core/verified-snapshot.js +506 -0
- package/dist/src/core/verified-snapshot.js.map +1 -0
- package/dist/src/core/verify.d.ts +336 -0
- package/dist/src/core/verify.js +549 -0
- package/dist/src/core/verify.js.map +1 -0
- package/dist/src/core/version.d.ts +8 -0
- package/dist/src/core/version.js +9 -0
- package/dist/src/core/version.js.map +1 -0
- package/dist/src/core/wysiwys.d.ts +370 -0
- package/dist/src/core/wysiwys.js +728 -0
- package/dist/src/core/wysiwys.js.map +1 -0
- package/dist/src/daemon/advance-child.d.ts +39 -0
- package/dist/src/daemon/advance-child.js +78 -0
- package/dist/src/daemon/advance-child.js.map +1 -0
- package/dist/src/daemon/advance.d.ts +466 -0
- package/dist/src/daemon/advance.js +849 -0
- package/dist/src/daemon/advance.js.map +1 -0
- package/dist/src/daemon/audit.d.ts +87 -0
- package/dist/src/daemon/audit.js +90 -0
- package/dist/src/daemon/audit.js.map +1 -0
- package/dist/src/daemon/daemon.d.ts +1180 -0
- package/dist/src/daemon/daemon.js +1988 -0
- package/dist/src/daemon/daemon.js.map +1 -0
- package/dist/src/daemon/dark-session.d.ts +64 -0
- package/dist/src/daemon/dark-session.js +119 -0
- package/dist/src/daemon/dark-session.js.map +1 -0
- package/dist/src/daemon/draw-child.d.ts +36 -0
- package/dist/src/daemon/draw-child.js +132 -0
- package/dist/src/daemon/draw-child.js.map +1 -0
- package/dist/src/daemon/draw.d.ts +154 -0
- package/dist/src/daemon/draw.js +458 -0
- package/dist/src/daemon/draw.js.map +1 -0
- package/dist/src/daemon/git-evidence.d.ts +173 -0
- package/dist/src/daemon/git-evidence.js +345 -0
- package/dist/src/daemon/git-evidence.js.map +1 -0
- package/dist/src/daemon/projection.d.ts +180 -0
- package/dist/src/daemon/projection.js +233 -0
- package/dist/src/daemon/projection.js.map +1 -0
- package/dist/src/daemon/prune.d.ts +207 -0
- package/dist/src/daemon/prune.js +376 -0
- package/dist/src/daemon/prune.js.map +1 -0
- package/dist/src/mcp/http.d.ts +113 -0
- package/dist/src/mcp/http.js +343 -0
- package/dist/src/mcp/http.js.map +1 -0
- package/dist/src/mcp/server.d.ts +265 -0
- package/dist/src/mcp/server.js +602 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/docs/adapter-api.md +106 -0
- package/docs/cli-reference.md +5716 -0
- package/docs/codex-enforced-session.md +30 -0
- package/package.json +53 -4
- package/schema/.gitkeep +0 -0
- package/schema/LICENSE +117 -0
- package/schema/codex-instance.schema.json +82 -0
- package/schema/envelope.schema.json +137 -0
- package/schema/event.schema.json +1811 -0
- package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
- package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
- package/schema/fixtures/envelope/invalid/action-missing-idempotency-key.json +15 -0
- package/schema/fixtures/envelope/invalid/action-unknown-class-format.json +14 -0
- package/schema/fixtures/envelope/invalid/confidence-out-of-range.json +11 -0
- package/schema/fixtures/envelope/invalid/est-cost-bare-number.json +14 -0
- package/schema/fixtures/envelope/invalid/est-cost-noncanonical-string.json +14 -0
- package/schema/fixtures/envelope/invalid/malformed-assignee.json +10 -0
- package/schema/fixtures/envelope/invalid/malformed-created-by.json +7 -0
- package/schema/fixtures/envelope/invalid/malformed-max-latency.json +11 -0
- package/schema/fixtures/envelope/invalid/malformed-payload-hash.json +14 -0
- package/schema/fixtures/envelope/invalid/max-cost-bare-number.json +11 -0
- package/schema/fixtures/envelope/invalid/missing-origin.json +3 -0
- package/schema/fixtures/envelope/invalid/negative-est-cost.json +14 -0
- package/schema/fixtures/envelope/invalid/unknown-state.json +7 -0
- package/schema/fixtures/envelope/invalid/unknown-top-level-field.json +8 -0
- package/schema/fixtures/envelope/valid/action-payload-hash.json +17 -0
- package/schema/fixtures/envelope/valid/actions-without-budget.json +18 -0
- package/schema/fixtures/envelope/valid/canonical.json +25 -0
- package/schema/fixtures/envelope/valid/minimal.json +7 -0
- package/schema/fixtures/envelope/valid/multi-action-executed.json +30 -0
- package/schema/fixtures/envelope/valid/record-write-stage.json +22 -0
- package/schema/fixtures/event/invalid/approval-granted-agent-actor.json +15 -0
- package/schema/fixtures/event/invalid/approval-granted-empty-batch-delivery-id.json +17 -0
- package/schema/fixtures/event/invalid/approval-granted-fifth-reaction.json +16 -0
- package/schema/fixtures/event/invalid/approval-granted-missing-actor.json +14 -0
- package/schema/fixtures/event/invalid/approval-requested-missing-action-key.json +14 -0
- package/schema/fixtures/event/invalid/approval-withdrawn-agent-policy-drift.json +15 -0
- package/schema/fixtures/event/invalid/approval-withdrawn-missing-reason.json +15 -0
- package/schema/fixtures/event/invalid/approval-withdrawn-system-actor.json +15 -0
- package/schema/fixtures/event/invalid/audit-decision-refused-human-actor.json +17 -0
- package/schema/fixtures/event/invalid/audit-decision-refused-missing-code.json +16 -0
- package/schema/fixtures/event/invalid/audit-reviewed-agent-actor.json +15 -0
- package/schema/fixtures/event/invalid/audit-reviewed-loved-no-note.json +16 -0
- package/schema/fixtures/event/invalid/audit-reviewed-system-actor.json +15 -0
- package/schema/fixtures/event/invalid/bad-actor-prefix.json +15 -0
- package/schema/fixtures/event/invalid/est-cost-bare-number.json +17 -0
- package/schema/fixtures/event/invalid/execution-completed-fabricated-exit-code.json +16 -0
- package/schema/fixtures/event/invalid/execution-completed-provider-ref-empty-id.json +18 -0
- package/schema/fixtures/event/invalid/execution-completed-provider-ref-extra-field.json +19 -0
- package/schema/fixtures/event/invalid/execution-completed-provider-ref-id-not-string.json +18 -0
- package/schema/fixtures/event/invalid/execution-completed-provider-ref-missing-adapter.json +17 -0
- package/schema/fixtures/event/invalid/execution-failed-open-reported-by.json +16 -0
- package/schema/fixtures/event/invalid/execution-indeterminate-open-reason.json +14 -0
- package/schema/fixtures/event/invalid/execution-reconciled-agent-actor.json +17 -0
- package/schema/fixtures/event/invalid/execution-started-negative-env-stripped.json +16 -0
- package/schema/fixtures/event/invalid/gate-bypassed-missing-opened-seq.json +15 -0
- package/schema/fixtures/event/invalid/gate-closed-non-integer-opened-seq.json +13 -0
- package/schema/fixtures/event/invalid/gate-opened-agent-actor.json +16 -0
- package/schema/fixtures/event/invalid/gate-organ-attested-absolute-path.json +14 -0
- package/schema/fixtures/event/invalid/gate-organ-attested-agent-actor.json +14 -0
- package/schema/fixtures/event/invalid/gate-organ-attested-missing-organ-path.json +13 -0
- package/schema/fixtures/event/invalid/harness-unknown-kind.json +18 -0
- package/schema/fixtures/event/invalid/harness-version-multiline.json +16 -0
- package/schema/fixtures/event/invalid/log-checkpoint-agent-actor.json +17 -0
- package/schema/fixtures/event/invalid/log-checkpoint-missing-signature.json +16 -0
- package/schema/fixtures/event/invalid/log-checkpoint-short-signed-hash.json +17 -0
- package/schema/fixtures/event/invalid/log-checkpoint-unknown-signature-alg.json +17 -0
- package/schema/fixtures/event/invalid/malformed-ts.json +15 -0
- package/schema/fixtures/event/invalid/missing-alg.json +14 -0
- package/schema/fixtures/event/invalid/missing-hash.json +14 -0
- package/schema/fixtures/event/invalid/non-integer-seq.json +15 -0
- package/schema/fixtures/event/invalid/payload-pruned-human-actor.json +14 -0
- package/schema/fixtures/event/invalid/payload-pruned-missing-hash.json +14 -0
- package/schema/fixtures/event/invalid/policy-declined-agent-actor.json +15 -0
- package/schema/fixtures/event/invalid/policy-proposed-missing-diff.json +19 -0
- package/schema/fixtures/event/invalid/policy-proposed-system-actor.json +26 -0
- package/schema/fixtures/event/invalid/short-hash.json +15 -0
- package/schema/fixtures/event/invalid/unknown-alg.json +15 -0
- package/schema/fixtures/event/invalid/unknown-event-type.json +15 -0
- package/schema/fixtures/event/invalid/unknown-top-level-field.json +16 -0
- package/schema/fixtures/event/valid/approval-expired.json +15 -0
- package/schema/fixtures/event/valid/approval-granted-batch.json +19 -0
- package/schema/fixtures/event/valid/approval-granted-reaction.json +16 -0
- package/schema/fixtures/event/valid/approval-granted.json +15 -0
- package/schema/fixtures/event/valid/approval-rejected.json +15 -0
- package/schema/fixtures/event/valid/approval-requested.json +19 -0
- package/schema/fixtures/event/valid/approval-revoked.json +15 -0
- package/schema/fixtures/event/valid/approval-withdrawn-policy-drift.json +17 -0
- package/schema/fixtures/event/valid/approval-withdrawn.json +16 -0
- package/schema/fixtures/event/valid/audit-decision-refused.json +20 -0
- package/schema/fixtures/event/valid/audit-reviewed-reaction.json +17 -0
- package/schema/fixtures/event/valid/audit-reviewed.json +15 -0
- package/schema/fixtures/event/valid/audit-sampled.json +14 -0
- package/schema/fixtures/event/valid/budget-exceeded.json +21 -0
- package/schema/fixtures/event/valid/envelope-drift.json +16 -0
- package/schema/fixtures/event/valid/execution-completed-harness-report.json +16 -0
- package/schema/fixtures/event/valid/execution-completed-provider-ref.json +18 -0
- package/schema/fixtures/event/valid/execution-completed.json +15 -0
- package/schema/fixtures/event/valid/execution-failed-harness-report.json +16 -0
- package/schema/fixtures/event/valid/execution-failed.json +15 -0
- package/schema/fixtures/event/valid/execution-indeterminate.json +15 -0
- package/schema/fixtures/event/valid/execution-reconciled.json +17 -0
- package/schema/fixtures/event/valid/execution-started-env-stripped.json +17 -0
- package/schema/fixtures/event/valid/execution-started.json +14 -0
- package/schema/fixtures/event/valid/gate-bypassed-harness-version.json +18 -0
- package/schema/fixtures/event/valid/gate-bypassed.json +19 -0
- package/schema/fixtures/event/valid/gate-closed.json +14 -0
- package/schema/fixtures/event/valid/gate-opened.json +16 -0
- package/schema/fixtures/event/valid/gate-organ-attested.json +14 -0
- package/schema/fixtures/event/valid/genesis-null-prev.json +14 -0
- package/schema/fixtures/event/valid/log-checkpoint.json +17 -0
- package/schema/fixtures/event/valid/payload-pruned-orphan.json +13 -0
- package/schema/fixtures/event/valid/payload-pruned.json +17 -0
- package/schema/fixtures/event/valid/policy-declined.json +16 -0
- package/schema/fixtures/event/valid/policy-proposed.json +35 -0
- package/schema/fixtures/event/valid/policy-updated.json +14 -0
- package/schema/fixtures/event/valid/reconciliation-required.json +18 -0
- package/schema/fixtures/event/valid/reconciliation-satisfied.json +17 -0
- package/schema/fixtures/event/valid/route-accepted.json +15 -0
- package/schema/fixtures/event/valid/route-proposed.json +16 -0
- package/schema/fixtures/event/valid/spec-example.json +15 -0
- package/schema/fixtures/event/valid/task-registered-harness-version.json +23 -0
- package/schema/fixtures/event/valid/task-registered.json +14 -0
- package/schema/fixtures/hash/known-answer-pre-121.json +74 -0
- package/schema/fixtures/hash/known-answer.json +74 -0
- package/schema/fixtures/policy/invalid/bad-approval-ttl.json +7 -0
- package/schema/fixtures/policy/invalid/bad-web-port.json +4 -0
- package/schema/fixtures/policy/invalid/checkpoint-key-not-base64.json +6 -0
- package/schema/fixtures/policy/invalid/class-rule-missing-autonomy.json +9 -0
- package/schema/fixtures/policy/invalid/empty-class-key.json +6 -0
- package/schema/fixtures/policy/invalid/live-rate-on-human-only.json +7 -0
- package/schema/fixtures/policy/invalid/malformed-class-key.json +6 -0
- package/schema/fixtures/policy/invalid/missing-version.json +8 -0
- package/schema/fixtures/policy/invalid/negative-limit.json +9 -0
- package/schema/fixtures/policy/invalid/non-numeric-limit.json +9 -0
- package/schema/fixtures/policy/invalid/non-positive-max-pending.json +9 -0
- package/schema/fixtures/policy/invalid/on-expiry-grant.json +8 -0
- package/schema/fixtures/policy/invalid/payload-retention-bare-number.json +4 -0
- package/schema/fixtures/policy/invalid/payload-retention-compound.json +4 -0
- package/schema/fixtures/policy/invalid/payload-retention-fractional.json +4 -0
- package/schema/fixtures/policy/invalid/payload-retention-zero.json +4 -0
- package/schema/fixtures/policy/invalid/protected-paths-escape.json +4 -0
- package/schema/fixtures/policy/invalid/protected-paths-glob.json +4 -0
- package/schema/fixtures/policy/invalid/retro-rate-on-human-only.json +7 -0
- package/schema/fixtures/policy/invalid/retro-rate-on-manual.json +7 -0
- package/schema/fixtures/policy/invalid/retro-rate-zero.json +7 -0
- package/schema/fixtures/policy/invalid/sample-rate-too-high.json +5 -0
- package/schema/fixtures/policy/invalid/sampling-secret-env-empty.json +7 -0
- package/schema/fixtures/policy/invalid/sampling-secret-env-not-string.json +6 -0
- package/schema/fixtures/policy/invalid/skew-tolerance-compound.json +6 -0
- package/schema/fixtures/policy/invalid/unknown-autonomy.json +7 -0
- package/schema/fixtures/policy/invalid/unknown-class-rule-key.json +6 -0
- package/schema/fixtures/policy/invalid/unknown-top-level-key.json +7 -0
- package/schema/fixtures/policy/invalid/vault-passphrase-env-empty.json +6 -0
- package/schema/fixtures/policy/invalid/vault-passphrase-literal.json +6 -0
- package/schema/fixtures/policy/invalid/version-not-string.json +4 -0
- package/schema/fixtures/policy/valid/canonical.json +47 -0
- package/schema/fixtures/policy/valid/checkpoint-keys.json +18 -0
- package/schema/fixtures/policy/valid/class-approvers-limits.json +25 -0
- package/schema/fixtures/policy/valid/class-retro-rate.json +17 -0
- package/schema/fixtures/policy/valid/global-budgets.json +19 -0
- package/schema/fixtures/policy/valid/human-only.json +9 -0
- package/schema/fixtures/policy/valid/minimal.json +6 -0
- package/schema/fixtures/policy/valid/protected-paths.json +10 -0
- package/schema/fixtures/policy/valid/record-namespace.json +13 -0
- package/schema/fixtures/policy/valid/request-volume-limits.json +26 -0
- package/schema/fixtures/policy/valid/retention-and-sampling-secret.json +16 -0
- package/schema/fixtures/policy/valid/skew-tolerance.json +15 -0
- package/schema/fixtures/policy/valid/vault-passphrase-env.json +14 -0
- package/schema/fixtures/policy/valid/wildcards.json +15 -0
- package/schema/fixtures/policy-md/invalid/alias-bomb.md +15 -0
- package/schema/fixtures/policy-md/invalid/no-fence.md +7 -0
- package/schema/fixtures/policy-md/invalid/protected-route-not-a-subclass.md +16 -0
- package/schema/fixtures/policy-md/invalid/schema-invalid-autonomy.md +16 -0
- package/schema/fixtures/policy-md/invalid/schema-invalid-read-proof.md +17 -0
- package/schema/fixtures/policy-md/invalid/two-fences.md +19 -0
- package/schema/fixtures/policy-md/invalid/unclosed-fence.md +11 -0
- package/schema/fixtures/policy-md/invalid/wrong-info-string.md +11 -0
- package/schema/fixtures/policy-md/invalid/yaml-syntax-error.md +13 -0
- package/schema/fixtures/policy-md/precedence/both/APPROVAL.md +7 -0
- package/schema/fixtures/policy-md/precedence/both/APPROVALS.md +7 -0
- package/schema/fixtures/policy-md/precedence/fallback-only/APPROVALS.md +7 -0
- package/schema/fixtures/policy-md/valid/canonical.md +50 -0
- package/schema/fixtures/policy-md/valid/daemon-read-proof.md +18 -0
- package/schema/fixtures/policy-md/valid/minimal.md +3 -0
- package/schema/fixtures/policy-md/valid/prose-lookalikes.md +54 -0
- package/schema/fixtures/policy-md/valid/routed-protected-paths.md +49 -0
- package/schema/fixtures/policy-md/valid/with-values.md +79 -0
- package/schema/fixtures/sample-record/invalid/bad-date-time.json +4 -0
- package/schema/fixtures/sample-record/invalid/missing-required-field.json +3 -0
- package/schema/fixtures/sample-record/invalid/unknown-top-level-field.json +5 -0
- package/schema/fixtures/sample-record/invalid/wrong-type.json +4 -0
- package/schema/fixtures/sample-record/valid/minimal.json +4 -0
- package/schema/fixtures/sample-record/valid/with-note.json +5 -0
- package/schema/fixtures/values/invalid/class-shaped.json +9 -0
- package/schema/fixtures/values/invalid/duplicate-entry.json +4 -0
- package/schema/fixtures/values/invalid/non-string-item.json +4 -0
- package/schema/fixtures/values/invalid/over-cap.json +26 -0
- package/schema/fixtures/values/invalid/unknown-key.json +5 -0
- package/schema/fixtures/values/invalid/version-string.json +1 -0
- package/schema/fixtures/values/valid/empty-lists.json +7 -0
- package/schema/fixtures/values/valid/full.json +20 -0
- package/schema/fixtures/values/valid/minimal.json +1 -0
- package/schema/fixtures/values-md/invalid/schema-invalid.md +62 -0
- package/schema/fixtures/values-md/invalid/two-blocks.md +69 -0
- package/schema/fixtures/values-md/invalid/unterminated.md +61 -0
- package/schema/fixtures/values-md/invalid/yaml-error.md +63 -0
- package/schema/fixtures/values-md/valid/absent.md +50 -0
- package/schema/fixtures/values-md/valid/with-values.md +79 -0
- package/schema/policy.schema.json +501 -0
- package/schema/sample-record.schema.json +26 -0
- package/schema/values.schema.json +55 -0
- package/templates/codex/README.md +9 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution tokens (SPEC.md §10.4, §11) — the hard-enforcement primitive.
|
|
3
|
+
*
|
|
4
|
+
* An adapter holds credentials and "MUST require a valid, unexpired, single-use
|
|
5
|
+
* execution token bound to the action's `idempotency_key`" (SPEC.md §10.4).
|
|
6
|
+
* This module mints those tokens, decides whether a presented one is still good,
|
|
7
|
+
* and spends it. Everything it knows it derives from the append-only log.
|
|
8
|
+
*
|
|
9
|
+
* ## The five settled properties (human decision, 2026-08-06)
|
|
10
|
+
*
|
|
11
|
+
* 1. **Minted at grant.** There is exactly one mint site: the grant path of
|
|
12
|
+
* `core/gate.ts`'s {@link import("./gate.js").decide}. No other code path
|
|
13
|
+
* creates a token, so a token's existence *is* a human's yes.
|
|
14
|
+
* 2. **Single-use.** Consumption is an `execution.started` event, so the second
|
|
15
|
+
* attempt is refused by reading the log rather than by remembering anything.
|
|
16
|
+
* Double-spend detection is chain-native: it survives a process restart, a
|
|
17
|
+
* different machine, and a lost in-memory cache, because the evidence is the
|
|
18
|
+
* log itself.
|
|
19
|
+
* 3. **Bound to the request, its `idempotency_key`, and its `payload_hash`**
|
|
20
|
+
* (amended SPEC.md §10, A1). A token is looked up by `action_key` — the
|
|
21
|
+
* envelope's `idempotency_key` — and is compared against the hash on *that*
|
|
22
|
+
* action's grant. A token minted for action A therefore cannot be presented
|
|
23
|
+
* for action B: B's grant carries a different hash (or no grant at all), and
|
|
24
|
+
* the comparison fails. The third binding is to the bytes: a consumer states
|
|
25
|
+
* the hash of the payload it is about to execute, and anything but the hash
|
|
26
|
+
* the grant recorded is refused `payload-mismatch`. A grant approves specific
|
|
27
|
+
* bytes; changing them after grant requires a new request. A grant that
|
|
28
|
+
* recorded *no* bytes is refused too — see {@link consumeToken}.
|
|
29
|
+
* 4. **Hash-only in the log.** `approval.granted` carries
|
|
30
|
+
* `payload.token_sha256`; the raw token is returned to the caller of `decide`
|
|
31
|
+
* and to nothing else. Possession is proven by presenting a preimage. An
|
|
32
|
+
* attacker with a copy of the log — the one artifact this system deliberately
|
|
33
|
+
* makes durable, copyable, and auditable — gains no ability to execute.
|
|
34
|
+
* 5. **No separate token TTL in v0.1.** A token dies exactly three ways:
|
|
35
|
+
* execution ({@link consumeToken}), revocation (`approval.revoked`), and the
|
|
36
|
+
* lapse of the *parent request's* TTL (`defaults.approval_ttl`, measured from
|
|
37
|
+
* the `approval.requested` timestamp). Inventing a second, independent clock
|
|
38
|
+
* would create a state where a request is live and its token is not, which no
|
|
39
|
+
* operator could explain from the log.
|
|
40
|
+
*
|
|
41
|
+
* ## Why the parent TTL bounds a *granted* request
|
|
42
|
+
*
|
|
43
|
+
* `requestState` deliberately stops applying the TTL once a decision lands: an
|
|
44
|
+
* answered request is answered. Token liveness is a stricter question than
|
|
45
|
+
* request state, and the settled design gives an approval a shelf life. So
|
|
46
|
+
* {@link tokenStatus} re-applies `requestTs + approval_ttl` to a *granted*
|
|
47
|
+
* request and refuses with `token-expired` past it. This never mutates the
|
|
48
|
+
* derived request state and never writes anything — an aged-out token is simply
|
|
49
|
+
* not spendable, and re-requesting the action is the repair. (Contrast
|
|
50
|
+
* `core/gate.ts`, which materialises `approval.expired` when it discovers a
|
|
51
|
+
* lapse on an *undecided* request. That branch belongs to the gate and this
|
|
52
|
+
* module does not duplicate it: a granted request's `approval.expired` would
|
|
53
|
+
* claim the human never answered.)
|
|
54
|
+
*
|
|
55
|
+
* ## Where this module sits between APRV-16 and APRV-18
|
|
56
|
+
*
|
|
57
|
+
* `core/gate.ts` deliberately appends no `execution.*` event. {@link
|
|
58
|
+
* consumeToken} is the **only sanctioned appender of `execution.started` on the
|
|
59
|
+
* manual path**, and it appends one only after a live token verifies — closing
|
|
60
|
+
* the gap APRV-16 flagged, where a manual action's start event had no guard at
|
|
61
|
+
* all.
|
|
62
|
+
*
|
|
63
|
+
* The supervised/autonomous paths are **not** this function's business. Under
|
|
64
|
+
* the amended SPEC.md §6.3 they produce no approval events and therefore no
|
|
65
|
+
* token; their `execution.started` is appended by APRV-18's `approval run`
|
|
66
|
+
* wrapper, which is also where their budget is charged (see the consumption
|
|
67
|
+
* contract in `core/budgets.ts`). One rule, stated once: *manual actions spend a
|
|
68
|
+
* token here; non-manual actions start there.*
|
|
69
|
+
*
|
|
70
|
+
* ## The budgets contract
|
|
71
|
+
*
|
|
72
|
+
* The appended `execution.started` carries `payload.class` and
|
|
73
|
+
* `payload.est_cost_usd`, **copied from the grant's payload** rather than
|
|
74
|
+
* re-derived. `core/budgets.ts` counts an `execution.started` only when the
|
|
75
|
+
* window holds no `approval.granted` with the same `action_key`, so a manual
|
|
76
|
+
* action that is granted and then consumed is charged exactly once — the grant.
|
|
77
|
+
* Copying rather than re-deriving keeps the two records agreeing about what was
|
|
78
|
+
* authorized even if the task file changed in between.
|
|
79
|
+
*
|
|
80
|
+
* ## Time
|
|
81
|
+
*
|
|
82
|
+
* {@link tokenStatus} and {@link verifyToken} are pure and take `now` as a
|
|
83
|
+
* parameter: they answer a question and write nothing, so a caller asking "was
|
|
84
|
+
* this token live at time T?" is asking something legitimate. {@link
|
|
85
|
+
* consumeToken} *writes*, and `execution.started` is a gate-typed event, so
|
|
86
|
+
* amended SPEC.md §8 (A2) gives its timestamp to the runtime: no `ts`
|
|
87
|
+
* parameter, one read of {@link TokenOptions.clock} at the top, and a spender
|
|
88
|
+
* that cannot choose the moment its own TTL is judged at.
|
|
89
|
+
*/
|
|
90
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
91
|
+
import { tick } from "./clock.js";
|
|
92
|
+
import { appendEvent, } from "./log.js";
|
|
93
|
+
import { usdOrZero } from "./money.js";
|
|
94
|
+
import { isPayloadHash } from "./payload.js";
|
|
95
|
+
import { loadPolicy } from "./policy-load.js";
|
|
96
|
+
import { humanOnlyRefusal, resolve } from "./policy-match.js";
|
|
97
|
+
import { asSealedToken, openSealedToken, readPrivateKey, SEALED_TOKEN_FIELD, } from "./seal.js";
|
|
98
|
+
import { readVerifiedRecords, requestState, } from "./state.js";
|
|
99
|
+
/** Token entropy. 32 bytes = 256 bits, rendered as 64 lowercase hex chars. */
|
|
100
|
+
export const TOKEN_BYTES = 32;
|
|
101
|
+
/** The payload key carrying the token's digest, on both grant and start. */
|
|
102
|
+
export const TOKEN_HASH_FIELD = "token_sha256";
|
|
103
|
+
/** The payload key carrying the content binding (amended SPEC.md §6.2, §10). */
|
|
104
|
+
export const PAYLOAD_HASH_FIELD = "payload_hash";
|
|
105
|
+
/**
|
|
106
|
+
* Mint a token: 32 cryptographically random bytes as lowercase hex.
|
|
107
|
+
*
|
|
108
|
+
* `randomBytes` (CSPRNG), never `Math.random`. The value is a bearer credential
|
|
109
|
+
* for a real-world side effect; 256 bits makes guessing irrelevant next to every
|
|
110
|
+
* other attack in SPEC.md §11's "not defended" list.
|
|
111
|
+
*/
|
|
112
|
+
export function mintToken() {
|
|
113
|
+
return randomBytes(TOKEN_BYTES).toString("hex");
|
|
114
|
+
}
|
|
115
|
+
/** The token's SHA-256, lowercase hex — the only form that ever reaches the log. */
|
|
116
|
+
export function tokenHash(token) {
|
|
117
|
+
return createHash("sha256").update(token, "utf8").digest("hex");
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Constant-time comparison of two 64-hex digests.
|
|
121
|
+
*
|
|
122
|
+
* Both operands are digests, so a timing leak reveals a prefix of a *hash*, not
|
|
123
|
+
* of a token — but this CLI runs on a shared developer machine beside the very
|
|
124
|
+
* agents it polices, and an oracle that says "your first N hex digits were
|
|
125
|
+
* right" is the kind of affordance that should not exist at all. `timingSafeEqual`
|
|
126
|
+
* costs nothing here and removes the question.
|
|
127
|
+
*
|
|
128
|
+
* Digests are compared as decoded bytes: a malformed stored digest decodes to a
|
|
129
|
+
* different length, which `timingSafeEqual` rejects by throwing, so the length
|
|
130
|
+
* guard comes first and a malformed digest simply fails to match.
|
|
131
|
+
*/
|
|
132
|
+
export function digestsEqual(a, b) {
|
|
133
|
+
if (!/^[a-f0-9]{64}$/u.test(a) || !/^[a-f0-9]{64}$/u.test(b))
|
|
134
|
+
return false;
|
|
135
|
+
const left = Buffer.from(a, "hex");
|
|
136
|
+
const right = Buffer.from(b, "hex");
|
|
137
|
+
if (left.length !== right.length)
|
|
138
|
+
return false;
|
|
139
|
+
return timingSafeEqual(left, right);
|
|
140
|
+
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Refusals
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
/**
|
|
145
|
+
* The token refusals proper — the closed set an agent branches on to learn *why*
|
|
146
|
+
* a token will not execute. Frozen public API, in the same sense the gate's
|
|
147
|
+
* codes and the exit codes are.
|
|
148
|
+
*
|
|
149
|
+
* The four death conditions are distinguishable on purpose: "you presented the
|
|
150
|
+
* wrong string", "this token was already spent", "a human took it back", and
|
|
151
|
+
* "it aged out" call for four different responses (fix the caller, stop
|
|
152
|
+
* retrying, escalate to the human, re-request).
|
|
153
|
+
*/
|
|
154
|
+
export const TOKEN_VERIFY_REFUSAL_CODES = [
|
|
155
|
+
/** No grant governs this action key: never requested, awaiting, or rejected. */
|
|
156
|
+
"not-granted",
|
|
157
|
+
/** A grant exists, but the presented token is not its preimage. */
|
|
158
|
+
"token-mismatch",
|
|
159
|
+
/** The token was already spent: an `execution.started` exists for this key. */
|
|
160
|
+
"token-consumed",
|
|
161
|
+
/** The parent request's TTL lapsed. There is no separate token TTL. */
|
|
162
|
+
"token-expired",
|
|
163
|
+
/** A human withdrew the grant (`approval.revoked`). */
|
|
164
|
+
"token-revoked",
|
|
165
|
+
/**
|
|
166
|
+
* The bytes do not match (amended SPEC.md §10, A1). The grant recorded a
|
|
167
|
+
* `payload_hash` and the consumer presented a different one — or none at all,
|
|
168
|
+
* which is the same fact stated by omission: an executor that cannot say what
|
|
169
|
+
* it is about to run has not shown that it is running what was approved.
|
|
170
|
+
*
|
|
171
|
+
* Distinct from `token-mismatch` on purpose. That one says "you are not the
|
|
172
|
+
* party who was approved"; this one says "you are, but that is not what was
|
|
173
|
+
* approved", and the repair is different: request the new payload rather than
|
|
174
|
+
* hunt for a lost token.
|
|
175
|
+
*/
|
|
176
|
+
"payload-mismatch",
|
|
177
|
+
/**
|
|
178
|
+
* The grant was for a harness-executed request and minted no token
|
|
179
|
+
* (APRV-106). Nothing is wrong: the requesting process runs the command
|
|
180
|
+
* itself and never had a token to spend, so there is nothing to present here
|
|
181
|
+
* and nothing to recover. Distinct from `token-mismatch`, which says a
|
|
182
|
+
* digest exists and does not match, and from `not-granted`, which says no
|
|
183
|
+
* authorization exists at all — this one says the authorization exists, is
|
|
184
|
+
* complete, and is not the kind that is spent.
|
|
185
|
+
*/
|
|
186
|
+
"harness-executed",
|
|
187
|
+
];
|
|
188
|
+
/**
|
|
189
|
+
* Everything {@link consumeToken} can refuse: the verification codes plus the
|
|
190
|
+
* three log/append failures, whose names and meanings are borrowed verbatim from
|
|
191
|
+
* `core/gate.ts` so the CLI can map them onto the frozen exit table identically.
|
|
192
|
+
*/
|
|
193
|
+
export const TOKEN_REFUSAL_CODES = [
|
|
194
|
+
...TOKEN_VERIFY_REFUSAL_CODES,
|
|
195
|
+
/**
|
|
196
|
+
* The action's class resolves to `human-only` (APRV-185, amended SPEC.md
|
|
197
|
+
* §5.2): the policy reserves it to human hands, so no token may be spent for
|
|
198
|
+
* it and none should ever have existed.
|
|
199
|
+
*
|
|
200
|
+
* Deliberately NOT a member of {@link TOKEN_VERIFY_REFUSAL_CODES}, and the
|
|
201
|
+
* split is the point. Verification is pure over the log and answers what the
|
|
202
|
+
* records say about one grant; this is a fact about the POLICY, which
|
|
203
|
+
* {@link verifyToken} does not read and must not start reading — a
|
|
204
|
+
* verification replayable from a log plus the policy that was in force is
|
|
205
|
+
* what makes an audit reproducible. So the check lives at the two places that
|
|
206
|
+
* hold a policy already: {@link consumeToken}, which spends, and the
|
|
207
|
+
* `approval token` verb, which would otherwise report a live token for an
|
|
208
|
+
* action nothing may execute.
|
|
209
|
+
*
|
|
210
|
+
* `core/gate.ts` refuses the request that would mint such a token, so a grant
|
|
211
|
+
* under a human-only class means the class was raised by a policy amendment
|
|
212
|
+
* after the grant. The token becomes unspendable at that moment, which is the
|
|
213
|
+
* fail-closed direction: the human who amended the policy took the class out
|
|
214
|
+
* of agent hands, and an authorization minted under the older rules is not
|
|
215
|
+
* the exception to that.
|
|
216
|
+
*/
|
|
217
|
+
"class-human-only",
|
|
218
|
+
/** The log could not be read, or holds a line that is not a record. */
|
|
219
|
+
"log-unreadable",
|
|
220
|
+
/** The log's final line is unterminated (a crashed write). */
|
|
221
|
+
"log-torn-tail",
|
|
222
|
+
/** The chain does not verify; nothing may be spent from an untrustworthy log. */
|
|
223
|
+
"log-corrupt",
|
|
224
|
+
/**
|
|
225
|
+
* The append itself failed; `append` carries the underlying error. Its `code`
|
|
226
|
+
* is `head-moved` when a record landed between this module's read and its
|
|
227
|
+
* append — the double-spend case, refused under `appendEvent`'s lock.
|
|
228
|
+
*/
|
|
229
|
+
"append-failed",
|
|
230
|
+
];
|
|
231
|
+
function refuse(code, message, extra = {}) {
|
|
232
|
+
return { ok: false, code, message, ...extra };
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Narrow a verified-read refusal onto this module's codes, unchanged.
|
|
236
|
+
*
|
|
237
|
+
* The three names are shared verbatim with `core/state.ts` (and with the gate
|
|
238
|
+
* and the executor) so the CLI maps all of them onto the frozen exit table with
|
|
239
|
+
* one function.
|
|
240
|
+
*/
|
|
241
|
+
function fromReadRefusal(refusal) {
|
|
242
|
+
return refuse(refusal.code, refusal.message);
|
|
243
|
+
}
|
|
244
|
+
function payloadOf(record) {
|
|
245
|
+
const payload = record.payload;
|
|
246
|
+
return typeof payload === "object" && payload !== null ? payload : {};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Is there a live, unspent token for `actionKey` — and what is its digest?
|
|
250
|
+
*
|
|
251
|
+
* Pure: no I/O, no clock. `now` is the moment the question is asked; `ttlMs` is
|
|
252
|
+
* `defaults.approval_ttl` as the policy loader parsed it, or `null` for a policy
|
|
253
|
+
* that declares no lapse (in which case a granted token stays spendable until it
|
|
254
|
+
* is used or revoked, exactly as an undecided request stays live).
|
|
255
|
+
*
|
|
256
|
+
* Check order, and why:
|
|
257
|
+
*
|
|
258
|
+
* 1. **Revoked**, then **expired-by-derivation**, then **anything not granted**.
|
|
259
|
+
* A withdrawn authorization and a lapsed one are different facts and get
|
|
260
|
+
* different codes; everything else — never requested, still awaiting,
|
|
261
|
+
* rejected — is `not-granted`, because from a token's point of view they are
|
|
262
|
+
* the same absence.
|
|
263
|
+
* 2. **The parent TTL, re-applied to the grant.** See the module header.
|
|
264
|
+
* 3. **The recorded digest.** A grant with no usable `token_sha256` is a grant
|
|
265
|
+
* minted before this module existed (or by something else); it cannot
|
|
266
|
+
* authenticate anything, so it fails closed as `token-mismatch`.
|
|
267
|
+
* 4. **Consumption.** Any `execution.started` for this action key spends it —
|
|
268
|
+
* matching digest or not. The narrow rule (same digest) is what makes
|
|
269
|
+
* double-spend detection chain-native; the broader rule (same action key)
|
|
270
|
+
* enforces SPEC.md §7's single-use idempotency key even against a start event
|
|
271
|
+
* that named no token, and both answer `token-consumed`.
|
|
272
|
+
*/
|
|
273
|
+
export function tokenStatus(records, actionKey, now, ttlMs = null) {
|
|
274
|
+
const derivation = requestState(records, actionKey, now, ttlMs);
|
|
275
|
+
if (derivation.state === "revoked") {
|
|
276
|
+
return refuse("token-revoked", `action ${actionKey} was revoked at seq ${String(derivation.decisionSeq)}; a revoked grant's token is dead`, {
|
|
277
|
+
state: derivation.state,
|
|
278
|
+
...(derivation.decisionSeq === null ? {} : { seq: derivation.decisionSeq }),
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
if (derivation.state === "expired") {
|
|
282
|
+
return refuse("token-expired", `action ${actionKey} expired: the request at ${String(derivation.requestTs)} lapsed before ${now}, so no token governs it`, { state: derivation.state });
|
|
283
|
+
}
|
|
284
|
+
if (derivation.state !== "granted") {
|
|
285
|
+
return refuse("not-granted", `action ${actionKey} is ${derivation.state === "none" ? "not requested" : derivation.state}; a token exists only for a granted action`, { state: derivation.state });
|
|
286
|
+
}
|
|
287
|
+
// The parent request's TTL bounds the token even though the request itself is
|
|
288
|
+
// decided. No separate token TTL exists; this is that one clock, re-read.
|
|
289
|
+
if (ttlMs !== null) {
|
|
290
|
+
const requestedAt = Date.parse(derivation.requestTs ?? "");
|
|
291
|
+
const asked = Date.parse(now);
|
|
292
|
+
if (Number.isNaN(requestedAt) || Number.isNaN(asked) || asked > requestedAt + ttlMs) {
|
|
293
|
+
return refuse("token-expired", `action ${actionKey}'s token expired: the request at ${String(derivation.requestTs)} lapsed its ${String(ttlMs)}ms TTL before ${now}. There is no separate token TTL — a token lives exactly as long as its parent request.`, { state: derivation.state });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
let grant = null;
|
|
297
|
+
const started = [];
|
|
298
|
+
for (const record of records) {
|
|
299
|
+
if (record.action_key !== actionKey)
|
|
300
|
+
continue;
|
|
301
|
+
if (record.event === "approval.granted")
|
|
302
|
+
grant = record;
|
|
303
|
+
if (record.event === "execution.started")
|
|
304
|
+
started.push(record);
|
|
305
|
+
}
|
|
306
|
+
if (grant === null) {
|
|
307
|
+
// Unreachable through `requestState`, which only reports `granted` when it
|
|
308
|
+
// saw the record. Kept as a fail-closed backstop rather than a `!`.
|
|
309
|
+
return refuse("not-granted", `action ${actionKey} derives as granted but carries no approval.granted record`, { state: derivation.state });
|
|
310
|
+
}
|
|
311
|
+
// APRV-106. Checked BEFORE the digest check, because "no digest was minted,
|
|
312
|
+
// on purpose, and the record says so" and "no digest is usable" are different
|
|
313
|
+
// facts with different repairs. A harness-executed grant is a complete grant:
|
|
314
|
+
// the human decided, and the decision was a permission answer to a process
|
|
315
|
+
// that runs the command itself. There is no key because there was never a
|
|
316
|
+
// door for one. Telling an agent `token-mismatch` here would send it hunting
|
|
317
|
+
// for a token that was deliberately never created.
|
|
318
|
+
if (payloadOf(grant)["execution"] === "harness") {
|
|
319
|
+
return refuse("harness-executed", `action ${actionKey} was granted at seq ${grant.seq} as a harness-executed request: no execution token was minted, because the requesting process runs the command itself and never spends one. There is nothing to present to \`approval run\` or \`approval consume\`. The grant is complete and the authorization it records is the harness's permission to proceed.`, { state: derivation.state, seq: grant.seq });
|
|
320
|
+
}
|
|
321
|
+
const recorded = payloadOf(grant)[TOKEN_HASH_FIELD];
|
|
322
|
+
if (typeof recorded !== "string" || !/^[a-f0-9]{64}$/u.test(recorded)) {
|
|
323
|
+
return refuse("token-mismatch", `the approval.granted record for ${actionKey} at seq ${grant.seq} carries no usable ${TOKEN_HASH_FIELD}; nothing can be proven against it and it authorizes no execution`, { state: derivation.state, seq: grant.seq });
|
|
324
|
+
}
|
|
325
|
+
for (const record of started) {
|
|
326
|
+
const presented = payloadOf(record)[TOKEN_HASH_FIELD];
|
|
327
|
+
const sameToken = typeof presented === "string" && digestsEqual(presented, recorded);
|
|
328
|
+
if (sameToken || record.seq > grant.seq) {
|
|
329
|
+
return refuse("token-consumed", `action ${actionKey} already executed: execution.started at seq ${record.seq} spent this token. A token is single-use and the log is the proof.`, { state: derivation.state, seq: record.seq });
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const payload = payloadOf(grant);
|
|
333
|
+
const cls = payload["class"];
|
|
334
|
+
const cost = payload["est_cost_usd"];
|
|
335
|
+
const bytes = payload[PAYLOAD_HASH_FIELD];
|
|
336
|
+
return {
|
|
337
|
+
ok: true,
|
|
338
|
+
actionKey,
|
|
339
|
+
task: derivation.task,
|
|
340
|
+
grantSeq: grant.seq,
|
|
341
|
+
tokenSha256: recorded,
|
|
342
|
+
class: typeof cls === "string" ? cls : derivation.declared.class ?? "",
|
|
343
|
+
est_cost_usd: usdOrZero(cost),
|
|
344
|
+
payloadHash: isPayloadHash(bytes) ? bytes : derivation.declared.payload_hash,
|
|
345
|
+
requestTs: derivation.requestTs,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// Sealed delivery (amended SPEC.md §10.4 — APRV-105)
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
/**
|
|
352
|
+
* The raw token for `actionKey`, recovered from the log's `token_sealed` with
|
|
353
|
+
* the private key this machine holds — or `null`.
|
|
354
|
+
*
|
|
355
|
+
* `null` means "no token was delivered here", and it means it for every reason
|
|
356
|
+
* at once: the policy is `manual` and nothing was sealed, this is a different
|
|
357
|
+
* machine from the one that requested, the key file has already been unlinked
|
|
358
|
+
* because the token was spent, or the ciphertext does not authenticate. The
|
|
359
|
+
* caller's response is identical in all four cases — fall back to the raw token
|
|
360
|
+
* the granting surface printed — and distinguishing them would be an oracle for
|
|
361
|
+
* a decryption capability nobody should be probing.
|
|
362
|
+
*
|
|
363
|
+
* Recovering a minted token is not minting one. The token still exists only
|
|
364
|
+
* because a human granted it, still binds to the payload, and is still spendable
|
|
365
|
+
* exactly once; what this function replaces is the human carrying it in a
|
|
366
|
+
* clipboard. Nothing here consults, relaxes, or substitutes for
|
|
367
|
+
* {@link verifyToken}: the value returned goes on to be verified against the
|
|
368
|
+
* log's digest like any pasted one.
|
|
369
|
+
*
|
|
370
|
+
* Pure with respect to the LOG (it appends nothing) and reads exactly one file.
|
|
371
|
+
* Never throws.
|
|
372
|
+
*/
|
|
373
|
+
export function deliveredToken(records, actionKey, keyDir) {
|
|
374
|
+
let grant = null;
|
|
375
|
+
for (const record of records) {
|
|
376
|
+
if (record.event === "approval.granted" && record.action_key === actionKey)
|
|
377
|
+
grant = record;
|
|
378
|
+
}
|
|
379
|
+
if (grant === null)
|
|
380
|
+
return null;
|
|
381
|
+
const sealed = asSealedToken(payloadOf(grant)[SEALED_TOKEN_FIELD]);
|
|
382
|
+
if (sealed === null)
|
|
383
|
+
return null;
|
|
384
|
+
const privateKey = readPrivateKey(keyDir, actionKey);
|
|
385
|
+
if (privateKey === null)
|
|
386
|
+
return null;
|
|
387
|
+
return openSealedToken(sealed, privateKey, actionKey);
|
|
388
|
+
}
|
|
389
|
+
// ---------------------------------------------------------------------------
|
|
390
|
+
// verify
|
|
391
|
+
// ---------------------------------------------------------------------------
|
|
392
|
+
/**
|
|
393
|
+
* Does `presentedToken` authorize `actionKey` right now?
|
|
394
|
+
*
|
|
395
|
+
* Accepts **iff** all five hold: the latest cycle for the key derives as
|
|
396
|
+
* `granted`; the parent request's TTL has not lapsed; the grant has not been
|
|
397
|
+
* revoked; no `execution.started` has spent it; and `sha256(presentedToken)`
|
|
398
|
+
* equals the digest recorded on the grant, compared in constant time.
|
|
399
|
+
*
|
|
400
|
+
* `ttlMs` is the parsed `defaults.approval_ttl`. It is a parameter rather than a
|
|
401
|
+
* policy read because this function is pure — {@link consumeToken} and the CLI
|
|
402
|
+
* load the policy and hand it in, so a verification can be replayed from the log
|
|
403
|
+
* plus the policy that was in force.
|
|
404
|
+
*/
|
|
405
|
+
export function verifyToken(records, actionKey, presentedToken, now, ttlMs = null) {
|
|
406
|
+
const status = tokenStatus(records, actionKey, now, ttlMs);
|
|
407
|
+
if (!status.ok)
|
|
408
|
+
return status;
|
|
409
|
+
if (!digestsEqual(tokenHash(presentedToken), status.tokenSha256)) {
|
|
410
|
+
return refuse("token-mismatch", `the token presented for ${actionKey} is not the one minted at seq ${status.grantSeq}. The raw token is printed once, by \`approval grant\`, and is stored nowhere — if it was lost, revoke the grant and request again.`, { state: "granted", seq: status.grantSeq });
|
|
411
|
+
}
|
|
412
|
+
return status;
|
|
413
|
+
}
|
|
414
|
+
function loadOptionsOf(options) {
|
|
415
|
+
const load = {};
|
|
416
|
+
if (options.policyFile !== undefined)
|
|
417
|
+
load.file = options.policyFile;
|
|
418
|
+
else
|
|
419
|
+
load.dir = options.policyDir ?? process.cwd();
|
|
420
|
+
if (options.schemaDir !== undefined)
|
|
421
|
+
load.schemaDir = options.schemaDir;
|
|
422
|
+
return load;
|
|
423
|
+
}
|
|
424
|
+
/** The parsed TTL, or `null` when the policy declares (or can declare) none. */
|
|
425
|
+
export function tokenTtlMs(options) {
|
|
426
|
+
const load = loadPolicy(loadOptionsOf(options));
|
|
427
|
+
return load.ok ? load.durations.approvalTtlMs : null;
|
|
428
|
+
}
|
|
429
|
+
/** The policy this module reads, loaded once per operation. */
|
|
430
|
+
export function tokenPolicy(options) {
|
|
431
|
+
return loadPolicy(loadOptionsOf(options));
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Is `actionClass` reserved to human hands under `load` (APRV-185)?
|
|
435
|
+
*
|
|
436
|
+
* Returns the refusal to emit, or `null`. Shared by {@link consumeToken} and by
|
|
437
|
+
* the `approval token` verb, which report the same fact about the same class
|
|
438
|
+
* and must not word it two ways.
|
|
439
|
+
*
|
|
440
|
+
* The §7 irreversibility floor is deliberately not consulted: it raises to
|
|
441
|
+
* `manual` at most and can neither produce `human-only` nor remove it, so the
|
|
442
|
+
* grant's declared `reversible` — which this module does not carry anyway —
|
|
443
|
+
* cannot change this answer.
|
|
444
|
+
*/
|
|
445
|
+
export function humanOnlyClassRefusal(load, actionClass, whatWasRefused) {
|
|
446
|
+
if (actionClass === null || actionClass.length === 0)
|
|
447
|
+
return null;
|
|
448
|
+
if (resolve(load, actionClass).autonomy !== "human-only")
|
|
449
|
+
return null;
|
|
450
|
+
return refuse("class-human-only", humanOnlyRefusal(actionClass, whatWasRefused));
|
|
451
|
+
}
|
|
452
|
+
export function verifyTokenSpend(records, actionKey, presentedToken, now, load, presentedPayloadHash) {
|
|
453
|
+
const verified = verifyToken(records, actionKey, presentedToken, now, load.ok ? load.durations.approvalTtlMs : null);
|
|
454
|
+
if (!verified.ok)
|
|
455
|
+
return verified;
|
|
456
|
+
const reserved = humanOnlyClassRefusal(load, verified.class, `the token for action ${actionKey}, granted at seq ${verified.grantSeq}, may not be spent and no execution.started was written`);
|
|
457
|
+
if (reserved !== null)
|
|
458
|
+
return reserved;
|
|
459
|
+
if (verified.payloadHash === null) {
|
|
460
|
+
return refuse("payload-mismatch", `the approval.granted record for ${actionKey} at seq ${verified.grantSeq} carries no payload_hash: it predates content binding, or was written by something other than this gate. Amended SPEC.md §6.2 makes the hash MUST for manual actions and §10 binds the token to it, so there is nothing here for an execution to be checked against and nothing that can be shown to be the approved bytes. This grant cannot be spent — revoke it and request the action again, which will bind to the payload.`, { state: "granted", seq: verified.grantSeq });
|
|
461
|
+
}
|
|
462
|
+
if (!isPayloadHash(presentedPayloadHash) || !digestsEqual(presentedPayloadHash, verified.payloadHash)) {
|
|
463
|
+
return refuse("payload-mismatch", presentedPayloadHash === undefined
|
|
464
|
+
? `the grant for ${actionKey} at seq ${verified.grantSeq} binds to payload_hash ${verified.payloadHash} and this consumer presented none. Amended SPEC.md §10: an executor MUST recompute the hash of the payload it is about to execute; a spend that cannot state its bytes cannot be shown to be executing the approved ones.`
|
|
465
|
+
: `the payload presented for ${actionKey} is not the one approved: the grant at seq ${verified.grantSeq} binds to ${verified.payloadHash}, this consumer presented ${JSON.stringify(presentedPayloadHash)}. A grant approves specific bytes; changing the payload after grant requires a new request. Nothing was appended and the token is still live.`, { state: "granted", seq: verified.grantSeq });
|
|
466
|
+
}
|
|
467
|
+
if (verified.task === null) {
|
|
468
|
+
return refuse("not-granted", `action ${actionKey} has a grant but no task id in its request cycle; execution.started requires one`, { state: "granted", seq: verified.grantSeq });
|
|
469
|
+
}
|
|
470
|
+
return { ...verified, task: verified.task, payloadHash: verified.payloadHash };
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Spend a token: verify it, then append `execution.started`.
|
|
474
|
+
*
|
|
475
|
+
* **This is the only sanctioned way to append `execution.started` for a manual
|
|
476
|
+
* action.** APRV-16 left that gap open deliberately — the gate appends no
|
|
477
|
+
* execution events — and this function closes it: on the manual path a start
|
|
478
|
+
* event now requires a live, verified, unspent token, so an agent cannot record
|
|
479
|
+
* an execution the human never authorized. Supervised and autonomous actions
|
|
480
|
+
* have no grant and therefore no token; their start event is APRV-18's `approval
|
|
481
|
+
* run` wrapper's job, and calling this for them correctly refuses `not-granted`.
|
|
482
|
+
*
|
|
483
|
+
* The payload is exactly `{class, est_cost_usd, token_sha256, payload_hash}`:
|
|
484
|
+
* the first two because `core/budgets.ts` meters authorization from them, the
|
|
485
|
+
* third because it is what makes the second consumption attempt refusable from
|
|
486
|
+
* the log alone, and the fourth because an auditor should be able to see from
|
|
487
|
+
* the log that what ran is what was approved. All four are copied from the
|
|
488
|
+
* grant, never re-derived. `payload_hash` is unconditional because a grant
|
|
489
|
+
* carrying none is refused (see below) rather than spent.
|
|
490
|
+
*
|
|
491
|
+
* Verification and append are made atomic by compare-and-append (APRV-20 finding
|
|
492
|
+
* B1): this function reads the log itself — never records handed in by a caller —
|
|
493
|
+
* and passes the head it read as `appendEvent`'s `expectedHead`. Two genuinely
|
|
494
|
+
* concurrent consumers of one token therefore cannot both start. Whichever takes
|
|
495
|
+
* the lockfile first appends `execution.started`; the loser finds the head moved
|
|
496
|
+
* under the lock and is refused `append-failed`/`head-moved` with nothing
|
|
497
|
+
* written. The loser is **not** retried here: re-reading would report
|
|
498
|
+
* `token-consumed`, but deciding to look again is the caller's call, and a core
|
|
499
|
+
* that silently retried would hide a double-spend attempt behind a tidy error.
|
|
500
|
+
*
|
|
501
|
+
* `actor` is not pre-validated: the event schema is the authority on actor
|
|
502
|
+
* shape, and a malformed one is refused at the write boundary as
|
|
503
|
+
* `append-failed`, with the schema's own error attached. One rule about actors,
|
|
504
|
+
* enforced in one place.
|
|
505
|
+
*/
|
|
506
|
+
export function consumeToken(logPath, actionKey, presentedToken, actor, options = {}) {
|
|
507
|
+
const ts = tick(options);
|
|
508
|
+
const read = readVerifiedRecords(logPath, options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir });
|
|
509
|
+
if (!read.ok)
|
|
510
|
+
return fromReadRefusal(read);
|
|
511
|
+
// One read of the policy for the whole spend: the TTL the verification
|
|
512
|
+
// applies and the class check below come from the same bytes.
|
|
513
|
+
const load = tokenPolicy(options);
|
|
514
|
+
const verified = verifyTokenSpend(read.records, actionKey, presentedToken, ts, load, options.presentedPayloadHash);
|
|
515
|
+
if (!verified.ok)
|
|
516
|
+
return verified;
|
|
517
|
+
const appended = appendEvent(logPath, {
|
|
518
|
+
ts,
|
|
519
|
+
event: "execution.started",
|
|
520
|
+
actor,
|
|
521
|
+
task: verified.task,
|
|
522
|
+
action_key: actionKey,
|
|
523
|
+
payload: {
|
|
524
|
+
class: verified.class,
|
|
525
|
+
est_cost_usd: verified.est_cost_usd,
|
|
526
|
+
[TOKEN_HASH_FIELD]: verified.tokenSha256,
|
|
527
|
+
// A1: the bytes that actually ran, recorded beside the token that
|
|
528
|
+
// authorized them, so an auditor reading the log alone can see that the
|
|
529
|
+
// execution and the approval named the same payload. Unconditional: a
|
|
530
|
+
// grant with no binding was refused above and never reaches this line.
|
|
531
|
+
[PAYLOAD_HASH_FIELD]: verified.payloadHash,
|
|
532
|
+
// APRV-205: how many credential-bearing variables the child was starved
|
|
533
|
+
// of. Optional and additive; an execution with no child records none,
|
|
534
|
+
// because "none withheld" and "no child" are different facts.
|
|
535
|
+
...(options.envStripped === undefined ? {} : { env_stripped: options.envStripped }),
|
|
536
|
+
// APRV-193: which room the child ran in. Same additive shape, and the
|
|
537
|
+
// manual path's usual value is `granted-egress` — a human approved
|
|
538
|
+
// these exact bytes, and `approval run` on a grant is the one door to
|
|
539
|
+
// the world the design leaves open.
|
|
540
|
+
...(options.sandbox === undefined ? {} : { sandbox: options.sandbox }),
|
|
541
|
+
},
|
|
542
|
+
}, {
|
|
543
|
+
...options.append,
|
|
544
|
+
...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
|
|
545
|
+
// Compare-and-append (APRV-20 finding B1): the verification above was made
|
|
546
|
+
// against the log ending at this head. If anything landed since — another
|
|
547
|
+
// consumer spending the same token, most of all — the append is refused
|
|
548
|
+
// `head-moved` under the lock and this token is not spent twice.
|
|
549
|
+
expectedHead: read.head,
|
|
550
|
+
});
|
|
551
|
+
if (!appended.ok) {
|
|
552
|
+
return refuse("append-failed", `execution.started could not be appended: ${appended.error.message}`, { append: appended.error });
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
ok: true,
|
|
556
|
+
record: appended.record,
|
|
557
|
+
tokenSha256: verified.tokenSha256,
|
|
558
|
+
grantSeq: verified.grantSeq,
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../../src/core/token.ts"],"names":[],"mappings":"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"}
|