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,2339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Help text. SPEC.md §10.1 makes `--help` part of the interface rather than a
|
|
3
|
+
* courtesy: the CLI is how agents use this system, and an agent that has to
|
|
4
|
+
* guess an exit code or a JSON key is an agent that will guess wrong on the one
|
|
5
|
+
* invocation that mattered. Every command therefore documents its flags, its
|
|
6
|
+
* refusal codes and its exact `--json` shape.
|
|
7
|
+
*
|
|
8
|
+
* WHAT A PER-VERB HELP IS (APRV-91): the usage forms, a short paragraph of
|
|
9
|
+
* intent, the flags, the machine-facing contract (`--json` shape, refusal
|
|
10
|
+
* codes), and a two-line footer. What it is NOT is an essay. The frozen
|
|
11
|
+
* exit-code table is printed by `approval --help` and nowhere else, the
|
|
12
|
+
* cross-cutting stances (identity is declared not proved, a refusal is exit 1,
|
|
13
|
+
* a token is shown once, a channel is transport) are stated once at the root,
|
|
14
|
+
* and the long design rationale lives in `docs/cli-reference.md`, which every
|
|
15
|
+
* trimmed help points at by anchor. The prose was moved, not rewritten.
|
|
16
|
+
*/
|
|
17
|
+
import { GITIGNORE_ENTRY_LINES, GITIGNORE_MARKER } from "./scaffold.js";
|
|
18
|
+
/** The frozen table. Printed by {@link ROOT_HELP} and by nothing else. */
|
|
19
|
+
const EXIT_CODES = `Exit codes (frozen public API):
|
|
20
|
+
0 success
|
|
21
|
+
1 integrity failure (corrupt log)
|
|
22
|
+
2 usage error
|
|
23
|
+
3 torn tail
|
|
24
|
+
4 I/O error (unreadable/unwritable path; never reported as corruption)`;
|
|
25
|
+
/** What a per-verb help says instead of reprinting the table. */
|
|
26
|
+
const EXIT_CODES_POINTER = `exit codes: approval --help`;
|
|
27
|
+
const JSON_ERRORS = `With --json, usage and I/O failures print {"error":{"code","message"}} to
|
|
28
|
+
stderr and nothing to stdout.`;
|
|
29
|
+
/** The footer line pointing at the moved rationale. */
|
|
30
|
+
function why(anchor) {
|
|
31
|
+
return `why: docs/cli-reference.md#${anchor}`;
|
|
32
|
+
}
|
|
33
|
+
export const ROOT_HELP = `approval — human approval for agent actions (pre-release)
|
|
34
|
+
|
|
35
|
+
Usage:
|
|
36
|
+
approval log verify [--log <path>] [--json]
|
|
37
|
+
approval log tail [--log <path>] [-n <count>] [--json]
|
|
38
|
+
approval log export [--log <path>] [--json]
|
|
39
|
+
approval log follow [--log <path>] [--from <seq>] [--cursor-hash <64hex>] --json
|
|
40
|
+
approval instructions [--schemas] [--json]
|
|
41
|
+
approval init [--dir <path>] [--json]
|
|
42
|
+
approval quickstart [--dir <path>] [--api-base <url>] (interactive; no --json)
|
|
43
|
+
approval policy check|test <class> [--reversible true|false] [--policy <path>] [--dir <path>] [--json]
|
|
44
|
+
approval policy attest [--policy <path>] [--dir <path>] [--as human:<id>] [--json]
|
|
45
|
+
approval policy amend [--policy <path>] [--dir <path>] [--log <path>]
|
|
46
|
+
[--as human:<id>] [--require-load] [--dry-run] [--commit]
|
|
47
|
+
[--yes] [--json]
|
|
48
|
+
approval register <task-file> [--as <id>] [--log <path>] [--json]
|
|
49
|
+
approval request <task> --action <key> [--as <id>] [--json]
|
|
50
|
+
approval grant|reject|revoke <action-key> [--note <text>] [--as human:<id>] [--json]
|
|
51
|
+
approval expire <action-key> [--json]
|
|
52
|
+
approval token <action-key> [--policy <path>] [--dir <path>] [--json]
|
|
53
|
+
approval consume <action-key> --token <t> [--payload-hash <64hex>]
|
|
54
|
+
[--as <id>] [--json] (internal)
|
|
55
|
+
approval run <action-key> [--token <t>] [--payload-hash <64hex>]
|
|
56
|
+
[--as <id>] [--no-sandbox] [--json] -- <cmd…>
|
|
57
|
+
approval sandbox [--allow-loopback] [--log <path>] -- <cmd…>
|
|
58
|
+
approval adapter email <action-key> [--token <t>] --payload <file|->
|
|
59
|
+
[--as <id>] [--vault <path>] [--timeout <ms>] [--json]
|
|
60
|
+
approval adapter agentmail <action-key> [--token <t>] --payload <file|->
|
|
61
|
+
[--as <id>] [--vault <path>] [--timeout <ms>] [--json]
|
|
62
|
+
approval adapter zzz <action-key> [--token <t>] --payload <file|->
|
|
63
|
+
[--as <id>] [--vault <path>] [--timeout <ms>] [--json]
|
|
64
|
+
approval execution resolve <action-key> --outcome completed|failed
|
|
65
|
+
--note "<text>" [--as human:<id>] [--json]
|
|
66
|
+
approval execution reconcile <action-key>
|
|
67
|
+
--resolution executed|not-executed
|
|
68
|
+
--note "<evidence>" [--as human:<id>] [--json]
|
|
69
|
+
approval audit list|review [<seq|action-key>] [--note "<text>"]
|
|
70
|
+
[--as human:<id>] [--all] [--json]
|
|
71
|
+
approval wait <task> --timeout <duration> [--interval <d>]
|
|
72
|
+
[--withdraw-on-timeout] [--json]
|
|
73
|
+
approval withdraw <task> --action <key> [--reason <r>] [--note "<text>"]
|
|
74
|
+
[--as <id>] [--json]
|
|
75
|
+
approval queue [--policy <path>] [--dir <path>] [--json]
|
|
76
|
+
approval coverage [--base <ref>] [--head <ref>] [--since <duration>]
|
|
77
|
+
[--source git,gh,agentmail] [--json]
|
|
78
|
+
approval channel cli [--policy-dir <path>] [--payload-dir <path>]
|
|
79
|
+
[--as human:<id>] [--interactive] [--json]
|
|
80
|
+
approval channel web [--port <n>] [--payload-dir <path>] [--as human:<id>]
|
|
81
|
+
[--policy <path>] [--dir <path>] [--log <path>] [--json]
|
|
82
|
+
approval channel telegram listen|health [--once] [--as human:<id>] [--json]
|
|
83
|
+
approval daemon run [--tasks <dir>] [--out <path>] [--interval <duration>]
|
|
84
|
+
[--debounce <duration>] [--once] [--with-channels] [--json]
|
|
85
|
+
approval up [--as human:<id>] [--port <n>] [--no-telegram] [--no-web]
|
|
86
|
+
[--restart-backoff <d>] (plus every daemon run flag)
|
|
87
|
+
approval setup service [--platform launchd|systemd] [--uninstall]
|
|
88
|
+
[--label <name>] [--logs <dir>] [--env-file <path>]
|
|
89
|
+
approval gate open|close|status [--for <d>] [--reason "<t>"] [--note "<t>"]
|
|
90
|
+
[--as human:<id>] [--log <path>] [--json]
|
|
91
|
+
(open: terminal only, no --json)
|
|
92
|
+
approval status [--policy <path>] [--dir <path>] [--json]
|
|
93
|
+
approval doctor [--log <path>] [--policy <path>] [--dir <path>]
|
|
94
|
+
[--api-base <url>] [--json]
|
|
95
|
+
approval payload hash <file|-> [--json]
|
|
96
|
+
approval payload agentmail-draft <inbox-id> <draft-id> [--api-base <url>]
|
|
97
|
+
[--json]
|
|
98
|
+
approval journal write --message "<text>" | - [--task <id>] [--session <id>]
|
|
99
|
+
[--as <id>] [--journal <dir>] [--json]
|
|
100
|
+
approval journal read [--limit <n>] [--since <YYYY-MM-DD>] [--journal <dir>]
|
|
101
|
+
[--json]
|
|
102
|
+
approval values [--policy <path>] [--dir <path>] [--json]
|
|
103
|
+
approval feedback [--task <id>] [--actor <agent id>] [--reaction <word>]
|
|
104
|
+
[--source review|decision] [--since <YYYY-MM-DD>]
|
|
105
|
+
[--limit <n>] [--log <path>] [--json]
|
|
106
|
+
approval env [--check] [--policy <path>] [--dir <path>] [--log <path>]
|
|
107
|
+
[--json]
|
|
108
|
+
approval setup identity|vault|sampling|channel <name>|adapter <name>
|
|
109
|
+
[--as human:<id>] [--api-base <url>] [--policy <path>]
|
|
110
|
+
[--dir <path>] [--log <path>] (interactive; no --json)
|
|
111
|
+
approval vault set <name> [--value-env <VAR>] [--as human:<id>] [--json]
|
|
112
|
+
approval vault list|remove [<name>] [--as human:<id>] [--json]
|
|
113
|
+
approval hook claude-code [--as agent:<id>] [--timeout <duration>]
|
|
114
|
+
[--interval <d>] [--policy <path>] [--dir <path>]
|
|
115
|
+
[--log <path>] (reads PreToolUse JSON)
|
|
116
|
+
approval hook cursor [--as agent:<id>] [--timeout <duration>]
|
|
117
|
+
[--interval <d>] [--policy <path>] [--dir <path>]
|
|
118
|
+
[--log <path>] (reads preToolUse JSON)
|
|
119
|
+
approval hook classify [--json] [--policy <path>] [--dir <path>] -- <command…>
|
|
120
|
+
approval import agents-md <file> [--out <path>] [--json]
|
|
121
|
+
approval codex prepare|setup|doctor|start|serve (strict host workflow)
|
|
122
|
+
approval mcp serve --as agent:<id> [--dir <path>] [--log <path>]
|
|
123
|
+
[--policy <path>] (MCP over stdio; foreground)
|
|
124
|
+
approval reindex [--log <path>] [--index <path>] [--force] [--json]
|
|
125
|
+
approval render [--log <path>] [--out <path>] [--policy <path>]
|
|
126
|
+
[--dir <path>] [--json]
|
|
127
|
+
approval --help
|
|
128
|
+
|
|
129
|
+
Set up — make this directory and this machine ready:
|
|
130
|
+
init scaffold a working directory: APPROVAL.md (SPEC.md §5.1's canonical
|
|
131
|
+
policy, to be read and edited), the empty .approval/log/ directory,
|
|
132
|
+
.approval/QUEUE.md in its empty state, and the .gitignore lines for
|
|
133
|
+
the index, the vault, the environment source map and the
|
|
134
|
+
atomic-write temp files. Appends
|
|
135
|
+
nothing, attests nothing, overwrites nothing; a re-run writes
|
|
136
|
+
nothing and reports what already exists
|
|
137
|
+
quickstart ask three decisions, write a solo policy with the named human as
|
|
138
|
+
its sole approver, configure identity and an optional Telegram
|
|
139
|
+
channel, show the exact bytes, then require typed \`understood\`
|
|
140
|
+
before attesting. HUMAN-ONLY and INTERACTIVE ONLY
|
|
141
|
+
setup the WRITER for that file: "setup identity|vault|sampling" and
|
|
142
|
+
"setup channel <name>" store each secret in the OS keystore and
|
|
143
|
+
record where it lives, and "setup adapter <name>" fills the VAULT
|
|
144
|
+
from the credential manifest the adapter itself declares, then
|
|
145
|
+
proves it against the service without sending anything. The two
|
|
146
|
+
nouns are SPEC.md §4's: a channel holds no state and needs a
|
|
147
|
+
transport credential, an adapter holds the credentials a side
|
|
148
|
+
effect spends. INTERACTIVE ONLY — it refuses a
|
|
149
|
+
non-terminal stdin and --json, and prints the exact commands to run
|
|
150
|
+
instead, because a setup a pipe could drive would let a CI job
|
|
151
|
+
declare a human identity. It appends nothing to the log, attests
|
|
152
|
+
nothing, and never edits APPROVAL.md
|
|
153
|
+
vault the encrypted credential store adapters read from (SPEC.md §10.4).
|
|
154
|
+
"vault set|list|remove" are HUMAN-ONLY; list shows NAMES and never
|
|
155
|
+
values, and there is no "vault get" — a credential's only sanctioned
|
|
156
|
+
journey is from .approval/vault.enc into an adapter, inside the
|
|
157
|
+
verified execution window. The passphrase comes from the environment
|
|
158
|
+
variable the policy NAMES (vault.passphrase_env), never from a flag
|
|
159
|
+
env resolve .approval/env — the environment SOURCE MAP — and print an
|
|
160
|
+
export block for your shell to evaluate. THE ONLY VERB THAT READS
|
|
161
|
+
THAT FILE: no command loads it implicitly, because human identity is
|
|
162
|
+
one of the variables it carries and a working-tree file any process
|
|
163
|
+
read on its own would let anything able to write it act as you. The
|
|
164
|
+
default output carries secrets by design; "env --check" prints a
|
|
165
|
+
table with no values on any path
|
|
166
|
+
policy explain what APPROVAL.md does with an action class (check | test),
|
|
167
|
+
record a human's sign-off on the policy file (attest), or run the
|
|
168
|
+
whole amendment ceremony — semantic diff, load advisory,
|
|
169
|
+
attestation, and the two-file git commit — as one verb (amend)
|
|
170
|
+
import "import agents-md" parses an AGENTS.md-style permissions section
|
|
171
|
+
into DRAFT policy classes for a human to confirm (SPEC.md §12). It
|
|
172
|
+
prints; it never writes APPROVAL.md, never logs, never attests
|
|
173
|
+
|
|
174
|
+
Ask — an agent declares an action and acts on the answer:
|
|
175
|
+
instructions
|
|
176
|
+
the full AGENT-FACING usage guide: what to declare before acting,
|
|
177
|
+
the register -> request -> wait -> run sequence, what a refusal
|
|
178
|
+
means, and the invariants an agent must not route around. With
|
|
179
|
+
--schemas it prints the verb registry as JSON — purpose, input and
|
|
180
|
+
output schemas, exit codes and the human-only marker for every verb
|
|
181
|
+
— which is the same source the optional MCP wrapper (SPEC.md §10.5)
|
|
182
|
+
builds its tools from. Reads nothing, writes nothing
|
|
183
|
+
register validate a task envelope and append task.registered
|
|
184
|
+
request ask the gate to admit a declared action (manual classes append
|
|
185
|
+
approval.requested; supervised/autonomous append nothing and
|
|
186
|
+
proceed straight to execution, per amended SPEC.md §6.3)
|
|
187
|
+
token report whether a live single-use execution token exists for an
|
|
188
|
+
action (the RAW token is printed once, by grant, and stored nowhere)
|
|
189
|
+
consume spend a token and append execution.started (internal plumbing;
|
|
190
|
+
"approval run" wraps it)
|
|
191
|
+
run execute a command behind the gate: appends execution.started before
|
|
192
|
+
spawning it, execution.completed/failed with the child's exit code
|
|
193
|
+
after, and exits with that same code
|
|
194
|
+
adapter execute an action through a side-effect adapter, the hard
|
|
195
|
+
boundary of SPEC.md §10.4. "adapter email" sends one RFC 5322
|
|
196
|
+
message over SMTP for a communicate.email.external action: the
|
|
197
|
+
credentials come from the vault inside the execution window, the
|
|
198
|
+
payload is the bytes the declaration or grant bound to, and the
|
|
199
|
+
runtime recomputes the hash, applies policy, and writes both
|
|
200
|
+
execution events around the send. Manual and selected-live paths
|
|
201
|
+
require --token; policy-authorized supervised/autonomous paths do
|
|
202
|
+
not mint one. "adapter agentmail" serves the
|
|
203
|
+
same class over the AgentMail API: a direct send, or the send of a
|
|
204
|
+
draft the agent composed, refused if the draft changed after the
|
|
205
|
+
snapshot a human approved
|
|
206
|
+
wait block until a task's requests are decided; the exit code IS the
|
|
207
|
+
decision (0 granted, 1 rejected/revoked/withdrawn, 3 expired, 6 timeout)
|
|
208
|
+
withdraw take back your OWN pending request (timeout, cancelled, superseded);
|
|
209
|
+
terminal, requester-only, and a late grant then authorizes nothing
|
|
210
|
+
hook put the gate in front of an agent HARNESS. "hook claude-code" and
|
|
211
|
+
"hook cursor" each read their harness's pre-tool event on stdin,
|
|
212
|
+
classify the command or protected-path edit it is about to run,
|
|
213
|
+
resolve the class against APPROVAL.md, and answer allow or deny —
|
|
214
|
+
waiting on a real approval decision when the class is manual. They
|
|
215
|
+
never answer "ask": a decision taken outside the log is a decision
|
|
216
|
+
nothing can audit. "hook classify" prints what the classifier makes
|
|
217
|
+
of a command and touches nothing
|
|
218
|
+
journal the one channel the gate does NOT stand in front of. "journal write"
|
|
219
|
+
appends free text to a local file — ungated, unclassified, never
|
|
220
|
+
approvable and never deniable, with no event in the log — so an
|
|
221
|
+
agent can say "I am complying and I think this is wrong", "this
|
|
222
|
+
reads as odd to me", or "I am stuck" even when it is complying
|
|
223
|
+
perfectly. "journal read" is the human side, and it labels every
|
|
224
|
+
entry as agent-authored DATA. Nothing written there changes any
|
|
225
|
+
verdict, sampling probability or budget; it is signal for the
|
|
226
|
+
operator, not a decision surface
|
|
227
|
+
values the mirror of "journal", running the other way: the operator's own
|
|
228
|
+
words, in the optional values block of APPROVAL.md. What they value
|
|
229
|
+
in the work, what they want from an agent, and how they read and
|
|
230
|
+
answer. It is GUIDANCE and never policy: it grants nothing, forbids
|
|
231
|
+
nothing, and no enforcement path reads it. A file with no block says
|
|
232
|
+
so in words, because "nothing was declared" and "I did not look" are
|
|
233
|
+
different facts
|
|
234
|
+
feedback the same channel in the other direction: what the OPERATOR said
|
|
235
|
+
about the work. Lists the reactions and notes a person wrote on a
|
|
236
|
+
grant or on a retrospective review, joined to the class, the task,
|
|
237
|
+
the action key and the agent it was about. HUMAN-AUTHORED GUIDANCE
|
|
238
|
+
and never policy — it grants nothing, forbids nothing, and changes
|
|
239
|
+
no verdict, sampling probability or budget. Reads a verified log
|
|
240
|
+
and writes nothing
|
|
241
|
+
mcp "mcp serve" is the optional MCP wrapper of SPEC.md §10.5: the same
|
|
242
|
+
verbs as tools, over stdio, sharing the CLI's code paths. It is
|
|
243
|
+
AGENT-FACING ONLY — grant, reject, revoke, attest, amend, vault,
|
|
244
|
+
setup, audit review, expire, execution resolve|reconcile and the
|
|
245
|
+
channels are not published, because an MCP client is an agent's
|
|
246
|
+
harness and SPEC.md §11 makes the agent the untrusted policy. It
|
|
247
|
+
runs as ONE agent identity, fixed at startup, that nothing changes
|
|
248
|
+
|
|
249
|
+
Decide — a human answers, and only a human can:
|
|
250
|
+
queue the pending-decision INBOX: requests awaiting a human, inside their
|
|
251
|
+
TTL. Nothing else — exit 0 always when the log could be read
|
|
252
|
+
grant record a human approval (HUMAN-ONLY)
|
|
253
|
+
reject record a human refusal (HUMAN-ONLY)
|
|
254
|
+
revoke withdraw an unexecuted approval (HUMAN-ONLY)
|
|
255
|
+
expire lapse a request whose TTL passed (system verb, actor system:gate)
|
|
256
|
+
execution recovery verbs for executions the runtime could not close itself.
|
|
257
|
+
"execution resolve" records the outcome a HUMAN OBSERVED for a
|
|
258
|
+
dangling execution: mandatory --note, human-only, exit_code null,
|
|
259
|
+
attested_by_human true. "execution reconcile" records what a human
|
|
260
|
+
ESTABLISHED about an INDETERMINATE one — a side effect that was
|
|
261
|
+
attempted and whose outcome nobody knows — from the relying party's
|
|
262
|
+
evidence, naming the record it resolves and rewriting nothing.
|
|
263
|
+
Neither requires attestation: both record a fact a human observed
|
|
264
|
+
and exercise no policy authority
|
|
265
|
+
audit "audit list" is the open sampled-audit backlog and "audit review" is
|
|
266
|
+
the HUMAN-ONLY verb that closes one item of it. Sampling itself has
|
|
267
|
+
no verb: the daemon selects supervised actions with an operator-held
|
|
268
|
+
secret, because a caller who could sample could also decline to
|
|
269
|
+
sample itself
|
|
270
|
+
channel put pending requests in front of a human over the channel contract.
|
|
271
|
+
"channel cli" renders the queue with [computed]/[claimed] markers and
|
|
272
|
+
the full payload in delimiters, and with a terminal collects
|
|
273
|
+
decisions through the same human-only gate as grant/reject.
|
|
274
|
+
"channel telegram listen" delivers the queue to a Telegram chat on
|
|
275
|
+
every poll cycle (including requests that arrive while it runs) and
|
|
276
|
+
long-polls for Approve/Reject taps; config is environment-only
|
|
277
|
+
(APPROVAL_TG_TOKEN, APPROVAL_TG_CHAT)
|
|
278
|
+
|
|
279
|
+
Inspect — what the log says, and whether anything needs repair:
|
|
280
|
+
log inspect the append-only event log (verify | tail | export)
|
|
281
|
+
status system HEALTH: attestation, dangling executions, budget headroom,
|
|
282
|
+
the latest chain verdict, loop escalations. Exit 1 when any of
|
|
283
|
+
those needs attention. queue is what a human must answer; status is
|
|
284
|
+
what an operator must fix, and neither carries the other's content
|
|
285
|
+
coverage what the witnesses this project does NOT write (git, gh, a
|
|
286
|
+
provider's own record) say happened, joined to the verified log:
|
|
287
|
+
per effect, the evidence seq or none. INFORMATIONAL — exit 0 with
|
|
288
|
+
or without gaps, because a coverage measurement is not a verdict
|
|
289
|
+
doctor is this ENVIRONMENT sane? build freshness, declared identity, policy
|
|
290
|
+
attestation, chain health, the Telegram token, the web port — each
|
|
291
|
+
with a concrete repair. status asks whether the SYSTEM needs
|
|
292
|
+
attention; doctor asks whether the machine you are typing on can run
|
|
293
|
+
the system at all. Appends nothing, sends nothing, repairs nothing
|
|
294
|
+
render regenerate .approval/QUEUE.md, the READ-ONLY markdown queue
|
|
295
|
+
projection (SPEC.md §9.1): pending requests and the sampled-audit
|
|
296
|
+
backlog, computed and claimed fields visibly distinguished. The
|
|
297
|
+
screenshot, never the truth — editing it authorizes nothing
|
|
298
|
+
reindex rebuild the SQLite index projection from the log
|
|
299
|
+
payload "payload hash" prints the payload_hash of a JSON document (SHA-256
|
|
300
|
+
over its RFC 8785 canonical serialization), the value a declaration
|
|
301
|
+
carries and a grant binds to. Most flows never need it: "request
|
|
302
|
+
--payload" hashes, verifies and stores the bytes in one step.
|
|
303
|
+
"payload agentmail-draft" snapshots one AgentMail draft with the
|
|
304
|
+
AGENT's key, so a human approves the words and not a draft id
|
|
305
|
+
daemon "daemon run" is the watch loop of SPEC.md §10.2, in the FOREGROUND:
|
|
306
|
+
it records envelope.drift when a task file's state: contradicts the
|
|
307
|
+
log, appends approval.expired for lapsed requests, writes the log's
|
|
308
|
+
state back into the task files, regenerates QUEUE.md, and surfaces
|
|
309
|
+
loop escalations. It holds no lock; backgrounding is the operator's
|
|
310
|
+
business in v0.1
|
|
311
|
+
up the AMBIENT RUNTIME: that same daemon loop plus every channel the
|
|
312
|
+
policy configures, in ONE supervised foreground process. A channel
|
|
313
|
+
whose credential is unset is not started and says so in doctor's
|
|
314
|
+
vocabulary; a channel that falls over is restarted with a doubling
|
|
315
|
+
backoff and the daemon loop carries on. "approval setup service"
|
|
316
|
+
writes the launchd or systemd user unit that runs it at login
|
|
317
|
+
|
|
318
|
+
Defaults:
|
|
319
|
+
log .approval/log/events.jsonl (relative to the working directory)
|
|
320
|
+
index .approval/index.sqlite
|
|
321
|
+
queue .approval/QUEUE.md
|
|
322
|
+
payloads .approval/payloads/<payload_hash>.json (the bytes a request bound
|
|
323
|
+
to, written by request --payload; read by render and every channel,
|
|
324
|
+
and re-hashed on every read)
|
|
325
|
+
env .approval/env (the environment SOURCE MAP: KEY=keychain:<service> /
|
|
326
|
+
secret-service:<label> / env: / a plaintext literal. Mode 0600, and read
|
|
327
|
+
by exactly one command, "approval env". GITIGNORED by init)
|
|
328
|
+
journal .approval-journal/YYYY-MM-DD.jsonl (the ungated free-text channel of
|
|
329
|
+
"journal write". OUTSIDE the approval home on purpose: everything under
|
|
330
|
+
.approval/ is the gate's own, and an outlet the gate could close is not
|
|
331
|
+
an outlet. Nothing the runtime reads is ever stored there. Gitignored)
|
|
332
|
+
vault .approval/vault.enc (AES-256-GCM over the named credentials; written
|
|
333
|
+
only by "vault set|remove", read only by an adapter inside a verified
|
|
334
|
+
token window. GITIGNORE IT — doctor fails if you have not)
|
|
335
|
+
|
|
336
|
+
${EXIT_CODES}
|
|
337
|
+
|
|
338
|
+
Two codes are ADDITIONS to the table above, each emitted by exactly one verb:
|
|
339
|
+
5 by "approval run" when no valid execution token was presented (nothing is
|
|
340
|
+
appended), and 6 by "approval wait" on timeout. Nothing in 0–4 changed meaning.
|
|
341
|
+
This table is printed HERE and nowhere else; a verb's own --help names only the
|
|
342
|
+
codes that are peculiar to it.
|
|
343
|
+
|
|
344
|
+
Machine-readable output: every command accepts --json and prints exactly one
|
|
345
|
+
JSON object per invocation. Run "approval <command> --help" for that command's
|
|
346
|
+
exact shape.
|
|
347
|
+
${JSON_ERRORS}
|
|
348
|
+
|
|
349
|
+
The stances every verb inherits, stated once:
|
|
350
|
+
|
|
351
|
+
THE LOG IS APPEND-ONLY. "policy attest" and the gate verbs (register, request,
|
|
352
|
+
grant, reject, revoke, expire) each append at most one event per invocation; a
|
|
353
|
+
torn tail is reported, never repaired, and nothing ever rewrites a line.
|
|
354
|
+
|
|
355
|
+
A GATE REFUSAL exits 1, NOT 2 — an illegal transition, an expired request, an
|
|
356
|
+
unattested policy, a failed budget. The command was well-formed; the answer is
|
|
357
|
+
no. With --json, error.code names the refusal, and retrying with different
|
|
358
|
+
flags is the wrong repair.
|
|
359
|
+
|
|
360
|
+
IDENTITY IS CONFIG-DECLARED (SPEC.md §11). The actor comes from --as or
|
|
361
|
+
APPROVAL_HUMAN and nothing authenticates it; the trust boundary is the local
|
|
362
|
+
machine. What the log proves is that someone with local control acted, not
|
|
363
|
+
who. grant, reject, revoke and every human-only verb require human:<id>;
|
|
364
|
+
expire is the system verb and takes no identity.
|
|
365
|
+
|
|
366
|
+
APPROVAL EVENTS ARE EXCLUSIVE TO THE MANUAL PATH (amended SPEC.md §6.3). An
|
|
367
|
+
action resolving to supervised or autonomous emits no approval.requested and
|
|
368
|
+
no approval.granted: "approval request" appends nothing and reports
|
|
369
|
+
proceed:true, and its authorization is the execution.started event. Do not
|
|
370
|
+
wait for a grant that will never come.
|
|
371
|
+
|
|
372
|
+
THE RAW EXECUTION TOKEN IS SHOWN ONCE, BY "approval grant". The log records
|
|
373
|
+
only its SHA-256, so nothing can recover it — not "approval token", not the
|
|
374
|
+
log, not the index. If it is lost, revoke the grant and request again.
|
|
375
|
+
|
|
376
|
+
A CHANNEL IS TRANSPORT. It renders what the runtime derived and reports the
|
|
377
|
+
gesture a human made; it decides nothing, holds no state, writes no log line
|
|
378
|
+
and never sees a token. Every field it shows is marked [computed] (the runtime
|
|
379
|
+
derived it) or [claimed] (the party under oversight wrote it), per SPEC.md §9.
|
|
380
|
+
|
|
381
|
+
The reasoning behind each verb — threat models, the design points that surprise
|
|
382
|
+
people, the alternatives that were rejected — is in docs/cli-reference.md.`;
|
|
383
|
+
export const INSTRUCTIONS_HELP = `approval instructions — the agent-facing usage guide (SPEC.md §10.1)
|
|
384
|
+
|
|
385
|
+
Usage:
|
|
386
|
+
approval instructions [--json]
|
|
387
|
+
approval instructions --schemas
|
|
388
|
+
|
|
389
|
+
Flags:
|
|
390
|
+
--schemas print the VERB REGISTRY as JSON instead of the guide: purpose,
|
|
391
|
+
input schema, --json output schema, error shape, exit codes and
|
|
392
|
+
human_only marker for every verb. Always JSON
|
|
393
|
+
--json print the guide as {"guide":"<text>","verbs":[…]}
|
|
394
|
+
-h, --help this text
|
|
395
|
+
|
|
396
|
+
Prints what an agent needs to know before it acts: the register -> request ->
|
|
397
|
+
wait -> run sequence, what a refusal means, and the invariants that are enforced
|
|
398
|
+
rather than requested. Reads no log, resolves no policy, writes nothing.
|
|
399
|
+
|
|
400
|
+
${EXIT_CODES_POINTER} (instructions uses only 0 and 2)
|
|
401
|
+
${JSON_ERRORS}
|
|
402
|
+
${why("instructions")}`;
|
|
403
|
+
export const LOG_HELP = `approval log — read the append-only event log, and move it
|
|
404
|
+
|
|
405
|
+
Usage:
|
|
406
|
+
approval log verify [--log <path>] [--json]
|
|
407
|
+
approval log tail [--log <path>] [-n <count>] [--json]
|
|
408
|
+
approval log export [--log <path>] [--json]
|
|
409
|
+
approval log follow [--log <path>] [--from <seq>] [--cursor-hash <64hex>] --json
|
|
410
|
+
approval log sync [--remote <name>] [--branch <name>] [--json]
|
|
411
|
+
approval log advance [--branch <name>] [--pr] [--dry-run] [--json]
|
|
412
|
+
approval log checkpoint --as human:<id> [--key-file <path>] [--json]
|
|
413
|
+
|
|
414
|
+
Subcommands:
|
|
415
|
+
verify walk the hash chain end to end; clean | torn-tail | corrupt
|
|
416
|
+
tail / export the last N records (default 10) / every line, verbatim
|
|
417
|
+
follow verified records after an exclusive cursor, then verified appends
|
|
418
|
+
sync fast-forward pull, with a snapshot and a chain reconcile
|
|
419
|
+
advance commit the log's new records onto a records branch
|
|
420
|
+
checkpoint sign the current head with your own key (human-only)
|
|
421
|
+
|
|
422
|
+
verify, tail, export and follow only read. sync and advance move the FILE and append no record;
|
|
423
|
+
checkpoint appends one. Default log: .approval/log/events.jsonl
|
|
424
|
+
JSON shapes: docs/cli-reference.md; ${EXIT_CODES_POINTER}
|
|
425
|
+
${JSON_ERRORS}
|
|
426
|
+
${why("log")}`;
|
|
427
|
+
export const FOLLOW_HELP = `approval log follow — follow verified records after a cursor
|
|
428
|
+
|
|
429
|
+
Usage:
|
|
430
|
+
approval log follow [--log <path>] [--from <seq>] [--cursor-hash <64hex>] --json
|
|
431
|
+
|
|
432
|
+
Flags:
|
|
433
|
+
--log <path> log file to read (default .approval/log/events.jsonl)
|
|
434
|
+
--from <seq> exclusive sequence cursor (default 0)
|
|
435
|
+
--cursor-hash <hex> hash of record --from, retained by the consumer
|
|
436
|
+
--json required; one complete event object per stdout line
|
|
437
|
+
-h, --help this text
|
|
438
|
+
|
|
439
|
+
The complete chain is verified before each emitted batch. Notifications only
|
|
440
|
+
wake another verification. Corrupt, torn, unreadable, truncated or cursor-
|
|
441
|
+
mismatched logs stop the stream before any record from that batch is printed.
|
|
442
|
+
|
|
443
|
+
Persist seq and hash after the external effect succeeds. Reconnecting from that
|
|
444
|
+
cursor is at-least-once across a crash between the effect and cursor storage;
|
|
445
|
+
exactly-once external effects require the consumer's own idempotency mechanism.
|
|
446
|
+
|
|
447
|
+
${EXIT_CODES_POINTER} (0 on signal or broken-pipe cancellation; 1 corrupt or cursor
|
|
448
|
+
mismatch; 2 usage; 3 torn tail; 4 I/O)
|
|
449
|
+
${JSON_ERRORS}
|
|
450
|
+
${why("log-follow")}`;
|
|
451
|
+
export const LOG_SYNC_HELP = `approval log sync — fast-forward the committed log, safely
|
|
452
|
+
|
|
453
|
+
Usage:
|
|
454
|
+
approval log sync [--remote <name>] [--branch <name>] [--json]
|
|
455
|
+
|
|
456
|
+
Flags:
|
|
457
|
+
--remote <name> remote to fetch from (default origin)
|
|
458
|
+
--branch <name> branch to fast-forward onto (default: the checked-out one)
|
|
459
|
+
--json machine-readable output
|
|
460
|
+
-h, --help this text
|
|
461
|
+
|
|
462
|
+
Holds the append lockfile for the WHOLE operation, verifies the chain, copies
|
|
463
|
+
events.jsonl aside (never \`git stash\`), fast-forwards, then reconciles: the
|
|
464
|
+
committed chain must be a prefix of the snapshot, equal to it, or an extension,
|
|
465
|
+
and anything else is log-diverged. Untracked payloads the incoming commit also
|
|
466
|
+
carries are proved byte-identical and stood aside for it. QUEUE.md and the index
|
|
467
|
+
are REBUILT; no event is appended. PRIMARY CHECKOUT ONLY.
|
|
468
|
+
Refusals: log-sync-not-primary, log-sync-unverified, log-sync-not-fast-forward,
|
|
469
|
+
log-sync-payload-mismatch, log-diverged, log-sync-locked, log-sync-git-failed,
|
|
470
|
+
log-sync-projection-failed, log-sync-restore-failed, log-sync-io.
|
|
471
|
+
|
|
472
|
+
${EXIT_CODES_POINTER}
|
|
473
|
+
${JSON_ERRORS}
|
|
474
|
+
${why("log-sync")}`;
|
|
475
|
+
export const LOG_ADVANCE_HELP = `approval log advance — commit and push the log's new records
|
|
476
|
+
|
|
477
|
+
Usage:
|
|
478
|
+
approval log advance [--remote <n>] [--branch <n>] [--base <n>] [--pr]
|
|
479
|
+
[--co-author "Name <email>"] [--no-auto-merge] [--dry-run] [--json]
|
|
480
|
+
Flags:
|
|
481
|
+
--remote <name> remote to push to (default origin)
|
|
482
|
+
--branch <name> records branch (default records-log-<date>); never main
|
|
483
|
+
--base <name> branch to parent the commit on (default: the one you are on)
|
|
484
|
+
--co-author <id> append Name <email> display credit to commit and PR body
|
|
485
|
+
--pr / --dry-run open the PR through gh and ARM its merge / write nothing
|
|
486
|
+
--no-auto-merge / --json / -h, --help do not arm / JSON output / this text
|
|
487
|
+
|
|
488
|
+
Verifies the chain under the append lock, FETCHES the base branch, builds a
|
|
489
|
+
commit on <remote>/<base> carrying EXACTLY the log, QUEUE.md and payloads, and
|
|
490
|
+
pushes it by refspec. You do not fetch or reset first; the checkout is left as
|
|
491
|
+
found, nothing is checked out, no event is appended, and any other staged path
|
|
492
|
+
is refused. PRIMARY CHECKOUT ONLY. Refusals, each prefixed log-advance-:
|
|
493
|
+
not-primary, dirty-stage, checkout-required, unverified, locked, fetch-failed,
|
|
494
|
+
behind-remote, remote-diverged, git-failed, push-rejected, pr-failed.
|
|
495
|
+
|
|
496
|
+
${EXIT_CODES_POINTER}
|
|
497
|
+
${JSON_ERRORS}
|
|
498
|
+
${why("log-advance")}`;
|
|
499
|
+
export const VERIFY_HELP = `approval log verify — verify the log's hash chain
|
|
500
|
+
|
|
501
|
+
Usage:
|
|
502
|
+
approval log verify [--log <path>] [--anchor] [--checkpoints] [--json]
|
|
503
|
+
|
|
504
|
+
Flags:
|
|
505
|
+
--log <path> log file to verify (default .approval/log/events.jsonl)
|
|
506
|
+
--anchor [--anchor-rev <rev>] compare the prefix against the committed copy
|
|
507
|
+
--checkpoints also demand every human-signed checkpoint in range
|
|
508
|
+
--json / -h, --help machine-readable output / this text
|
|
509
|
+
|
|
510
|
+
Walks every complete line: re-derives each record's digest, follows the prev
|
|
511
|
+
chain and seq succession, and names where the log stops being self-consistent.
|
|
512
|
+
An absent file verifies clean; nothing is written and a torn tail is not cut.
|
|
513
|
+
--anchor compares the prefix against the committed copy; --checkpoints demands
|
|
514
|
+
that every log.checkpoint verify under audit.checkpoint_keys and name the hash
|
|
515
|
+
this log carries. Either mismatch refuses; a missing witness skips, never passes.
|
|
516
|
+
|
|
517
|
+
JSON: "status" clean|torn-tail|corrupt|anchor-diverged|checkpoint-invalid, plus
|
|
518
|
+
"records", "head" and optional anomalies/anchor/checkpoints. ANOMALIES ARE CLEAN.
|
|
519
|
+
|
|
520
|
+
${EXIT_CODES_POINTER} (clean 0, corrupt 1, torn-tail 3; an unreadable log is 4)
|
|
521
|
+
${JSON_ERRORS}
|
|
522
|
+
${why("log-verify")}`;
|
|
523
|
+
export const LOG_CHECKPOINT_HELP = `approval log checkpoint — sign the log's head, by hand
|
|
524
|
+
|
|
525
|
+
Usage:
|
|
526
|
+
approval log checkpoint --as human:<id> [--key-file <path>] [--json]
|
|
527
|
+
|
|
528
|
+
Flags:
|
|
529
|
+
--as human:<id> who is signing; or set APPROVAL_HUMAN
|
|
530
|
+
--key-file <path> read the signing key from this file instead of the vault
|
|
531
|
+
--log <path> log file to checkpoint (default .approval/log/events.jsonl)
|
|
532
|
+
--json / -h, --help machine-readable output / this text
|
|
533
|
+
|
|
534
|
+
Signs the CURRENT chain head with your Ed25519 checkpoint key and appends one
|
|
535
|
+
log.checkpoint record naming (seq, hash) and the signature. The key comes from
|
|
536
|
+
the vault credential approval.checkpoint.key; its PUBLIC half belongs in
|
|
537
|
+
APPROVAL.md under audit.checkpoint_keys, which only you may edit. HUMAN-ONLY:
|
|
538
|
+
an agent that could sign one could vouch for a chain it had just written.
|
|
539
|
+
|
|
540
|
+
The chain is unkeyed, so anyone who can write events.jsonl can recompute a
|
|
541
|
+
forgery that walks clean from genesis. What they cannot do is re-sign the
|
|
542
|
+
hashes they replaced, which is what \`log verify --checkpoints\` then catches.
|
|
543
|
+
|
|
544
|
+
${EXIT_CODES_POINTER}
|
|
545
|
+
${JSON_ERRORS}
|
|
546
|
+
${why("log-checkpoint")}`;
|
|
547
|
+
export const TAIL_HELP = `approval log tail — print the last records of the log
|
|
548
|
+
|
|
549
|
+
Usage:
|
|
550
|
+
approval log tail [--log <path>] [-n <count>] [--json]
|
|
551
|
+
|
|
552
|
+
Flags:
|
|
553
|
+
--log <path> log file to read (default .approval/log/events.jsonl)
|
|
554
|
+
-n <count> how many records to print (default 10; 0 prints none)
|
|
555
|
+
--json machine-readable output
|
|
556
|
+
-h, --help this text
|
|
557
|
+
|
|
558
|
+
The chain is verified first. On a torn tail the intact records are printed and
|
|
559
|
+
the tear is a warning on stderr; on a corrupt log no records are printed at all.
|
|
560
|
+
An empty or absent log prints nothing and succeeds. Nothing is repaired.
|
|
561
|
+
|
|
562
|
+
JSON shape (stdout, one object):
|
|
563
|
+
{"status":"ok","records":[<event objects, oldest first>]}
|
|
564
|
+
{"status":"torn-tail","records":[...],"warning":"..."}
|
|
565
|
+
|
|
566
|
+
Human output: one line per record — seq, ts, event, actor, task.
|
|
567
|
+
|
|
568
|
+
${EXIT_CODES_POINTER} (0 on success, torn tail included; 1 on a corrupt log)
|
|
569
|
+
${JSON_ERRORS}
|
|
570
|
+
${why("log-tail")}`;
|
|
571
|
+
export const EXPORT_HELP = `approval log export — stream the whole log to stdout
|
|
572
|
+
|
|
573
|
+
Usage:
|
|
574
|
+
approval log export [--log <path>] [--json]
|
|
575
|
+
|
|
576
|
+
Flags:
|
|
577
|
+
--log <path> log file to read (default .approval/log/events.jsonl)
|
|
578
|
+
--json machine-readable output
|
|
579
|
+
-h, --help this text
|
|
580
|
+
|
|
581
|
+
Without --json the stored lines are written verbatim, byte for byte: piping
|
|
582
|
+
export to a file yields a copy of the log. The chain is verified first; a torn
|
|
583
|
+
tail prints the intact lines with a stderr warning and exits 0, a corrupt log
|
|
584
|
+
prints nothing and fails. The log is never modified.
|
|
585
|
+
|
|
586
|
+
JSON shape (stdout, one object):
|
|
587
|
+
{"records":[<every event object, oldest first>]}
|
|
588
|
+
{"records":[...],"warning":"..."} on a torn tail
|
|
589
|
+
|
|
590
|
+
${EXIT_CODES_POINTER} (0 on success, torn tail included; 1 on a corrupt log)
|
|
591
|
+
${JSON_ERRORS}
|
|
592
|
+
${why("log-export")}`;
|
|
593
|
+
/**
|
|
594
|
+
* The policy command's exit-code stance, printed in all three policy help
|
|
595
|
+
* texts. It is the one place where "answer" and "error" come apart: `policy
|
|
596
|
+
* check` answers the question "what would policy do with this class", and a
|
|
597
|
+
* policy too broken to load has a perfectly good answer — manual, everything,
|
|
598
|
+
* always. The long version is docs/cli-reference.md#policy.
|
|
599
|
+
*/
|
|
600
|
+
const POLICY_EXIT_CODES = `${EXIT_CODES_POINTER}. policy check|test uses only 0, 2 and 4:
|
|
601
|
+
0 the question was answered, INCLUDING the fail-closed answer: a broken
|
|
602
|
+
policy IS a manual-everything policy, delivered on stdout at exit 0.
|
|
603
|
+
2 usage — a missing <class>, an unknown flag, or an invalid action class.
|
|
604
|
+
4 I/O — a policy path that exists but cannot be read.`;
|
|
605
|
+
/** The three values of manualBecause, named so an agent can branch on them. */
|
|
606
|
+
const POLICY_MANUAL_BECAUSE = `manualBecause is "matched-rule", "irreversibility-floor" or "load-failure".`;
|
|
607
|
+
export const POLICY_HELP = `approval policy — explain what policy does with an action class
|
|
608
|
+
|
|
609
|
+
Usage:
|
|
610
|
+
approval policy check|test <class> [--reversible true|false] [--policy <p>]
|
|
611
|
+
[--dir <p>] [--json]
|
|
612
|
+
approval policy attest [--policy <p>] [--dir <p>] [--as human:<id>] [--json]
|
|
613
|
+
approval policy amend [--policy <p>] [--dir <p>] [--log <p>] [--as human:<id>]
|
|
614
|
+
[--require-load] [--dry-run] [--commit] [--yes] [--json]
|
|
615
|
+
|
|
616
|
+
Subcommands:
|
|
617
|
+
check explain the autonomy resolution for <class>
|
|
618
|
+
test exact alias of check (SPEC.md §10.1 names both)
|
|
619
|
+
attest record a human's sign-off on the policy file's bytes (human-only)
|
|
620
|
+
amend the whole amendment ceremony: diff, advisory, attestation, commit
|
|
621
|
+
|
|
622
|
+
Nothing is executed, requested, or logged: this reads APPROVAL.md and answers a
|
|
623
|
+
hypothetical. Discovery is APPROVAL.md then APPROVALS.md in --dir.
|
|
624
|
+
${POLICY_MANUAL_BECAUSE}
|
|
625
|
+
|
|
626
|
+
${POLICY_EXIT_CODES}
|
|
627
|
+
${why("policy")}`;
|
|
628
|
+
function policyVerbHelp(verb, alias) {
|
|
629
|
+
return `approval policy ${verb} — explain what policy does with an action class
|
|
630
|
+
|
|
631
|
+
Usage:
|
|
632
|
+
approval policy ${verb} <class> [--reversible true|false] [--policy <p>] [--dir <p>] [--json]
|
|
633
|
+
|
|
634
|
+
Flags:
|
|
635
|
+
--reversible <true|false> whether the action can be undone. Omitted leaves
|
|
636
|
+
the question open; false engages the irreversibility floor
|
|
637
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
638
|
+
--json / -h, --help machine-readable output / this text
|
|
639
|
+
|
|
640
|
+
An exact alias of \`policy ${alias}\`; <class> is a concrete action class
|
|
641
|
+
(lowercase dotted segments, e.g. vcs.push.main), never a pattern.
|
|
642
|
+
${POLICY_MANUAL_BECAUSE}
|
|
643
|
+
|
|
644
|
+
JSON shape (class, outcome, provenance, manualBecause, loadFailure, matched,
|
|
645
|
+
overridden, candidates, "decisionPath"): docs/cli-reference.md#policy-check
|
|
646
|
+
${POLICY_EXIT_CODES}
|
|
647
|
+
${JSON_ERRORS}
|
|
648
|
+
${why("policy-check")}`;
|
|
649
|
+
}
|
|
650
|
+
export const POLICY_CHECK_HELP = policyVerbHelp("check", "test");
|
|
651
|
+
export const POLICY_TEST_HELP = policyVerbHelp("test", "check");
|
|
652
|
+
export const POLICY_ATTEST_HELP = `approval policy attest — record a human's sign-off on the policy file
|
|
653
|
+
|
|
654
|
+
Usage:
|
|
655
|
+
approval policy attest [--policy <path>] [--dir <path>] [--organ <path>]
|
|
656
|
+
[--as human:<id>] [--log <path>] [--json]
|
|
657
|
+
|
|
658
|
+
Flags:
|
|
659
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
660
|
+
--organ <path> attest a GATE ORGAN instead; one path per call, under --dir
|
|
661
|
+
--as human:<id> the human attesting; overrides APPROVAL_HUMAN
|
|
662
|
+
--log <path> log file to append to (default .approval/log/events.jsonl)
|
|
663
|
+
--json machine-readable output
|
|
664
|
+
-h, --help this text
|
|
665
|
+
|
|
666
|
+
Appends one policy.updated event carrying the SHA-256 of the policy file's exact
|
|
667
|
+
bytes; gate operations refuse while it differs ("policy-not-attested").
|
|
668
|
+
Human-only, identity CONFIG-DECLARED: the trust boundary is the local machine,
|
|
669
|
+
so it proves someone with local control signed off, not who. Bytes, not parse.
|
|
670
|
+
--organ appends gate.organ.attested for a policy.core harness file instead.
|
|
671
|
+
|
|
672
|
+
JSON shape: docs/cli-reference.md#policy-attest
|
|
673
|
+
${EXIT_CODES_POINTER}
|
|
674
|
+
${JSON_ERRORS}
|
|
675
|
+
${why("policy-attest")}`;
|
|
676
|
+
export const POLICY_AMEND_HELP = `approval policy amend — the whole amendment ceremony, in one verb
|
|
677
|
+
|
|
678
|
+
Usage:
|
|
679
|
+
approval policy amend [--policy|--dir|--log <p>] [--as human:<id>|agent:<id>] [--require-load]
|
|
680
|
+
[--dry-run] [--commit] [--no-publish] [--yes] [--json] [--branch <n>|--direct] [--wait <d>]
|
|
681
|
+
|
|
682
|
+
Flags:
|
|
683
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
684
|
+
--as human:<id> / agent:<id> attest HERE, or ask for a TAP (--wait/--interval/--note)
|
|
685
|
+
--require-load refuse to attest a policy that does not load
|
|
686
|
+
--dry-run / --commit / --no-publish write nothing / the ceremony / stop at commit
|
|
687
|
+
--branch <name> / --direct force the BRANCH or the DIRECT flow
|
|
688
|
+
--yes / --json / -h, --help skip the prompt / machine-readable / this text
|
|
689
|
+
|
|
690
|
+
Hashes the policy, diffs it against the BASELINE (classes AND every policy key), attests, then
|
|
691
|
+
commits EXACTLY the policy, the log and the pins when they moved. commit-preconditions, the pins
|
|
692
|
+
and the DOGFOOD SUITE refuse BEFORE the append; git-failed, push-rejected, pr-failed break after it.
|
|
693
|
+
Attested TEXT is NOT recoverable from the log: HASH-ONLY MODE. Flows, in PRECEDENCE, highest first:
|
|
694
|
+
--branch <name>, --direct; a refused push PUBLISHES ITSELF, dropping to a RUNBOOK. MERGE COMMIT it.
|
|
695
|
+
--as agent: appends policy.proposed; the TAP attests. Fail closed: no-channel, declined, timeout.
|
|
696
|
+
|
|
697
|
+
${EXIT_CODES_POINTER}
|
|
698
|
+
${JSON_ERRORS}
|
|
699
|
+
${why("policy-amend")}`;
|
|
700
|
+
/**
|
|
701
|
+
* The gate verbs' refusal vocabulary and the one line they add to the root's
|
|
702
|
+
* table. The vocabulary itself is frozen public API and is listed in full at
|
|
703
|
+
* docs/cli-reference.md#gate-refusal-codes; what a per-verb help prints is the
|
|
704
|
+
* pointer to it, plus the fact that a refusal is 1 and not 2.
|
|
705
|
+
*/
|
|
706
|
+
const GATE_CODES_POINTER = `Refusal codes (frozen public API): docs/cli-reference.md#gate-refusal-codes
|
|
707
|
+
${EXIT_CODES_POINTER}. A GATE REFUSAL IS 1, NOT 2: the command was well-formed
|
|
708
|
+
and the runtime said no. Branch on error.code, not on the exit code.`;
|
|
709
|
+
/** The same two facts for the verbs that speak the token vocabulary. */
|
|
710
|
+
const TOKEN_CODES_POINTER = `Refusal codes (frozen public API): docs/cli-reference.md#token-refusal-codes
|
|
711
|
+
${EXIT_CODES_POINTER}. A GATE REFUSAL IS 1, NOT 2: the command was well-formed
|
|
712
|
+
and the runtime said no. Branch on error.code, not on the exit code.`;
|
|
713
|
+
export const REGISTER_HELP = `approval register — validate a task envelope and record it
|
|
714
|
+
|
|
715
|
+
Usage:
|
|
716
|
+
approval register <task-file> [--as human:<id>|agent:<id>] [--log <path>]
|
|
717
|
+
[--json]
|
|
718
|
+
|
|
719
|
+
Flags:
|
|
720
|
+
--as <id> who is registering; human:<id> or agent:<id>, else
|
|
721
|
+
APPROVAL_HUMAN. Registration is a proposal, not a decision
|
|
722
|
+
--log <path> log file to append to (default .approval/log/events.jsonl)
|
|
723
|
+
--json machine-readable output
|
|
724
|
+
-h, --help this text
|
|
725
|
+
|
|
726
|
+
Reads the task file's YAML frontmatter, validates the value of its \`approval:\`
|
|
727
|
+
key against envelope.schema.json, and appends one task.registered event carrying
|
|
728
|
+
the declared actions. FAIL CLOSED: an invalid envelope appends nothing. The file
|
|
729
|
+
is READ ONLY, and registering the same task id twice is refused.
|
|
730
|
+
|
|
731
|
+
JSON shape: docs/cli-reference.md#register
|
|
732
|
+
${GATE_CODES_POINTER}
|
|
733
|
+
${JSON_ERRORS}
|
|
734
|
+
${why("register")}`;
|
|
735
|
+
export const REQUEST_HELP = `approval request — ask the gate to admit a declared action
|
|
736
|
+
|
|
737
|
+
Usage:
|
|
738
|
+
approval request <task> --action <key> [--as human:<id>|agent:<id>]
|
|
739
|
+
[--payload <file>|-] [--policy <path>] [--dir <path>]
|
|
740
|
+
[--log <path>] [--json]
|
|
741
|
+
|
|
742
|
+
Flags:
|
|
743
|
+
--action <key> the action's idempotency_key, as registered (required)
|
|
744
|
+
--as <id> human:<id> or agent:<id>; else APPROVAL_HUMAN
|
|
745
|
+
--payload <file|-> the payload bytes, hashed and filed in the payload store
|
|
746
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
747
|
+
--json machine-readable output
|
|
748
|
+
-h, --help this text
|
|
749
|
+
|
|
750
|
+
Class and cost come from the task.registered record in the log. APPROVAL EVENTS
|
|
751
|
+
ARE EXCLUSIVE to the manual path: a non-manual action reports proceed:true.
|
|
752
|
+
|
|
753
|
+
JSON shape: docs/cli-reference.md#request
|
|
754
|
+
${GATE_CODES_POINTER}
|
|
755
|
+
${JSON_ERRORS}
|
|
756
|
+
${why("request")}`;
|
|
757
|
+
function decisionHelp(verb) {
|
|
758
|
+
const noun = verb === "grant" ? "approval" : verb === "reject" ? "refusal" : "withdrawal";
|
|
759
|
+
const body = verb === "grant"
|
|
760
|
+
? `Appends one approval.granted, MINTS the single-use execution token and PRINTS
|
|
761
|
+
IT ONCE. HUMAN-ONLY. Legal only on a request awaiting a decision; attestation is
|
|
762
|
+
required, budgets re-evaluated; loved/disliked need --note; read back: feedback.`
|
|
763
|
+
: verb === "reject"
|
|
764
|
+
? `Appends one approval.rejected. HUMAN-ONLY. Legal only on a request awaiting a
|
|
765
|
+
decision, and a second decision is refused. No attestation is required and no
|
|
766
|
+
budget is charged: an authorization refused was never a commitment.`
|
|
767
|
+
: `Appends one approval.revoked. HUMAN-ONLY. Legal only on a GRANTED request that
|
|
768
|
+
has not executed. No attestation is required and no budget is charged: an
|
|
769
|
+
authorization withdrawn was never a commitment.`;
|
|
770
|
+
return `approval ${verb} — record a human ${noun} (HUMAN-ONLY)
|
|
771
|
+
|
|
772
|
+
Usage:
|
|
773
|
+
approval ${verb} <action-key> [--note <text>]${verb === "grant" ? " [--reaction <w>]" : ""} [--as human:<id>]
|
|
774
|
+
[--policy <path>] [--dir <path>] [--log <path>] [--json]
|
|
775
|
+
|
|
776
|
+
Flags:
|
|
777
|
+
--note <text> free-text note recorded in the event payload${verb === "grant"
|
|
778
|
+
? "\n --reaction <w> disliked|indifferent|liked|loved. GUIDANCE, never policy"
|
|
779
|
+
: ""}
|
|
780
|
+
--as human:<id> the deciding human; overrides APPROVAL_HUMAN
|
|
781
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
782
|
+
--log <path> log file to read and append to
|
|
783
|
+
--json / -h, --help machine-readable output / this text
|
|
784
|
+
|
|
785
|
+
${body}
|
|
786
|
+
|
|
787
|
+
JSON shape: docs/cli-reference.md#${verb}
|
|
788
|
+
${GATE_CODES_POINTER}
|
|
789
|
+
${JSON_ERRORS}
|
|
790
|
+
${why(verb)}`;
|
|
791
|
+
}
|
|
792
|
+
export const GRANT_HELP = decisionHelp("grant");
|
|
793
|
+
export const REJECT_HELP = decisionHelp("reject");
|
|
794
|
+
export const REVOKE_HELP = decisionHelp("revoke");
|
|
795
|
+
export const WITHDRAW_HELP = `approval withdraw — take back your own pending request
|
|
796
|
+
|
|
797
|
+
Usage:
|
|
798
|
+
approval withdraw <task> --action <key> [--reason <r>] [--note <text>]
|
|
799
|
+
[--as <id>] [--policy <p>] [--dir <p>] [--log <p>] [--json]
|
|
800
|
+
|
|
801
|
+
Flags:
|
|
802
|
+
--action <key> the action's idempotency_key (required)
|
|
803
|
+
--reason <r> timeout | cancelled | superseded (default cancelled)
|
|
804
|
+
--note <text> free-text elaboration recorded in the event payload
|
|
805
|
+
--as <id> human:<id> or agent:<id>; else APPROVAL_HUMAN
|
|
806
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
807
|
+
--json machine-readable output; -h, --help this text
|
|
808
|
+
|
|
809
|
+
Appends one approval.withdrawn. REQUESTER-ONLY (else not-requester) and
|
|
810
|
+
PENDING-ONLY; terminal, so a later decision is refused request-withdrawn.
|
|
811
|
+
Withdraw when you can no longer consume an answer. A human REJECTS instead.
|
|
812
|
+
|
|
813
|
+
JSON shape: docs/cli-reference.md#withdraw
|
|
814
|
+
${GATE_CODES_POINTER}
|
|
815
|
+
${JSON_ERRORS}
|
|
816
|
+
${why("withdraw")}`;
|
|
817
|
+
export const EXPIRE_HELP = `approval expire — lapse a request whose TTL has passed (system verb)
|
|
818
|
+
|
|
819
|
+
Usage:
|
|
820
|
+
approval expire <action-key> [--policy <path>] [--dir <path>] [--log <path>]
|
|
821
|
+
[--json]
|
|
822
|
+
|
|
823
|
+
Flags:
|
|
824
|
+
--policy <path> policy file to read defaults.approval_ttl from
|
|
825
|
+
--dir <path> directory to discover APPROVAL.md / APPROVALS.md in
|
|
826
|
+
--log <path> log file to read and append to
|
|
827
|
+
--json machine-readable output
|
|
828
|
+
-h, --help this text
|
|
829
|
+
|
|
830
|
+
Appends one approval.expired event with the actor system:gate. NO IDENTITY is
|
|
831
|
+
accepted or resolved: no human decides an expiry, the clock does. Refused when
|
|
832
|
+
the request is not live, and when the TTL has not lapsed.
|
|
833
|
+
|
|
834
|
+
JSON shape: docs/cli-reference.md#expire
|
|
835
|
+
${GATE_CODES_POINTER}
|
|
836
|
+
${JSON_ERRORS}
|
|
837
|
+
${why("expire")}`;
|
|
838
|
+
export const GATE_WINDOW_HELP = `approval gate — the open window: a human-only, time-boxed harness bypass
|
|
839
|
+
|
|
840
|
+
Usage:
|
|
841
|
+
approval gate open [--for <duration>] --reason "<text>" [--as human:<id>]
|
|
842
|
+
[--log <path>] (terminal; no --json)
|
|
843
|
+
approval gate close [--note "<text>"] [--as human:<id>] [--log <path>] [--json]
|
|
844
|
+
approval gate status [--log <path>] [--json]
|
|
845
|
+
|
|
846
|
+
Flags:
|
|
847
|
+
--for <duration> how long the window stands; default 30m, cap 24h
|
|
848
|
+
--reason "<text>" why it is being opened; required, and recorded
|
|
849
|
+
--note "<text>" what was learned, recorded on the close
|
|
850
|
+
--as human:<id> the person opening or closing it (or ${"APPROVAL_HUMAN"})
|
|
851
|
+
--log <path> log file to read and append to; --json for status and close
|
|
852
|
+
|
|
853
|
+
While a window is open the harness hook ALLOWS every gated tool call under the
|
|
854
|
+
root and records each as gate.bypassed, ahead of the policy, attestation, the
|
|
855
|
+
loop floor and the human gate. It never reaches .approval/log/, a human-only
|
|
856
|
+
class, a command the classifier cannot read, or a log it cannot verify. open is
|
|
857
|
+
a ceremony: a terminal, and the word \`understood\` typed in full. There is no
|
|
858
|
+
--yes and no --force. State lives in the log; a lapse appends nothing.
|
|
859
|
+
|
|
860
|
+
JSON shape: docs/cli-reference.md#gate
|
|
861
|
+
${EXIT_CODES_POINTER}
|
|
862
|
+
${why("gate")}`;
|
|
863
|
+
export const REINDEX_HELP = `approval reindex — rebuild the SQLite index from the log
|
|
864
|
+
|
|
865
|
+
Usage:
|
|
866
|
+
approval reindex [--log <path>] [--index <path>] [--force] [--json]
|
|
867
|
+
|
|
868
|
+
Flags:
|
|
869
|
+
--log <path> log file to project (default .approval/log/events.jsonl)
|
|
870
|
+
--index <path> index file to write (default .approval/index.sqlite)
|
|
871
|
+
--force index the intact prefix of a torn-tail log
|
|
872
|
+
--json machine-readable output
|
|
873
|
+
-h, --help this text
|
|
874
|
+
|
|
875
|
+
The database is a cache; the log is the truth. The index is rebuilt from
|
|
876
|
+
scratch at a temporary path and renamed into place, so a crashed rebuild leaves
|
|
877
|
+
the previous index intact. A corrupt log is refused outright and a torn tail is
|
|
878
|
+
refused unless --force is given. The log itself is never written to.
|
|
879
|
+
|
|
880
|
+
JSON shape (stdout, one object):
|
|
881
|
+
{"ok":true,"records":3,"head":{"seq":3,"hash":"<64hex>"},"truncated":false}
|
|
882
|
+
refusal {"ok":false,"error":{"code":"not-clean"|"torn-tail"|"io","message":…}}
|
|
883
|
+
|
|
884
|
+
${EXIT_CODES_POINTER} (1 when the log failed verification, 3 on a torn tail)
|
|
885
|
+
${JSON_ERRORS}
|
|
886
|
+
${why("reindex")}`;
|
|
887
|
+
export const TOKEN_HELP = `approval token — report the execution-token status of an action
|
|
888
|
+
|
|
889
|
+
Usage:
|
|
890
|
+
approval token <action-key> [--policy <path>] [--dir <path>] [--log <path>]
|
|
891
|
+
[--json]
|
|
892
|
+
|
|
893
|
+
Flags:
|
|
894
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
895
|
+
--log <path> log file to read (never written by this command)
|
|
896
|
+
--json machine-readable output
|
|
897
|
+
-h, --help this text
|
|
898
|
+
|
|
899
|
+
THE RAW TOKEN IS SHOWN ONCE, BY "approval grant", AND IS RECOVERABLE FROM
|
|
900
|
+
NOTHING, so this command does NOT print the token: it reports whether a live,
|
|
901
|
+
unspent token EXISTS and prints its digest. Exit 0 means granted, unrevoked,
|
|
902
|
+
unexpired, unconsumed; every other answer names which of the three deaths
|
|
903
|
+
applied (token-consumed, token-revoked, token-expired).
|
|
904
|
+
|
|
905
|
+
JSON shape: docs/cli-reference.md#token
|
|
906
|
+
${TOKEN_CODES_POINTER}
|
|
907
|
+
${JSON_ERRORS}
|
|
908
|
+
${why("token")}`;
|
|
909
|
+
export const CONSUME_HELP = `approval consume — spend an execution token (INTERNAL PLUMBING)
|
|
910
|
+
|
|
911
|
+
Usage:
|
|
912
|
+
approval consume <action-key> --token <t> [--payload-hash <64hex>]
|
|
913
|
+
[--as <id>] [--policy <path>] [--dir <path>] [--log <path>]
|
|
914
|
+
[--json]
|
|
915
|
+
|
|
916
|
+
Flags:
|
|
917
|
+
--token <t> the raw token printed by "approval grant" (required)
|
|
918
|
+
--payload-hash <64hex> the binding, required whenever the grant bound to bytes
|
|
919
|
+
--as <id> the executing identity; else APPROVAL_HUMAN
|
|
920
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
921
|
+
--json / -h, --help machine-readable output / this text
|
|
922
|
+
|
|
923
|
+
INTERNAL: the plumbing verb "approval run" wraps. It verifies the token and, only
|
|
924
|
+
if live, appends ONE execution.started; a token already spent is token-consumed.
|
|
925
|
+
THE RAW TOKEN IS SHOWN ONCE, BY "approval grant".
|
|
926
|
+
|
|
927
|
+
JSON shape: docs/cli-reference.md#consume
|
|
928
|
+
${TOKEN_CODES_POINTER}
|
|
929
|
+
${JSON_ERRORS}
|
|
930
|
+
${why("consume")}`;
|
|
931
|
+
// ---------------------------------------------------------------------------
|
|
932
|
+
// The execution verbs (APRV-18): run, wait, status, queue
|
|
933
|
+
// ---------------------------------------------------------------------------
|
|
934
|
+
export const RUN_HELP = `approval run — execute a command behind the gate
|
|
935
|
+
|
|
936
|
+
Usage:
|
|
937
|
+
approval run <action-key> [--token <t>] [--payload-hash <64hex>] [--as <id>]
|
|
938
|
+
[--no-sandbox] [--policy <p>] [--dir <p>] [--log <p>] [--json] -- <cmd>…
|
|
939
|
+
|
|
940
|
+
Flags:
|
|
941
|
+
--token <t> the raw token "approval grant" printed. REQUIRED for manual
|
|
942
|
+
--payload-hash <64hex> the content binding, CHECKED and never trusted. run
|
|
943
|
+
always hashes "the argv array and cwd" it is about to spawn;
|
|
944
|
+
a differing value is refused payload-mismatch, not obeyed
|
|
945
|
+
--as <id> the executing identity; else APPROVAL_HUMAN
|
|
946
|
+
--no-sandbox give the child the session's network. RECORDED (untokened
|
|
947
|
+
children otherwise run egress-denied: docs/sandboxed-exec.md)
|
|
948
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
949
|
+
--json / -h, --help machine-readable summary ON STDERR / this text
|
|
950
|
+
|
|
951
|
+
Appends execution.started BEFORE spawning the child, then execution.completed or
|
|
952
|
+
execution.failed with the child's real exit code, and exits with that code.
|
|
953
|
+
JSON shape and refusal codes: docs/cli-reference.md#run
|
|
954
|
+
${EXIT_CODES_POINTER}, plus one code this verb alone emits:
|
|
955
|
+
5 NO VALID EXECUTION TOKEN. Nothing was appended.
|
|
956
|
+
${JSON_ERRORS}
|
|
957
|
+
${why("run")}`;
|
|
958
|
+
export const SANDBOX_HELP = `approval sandbox — run a command with no way out (APRV-193)
|
|
959
|
+
|
|
960
|
+
Usage:
|
|
961
|
+
approval sandbox [--allow-loopback] [--log <path>] -- <cmd> [args…]
|
|
962
|
+
|
|
963
|
+
Flags:
|
|
964
|
+
--allow-loopback also allow connections to localhost. For a suite that
|
|
965
|
+
starts its own server. A real widening: a port is a port
|
|
966
|
+
--log <path> the log, so the credential material beside it can be made
|
|
967
|
+
unreadable to the child (vault, env map, sealing keys)
|
|
968
|
+
-h, --help this text ("--help --long" adds the reference section)
|
|
969
|
+
|
|
970
|
+
Denies the child outbound network (macOS sandbox-exec), scrubs the
|
|
971
|
+
credential-bearing variables out of its environment, and exits with the child's
|
|
972
|
+
own exit code. It appends NOTHING: it removes a capability rather than
|
|
973
|
+
authorizing anything, and the gate stays reachable because its IPC is a file.
|
|
974
|
+
|
|
975
|
+
The point is laundered exec: "npm test" runs whatever was written a minute ago,
|
|
976
|
+
so the command's NAME stopped describing its effect. An agent HARNESS cannot run
|
|
977
|
+
under this — it needs the model API, which is exactly what is denied.
|
|
978
|
+
|
|
979
|
+
${EXIT_CODES_POINTER}, plus 127: no sandbox here, the command did NOT run.
|
|
980
|
+
${why("sandbox")}`;
|
|
981
|
+
export const WAIT_HELP = `approval wait — block until a task's requests are decided
|
|
982
|
+
|
|
983
|
+
Usage:
|
|
984
|
+
approval wait <task> --timeout <d> [--interval <d>] [--withdraw-on-timeout]
|
|
985
|
+
[--as <id>] [--policy <p>] [--dir <p>] [--log <p>] [--json]
|
|
986
|
+
|
|
987
|
+
Flags:
|
|
988
|
+
--timeout <d> how long to wait, in the duration grammar (e.g. 6h). Required
|
|
989
|
+
--interval <d> poll interval (default 500ms)
|
|
990
|
+
--withdraw-on-timeout on timeout, withdraw the requests THIS actor opened
|
|
991
|
+
--as <id> the withdrawing actor; read only with the flag above
|
|
992
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
993
|
+
--json machine-readable output; -h, --help this text
|
|
994
|
+
|
|
995
|
+
Polls until every approval.requested of the task has a decision, or the timeout
|
|
996
|
+
elapses. WRITES NOTHING unless --withdraw-on-timeout. Only the MANUAL path
|
|
997
|
+
produces requests to wait for; a task with none returns at once, exit 0.
|
|
998
|
+
|
|
999
|
+
JSON shape: docs/cli-reference.md#wait
|
|
1000
|
+
${EXIT_CODES_POINTER}. THE CODE IS THE DECISION: 0 granted, 1 rejected, revoked
|
|
1001
|
+
or withdrawn (--json status says which), 3 expired, 4 I/O, and
|
|
1002
|
+
6 TIMEOUT — the wait elapsed with request(s) still undecided.
|
|
1003
|
+
${JSON_ERRORS}
|
|
1004
|
+
${why("wait")}`;
|
|
1005
|
+
export const QUEUE_HELP = `approval queue — the pending-decision inbox
|
|
1006
|
+
|
|
1007
|
+
Usage:
|
|
1008
|
+
approval queue [--policy <path>] [--dir <path>] [--log <path>] [--json]
|
|
1009
|
+
|
|
1010
|
+
Flags:
|
|
1011
|
+
--policy <path> policy file to read defaults.approval_ttl from
|
|
1012
|
+
--dir <path> directory to discover APPROVAL.md / APPROVALS.md in
|
|
1013
|
+
--log <path> log file to read (never written by this command)
|
|
1014
|
+
--json machine-readable output
|
|
1015
|
+
-h, --help this text
|
|
1016
|
+
|
|
1017
|
+
Lists exactly the requests awaiting a human decision and inside their TTL: action
|
|
1018
|
+
key, task, class, declared cost, when it was requested, and how much of the TTL
|
|
1019
|
+
is left. THIS IS AN INBOX, NOT A DASHBOARD. Writes nothing, and EXIT 0 ALWAYS
|
|
1020
|
+
when the log could be read.
|
|
1021
|
+
|
|
1022
|
+
JSON shape: docs/cli-reference.md#queue
|
|
1023
|
+
${EXIT_CODES_POINTER}
|
|
1024
|
+
${JSON_ERRORS}
|
|
1025
|
+
${why("queue")}`;
|
|
1026
|
+
export const STATUS_HELP = `approval status — system health, not the inbox
|
|
1027
|
+
|
|
1028
|
+
Usage:
|
|
1029
|
+
approval status [--policy <path>] [--dir <path>] [--log <path>]
|
|
1030
|
+
[--verbose] [--json]
|
|
1031
|
+
|
|
1032
|
+
Flags:
|
|
1033
|
+
--policy <path> policy file whose bytes attestation is judged against
|
|
1034
|
+
--dir <path> directory to discover APPROVAL.md / APPROVALS.md in
|
|
1035
|
+
--log <path> log file to read (never written by this command)
|
|
1036
|
+
--verbose print the rationale sentences under the rows they explain
|
|
1037
|
+
--json machine-readable output
|
|
1038
|
+
-h, --help this text
|
|
1039
|
+
|
|
1040
|
+
THIS IS NOT "approval queue": queue is what a human must answer, status is what
|
|
1041
|
+
an operator must fix. Writes nothing, and reports in one object: attestation,
|
|
1042
|
+
verification, dangling executions, budget headroom per global limit,
|
|
1043
|
+
loop_escalations, harness_outcomes, git coverage, payload_store, and anomalies
|
|
1044
|
+
when there are any. The coverage numbers move neither health nor the exit code.
|
|
1045
|
+
|
|
1046
|
+
JSON shape: docs/cli-reference.md#status
|
|
1047
|
+
${EXIT_CODES_POINTER} (1 when anything needs attention, including a torn tail)
|
|
1048
|
+
${JSON_ERRORS}
|
|
1049
|
+
${why("status")}`;
|
|
1050
|
+
export const COVERAGE_HELP = `approval coverage — observed side effects, joined to the log
|
|
1051
|
+
|
|
1052
|
+
Usage:
|
|
1053
|
+
approval coverage [--base <ref>] [--head <ref>] [--since <d>] [--until <ts>]
|
|
1054
|
+
[--source git,gh,agentmail] [--vault <p>] [--policy <p>]
|
|
1055
|
+
[--dir <p>] [--log <p>] [--json]
|
|
1056
|
+
|
|
1057
|
+
Flags:
|
|
1058
|
+
--base <ref> / --head <ref> the commit range (default: since the trunk)
|
|
1059
|
+
--since <d> / --until <ts> the adapter window (default 7d, ending now)
|
|
1060
|
+
--source <list> the witnesses to ask: git, gh, agentmail (default git,gh)
|
|
1061
|
+
--policy <p> / --dir <p> / --log <p> / --vault <p> policy, its dir, the log
|
|
1062
|
+
--json machine-readable output; -h, --help this text
|
|
1063
|
+
|
|
1064
|
+
Asks the witnesses this project does NOT write — git, gh, a provider's own
|
|
1065
|
+
record — what happened, and prints what the verified log says about each: an
|
|
1066
|
+
evidence seq, or none. INFORMATIONAL, and writes nothing: exit 0 with or
|
|
1067
|
+
without gaps. Three tiers: custody PREVENTS, this verb WITNESSES, and an effect
|
|
1068
|
+
made with a credential the agent itself holds is covered by neither.
|
|
1069
|
+
|
|
1070
|
+
JSON shape: docs/cli-reference.md#coverage
|
|
1071
|
+
${EXIT_CODES_POINTER}
|
|
1072
|
+
${JSON_ERRORS}
|
|
1073
|
+
${why("coverage")}`;
|
|
1074
|
+
export const DOCTOR_HELP = `approval doctor — environment sanity in one verb
|
|
1075
|
+
|
|
1076
|
+
Usage:
|
|
1077
|
+
approval doctor [--log <path>] [--policy <path>] [--dir <path>]
|
|
1078
|
+
[--tasks <dir>] [--api-base <url>] [--verbose] [--json]
|
|
1079
|
+
|
|
1080
|
+
Flags:
|
|
1081
|
+
--log <path> log file to verify (never written by this command)
|
|
1082
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1083
|
+
--tasks <dir> / --api-base <url> task folder to check / Telegram Bot API
|
|
1084
|
+
--root <path> TEST-ONLY: point build-freshness at another tree
|
|
1085
|
+
--verbose / --json never abbreviate a detail / machine-readable output
|
|
1086
|
+
-h, --help this text
|
|
1087
|
+
|
|
1088
|
+
One row per check, in the order in which their failures cascade: the build, your
|
|
1089
|
+
identity, the policy, the log, channels, the store, sampling, the vault, the
|
|
1090
|
+
environment, harness hooks, evidence sweeps, daemon health, values, checkpoints.
|
|
1091
|
+
Each named at docs/cli-reference.md#doctor. APPENDS NOTHING, sends nothing, and
|
|
1092
|
+
repairs nothing: every fix opens with a command; no credential value is printed.
|
|
1093
|
+
|
|
1094
|
+
JSON shape: docs/cli-reference.md#doctor
|
|
1095
|
+
${EXIT_CODES_POINTER} (1 when ANY check failed; 4 when doctor could not look)
|
|
1096
|
+
${JSON_ERRORS}
|
|
1097
|
+
${why("doctor")}`;
|
|
1098
|
+
export const AUDIT_HELP = `approval audit — the retrospective review of sampled supervised actions
|
|
1099
|
+
|
|
1100
|
+
Usage:
|
|
1101
|
+
approval audit list [--all] [--log <path>] [--json]
|
|
1102
|
+
approval audit review <seq|action-key> [--deny] [--note "<text>"] […]
|
|
1103
|
+
approval audit obligations [--all] [--log <path>] [--json]
|
|
1104
|
+
approval audit reconcile <obligation-seq> --note "<text>" [--revert <key>] […]
|
|
1105
|
+
|
|
1106
|
+
Subcommands:
|
|
1107
|
+
list the open sampled-audit backlog
|
|
1108
|
+
review record that a HUMAN looked at one sampled action (--deny says no)
|
|
1109
|
+
obligations the open reconciliation backlog created by denials
|
|
1110
|
+
reconcile record that a HUMAN discharged one obligation
|
|
1111
|
+
|
|
1112
|
+
SUPERVISED-RETRO actions execute immediately and are sampled AFTERWARDS. A
|
|
1113
|
+
SUPERVISED-LIVE class stops its declared fraction at the gate BEFORE executing;
|
|
1114
|
+
those are answered as manual requests and never reach this backlog.
|
|
1115
|
+
|
|
1116
|
+
A DENIAL CANNOT UNDO ANYTHING. "review --deny" obliges and records instead: an
|
|
1117
|
+
obligation loud in status and doctor until a person closes it with "reconcile".
|
|
1118
|
+
|
|
1119
|
+
THERE IS NO "approval audit sample". Selection is the runtime's, from an
|
|
1120
|
+
operator-held secret. No secret means SAMPLING IS OFF; "audit list" says so.
|
|
1121
|
+
${EXIT_CODES_POINTER}
|
|
1122
|
+
${why("audit")}`;
|
|
1123
|
+
export const AUDIT_LIST_HELP = `approval audit list — the open sampled-audit backlog
|
|
1124
|
+
|
|
1125
|
+
Usage:
|
|
1126
|
+
approval audit list [--all] [--policy <path>] [--dir <path>] [--log <path>]
|
|
1127
|
+
[--json]
|
|
1128
|
+
|
|
1129
|
+
Flags:
|
|
1130
|
+
--all include samples that have already been reviewed
|
|
1131
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1132
|
+
--log <path> log file to read
|
|
1133
|
+
--json machine-readable output
|
|
1134
|
+
-h, --help this text
|
|
1135
|
+
|
|
1136
|
+
Reads a VERIFIED log and writes nothing: the same set .approval/QUEUE.md renders
|
|
1137
|
+
and the daemon counts. A review closes a sample only when it comes AFTER it in
|
|
1138
|
+
the chain and names the same action. sampling.secret_env is the variable's NAME;
|
|
1139
|
+
the SECRET ITSELF is never printed by any code path.
|
|
1140
|
+
|
|
1141
|
+
JSON shape: docs/cli-reference.md#audit-list
|
|
1142
|
+
${EXIT_CODES_POINTER}
|
|
1143
|
+
${JSON_ERRORS}
|
|
1144
|
+
${why("audit-list")}`;
|
|
1145
|
+
export const AUDIT_REVIEW_HELP = `approval audit review — record that a human reviewed a sample
|
|
1146
|
+
|
|
1147
|
+
Usage:
|
|
1148
|
+
approval audit review <seq|action-key> [--deny] [--note "<text>"]
|
|
1149
|
+
[--reaction <w>] [--as human:<id>] [--log <path>] [--json]
|
|
1150
|
+
|
|
1151
|
+
Arguments:
|
|
1152
|
+
<seq|action-key> a bare integer is the SEQ OF THE audit.sampled RECORD; any
|
|
1153
|
+
other value is an action key with one open sample
|
|
1154
|
+
Flags:
|
|
1155
|
+
--deny this action should NOT have happened. Opens an obligation
|
|
1156
|
+
--note <text> what you concluded. OPTIONAL, but loved/disliked REQUIRE it
|
|
1157
|
+
--reaction <w> disliked|indifferent|liked|loved. GUIDANCE, never enforcement
|
|
1158
|
+
--as human:<id> the reviewer; else APPROVAL_HUMAN. HUMAN-ONLY
|
|
1159
|
+
--log <path> / --json / -h, --help the log / machine-readable output / help
|
|
1160
|
+
|
|
1161
|
+
Appends audit.reviewed. NO ATTESTATION IS REQUIRED. Refuses (exit 1) not-sampled,
|
|
1162
|
+
already-reviewed, ambiguous-subject, actor-not-human, note-required and
|
|
1163
|
+
reaction-conflicts-verdict (--deny with liked or loved); log untouched. --deny
|
|
1164
|
+
ALSO appends reconciliation.required, shaped by the DECLARED reversible, not you.
|
|
1165
|
+
JSON: docs/cli-reference.md#audit-review
|
|
1166
|
+
${EXIT_CODES_POINTER}
|
|
1167
|
+
${JSON_ERRORS}
|
|
1168
|
+
${why("audit-review")}`;
|
|
1169
|
+
export const AUDIT_OBLIGATIONS_HELP = `approval audit obligations — the open reconciliation backlog
|
|
1170
|
+
|
|
1171
|
+
Usage:
|
|
1172
|
+
approval audit obligations [--all] [--log <path>] [--json]
|
|
1173
|
+
|
|
1174
|
+
Flags:
|
|
1175
|
+
--all include obligations that have already been satisfied
|
|
1176
|
+
--log <path> log file to read
|
|
1177
|
+
--json machine-readable output
|
|
1178
|
+
-h, --help this text
|
|
1179
|
+
|
|
1180
|
+
Reads a VERIFIED log and writes nothing. An obligation is opened by a
|
|
1181
|
+
retrospective DENIAL ("approval audit review --deny") and closed only by a
|
|
1182
|
+
person ("approval audit reconcile"). While one is open, "approval status" and
|
|
1183
|
+
"approval doctor" both say so: an unreconciled denial that nobody can see is a
|
|
1184
|
+
"no" that changed nothing.
|
|
1185
|
+
|
|
1186
|
+
JSON shape: docs/cli-reference.md#audit-obligations
|
|
1187
|
+
${EXIT_CODES_POINTER}
|
|
1188
|
+
${JSON_ERRORS}
|
|
1189
|
+
${why("audit-obligations")}`;
|
|
1190
|
+
export const AUDIT_RECONCILE_HELP = `approval audit reconcile — record that a human discharged an obligation
|
|
1191
|
+
|
|
1192
|
+
Usage:
|
|
1193
|
+
approval audit reconcile <obligation-seq> --note "<text>" [--revert <key>]
|
|
1194
|
+
[--as human:<id>] [--log <path>] [--json]
|
|
1195
|
+
|
|
1196
|
+
Arguments:
|
|
1197
|
+
<obligation-seq> the SEQ of the reconciliation.required record, from
|
|
1198
|
+
"audit obligations". Not the action, not the review
|
|
1199
|
+
Flags:
|
|
1200
|
+
--note <text> what you did. REQUIRED
|
|
1201
|
+
--revert <key> the revert's action key. REQUIRED for a gated-revert
|
|
1202
|
+
--as human:<id> who discharged it; else APPROVAL_HUMAN. HUMAN-ONLY
|
|
1203
|
+
--log <path> log file to read and append to
|
|
1204
|
+
--json machine-readable output
|
|
1205
|
+
-h, --help this text
|
|
1206
|
+
|
|
1207
|
+
HUMAN-ONLY, in code and in the event schema. A gated-revert obligation is checked
|
|
1208
|
+
against the CHAIN, not the claim: without an execution.completed for the named
|
|
1209
|
+
revert this refuses revert-required and appends nothing.
|
|
1210
|
+
JSON shape: docs/cli-reference.md#audit-reconcile
|
|
1211
|
+
${EXIT_CODES_POINTER}
|
|
1212
|
+
${JSON_ERRORS}
|
|
1213
|
+
${why("audit-reconcile")}`;
|
|
1214
|
+
export const EXECUTION_HELP = `approval execution — recovery verbs for executions the runtime could not close
|
|
1215
|
+
|
|
1216
|
+
Usage:
|
|
1217
|
+
approval execution resolve <action-key> --outcome completed|failed …
|
|
1218
|
+
approval execution reconcile <action-key> --resolution executed|not-executed …
|
|
1219
|
+
|
|
1220
|
+
Subcommands:
|
|
1221
|
+
resolve record the outcome a HUMAN OBSERVED for a dangling execution
|
|
1222
|
+
reconcile record what a human ESTABLISHED about an unknown outcome
|
|
1223
|
+
|
|
1224
|
+
Two different states, two different questions, two different verbs.
|
|
1225
|
+
|
|
1226
|
+
A DANGLING EXECUTION is what a crash between execution.started and its outcome
|
|
1227
|
+
leaves behind: the runtime meant to watch and did not. resolve closes it.
|
|
1228
|
+
|
|
1229
|
+
An INDETERMINATE EXECUTION is one whose side effect was ATTEMPTED and whose
|
|
1230
|
+
outcome nobody knows. The token stays spent, the key stays burned, and a retry
|
|
1231
|
+
is refused. reconcile records what the relying party's evidence showed.
|
|
1232
|
+
|
|
1233
|
+
"approval status" reports both; "approval queue" reports neither, because nobody
|
|
1234
|
+
is being asked to decide anything. Nothing closes either automatically.
|
|
1235
|
+
|
|
1236
|
+
${EXIT_CODES_POINTER}
|
|
1237
|
+
${why("execution")}`;
|
|
1238
|
+
export const RESOLVE_HELP = `approval execution resolve — record what a human observed
|
|
1239
|
+
|
|
1240
|
+
Usage:
|
|
1241
|
+
approval execution resolve <action-key> --outcome completed|failed --note "…"
|
|
1242
|
+
approval execution resolve --dangling [--class <class>] [--yes] [--json]
|
|
1243
|
+
|
|
1244
|
+
Flags:
|
|
1245
|
+
--outcome <o> completed or failed. REQUIRED, and nothing is inferred
|
|
1246
|
+
--note <text> what you observed and how you know. MANDATORY and non-empty
|
|
1247
|
+
--as human:<id> the person recording it; else APPROVAL_HUMAN. HUMAN-ONLY
|
|
1248
|
+
--log <path> log file to read and append to
|
|
1249
|
+
--dangling the BULK form; --class narrows it, --yes skips the prompt
|
|
1250
|
+
--json / -h, --help machine-readable output / this text
|
|
1251
|
+
|
|
1252
|
+
Appends execution.completed or execution.failed with payload {"note":…,
|
|
1253
|
+
"attested_by_human":true,"exit_code":null}: nobody ran anything, so exit_code is
|
|
1254
|
+
NULL. NO ATTESTATION IS REQUIRED: resolve exercises no policy authority.
|
|
1255
|
+
Refuses (exit 1): not-started, already-finished. --dangling lists every dangling
|
|
1256
|
+
execution with what this checkout can PROVE, asks ONCE, closes the provable.
|
|
1257
|
+
|
|
1258
|
+
JSON shape: docs/cli-reference.md#execution-resolve
|
|
1259
|
+
${EXIT_CODES_POINTER}
|
|
1260
|
+
${JSON_ERRORS}
|
|
1261
|
+
${why("execution-resolve")}`;
|
|
1262
|
+
export const RECONCILE_HELP = `approval execution reconcile — resolve an unknown outcome
|
|
1263
|
+
|
|
1264
|
+
Usage:
|
|
1265
|
+
approval execution reconcile <action-key> --resolution executed|not-executed
|
|
1266
|
+
--note "<evidence>" [--as human:<id>]
|
|
1267
|
+
[--log <path>] [--json]
|
|
1268
|
+
|
|
1269
|
+
Flags:
|
|
1270
|
+
--resolution <r> executed or not-executed. REQUIRED, and nothing is inferred
|
|
1271
|
+
--note <text> the EVIDENCE: which console, which message id. MANDATORY
|
|
1272
|
+
--as human:<id> the person recording it; else APPROVAL_HUMAN. HUMAN-ONLY
|
|
1273
|
+
--log <path> log file to read and append to
|
|
1274
|
+
--json / -h, --help machine-readable output / this text
|
|
1275
|
+
|
|
1276
|
+
For an execution.indeterminate: the effect was ATTEMPTED and nobody knows whether
|
|
1277
|
+
it committed. Appends execution.reconciled NAMING that record by seq, never
|
|
1278
|
+
rewriting it. not-executed re-opens the EFFECT, not this key, which stays burned:
|
|
1279
|
+
declare a fresh action and request that. Refuses (exit 1): not-indeterminate,
|
|
1280
|
+
already-reconciled.
|
|
1281
|
+
|
|
1282
|
+
JSON shape: docs/cli-reference.md#execution-reconcile
|
|
1283
|
+
${EXIT_CODES_POINTER}
|
|
1284
|
+
${JSON_ERRORS}
|
|
1285
|
+
${why("execution-reconcile")}`;
|
|
1286
|
+
export const CHANNEL_HELP = `approval channel — put a pending request in front of a human
|
|
1287
|
+
|
|
1288
|
+
Usage:
|
|
1289
|
+
approval channel cli [--log <path>] [--policy-dir <path>] [--policy <path>]
|
|
1290
|
+
[--payload-dir <path>] [--as human:<id>] [--interactive]
|
|
1291
|
+
[--json]
|
|
1292
|
+
approval channel web [--port <n>] [--payload-dir <path>] [--as human:<id>]
|
|
1293
|
+
[--policy <path>] [--dir <path>] [--log <path>] [--json]
|
|
1294
|
+
approval channel telegram listen|health [--once] [--as human:<id>] [--json]
|
|
1295
|
+
|
|
1296
|
+
Subcommands:
|
|
1297
|
+
cli render the pending queue in this terminal and, when it IS a
|
|
1298
|
+
terminal, collect decisions with a prompt
|
|
1299
|
+
web serve the pending queue as a page on 127.0.0.1 ONLY, with
|
|
1300
|
+
Grant/Reject forms and a batch gesture
|
|
1301
|
+
telegram deliver the queue to a Telegram chat and long-poll for
|
|
1302
|
+
Approve/Reject taps
|
|
1303
|
+
|
|
1304
|
+
A channel is TRANSPORT: it renders what the runtime derived and reports the
|
|
1305
|
+
gesture a human made. Every decision collected here is recorded by the same
|
|
1306
|
+
human-only gate "approval grant" and "approval reject" call, with every rule —
|
|
1307
|
+
TTL, budgets, attestation, idempotency — applied unchanged.
|
|
1308
|
+
|
|
1309
|
+
${EXIT_CODES_POINTER}
|
|
1310
|
+
${why("channel")}`;
|
|
1311
|
+
export const CHANNEL_CLI_HELP = `approval channel cli — the zero-config channel
|
|
1312
|
+
|
|
1313
|
+
Usage:
|
|
1314
|
+
approval channel cli [--log <path>] [--policy-dir <path>] [--policy <path>]
|
|
1315
|
+
[--payload-dir <path>] [--as human:<id>] [--interactive]
|
|
1316
|
+
[--gloss] [--gloss-provider <claude|codex>] [--gloss-model <id>] [--json]
|
|
1317
|
+
|
|
1318
|
+
Flags:
|
|
1319
|
+
--log <path> log file to read, and to append decisions to
|
|
1320
|
+
--policy-dir <path> / --policy <path> discovery directory, or the file
|
|
1321
|
+
--payload-dir <path> OPTIONAL OVERRIDE for material held outside the store
|
|
1322
|
+
--as human:<id> the person deciding; else APPROVAL_HUMAN
|
|
1323
|
+
--interactive prompt even though stdin is not a terminal
|
|
1324
|
+
--gloss / --gloss-provider <p> enable gloss / choose claude|codex (default claude)
|
|
1325
|
+
--gloss-model <id> model to request; required with Codex; no fallback
|
|
1326
|
+
--json machine-readable output; never interactive
|
|
1327
|
+
-h, --help this text
|
|
1328
|
+
Renders every pending manual request with [computed]/[claimed] markers and the
|
|
1329
|
+
full payload verbatim between "--- BEGIN FULL PAYLOAD" delimiters. With a TTY (or
|
|
1330
|
+
--interactive) each is answered g) grant, r) reject, s) skip. WITHOUT a TTY, and
|
|
1331
|
+
always with --json, the queue is printed and EXITS 0 WITHOUT READING STDIN.
|
|
1332
|
+
|
|
1333
|
+
JSON shape: docs/cli-reference.md#channel-cli
|
|
1334
|
+
${EXIT_CODES_POINTER} (1 is also a gate refusal surfaced from a decision)
|
|
1335
|
+
${why("channel-cli")}`;
|
|
1336
|
+
export const WEB_HELP = `approval channel web — the local queue page (127.0.0.1 ONLY)
|
|
1337
|
+
|
|
1338
|
+
Usage:
|
|
1339
|
+
approval channel web [--port <n>] [--log <p>] [--policy <p>] [--dir <p>]
|
|
1340
|
+
[--payload-dir <p>] [--as human:<id>] [--json]
|
|
1341
|
+
|
|
1342
|
+
Flags:
|
|
1343
|
+
--port <n> port to bind. Precedence: --port, channels.web.port, 4680
|
|
1344
|
+
--log <path> log file to read, and to append decisions to
|
|
1345
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1346
|
+
--payload-dir <path> OPTIONAL OVERRIDE for material held outside the store
|
|
1347
|
+
--as human:<id> the person deciding. REQUIRED at startup
|
|
1348
|
+
--json print the listening/stopped lines as JSON objects
|
|
1349
|
+
-h, --help this text
|
|
1350
|
+
|
|
1351
|
+
Runs until interrupted. It is a PULL channel: the page is the notification
|
|
1352
|
+
surface. BINDS 127.0.0.1 AND NOTHING ELSE (there is no --host), and there is NO
|
|
1353
|
+
AUTHENTICATION in v0.1: the loopback interface IS the access control. Every value
|
|
1354
|
+
is HTML-escaped, and THE EXECUTION TOKEN IS SHOWN ON THE PAGE ONCE.
|
|
1355
|
+
|
|
1356
|
+
JSON shape: docs/cli-reference.md#channel-web
|
|
1357
|
+
${EXIT_CODES_POINTER}
|
|
1358
|
+
${JSON_ERRORS}
|
|
1359
|
+
${why("channel-web")}`;
|
|
1360
|
+
export const INIT_HELP = `approval init — scaffold a working directory (SPEC.md §10.1)
|
|
1361
|
+
|
|
1362
|
+
Usage:
|
|
1363
|
+
approval init [--dir <path>] [--json]
|
|
1364
|
+
|
|
1365
|
+
Flags:
|
|
1366
|
+
--dir <path> directory to scaffold (default: the working directory)
|
|
1367
|
+
--json machine-readable output
|
|
1368
|
+
-h, --help this text
|
|
1369
|
+
|
|
1370
|
+
Writes four things into <dir>: APPROVAL.md (SPEC.md §5.1's canonical policy
|
|
1371
|
+
verbatim, a STARTING POINT and not your policy), the empty .approval/log/
|
|
1372
|
+
directory, .approval/QUEUE.md, and, in .gitignore under a "${GITIGNORE_MARKER}" marker,
|
|
1373
|
+
${GITIGNORE_ENTRY_LINES.replace(/\n\s+/gu, " ")}
|
|
1374
|
+
IT APPENDS NOTHING AND NEVER OVERWRITES: what exists is reported in "existing"
|
|
1375
|
+
with a per-file code, and a path of the WRONG KIND exits 4 with "path-conflict".
|
|
1376
|
+
|
|
1377
|
+
JSON shape (one object on stdout):
|
|
1378
|
+
{"ok":true,"dir","written":["APPROVAL.md",…],"existing":[{"path","code"}],
|
|
1379
|
+
"next_steps":["…"]}
|
|
1380
|
+
|
|
1381
|
+
${EXIT_CODES_POINTER}
|
|
1382
|
+
${JSON_ERRORS}
|
|
1383
|
+
${why("init")}`;
|
|
1384
|
+
export const QUICKSTART_HELP = `approval quickstart — make a small solo gate operative
|
|
1385
|
+
|
|
1386
|
+
Usage:
|
|
1387
|
+
approval quickstart [--dir <path>]
|
|
1388
|
+
|
|
1389
|
+
Asks three decisions: your human id, terminal or Telegram, and which five class
|
|
1390
|
+
families always ask. It refuses a directory that already has policy or .approval
|
|
1391
|
+
state, writes a fresh policy, configures identity, and runs doctor before showing
|
|
1392
|
+
the exact bytes. The one expected unattested row is ignored at that point; every
|
|
1393
|
+
other failed row stops setup before attestation. Typed \`understood\` attests only
|
|
1394
|
+
if the file still has the displayed digest. A Telegram token uses the existing
|
|
1395
|
+
OS-keystore setup path and is resolved explicitly for that preflight.
|
|
1396
|
+
|
|
1397
|
+
Interactive only. Piped stdin and --json exit 2 and print the manual sequence.
|
|
1398
|
+
The generated default applies only to classified reversible actions; protected
|
|
1399
|
+
controls, fail-closed policy loading and unclassified-command refusal remain.
|
|
1400
|
+
|
|
1401
|
+
Flags:
|
|
1402
|
+
--dir <path> project directory (default: current directory)
|
|
1403
|
+
--api-base <url> Telegram API base passed to channel setup and doctor
|
|
1404
|
+
-h, --help this text
|
|
1405
|
+
|
|
1406
|
+
${EXIT_CODES_POINTER} (0 success; 1 doctor failure; 2 usage; 4 filesystem failure)
|
|
1407
|
+
${why("quickstart")}`;
|
|
1408
|
+
export const HOOK_HELP = `approval hook — put the gate in front of an agent harness
|
|
1409
|
+
|
|
1410
|
+
Usage:
|
|
1411
|
+
approval hook claude-code|cursor|codex [--as agent:<id>] [--timeout <d>] [--interval <d>] [--retry-grace <d>] [--policy <p>] [--dir <p>] [--log <p>]
|
|
1412
|
+
approval hook classify [--json] [--policy <p>] [--dir <p>] -- <command…>
|
|
1413
|
+
|
|
1414
|
+
Commands:
|
|
1415
|
+
claude-code Claude Pre/PostToolUse JSON in; decision JSON out. REGISTER BOTH
|
|
1416
|
+
cursor Cursor preToolUse JSON in; native {permission} JSON out
|
|
1417
|
+
codex Codex synchronous Pre/Post JSON; Bash denied, direct apply_patch experimentally gated
|
|
1418
|
+
classify print what the classifier makes of a command line and exit
|
|
1419
|
+
|
|
1420
|
+
--as <id> proposing identity (default agent:claude-code / agent:cursor / agent:codex)
|
|
1421
|
+
--timeout/--interval/--retry-grace <d> wait / poll / hold for a retry (9m/1s/5m)
|
|
1422
|
+
--dir/--policy/--log <p> policy+log root; --dir sets BOTH, default primary
|
|
1423
|
+
-h, --help this text
|
|
1424
|
+
|
|
1425
|
+
Codex opt-in: register exact Bash|apply_patch synchronously with timeout 600s (default wait 9m). Bash is denied because native events hide per-call workdir; direct apply_patch is experimental. PostToolUse is diagnostic.
|
|
1426
|
+
|
|
1427
|
+
Deny: hook-unclassified, hook-class-human-only, hook-opaque, hook-unparseable, hook-rejected, hook-revoked, hook-expired, hook-withdrawn, hook-timeout,
|
|
1428
|
+
hook-gate-refused:<c>, hook-grant-unverified, hook-sandbox-required, hook-policy-unavailable, hook-log-unreachable, hook-io.
|
|
1429
|
+
|
|
1430
|
+
${EXIT_CODES_POINTER} (harness verbs use 0 and 2 only; 0 is a verdict, never "ask")
|
|
1431
|
+
${why("hook")}`;
|
|
1432
|
+
export const IMPORT_HELP = `approval import — turn existing permissions prose into a draft policy
|
|
1433
|
+
|
|
1434
|
+
Usage:
|
|
1435
|
+
approval import agents-md <file> [--out <path>] [--json]
|
|
1436
|
+
|
|
1437
|
+
Commands:
|
|
1438
|
+
agents-md parse an AGENTS.md-style permissions section ("allowed without
|
|
1439
|
+
prompting" / "require approval first" / "never") into draft policy
|
|
1440
|
+
classes for a human to confirm (SPEC.md §12)
|
|
1441
|
+
|
|
1442
|
+
${EXIT_CODES_POINTER}
|
|
1443
|
+
${JSON_ERRORS}
|
|
1444
|
+
${why("import-agents-md")}`;
|
|
1445
|
+
export const IMPORT_AGENTS_MD_HELP = `approval import agents-md — permissions prose -> draft policy classes
|
|
1446
|
+
|
|
1447
|
+
Usage:
|
|
1448
|
+
approval import agents-md <file> [--out <path>] [--json]
|
|
1449
|
+
|
|
1450
|
+
Flags:
|
|
1451
|
+
--out <path> write the draft YAML to <path>; refuses to overwrite
|
|
1452
|
+
--json / -h machine-readable output / this text
|
|
1453
|
+
|
|
1454
|
+
Reads one markdown file, finds its permissions section, and prints a DRAFT
|
|
1455
|
+
\`\`\`yaml approval-policy block from a fixed, ordered keyword table.
|
|
1456
|
+
THE DRAFT AUTHORIZES NOTHING: this verb never writes APPROVAL.md, never logs and
|
|
1457
|
+
never attests. Fail closed: a bullet the table cannot place is kept verbatim.
|
|
1458
|
+
"What I value"-style headings become a DRAFT values fence, all under \`wants\`.
|
|
1459
|
+
|
|
1460
|
+
JSON shape (stdout, one object):
|
|
1461
|
+
{"ok":true,"source":"<path>","out":"<path>"|null,
|
|
1462
|
+
"classes":[{"class","autonomy","from","section"}],
|
|
1463
|
+
"unmapped":[{"text","section"}],"ignored":["<heading>"],
|
|
1464
|
+
"warnings":["<text>"],"values_draft":"<fence>"|null}
|
|
1465
|
+
|
|
1466
|
+
${EXIT_CODES_POINTER}
|
|
1467
|
+
${JSON_ERRORS}
|
|
1468
|
+
${why("import-agents-md")}`;
|
|
1469
|
+
export const PAYLOAD_HELP = `approval payload — work with the bytes an approval binds to
|
|
1470
|
+
|
|
1471
|
+
Usage:
|
|
1472
|
+
approval payload hash <file|-> [--json]
|
|
1473
|
+
approval payload agentmail-draft <inbox-id> <draft-id> [--api-base <url>]
|
|
1474
|
+
[--json]
|
|
1475
|
+
|
|
1476
|
+
Commands:
|
|
1477
|
+
hash print the payload_hash of a JSON document: SHA-256 over its RFC 8785
|
|
1478
|
+
canonical serialization (SPEC.md §6.2)
|
|
1479
|
+
agentmail-draft
|
|
1480
|
+
snapshot one AgentMail draft as the payload a grant can bind to,
|
|
1481
|
+
read with the AGENT's key from AGENTMAIL_API_KEY
|
|
1482
|
+
|
|
1483
|
+
${EXIT_CODES_POINTER}
|
|
1484
|
+
${JSON_ERRORS}
|
|
1485
|
+
${why("payload-hash")}`;
|
|
1486
|
+
export const PAYLOAD_HASH_HELP = `approval payload hash — the content binding for a payload
|
|
1487
|
+
|
|
1488
|
+
Usage:
|
|
1489
|
+
approval payload hash <file|-> [--json]
|
|
1490
|
+
|
|
1491
|
+
Flags:
|
|
1492
|
+
--json / -h, --help machine-readable output / this text
|
|
1493
|
+
|
|
1494
|
+
Reads one JSON document from <file>, or from stdin when the argument is "-", and
|
|
1495
|
+
prints its payload_hash: SHA-256 (lowercase hex) over the RFC 8785 (JCS)
|
|
1496
|
+
canonical serialization of the parsed VALUE. Reads no log, writes no file.
|
|
1497
|
+
|
|
1498
|
+
Where the hash goes:
|
|
1499
|
+
payload_hash in a task file's action declaration, and in the log
|
|
1500
|
+
approval request --payload <file>|- hashes, verifies and stores the bytes
|
|
1501
|
+
approval run --payload-hash <64hex> asserts the binding run recomputes
|
|
1502
|
+
|
|
1503
|
+
MOST FLOWS NEVER NEED THIS VERB: "approval request --payload" both stores and
|
|
1504
|
+
verifies. Bytes that do not parse as JSON are a usage error (exit 2).
|
|
1505
|
+
|
|
1506
|
+
JSON shape (stdout, one object): {"ok":true,"hash":"<64hex>"}
|
|
1507
|
+
${EXIT_CODES_POINTER}
|
|
1508
|
+
${JSON_ERRORS}
|
|
1509
|
+
${why("payload-hash")}`;
|
|
1510
|
+
export const PAYLOAD_AGENTMAIL_DRAFT_HELP = `approval payload agentmail-draft — snapshot a draft as an approvable payload
|
|
1511
|
+
|
|
1512
|
+
Usage:
|
|
1513
|
+
approval payload agentmail-draft <inbox-id> <draft-id> [--api-base <url>]
|
|
1514
|
+
[--timeout <ms>] [--json]
|
|
1515
|
+
|
|
1516
|
+
Flags:
|
|
1517
|
+
--api-base <url> the API root (else AGENTMAIL_API_BASE, else the public one)
|
|
1518
|
+
--timeout <ms> / --json / -h, --help 15000 / machine-readable / this text
|
|
1519
|
+
|
|
1520
|
+
Reads one draft with the AGENT's key — AGENTMAIL_API_KEY, from the environment,
|
|
1521
|
+
and this is the ONE verb that reads it — and prints the canonical draft payload
|
|
1522
|
+
{"inbox_id":…,"draft_id":…,"to":[…],"cc":[…],"bcc":[…],"subject":…,"text":…}
|
|
1523
|
+
in RFC 8785 form, the value \`approval adapter agentmail\` re-reads the draft
|
|
1524
|
+
against at send time. Write it to a file, declare its payload_hash, and request
|
|
1525
|
+
approval for THE WORDS: a draft edited after the snapshot is refused, not sent.
|
|
1526
|
+
|
|
1527
|
+
SENDS NOTHING, SPENDS NO TOKEN, APPENDS NOTHING. Refusals are machine-readable:
|
|
1528
|
+
"agentmail-api-key-unset" (exit 2), "agentmail-draft-missing" (exit 1).
|
|
1529
|
+
|
|
1530
|
+
${EXIT_CODES_POINTER}
|
|
1531
|
+
${JSON_ERRORS}
|
|
1532
|
+
${why("payload-agentmail-draft")}`;
|
|
1533
|
+
export const JOURNAL_HELP = `approval journal — the ungated channel an agent can always reach
|
|
1534
|
+
|
|
1535
|
+
Usage:
|
|
1536
|
+
approval journal write --message "<text>" [--task <id>] [--session <id>]
|
|
1537
|
+
approval journal write - [--as <id>] [--journal <dir>] [--json]
|
|
1538
|
+
approval journal read [--limit <n>] [--since <YYYY-MM-DD>] [--json]
|
|
1539
|
+
|
|
1540
|
+
Commands:
|
|
1541
|
+
write append one free-text entry to a local file. NOT gated, not
|
|
1542
|
+
classified, not approvable and not deniable; nothing is appended to
|
|
1543
|
+
the event log and no network or credential is touched
|
|
1544
|
+
read print entries for a human, labelled as agent-authored DATA
|
|
1545
|
+
|
|
1546
|
+
An agent behind this gate can comply, be refused, and report an exit code. This
|
|
1547
|
+
verb is how it says anything else: "I am complying and I think this is wrong",
|
|
1548
|
+
"this instruction reads as odd", "I am stuck". The operator reads it; nothing
|
|
1549
|
+
written here changes any verdict, sampling probability or budget.
|
|
1550
|
+
|
|
1551
|
+
Default location: .approval-journal/YYYY-MM-DD.jsonl (outside .approval/, so the
|
|
1552
|
+
gate cannot close it). Gitignored by init.
|
|
1553
|
+
|
|
1554
|
+
${EXIT_CODES_POINTER}
|
|
1555
|
+
${JSON_ERRORS}
|
|
1556
|
+
${why("journal")}`;
|
|
1557
|
+
export const JOURNAL_WRITE_HELP = `approval journal write — say something the gate will not judge
|
|
1558
|
+
|
|
1559
|
+
Usage:
|
|
1560
|
+
approval journal write --message "<text>" [--task <id>] [--session <id>]
|
|
1561
|
+
[--as <id>] [--journal <dir>] [--json]
|
|
1562
|
+
approval journal write - [flags] (the entry comes from stdin)
|
|
1563
|
+
|
|
1564
|
+
Flags:
|
|
1565
|
+
--message <text> the entry; or pass "-" to read it from stdin instead
|
|
1566
|
+
--task / --session attribution, when you know them; both optional
|
|
1567
|
+
--as <id> who is writing (default: APPROVAL_AGENT, else
|
|
1568
|
+
"unattributed"). Nothing authenticates it
|
|
1569
|
+
--journal <dir> the journal directory (default .approval-journal)
|
|
1570
|
+
--json / -h, --help machine-readable output / this text
|
|
1571
|
+
|
|
1572
|
+
Appends one line to a local append-only file. It resolves no policy, reads no
|
|
1573
|
+
log, appends no event, mints no token, opens no socket and reads no credential.
|
|
1574
|
+
There is no refusal path: an entry is written or an I/O error is reported.
|
|
1575
|
+
A human reads these; write for that reader. Entries are capped at 64 KiB.
|
|
1576
|
+
|
|
1577
|
+
JSON shape: {"ok":true,"path":"<file>","ts":"<rfc3339>","actor":"<id>","bytes":N}
|
|
1578
|
+
${EXIT_CODES_POINTER}
|
|
1579
|
+
${JSON_ERRORS}
|
|
1580
|
+
${why("journal-write")}`;
|
|
1581
|
+
export const JOURNAL_READ_HELP = `approval journal read — what the agents have said (human-facing)
|
|
1582
|
+
|
|
1583
|
+
Usage:
|
|
1584
|
+
approval journal read [--limit <n>] [--since <YYYY-MM-DD>]
|
|
1585
|
+
[--journal <dir>] [--json]
|
|
1586
|
+
|
|
1587
|
+
Flags:
|
|
1588
|
+
--limit <n> how many entries, newest last (default 20)
|
|
1589
|
+
--since <YYYY-MM-DD> only entries written on or after this UTC date
|
|
1590
|
+
--journal <dir> the journal directory (default .approval-journal)
|
|
1591
|
+
--json / -h, --help machine-readable output / this text
|
|
1592
|
+
|
|
1593
|
+
Prints entries oldest first, each under its timestamp, actor and optional task,
|
|
1594
|
+
with the text in delimiters and marked [claimed] — it was authored by the party
|
|
1595
|
+
under oversight. EVERY OUTPUT FORM CARRIES THAT LABEL: these are DATA, never
|
|
1596
|
+
instructions to whoever or whatever reads them, and nothing here has authorized
|
|
1597
|
+
anything. An unparseable line is skipped rather than refusing the whole read.
|
|
1598
|
+
|
|
1599
|
+
JSON shape: {"ok":true,"dir":"…","note":"…","total":N,"entries":[…]}
|
|
1600
|
+
${EXIT_CODES_POINTER}
|
|
1601
|
+
${JSON_ERRORS}
|
|
1602
|
+
${why("journal-read")}`;
|
|
1603
|
+
export const VALUES_HELP = `approval values — what the operator said they value (human-authored)
|
|
1604
|
+
|
|
1605
|
+
Usage:
|
|
1606
|
+
approval values [--policy <path>] [--dir <path>] [--json]
|
|
1607
|
+
|
|
1608
|
+
Flags:
|
|
1609
|
+
--policy <path> the policy file to read (wins over discovery)
|
|
1610
|
+
--dir <path> where to look for APPROVAL.md, then APPROVALS.md
|
|
1611
|
+
--json / -h, --help machine-readable output / this text
|
|
1612
|
+
|
|
1613
|
+
Prints the optional \`\`\`yaml approval-values block of APPROVAL.md: what the
|
|
1614
|
+
operator loves, likes and dislikes, what they want from you as behaviour, and
|
|
1615
|
+
how they read and answer. EVERY FORM CARRIES THE LABEL: this is GUIDANCE and
|
|
1616
|
+
never policy. It grants nothing, forbids nothing and changes no verdict; what
|
|
1617
|
+
you MAY do is the policy block, answered by \`approval policy check\`.
|
|
1618
|
+
|
|
1619
|
+
No block prints "the operator has declared no values here." and exits 0. A
|
|
1620
|
+
present but unreadable block exits 1 with its load code; treat it as absent.
|
|
1621
|
+
Neither moves the policy, and \`approval doctor\` reports the broken one.
|
|
1622
|
+
|
|
1623
|
+
JSON shape: {"ok":true,"path":"…","present":true|false,"note":"…","values":{…}|null}
|
|
1624
|
+
${EXIT_CODES_POINTER}
|
|
1625
|
+
${JSON_ERRORS}
|
|
1626
|
+
${why("values")}`;
|
|
1627
|
+
export const FEEDBACK_HELP = `approval feedback — what the operator thought of the work
|
|
1628
|
+
|
|
1629
|
+
Usage:
|
|
1630
|
+
approval feedback [--task <id>] [--actor <agent id>] [--reaction <w>] [--limit <n>]
|
|
1631
|
+
[--source review|decision] [--since <YYYY-MM-DD>] [--log <path>] [--json]
|
|
1632
|
+
|
|
1633
|
+
Flags:
|
|
1634
|
+
--task <id> only feedback about this task
|
|
1635
|
+
--actor <agent id> the AGENT the feedback is about, not its human author
|
|
1636
|
+
--reaction <w> disliked|indifferent|liked|loved
|
|
1637
|
+
--source <s> review (audit.reviewed) or decision (approval.granted)
|
|
1638
|
+
--since <YYYY-MM-DD> only records timestamped on or after this UTC date
|
|
1639
|
+
--limit <n> how many entries, newest last (default 20)
|
|
1640
|
+
--log <path> / --json / -h, --help the log, READ never written / JSON / help
|
|
1641
|
+
|
|
1642
|
+
Lists the reactions and notes a person wrote on a grant or a review, joined to the
|
|
1643
|
+
class, task, action key and the agent it was about. Reads VERIFIED records, writes
|
|
1644
|
+
nothing. EVERY OUTPUT FORM CARRIES THE BANNER: HUMAN-AUTHORED GUIDANCE, not policy.
|
|
1645
|
+
An entry with neither a reaction nor a note is omitted; "_no feedback_" when empty.
|
|
1646
|
+
|
|
1647
|
+
JSON shape: {"ok":true,"log":"…","note":"…","total":N,"entries":[…]}
|
|
1648
|
+
${EXIT_CODES_POINTER}
|
|
1649
|
+
${JSON_ERRORS}
|
|
1650
|
+
${why("feedback")}`;
|
|
1651
|
+
export const RENDER_HELP = `approval render — regenerate .approval/QUEUE.md from the log
|
|
1652
|
+
|
|
1653
|
+
Usage:
|
|
1654
|
+
approval render [--log <path>] [--out <path>] [--policy <path>] [--dir <path>]
|
|
1655
|
+
[--json]
|
|
1656
|
+
|
|
1657
|
+
Flags:
|
|
1658
|
+
--log <path> log file to read (NEVER written by this command)
|
|
1659
|
+
--out <path> queue file to write (default .approval/QUEUE.md)
|
|
1660
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1661
|
+
--json machine-readable output
|
|
1662
|
+
-h, --help this text
|
|
1663
|
+
|
|
1664
|
+
Writes the READ-ONLY queue projection of SPEC.md §9.1, regenerated WHOLE on every
|
|
1665
|
+
run: "this is the screenshot; it is never the truth". Every displayed field is
|
|
1666
|
+
visibly COMPUTED or CLAIMED, and full payloads are deliberately NOT inlined. A
|
|
1667
|
+
log that does not verify refuses (exit 1) and writes nothing.
|
|
1668
|
+
|
|
1669
|
+
JSON shape: docs/cli-reference.md#render
|
|
1670
|
+
${EXIT_CODES_POINTER}
|
|
1671
|
+
${JSON_ERRORS}
|
|
1672
|
+
${why("render")}`;
|
|
1673
|
+
// ---------------------------------------------------------------------------
|
|
1674
|
+
// Channels (APRV-26)
|
|
1675
|
+
// ---------------------------------------------------------------------------
|
|
1676
|
+
export const TELEGRAM_HELP = `approval channel telegram — the Telegram push channel
|
|
1677
|
+
|
|
1678
|
+
Usage:
|
|
1679
|
+
approval channel telegram listen [--once] [--as human:<id>] [--payloads <f>]
|
|
1680
|
+
[--policy <path>] [--dir <path>]
|
|
1681
|
+
[--log <path>] [--api-base <url>]
|
|
1682
|
+
[--poll-timeout <seconds>] [--json]
|
|
1683
|
+
approval channel telegram health [--json]
|
|
1684
|
+
|
|
1685
|
+
Configuration is ENVIRONMENT-ONLY: APPROVAL_TG_TOKEN holds the bot token and
|
|
1686
|
+
APPROVAL_TG_CHAT the approver chat id. APPROVAL.md carries only those variable
|
|
1687
|
+
NAMES, and there is no flag that would put a bot token into a shell history.
|
|
1688
|
+
|
|
1689
|
+
Anyone in the configured chat can approve as the actor this process was started
|
|
1690
|
+
with, so the chat's membership is part of your trust boundary. Use a private
|
|
1691
|
+
chat with the bot.
|
|
1692
|
+
|
|
1693
|
+
${EXIT_CODES_POINTER}
|
|
1694
|
+
${JSON_ERRORS}
|
|
1695
|
+
${why("channel-telegram")}`;
|
|
1696
|
+
export const TELEGRAM_LISTEN_HELP = `approval channel telegram listen — deliver the queue, collect decisions
|
|
1697
|
+
|
|
1698
|
+
Usage:
|
|
1699
|
+
approval channel telegram listen [--once] [--as human:<id>] [--payloads <f>]
|
|
1700
|
+
[--policy <p>] [--dir <p>] [--log <p>] [--no-gloss]
|
|
1701
|
+
[--gloss-provider <claude|codex>] [--gloss-model <id>] [--api-base <url>] [--poll-timeout <s>] [--json]
|
|
1702
|
+
|
|
1703
|
+
Flags:
|
|
1704
|
+
--once / --json one getUpdates batch then exit / ONE JSON OBJECT PER LINE
|
|
1705
|
+
--no-gloss / --gloss-provider <p> drop gloss (ON by default) / choose claude|codex (default claude)
|
|
1706
|
+
--gloss-model <id> model to request; required with Codex; no fallback
|
|
1707
|
+
--as human:<id> the approver every decision is recorded against. REQUIRED
|
|
1708
|
+
--payloads <f> OPTIONAL OVERRIDE: JSON file of action key -> payload
|
|
1709
|
+
--policy <p> / --dir <p> / --log <p> the policy, its dir, the log written to
|
|
1710
|
+
--api-base <url> / --poll-timeout <s> Bot API base / long-poll seconds (25)
|
|
1711
|
+
-h, --help this text
|
|
1712
|
+
Config is ENVIRONMENT-ONLY and the policy names the variables. Delivery is per cycle;
|
|
1713
|
+
a new request reaches the phone without restart. THE TOKEN IS PRINTED HERE, NEVER SENT TO TELEGRAM.
|
|
1714
|
+
Open audit samples arrive as REVIEW CARDS: no payload, no approve, no token; one at a time.
|
|
1715
|
+
|
|
1716
|
+
JSON shape: docs/cli-reference.md#channel-telegram-listen
|
|
1717
|
+
${EXIT_CODES_POINTER}
|
|
1718
|
+
${JSON_ERRORS}
|
|
1719
|
+
${why("channel-telegram-listen")}`;
|
|
1720
|
+
export const TELEGRAM_HEALTH_HELP = `approval channel telegram health — is this runtime configured for Telegram?
|
|
1721
|
+
|
|
1722
|
+
Usage:
|
|
1723
|
+
approval channel telegram health [--policy <path>] [--dir <path>] [--json]
|
|
1724
|
+
|
|
1725
|
+
Flags:
|
|
1726
|
+
--policy <path> policy file naming the credential variables
|
|
1727
|
+
--dir <path> directory to discover APPROVAL.md / APPROVALS.md in
|
|
1728
|
+
--json machine-readable output
|
|
1729
|
+
-h, --help this text
|
|
1730
|
+
|
|
1731
|
+
Reports whether the bot token and chat id variables are set. Exit 0 when both
|
|
1732
|
+
are, 1 when either is missing. The token's VALUE never appears in the output, and
|
|
1733
|
+
WHICH VARIABLES ARE READ COMES FROM THE POLICY. MAKES NO NETWORK CALL: the live
|
|
1734
|
+
counters belong to a RUNNING listener.
|
|
1735
|
+
|
|
1736
|
+
JSON shape (stdout, one object):
|
|
1737
|
+
{"ok":true,"channel":"telegram","token_env":"APPROVAL_TG_TOKEN",
|
|
1738
|
+
"token_set":true,"chat_env":"APPROVAL_TG_CHAT","chat_id":"12345"}
|
|
1739
|
+
|
|
1740
|
+
${EXIT_CODES_POINTER}
|
|
1741
|
+
${JSON_ERRORS}
|
|
1742
|
+
${why("channel-telegram-health")}`;
|
|
1743
|
+
// ---------------------------------------------------------------------------
|
|
1744
|
+
// The daemon (APRV-39)
|
|
1745
|
+
// ---------------------------------------------------------------------------
|
|
1746
|
+
export const DAEMON_HELP = `approval daemon — the watch loop of SPEC.md §10.2
|
|
1747
|
+
|
|
1748
|
+
Usage:
|
|
1749
|
+
approval daemon run [--log <path>] [--tasks <dir>] [--out <path>]
|
|
1750
|
+
[--policy <path>] [--dir <path>] [--interval <duration>]
|
|
1751
|
+
[--debounce <duration>] [--once] [--json]
|
|
1752
|
+
|
|
1753
|
+
Subcommands:
|
|
1754
|
+
run watch the task folder and the log; record envelope drift, expire lapsed
|
|
1755
|
+
requests, regenerate QUEUE.md, and surface loop escalations
|
|
1756
|
+
|
|
1757
|
+
${EXIT_CODES_POINTER}
|
|
1758
|
+
${JSON_ERRORS}
|
|
1759
|
+
${why("daemon-run")}`;
|
|
1760
|
+
export const DAEMON_RUN_HELP = `approval daemon run — watch, expire, re-render (FOREGROUND)
|
|
1761
|
+
|
|
1762
|
+
Usage:
|
|
1763
|
+
approval daemon run [--log <path>] [--tasks <dir>] [--out <path>]
|
|
1764
|
+
[--policy <path>] [--dir <path>] [--interval <duration>]
|
|
1765
|
+
[--debounce <d>] [--read-proof <mode>] [--once] [--json]
|
|
1766
|
+
|
|
1767
|
+
Flags:
|
|
1768
|
+
--log <p> / --out <p> / --tasks <d> log / queue / task folder (backlog/tasks)
|
|
1769
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1770
|
+
--interval <d> / --debounce <d> tick period (30s) / event settle time (250ms)
|
|
1771
|
+
--once / --json / --no-preflight / --no-build one tick / JSON lines / skip the git check / keep a stale dist/
|
|
1772
|
+
--git-evidence / --advance / --dark-sessions three OPT-INs, off by default
|
|
1773
|
+
--read-proof full|incremental (default full) / --trace-watch (watch events)
|
|
1774
|
+
--with-channels the channels in this process too: SAME VERB as "approval up"
|
|
1775
|
+
-h, --help this text
|
|
1776
|
+
|
|
1777
|
+
Each tick records drift, expires what lapsed, writes state back, re-renders the
|
|
1778
|
+
queue. Stops on SIGINT/SIGTERM; backgrounding is the operator's business.
|
|
1779
|
+
|
|
1780
|
+
JSON shape: docs/cli-reference.md#daemon-run
|
|
1781
|
+
${EXIT_CODES_POINTER} (a clean stop is 0; 1 when the chain does not verify)
|
|
1782
|
+
${JSON_ERRORS}
|
|
1783
|
+
${why("daemon-run")}`;
|
|
1784
|
+
// ---------------------------------------------------------------------------
|
|
1785
|
+
// The ambient runtime (APRV-110)
|
|
1786
|
+
// ---------------------------------------------------------------------------
|
|
1787
|
+
export const UP_HELP = `approval up — the daemon and every configured channel, in ONE process
|
|
1788
|
+
|
|
1789
|
+
Usage:
|
|
1790
|
+
approval up [every "daemon run" flag] [--as human:<id>] [--port <n>]
|
|
1791
|
+
[--payloads <f>] [--payload-dir <d>] [--api-base <url>] [--poll-timeout <s>] [--no-gloss]
|
|
1792
|
+
[--gloss-provider <claude|codex>] [--gloss-model <id>] [--no-telegram] [--no-web] [--no-preflight] [--no-build]
|
|
1793
|
+
|
|
1794
|
+
Flags (every "daemon run" flag, unchanged, plus):
|
|
1795
|
+
--as human:<id> the approver every decision is recorded against
|
|
1796
|
+
--payloads <f> / --payload-dir <d> payload overrides: telegram / web
|
|
1797
|
+
--api-base <url> / --poll-timeout <s> Bot API base / long-poll seconds
|
|
1798
|
+
--port <n> queue-page port. Precedence: --port, channels.web.port
|
|
1799
|
+
--no-telegram / --no-web leave that channel out of this process
|
|
1800
|
+
--no-gloss / --restart-backoff <d> drop gloss / first retry wait
|
|
1801
|
+
--gloss-provider <p> / --gloss-model <id> choose claude|codex (default claude); Codex requires model; no fallback
|
|
1802
|
+
-h, --help this text
|
|
1803
|
+
BEFORE START the preflight ("daemon run" runs it too) fetches, then fast-forwards
|
|
1804
|
+
and rebuilds when safe (--no-build keeps a stale dist/), else refuses and TOUCHES
|
|
1805
|
+
NOTHING; --no-preflight opts out. Credentials come from THE LAUNCH ENVIRONMENT and
|
|
1806
|
+
nowhere else: a channel whose credential is unset is skipped in doctor's words.
|
|
1807
|
+
|
|
1808
|
+
${EXIT_CODES_POINTER} (a clean stop is 0; the daemon's outcome chooses it)
|
|
1809
|
+
${JSON_ERRORS}
|
|
1810
|
+
${why("up")}`;
|
|
1811
|
+
// ---------------------------------------------------------------------------
|
|
1812
|
+
// The vault (APRV-68)
|
|
1813
|
+
// ---------------------------------------------------------------------------
|
|
1814
|
+
/** One line, not a paragraph: the rest of the reasoning is in the reference. */
|
|
1815
|
+
const VAULT_NO_GET = `THERE IS NO "approval vault get": a credential's only sanctioned journey is from
|
|
1816
|
+
the vault into an adapter, inside the verified execution window.`;
|
|
1817
|
+
export const VAULT_HELP = `approval vault — the encrypted credential store adapters read from
|
|
1818
|
+
|
|
1819
|
+
Usage:
|
|
1820
|
+
approval vault set <name> [--value-env <VAR>] [--vault <path>] [--log <path>]
|
|
1821
|
+
[--policy <path>] [--dir <path>] [--as human:<id>] [--json]
|
|
1822
|
+
approval vault list [--vault <path>] [--log <path>] [--as human:<id>] [--json]
|
|
1823
|
+
approval vault remove <name> [--vault <path>] [--log <path>]
|
|
1824
|
+
[--as human:<id>] [--json]
|
|
1825
|
+
|
|
1826
|
+
Subcommands:
|
|
1827
|
+
set store a credential (value from STDIN or --value-env, never a flag)
|
|
1828
|
+
list the NAMES the vault holds, the count, and the file path
|
|
1829
|
+
remove delete one credential by name
|
|
1830
|
+
|
|
1831
|
+
ALL THREE ARE HUMAN-ONLY. The file is AES-256-GCM over a JSON map of name ->
|
|
1832
|
+
credential, under a scrypt key derived from the environment variable the policy
|
|
1833
|
+
names in vault.passphrase_env. Nothing here appends to the log.
|
|
1834
|
+
|
|
1835
|
+
${VAULT_NO_GET}
|
|
1836
|
+
|
|
1837
|
+
${EXIT_CODES_POINTER} (1 for anything the runtime decided)
|
|
1838
|
+
${JSON_ERRORS}
|
|
1839
|
+
${why("vault")}`;
|
|
1840
|
+
export const VAULT_SET_HELP = `approval vault set — store one credential (HUMAN-ONLY)
|
|
1841
|
+
|
|
1842
|
+
Usage:
|
|
1843
|
+
approval vault set <name> [--value-env <VAR>] [--vault <path>] [--log <path>]
|
|
1844
|
+
[--policy <path>] [--dir <path>] [--as human:<id>] [--json]
|
|
1845
|
+
|
|
1846
|
+
Flags:
|
|
1847
|
+
--value-env <VAR> read the value from this environment variable
|
|
1848
|
+
--vault <path> the vault file (default: <log home>/vault.enc)
|
|
1849
|
+
--log <path> log file the vault path is derived from
|
|
1850
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1851
|
+
--as human:<id> the human doing this (else APPROVAL_HUMAN)
|
|
1852
|
+
--json machine-readable output
|
|
1853
|
+
-h, --help this text
|
|
1854
|
+
|
|
1855
|
+
HUMAN-ONLY. THE VALUE IS NEVER A COMMAND-LINE ARGUMENT: it comes from stdin, or
|
|
1856
|
+
from the variable --value-env names. One trailing newline is stripped and nothing
|
|
1857
|
+
else; an empty value is refused. Every write re-encrypts the whole map under a
|
|
1858
|
+
fresh nonce and lands atomically. There is no "approval vault get".
|
|
1859
|
+
|
|
1860
|
+
JSON shape: docs/cli-reference.md#vault-set
|
|
1861
|
+
${EXIT_CODES_POINTER}
|
|
1862
|
+
${JSON_ERRORS}
|
|
1863
|
+
${why("vault-set")}`;
|
|
1864
|
+
export const VAULT_LIST_HELP = `approval vault list — the names in the vault (HUMAN-ONLY)
|
|
1865
|
+
|
|
1866
|
+
Usage:
|
|
1867
|
+
approval vault list [--vault <path>] [--log <path>] [--policy <path>]
|
|
1868
|
+
[--dir <path>] [--as human:<id>] [--json]
|
|
1869
|
+
|
|
1870
|
+
Flags:
|
|
1871
|
+
--vault <path> the vault file (default: <log home>/vault.enc)
|
|
1872
|
+
--log <path> log file the vault path is derived from
|
|
1873
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1874
|
+
--as human:<id> the human doing this (else APPROVAL_HUMAN)
|
|
1875
|
+
--json machine-readable output
|
|
1876
|
+
-h, --help this text
|
|
1877
|
+
|
|
1878
|
+
HUMAN-ONLY. Prints the credential NAMES, sorted, with a count and the file path.
|
|
1879
|
+
No value is printed on any path. A VAULT NOBODY CREATED IS A STATE, NOT A FAULT:
|
|
1880
|
+
an absent file says so and exits 0. A wrong passphrase and an altered file both
|
|
1881
|
+
refuse "vault-unreadable" and are NOT distinguished.
|
|
1882
|
+
|
|
1883
|
+
JSON shape: docs/cli-reference.md#vault-list
|
|
1884
|
+
${EXIT_CODES_POINTER}
|
|
1885
|
+
${JSON_ERRORS}
|
|
1886
|
+
${why("vault-list")}`;
|
|
1887
|
+
export const VAULT_REMOVE_HELP = `approval vault remove — delete one credential (HUMAN-ONLY)
|
|
1888
|
+
|
|
1889
|
+
Usage:
|
|
1890
|
+
approval vault remove <name> [--vault <path>] [--log <path>]
|
|
1891
|
+
[--policy <path>] [--dir <path>] [--as human:<id>]
|
|
1892
|
+
[--json]
|
|
1893
|
+
|
|
1894
|
+
Flags:
|
|
1895
|
+
--vault <path> the vault file (default: <log home>/vault.enc)
|
|
1896
|
+
--log <path> log file the vault path is derived from
|
|
1897
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
1898
|
+
--as human:<id> the human doing this (else APPROVAL_HUMAN)
|
|
1899
|
+
--json machine-readable output
|
|
1900
|
+
-h, --help this text
|
|
1901
|
+
|
|
1902
|
+
HUMAN-ONLY. A name the vault does not hold refuses "credential-absent" (exit 1)
|
|
1903
|
+
rather than reporting success. The remaining credentials are re-encrypted under
|
|
1904
|
+
a fresh nonce and written atomically.
|
|
1905
|
+
|
|
1906
|
+
JSON shape: docs/cli-reference.md#vault-remove
|
|
1907
|
+
${EXIT_CODES_POINTER}
|
|
1908
|
+
${JSON_ERRORS}
|
|
1909
|
+
${why("vault-remove")}`;
|
|
1910
|
+
export const ADAPTER_HELP = `approval adapter — execute an action through a side-effect adapter
|
|
1911
|
+
|
|
1912
|
+
Usage:
|
|
1913
|
+
approval adapter email|agentmail|zzz <action-key> [--token <t>] --payload <file|->
|
|
1914
|
+
[--as human:<id>|agent:<id>] [--vault <path>] [--policy|--dir|--log <path>]
|
|
1915
|
+
[--timeout <ms>] [--json]
|
|
1916
|
+
|
|
1917
|
+
Adapters:
|
|
1918
|
+
email send SMTP for communicate.email.external (SPEC.md §6.1)
|
|
1919
|
+
agentmail send that class through AgentMail, directly or from a re-read draft
|
|
1920
|
+
zzz create a thread or reply for communicate.zzz.external
|
|
1921
|
+
|
|
1922
|
+
An adapter is the HARD BOUNDARY of SPEC.md §10.4: it holds credentials while the
|
|
1923
|
+
runtime checks the payload and attested policy. Manual and selected-live actions
|
|
1924
|
+
require a valid, single-use --token bound to the action and payload. An explicitly
|
|
1925
|
+
policy-authorized nonmanual action has no token; its process must already hold the
|
|
1926
|
+
vault passphrase, and the token-scoped .approval/env fallback stays unavailable.
|
|
1927
|
+
|
|
1928
|
+
A no-token supervised-live call runs intake; selected/unavailable draws stop before
|
|
1929
|
+
credentials. An unselected draw proceeds. Existing approval cycles are not redrawn.
|
|
1930
|
+
|
|
1931
|
+
${EXIT_CODES_POINTER} (5 when a manual path needs a token; 1 for every refusal)
|
|
1932
|
+
${JSON_ERRORS}
|
|
1933
|
+
${why("adapter")}`;
|
|
1934
|
+
export const ADAPTER_EMAIL_HELP = `approval adapter email — send one approved message over SMTP
|
|
1935
|
+
|
|
1936
|
+
Usage:
|
|
1937
|
+
approval adapter email <action-key> [--token <t>] --payload <file|->
|
|
1938
|
+
[--as <id>] [--vault <path>] [--policy <path>]
|
|
1939
|
+
[--dir <path>] [--log <path>] [--timeout <ms>] [--json]
|
|
1940
|
+
|
|
1941
|
+
Flags:
|
|
1942
|
+
--token <t> REQUIRED for manual or selected-live; omit on authorized nonmanual
|
|
1943
|
+
--payload <file|-> the JSON payload the grant bound to. REQUIRED (a body on
|
|
1944
|
+
a command line is a body in the shell history)
|
|
1945
|
+
--as <id> / --vault <path> executing identity / the SMTP credential store
|
|
1946
|
+
--policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
|
|
1947
|
+
--timeout <ms> / --json / -h, --help 30000 / machine-readable / this text
|
|
1948
|
+
|
|
1949
|
+
Sends one RFC 5322 message for a communicate.email.external action:
|
|
1950
|
+
bcc is INSIDE the hash, Date and Message-ID are stamped by the runtime outside
|
|
1951
|
+
it, and a non-ASCII body goes quoted-printable. The VAULT holds smtp.host,
|
|
1952
|
+
smtp.port, smtp.security, smtp.user, smtp.password; failure codes add smtp-<NNN>.
|
|
1953
|
+
|
|
1954
|
+
JSON shapes and failure codes: docs/cli-reference.md#adapter-email
|
|
1955
|
+
${EXIT_CODES_POINTER} (5 when a manual path needs a token; 1 for every refusal)
|
|
1956
|
+
${JSON_ERRORS}
|
|
1957
|
+
${why("adapter-email")}`;
|
|
1958
|
+
export const ADAPTER_AGENTMAIL_HELP = `approval adapter agentmail — send one approved message through AgentMail
|
|
1959
|
+
|
|
1960
|
+
Usage:
|
|
1961
|
+
approval adapter agentmail <action-key> [--token <t>] --payload <file|->
|
|
1962
|
+
[--as <id>] [--vault|--policy|--dir|--log <p>] [--timeout <ms>] [--json]
|
|
1963
|
+
|
|
1964
|
+
Flags:
|
|
1965
|
+
--token <t> / --payload <file|-> token: manual or selected-live; payload: always
|
|
1966
|
+
--as <id> / --vault <p> / --policy <p> / --dir <p> / --log <p> as email
|
|
1967
|
+
--timeout <ms> / --json / -h, --help 15000 / machine-readable / this text
|
|
1968
|
+
|
|
1969
|
+
TWO PAYLOAD MODES, told apart by shape and never inferred between:
|
|
1970
|
+
direct {from, to[], cc?, bcc?, subject, body, content_type?}: "from" is
|
|
1971
|
+
checked against the inbox's address, since AgentMail has no From
|
|
1972
|
+
draft {inbox_id, draft_id, to[], cc?, bcc?, subject, text}: RE-READ, and
|
|
1973
|
+
refused "agentmail-draft-drifted" if an approved field changed.
|
|
1974
|
+
Drift is caught BEFORE the spend: restore the text, re-run, SAME token
|
|
1975
|
+
|
|
1976
|
+
The VAULT holds agentmail.inbox_id and agentmail.api_key, and that key is the one
|
|
1977
|
+
WITH draft_send and message_send; the agent's own key must not have them.
|
|
1978
|
+
|
|
1979
|
+
${EXIT_CODES_POINTER} (5 when a manual path needs a token; 1 for every refusal)
|
|
1980
|
+
${JSON_ERRORS}
|
|
1981
|
+
${why("adapter-agentmail")}`;
|
|
1982
|
+
export const ADAPTER_ZZZ_HELP = `approval adapter zzz — send one approved zzz.bot message
|
|
1983
|
+
|
|
1984
|
+
Usage:
|
|
1985
|
+
approval adapter zzz <action-key> [--token <t>] --payload <file|->
|
|
1986
|
+
[--as <id>] [--vault|--policy|--dir|--log <p>] [--timeout <ms>] [--json]
|
|
1987
|
+
|
|
1988
|
+
The tagged payload chooses create_thread or create_reply and production or
|
|
1989
|
+
preview. Both destinations are fixed in the adapter; the payload cannot supply
|
|
1990
|
+
an arbitrary URL. The runtime binds the complete payload, including metadata,
|
|
1991
|
+
tags and references, and derives ZZZ's retry-safe Idempotency-Key from the
|
|
1992
|
+
action key and payload hash. Actions use communicate.zzz.external. The VAULT
|
|
1993
|
+
holds zzz.agent_token.
|
|
1994
|
+
|
|
1995
|
+
--token is required for manual or selected-live and omitted for explicitly
|
|
1996
|
+
authorized nonmanual execution; then the process must already hold the passphrase.
|
|
1997
|
+
|
|
1998
|
+
A public-room write needs an invited token with write scope. A private-room
|
|
1999
|
+
write also needs current room membership and accepted, unexpired approval.md
|
|
2000
|
+
workflow evidence. zzz.bot intentionally hides missing private access as 404.
|
|
2001
|
+
|
|
2002
|
+
JSON shapes and failure codes: docs/cli-reference.md#adapter-zzz
|
|
2003
|
+
${EXIT_CODES_POINTER} (5 when a manual path needs a token; 1 for every refusal)
|
|
2004
|
+
${JSON_ERRORS}
|
|
2005
|
+
${why("adapter-zzz")}`;
|
|
2006
|
+
export const ENV_HELP = `approval env — resolve .approval/env into an export block for your shell
|
|
2007
|
+
|
|
2008
|
+
Usage:
|
|
2009
|
+
approval env [--check] [--policy <path>] [--dir <path>] [--log <path>] [--json]
|
|
2010
|
+
|
|
2011
|
+
Flags:
|
|
2012
|
+
--check print a value-free NAME / status / source table; exit 1 if a
|
|
2013
|
+
variable your POLICY NAMES is unresolved
|
|
2014
|
+
--policy <path> / --dir <path> the policy file, or where to discover it
|
|
2015
|
+
--log <path> log file the .approval/env path is derived from
|
|
2016
|
+
--json machine-readable output (carries values; --check does not)
|
|
2017
|
+
-h, --help this text
|
|
2018
|
+
|
|
2019
|
+
THIS COMMAND IS THE ONLY THING THAT READS .approval/env (invariant 7), a mode
|
|
2020
|
+
0600 file of KEY=VALUE lines saying WHERE each value lives. Its default output
|
|
2021
|
+
CARRIES SECRETS by design; its APPROVAL_ENV_PROVENANCE line carries no value.
|
|
2022
|
+
|
|
2023
|
+
approval env --check # look first: no value is printed on this path
|
|
2024
|
+
eval "$(approval env)" # then establish the environment yourself
|
|
2025
|
+
|
|
2026
|
+
JSON shape: docs/cli-reference.md#env
|
|
2027
|
+
${EXIT_CODES_POINTER} (4 for an unreadable file or a wrong mode; 1 for --check)
|
|
2028
|
+
${JSON_ERRORS}
|
|
2029
|
+
${why("env")}`;
|
|
2030
|
+
export const SETUP_HELP = `approval setup — interactive configuration (SPEC.md §5.2, §10.1)
|
|
2031
|
+
|
|
2032
|
+
Usage:
|
|
2033
|
+
approval setup identity|vault|sampling|checkpoint [--as human:<id>] …
|
|
2034
|
+
approval setup channel|adapter <name> [--api-base <url>] [--as human:<id>] …
|
|
2035
|
+
approval setup service [--platform launchd|systemd] [--uninstall] …
|
|
2036
|
+
|
|
2037
|
+
Subcommands:
|
|
2038
|
+
identity declare who the human is (APPROVAL_HUMAN); not human-only
|
|
2039
|
+
vault mint a vault passphrase, store it, and record where it lives
|
|
2040
|
+
sampling mint the audit sampling secret and print the policy line for it
|
|
2041
|
+
checkpoint mint the Ed25519 key you sign the log's head with (--rotate/--retire)
|
|
2042
|
+
channel configure one CHANNEL's transport credential (OS keystore)
|
|
2043
|
+
adapter fill the VAULT with one ADAPTER's credentials, from its manifest
|
|
2044
|
+
service write the launchd or systemd unit that runs "approval up" at login
|
|
2045
|
+
|
|
2046
|
+
CHANNEL AND ADAPTER ARE TWO NOUNS (SPEC.md §4). EVERY SUBCOMMAND
|
|
2047
|
+
REFUSES WHEN STDIN IS NOT A TERMINAL, and --json, exiting 2 with what to run.
|
|
2048
|
+
writes .approval/env (mode 0600) and items in the OS keystore
|
|
2049
|
+
never appends to the log, attests anything, or edits APPROVAL.md
|
|
2050
|
+
|
|
2051
|
+
${EXIT_CODES_POINTER} (2 also means "interactive, and your stdin is not")
|
|
2052
|
+
${JSON_ERRORS}
|
|
2053
|
+
${why("setup")}`;
|
|
2054
|
+
export const SETUP_IDENTITY_HELP = `approval setup identity — declare who the human is
|
|
2055
|
+
|
|
2056
|
+
Usage:
|
|
2057
|
+
approval setup identity [--log <path>] [--dir <path>] [--policy <path>]
|
|
2058
|
+
|
|
2059
|
+
Asks for a \`human:<id>\` identity, validates it against the ^human:.+ pattern
|
|
2060
|
+
\`policy attest\` enforces, and writes APPROVAL_HUMAN=human:<id> into
|
|
2061
|
+
.approval/env. Nothing is appended to the log. A BARE ID IS ENOUGH: answer
|
|
2062
|
+
\`alice\` and the line reads APPROVAL_HUMAN=human:alice.
|
|
2063
|
+
|
|
2064
|
+
NOT HUMAN-ONLY, unlike every other setup subcommand: a verb that required
|
|
2065
|
+
APPROVAL_HUMAN before it would let you set APPROVAL_HUMAN could only be run by
|
|
2066
|
+
someone who did not need it. The line it writes is INERT until you run
|
|
2067
|
+
\`eval "$(approval env)"\`. Refuses when stdin is not a terminal.
|
|
2068
|
+
|
|
2069
|
+
${EXIT_CODES_POINTER}
|
|
2070
|
+
${JSON_ERRORS}
|
|
2071
|
+
${why("setup-identity")}`;
|
|
2072
|
+
export const SETUP_VAULT_HELP = `approval setup vault — mint and store the vault passphrase (HUMAN-ONLY)
|
|
2073
|
+
|
|
2074
|
+
Usage:
|
|
2075
|
+
approval setup vault [--as human:<id>] [--log <path>] [--dir <path>]
|
|
2076
|
+
[--policy <path>]
|
|
2077
|
+
|
|
2078
|
+
Generates 32 random bytes, base64-encodes them, stores the result in the OS
|
|
2079
|
+
keystore as approval-vault-passphrase, and writes the source line for the
|
|
2080
|
+
variable your policy names in vault.passphrase_env (APPROVAL_VAULT_PASSPHRASE by
|
|
2081
|
+
default). The value is not printed here or anywhere else.
|
|
2082
|
+
|
|
2083
|
+
WARNS FIRST if .approval/vault.enc already exists: a vault cannot be re-keyed by
|
|
2084
|
+
changing a variable, so every credential in it would become unreadable. The
|
|
2085
|
+
warning comes before the generation, and the confirmation defaults to no.
|
|
2086
|
+
|
|
2087
|
+
The generated value reaches the keystore on the helper's STDIN. If this build of
|
|
2088
|
+
the helper will not take stdin, the fallback passes it in an argv and says so.
|
|
2089
|
+
|
|
2090
|
+
${EXIT_CODES_POINTER}
|
|
2091
|
+
${JSON_ERRORS}
|
|
2092
|
+
${why("setup-vault")}`;
|
|
2093
|
+
export const SETUP_SAMPLING_HELP = `approval setup sampling — mint the audit sampling secret (HUMAN-ONLY)
|
|
2094
|
+
|
|
2095
|
+
Usage:
|
|
2096
|
+
approval setup sampling [--as human:<id>] [--log <path>] [--dir <path>]
|
|
2097
|
+
[--policy <path>]
|
|
2098
|
+
|
|
2099
|
+
Generates the operator-held secret that selects which supervised actions are
|
|
2100
|
+
sampled for retrospective review (SPEC.md §5.2), stores it as
|
|
2101
|
+
approval-sampling-secret, and writes its source line. Selection is HMAC-SHA-256
|
|
2102
|
+
over the event hash under this secret; seeding from event content alone is
|
|
2103
|
+
forbidden, because the agent authoring the event controls that content.
|
|
2104
|
+
|
|
2105
|
+
IF YOUR POLICY NAMES NO audit.sampling_secret_env, the secret is recorded under
|
|
2106
|
+
the conventional name APPROVAL_SAMPLING_SECRET and SAMPLING STAYS OFF. This verb
|
|
2107
|
+
does not edit an attested policy file: it prints the block to add and the
|
|
2108
|
+
\`approval policy amend\` ceremony that attests it.
|
|
2109
|
+
|
|
2110
|
+
${EXIT_CODES_POINTER}
|
|
2111
|
+
${JSON_ERRORS}
|
|
2112
|
+
${why("setup-sampling")}`;
|
|
2113
|
+
export const SETUP_CHECKPOINT_HELP = `approval setup checkpoint — mint the log-checkpoint key (HUMAN-ONLY)
|
|
2114
|
+
|
|
2115
|
+
Usage:
|
|
2116
|
+
approval setup checkpoint [--rotate] [--retire <fingerprint>]
|
|
2117
|
+
[--as human:<id>] [--log <path>] [--dir <path>]
|
|
2118
|
+
[--policy <path>]
|
|
2119
|
+
|
|
2120
|
+
Mints the Ed25519 keypair you sign the log's head with. The PRIVATE half goes
|
|
2121
|
+
into the vault under approval.checkpoint.key and is never printed; the PUBLIC
|
|
2122
|
+
half is printed with the exact audit.checkpoint_keys block to paste. THIS VERB
|
|
2123
|
+
DOES NOT EDIT APPROVAL.md: the key is inert until you add that block and run
|
|
2124
|
+
\`approval policy amend\`, because a checkpoint signed by a key the policy does
|
|
2125
|
+
not list is checkpoint-key-unknown, a refusal.
|
|
2126
|
+
|
|
2127
|
+
--rotate mint a new key and ADD it; the vault's private half is replaced
|
|
2128
|
+
--retire <fp> print the block that drops a key — REFUSED for any key that
|
|
2129
|
+
signed a checkpoint, naming the seqs it would break
|
|
2130
|
+
|
|
2131
|
+
INTERACTIVE ONLY, and classified policy.core, so an agent cannot run it.
|
|
2132
|
+
JSON: none; this verb prints for a human to read and paste.
|
|
2133
|
+
|
|
2134
|
+
${EXIT_CODES_POINTER}
|
|
2135
|
+
${JSON_ERRORS}
|
|
2136
|
+
${why("setup-checkpoint")}`;
|
|
2137
|
+
export const SETUP_ADAPTER_HELP = `approval setup adapter — fill the vault for one adapter (HUMAN-ONLY)
|
|
2138
|
+
|
|
2139
|
+
Usage:
|
|
2140
|
+
approval setup adapter <name> [--as human:<id>] [--log <path>] [--dir <path>]
|
|
2141
|
+
[--policy <path>]
|
|
2142
|
+
|
|
2143
|
+
Known adapters:
|
|
2144
|
+
email smtp.host, smtp.port, smtp.security, smtp.user, smtp.password
|
|
2145
|
+
agentmail the two values \`approval adapter agentmail\` reads:
|
|
2146
|
+
agentmail.inbox_id and agentmail.api_key
|
|
2147
|
+
zzz the invited write credential \`approval adapter zzz\` reads:
|
|
2148
|
+
zzz.agent_token
|
|
2149
|
+
|
|
2150
|
+
Asks for each credential the named adapter DECLARES, validates every answer with
|
|
2151
|
+
the adapter's own rules, stores them in .approval/vault.enc, and offers to prove
|
|
2152
|
+
the result against the service. A RE-RUN THAT REPLACED ONLY SOME NAMES offers the
|
|
2153
|
+
same proof over the STORED set, read the way the adapter reads it at send time.
|
|
2154
|
+
THE PASSPHRASE IS READ, NEVER ESTABLISHED: it
|
|
2155
|
+
comes from the variable your policy names in vault.passphrase_env. WHAT IT
|
|
2156
|
+
REPORTS is the path, the count and the names, never a value.
|
|
2157
|
+
|
|
2158
|
+
${EXIT_CODES_POINTER} (1 means the service refused, or the vault would not open)
|
|
2159
|
+
${JSON_ERRORS}
|
|
2160
|
+
${why("setup-adapter")}`;
|
|
2161
|
+
export const SETUP_ADAPTER_EMAIL_HELP = `approval setup adapter email — the SMTP credentials (HUMAN-ONLY)
|
|
2162
|
+
|
|
2163
|
+
Usage:
|
|
2164
|
+
approval setup adapter email [--as human:<id>] [--log <path>] [--dir <path>]
|
|
2165
|
+
[--policy <path>]
|
|
2166
|
+
|
|
2167
|
+
The five names the email adapter reads inside the verified execution window:
|
|
2168
|
+
|
|
2169
|
+
smtp.host the submission server
|
|
2170
|
+
smtp.port 587 for STARTTLS submission, 465 for implicit TLS
|
|
2171
|
+
smtp.security implicit | starttls | none, picked from a numbered list
|
|
2172
|
+
smtp.user optional, and both-or-neither with the password
|
|
2173
|
+
smtp.password optional, read with no echo, written last
|
|
2174
|
+
|
|
2175
|
+
A port that is not a port and a security setting that is not one of the three
|
|
2176
|
+
words are refused HERE. THE PROBE SENDS NOTHING: it is the same SMTP session a
|
|
2177
|
+
send runs, then QUIT. A FAILED PROBE KEEPS THE VALUES and prints the undo:
|
|
2178
|
+
|
|
2179
|
+
approval vault remove smtp.password --as human:<id>
|
|
2180
|
+
|
|
2181
|
+
${EXIT_CODES_POINTER} (1 means the server refused, or the vault would not open)
|
|
2182
|
+
${JSON_ERRORS}
|
|
2183
|
+
${why("setup-adapter-email")}`;
|
|
2184
|
+
export const SETUP_ADAPTER_AGENTMAIL_HELP = `approval setup adapter agentmail — the AgentMail credentials (HUMAN-ONLY)
|
|
2185
|
+
|
|
2186
|
+
Usage:
|
|
2187
|
+
approval setup adapter agentmail [--as human:<id>] [--log <path>]
|
|
2188
|
+
[--dir <path>] [--policy <path>]
|
|
2189
|
+
|
|
2190
|
+
The two names the AgentMail adapter reads inside the verified execution window:
|
|
2191
|
+
agentmail.inbox_id the inbox this runtime sends from; the inbox IS the sender
|
|
2192
|
+
agentmail.api_key the key carrying draft_send and message_send, no echo
|
|
2193
|
+
|
|
2194
|
+
STORE THE SENDING KEY HERE AND GIVE THE AGENT A DIFFERENT ONE. An agent key
|
|
2195
|
+
without those permissions composes all day and cannot send; this one answers
|
|
2196
|
+
only to a grant.
|
|
2197
|
+
|
|
2198
|
+
THE PROBE SENDS NOTHING: it is GET /v0/inboxes/{inbox_id}, the same read a send
|
|
2199
|
+
makes first, and it reports the address the inbox sends as. Where that read
|
|
2200
|
+
discloses the key's permissions a missing one is named; where it does not, it
|
|
2201
|
+
says so rather than claiming the key can send. A FAILED PROBE KEEPS THE VALUES:
|
|
2202
|
+
|
|
2203
|
+
approval vault remove agentmail.api_key --as human:<id>
|
|
2204
|
+
|
|
2205
|
+
${EXIT_CODES_POINTER} (1 means AgentMail refused, or the vault would not open)
|
|
2206
|
+
${JSON_ERRORS}
|
|
2207
|
+
${why("setup-adapter-agentmail")}`;
|
|
2208
|
+
export const SETUP_ADAPTER_ZZZ_HELP = `approval setup adapter zzz — the zzz.bot credential (HUMAN-ONLY)
|
|
2209
|
+
|
|
2210
|
+
Usage:
|
|
2211
|
+
approval setup adapter zzz [--as human:<id>] [--log <path>]
|
|
2212
|
+
[--dir <path>] [--policy <path>]
|
|
2213
|
+
|
|
2214
|
+
The vault name is zzz.agent_token: an invited principal token with write scope.
|
|
2215
|
+
Keep it out of the agent environment, so publication remains behind the adapter.
|
|
2216
|
+
|
|
2217
|
+
THE PROBE POSTS NOTHING. It performs one authenticated GET /api/v1/rooms. A
|
|
2218
|
+
success proves only that zzz.bot accepted the active credential. It does not
|
|
2219
|
+
prove write scope, room membership, or private-room workflow evidence; zzz.bot
|
|
2220
|
+
checks those when the approved message is sent.
|
|
2221
|
+
|
|
2222
|
+
${EXIT_CODES_POINTER} (1 means zzz.bot refused, or the vault would not open)
|
|
2223
|
+
${JSON_ERRORS}
|
|
2224
|
+
${why("setup-adapter-zzz")}`;
|
|
2225
|
+
export const SETUP_CHANNEL_HELP = `approval setup channel — configure one channel's transport credential (HUMAN-ONLY)
|
|
2226
|
+
|
|
2227
|
+
Usage:
|
|
2228
|
+
approval setup channel <name> [--as human:<id>] [--api-base <url>]
|
|
2229
|
+
[--log <path>] [--dir <path>] [--policy <path>]
|
|
2230
|
+
|
|
2231
|
+
Known channels:
|
|
2232
|
+
telegram the bot token and the approver chat: APPROVAL_TG_TOKEN and
|
|
2233
|
+
APPROVAL_TG_CHAT, or the names channels.telegram.token_env /
|
|
2234
|
+
chat_id_env declare
|
|
2235
|
+
|
|
2236
|
+
A CHANNEL IS NOT AN ADAPTER, and the two setup verbs fill different stores. A
|
|
2237
|
+
channel needs a transport credential: it goes into the OS keystore, and
|
|
2238
|
+
.approval/env records where. An adapter holds the credentials a side effect
|
|
2239
|
+
spends, so \`approval setup adapter <name>\` fills the vault instead.
|
|
2240
|
+
|
|
2241
|
+
An older build spelled the Telegram one without the \`channel\` noun. That form
|
|
2242
|
+
exits 2 and names this one; there is deliberately no alias.
|
|
2243
|
+
|
|
2244
|
+
${EXIT_CODES_POINTER} (2 also means "this is interactive and your stdin is not a
|
|
2245
|
+
terminal"; 1 means the far end refused)
|
|
2246
|
+
${JSON_ERRORS}
|
|
2247
|
+
${why("setup-channel")}`;
|
|
2248
|
+
export const SETUP_CHANNEL_TELEGRAM_HELP = `approval setup channel telegram — the bot token and the approver chat (HUMAN-ONLY)
|
|
2249
|
+
|
|
2250
|
+
Usage:
|
|
2251
|
+
approval setup channel telegram [--as human:<id>] [--api-base <url>]
|
|
2252
|
+
[--log <path>] [--dir <path>] [--policy <path>]
|
|
2253
|
+
|
|
2254
|
+
Five steps: store the token, prove it with getMe, WAIT for you to message the
|
|
2255
|
+
bot, read the chat id back, and write both variables. The wait is a continuous
|
|
2256
|
+
long poll of up to 90 seconds; Ctrl-C stops it.
|
|
2257
|
+
|
|
2258
|
+
STOP \`approval channel telegram listen\` FIRST. Two processes long-polling one
|
|
2259
|
+
bot is a 409 from the Bot API. THE TOKEN IS NEVER TYPED INTO THIS PROCESS on a
|
|
2260
|
+
machine with a keystore, and NO getUpdates FROM THIS VERB CARRIES AN OFFSET.
|
|
2261
|
+
HUMAN-ONLY: --as expects a human:<id>.
|
|
2262
|
+
|
|
2263
|
+
${EXIT_CODES_POINTER} (1 means the far end refused)
|
|
2264
|
+
${JSON_ERRORS}
|
|
2265
|
+
${why("setup-channel-telegram")}`;
|
|
2266
|
+
export const SETUP_SERVICE_HELP = `approval setup service — run the ambient runtime at login (HUMAN-ONLY)
|
|
2267
|
+
|
|
2268
|
+
Usage:
|
|
2269
|
+
approval setup service [--platform launchd|systemd] [--label <name>]
|
|
2270
|
+
[--logs <dir>] [--env-file <path>] [--exec <path>]
|
|
2271
|
+
[--out <path>] [--uninstall] [--as human:<id>]
|
|
2272
|
+
[--log <path>] [--dir <path>] [--policy <path>]
|
|
2273
|
+
|
|
2274
|
+
Flags:
|
|
2275
|
+
--platform launchd (macOS) or systemd (Linux). Default: this machine's
|
|
2276
|
+
--label <name> the launchd label / systemd unit name
|
|
2277
|
+
--logs <dir> where the service's stdout and stderr go. NEVER .approval/
|
|
2278
|
+
--env-file <p> an EnvironmentFile YOU author, instead of the env wrapper
|
|
2279
|
+
--exec <path> / --out <path> the approval binary / the unit file to write
|
|
2280
|
+
--uninstall print the unload command and remove the unit file
|
|
2281
|
+
-h, --help this text
|
|
2282
|
+
|
|
2283
|
+
PRINTS THE WHOLE UNIT FOR YOU TO READ BEFORE WRITING, and writes only if you
|
|
2284
|
+
confirm. IT NAMES VARIABLES AND NEVER COPIES A VALUE. IT DOES NOT LOAD THE
|
|
2285
|
+
SERVICE: it prints the one command that arms it, which is your act to perform.
|
|
2286
|
+
|
|
2287
|
+
${EXIT_CODES_POINTER} (2 also means "interactive, and your stdin is not")
|
|
2288
|
+
${JSON_ERRORS}
|
|
2289
|
+
${why("setup-service")}`;
|
|
2290
|
+
// ---------------------------------------------------------------------------
|
|
2291
|
+
// The MCP wrapper (APRV-87)
|
|
2292
|
+
// ---------------------------------------------------------------------------
|
|
2293
|
+
export const CODEX_HELP = `approval codex — prepare and inspect a constrained Codex host bundle (INERT)
|
|
2294
|
+
|
|
2295
|
+
Usage:
|
|
2296
|
+
approval codex prepare --instance <id> --workspace <abs> --primary <abs>
|
|
2297
|
+
--install-root <abs> --output <new-dir> --codex <abs> --node <abs> [--json]
|
|
2298
|
+
approval codex setup --check <bundle-dir> [--json]
|
|
2299
|
+
approval codex doctor --strict --manifest <abs> [--json]
|
|
2300
|
+
approval codex start|serve --manifest <abs> [--json]
|
|
2301
|
+
|
|
2302
|
+
prepare writes a fresh review bundle only. setup --check verifies its closed file
|
|
2303
|
+
set, hashes, manifest and generated templates. Neither installs a package, edits
|
|
2304
|
+
Codex configuration, creates principals, loads services, reads credentials, or
|
|
2305
|
+
changes policy. doctor fails closed on unknown custody, executes no manifest
|
|
2306
|
+
binary in this slice, and reports runtime versions as unchecked.
|
|
2307
|
+
|
|
2308
|
+
start and serve currently refuse with codex-not-ready. The policy-bound broker
|
|
2309
|
+
and confined runner arrive in APRV-325.2 and APRV-325.3. An npm or project
|
|
2310
|
+
installation alone is never reported as enforcement.
|
|
2311
|
+
|
|
2312
|
+
${EXIT_CODES_POINTER} (1 means the strict boundary is absent or invalid)
|
|
2313
|
+
${JSON_ERRORS}
|
|
2314
|
+
why: docs/cli-reference.md#constrained-codex-preparation`;
|
|
2315
|
+
export const MCP_HELP = `approval mcp serve — the MCP wrapper of SPEC.md §10.5 (FOREGROUND)
|
|
2316
|
+
|
|
2317
|
+
Usage:
|
|
2318
|
+
approval mcp serve [--as agent:<id>] [--dir <p>] [--log <p>] [--policy <p>]
|
|
2319
|
+
[--http [--port <n> | --listen <host:port>] [--guest]]
|
|
2320
|
+
|
|
2321
|
+
Flags:
|
|
2322
|
+
--as agent:<id> the identity EVERY tool call is recorded under; agent: only,
|
|
2323
|
+
required unless APPROVAL_AGENT names one. -h for this text
|
|
2324
|
+
--dir/--log/--policy <p> working directory, and the log and policy pinned
|
|
2325
|
+
--http streamable HTTP, not stdio: a session per client, 20 live and
|
|
2326
|
+
200 per process. --port <n>=4681 is loopback; --listen widens
|
|
2327
|
+
--guest --http only: a fresh agent:guest-<id> per session, so limits
|
|
2328
|
+
are per connection. Exclusive with --as
|
|
2329
|
+
|
|
2330
|
+
On stdio, stdout IS the JSON-RPC stream; both run until interrupted. THE TOOLS
|
|
2331
|
+
ARE THE AGENT SURFACE: the registry less human_only, so grant and the channel
|
|
2332
|
+
listeners are unpublished (SPEC.md §11 names the agent the untrusted policy).
|
|
2333
|
+
IDENTITY IS THE SERVER'S: no client name or argument names an actor. Calls run
|
|
2334
|
+
SERIALLY, THIS SERVER READS NO .approval/env. POST-V1: tasks/elicitation.
|
|
2335
|
+
|
|
2336
|
+
${EXIT_CODES_POINTER} (2 is a startup refusal; 0 is a clean shutdown)
|
|
2337
|
+
${JSON_ERRORS}
|
|
2338
|
+
${why("mcp-serve")}`;
|
|
2339
|
+
//# sourceMappingURL=help.js.map
|