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,458 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The daemon's live-draw server (APRV-208).
|
|
3
|
+
*
|
|
4
|
+
* The daemon is the one process on this machine that legitimately holds the
|
|
5
|
+
* sampling secret: an operator starts it in a terminal where `eval "$(approval
|
|
6
|
+
* env)"` has run, and `core/child-env.ts` (APRV-205) strips `APPROVAL_*` from
|
|
7
|
+
* every child it spawns, so the secret goes no further. This module lets short
|
|
8
|
+
* lived gate processes that hold no secret — the harness hook, above all — ASK
|
|
9
|
+
* for a draw instead of failing closed on every action of a `supervised-live`
|
|
10
|
+
* class. `core/live-draw.ts` carries the protocol and the argument; this is the
|
|
11
|
+
* server half.
|
|
12
|
+
*
|
|
13
|
+
* ## Three things this server refuses to take on the asker's word
|
|
14
|
+
*
|
|
15
|
+
* 1. **The action.** It answers only for an `action_key` already carried by a
|
|
16
|
+
* `task.registered` record in the VERIFIED log, declaring exactly this
|
|
17
|
+
* `payload_hash`. That is what stops the socket being a private oracle: an
|
|
18
|
+
* agent that wants to grind candidate payloads until one draws unsampled must
|
|
19
|
+
* append a registration for each candidate first, in the append-only log,
|
|
20
|
+
* where the attempt is permanent and countable. See `core/live-draw.ts`'s
|
|
21
|
+
* header on why this matters more than the socket's file mode does.
|
|
22
|
+
* 2. **The rate.** It resolves the action's class against its own policy and
|
|
23
|
+
* uses the `live_rate` IT derives. A `live_rate` in the question is a
|
|
24
|
+
* proposal, never an instruction; the derived one is echoed back and the
|
|
25
|
+
* asker refuses an answer to a different question.
|
|
26
|
+
* 3. **The policy.** Same: it checks its own attestation and echoes its own
|
|
27
|
+
* `policy_sha256`. A daemon and a hook reading different policy files fail
|
|
28
|
+
* closed rather than agreeing on the wrong rules.
|
|
29
|
+
*
|
|
30
|
+
* A fresh verified read per question is what makes (1) usable at all: the hook
|
|
31
|
+
* registers the task microseconds before it asks, and a daemon answering out of
|
|
32
|
+
* a tick's stale memory would refuse every real request. The read is cheap for
|
|
33
|
+
* the reason APRV-188 exists — the daemon's cache is warm and only the appended
|
|
34
|
+
* tail is walked.
|
|
35
|
+
*
|
|
36
|
+
* ## The secret
|
|
37
|
+
*
|
|
38
|
+
* Held in one private field, closed over by nothing, and never emitted: not in
|
|
39
|
+
* an answer, not in a warning, not in the `started` line. What leaves this
|
|
40
|
+
* process is a verdict and a MAC.
|
|
41
|
+
*/
|
|
42
|
+
import { chmodSync, mkdirSync, rmSync, statSync } from "node:fs";
|
|
43
|
+
import { createServer } from "node:net";
|
|
44
|
+
import { checkAttestation } from "../core/attest.js";
|
|
45
|
+
import { DRAW_PROTOCOL_VERSION, DRAW_SOCKET_PATH_LIMIT, drawDirFor, drawMac, drawSocketPathFor, isHex64, isSamplingQuery, liveClassesOf, } from "../core/live-draw.js";
|
|
46
|
+
import { loadPolicy } from "../core/policy-load.js";
|
|
47
|
+
import { resolve as resolveClass } from "../core/policy-match.js";
|
|
48
|
+
import { isSampled, resolveLiveSelector, resolveSampler, } from "../core/sampler.js";
|
|
49
|
+
import { readVerifiedRecords } from "../core/state.js";
|
|
50
|
+
/**
|
|
51
|
+
* The server this environment can run, or the reason it cannot (APRV-208).
|
|
52
|
+
*
|
|
53
|
+
* ## Where the secret comes from, and why that is the whole opt-in
|
|
54
|
+
*
|
|
55
|
+
* From the daemon's OWN environment, and nowhere else. `.approval/env` is a
|
|
56
|
+
* source MAP and `core/env-file.ts`'s load-bearing rule is that no verb reads it
|
|
57
|
+
* into its own environment (the reason is `APPROVAL_HUMAN`: a working-tree file
|
|
58
|
+
* that could set identity would put the human-only gate one `echo >>` away from
|
|
59
|
+
* being nobody's gate). That rule is not weakened here. The operator runs `eval
|
|
60
|
+
* "$(approval env)"` in the terminal they start the daemon from — the same act
|
|
61
|
+
* `approval setup sampling` already documents, resolving the keychain item or the
|
|
62
|
+
* env file's declared source — and this reads what that established.
|
|
63
|
+
*
|
|
64
|
+
* That act is also the feature's opt-in, which is why there is no flag to turn
|
|
65
|
+
* it on. Serving draws changes VERDICTS: a class an operator declared
|
|
66
|
+
* `supervised-live` at 0.1 goes from gating 100% to gating 10%, and a default
|
|
67
|
+
* that moved that under someone on an upgrade would be the surprise this project
|
|
68
|
+
* exists to prevent. But it moves only for an operator who has exported the
|
|
69
|
+
* secret into the daemon's shell on purpose, having already amended their policy
|
|
70
|
+
* to declare the class live. Both halves are deliberate acts by the human. What
|
|
71
|
+
* exists instead is a way OUT — `approval daemon run --no-draw` — because the
|
|
72
|
+
* one thing an operator must always be able to do is take a control back.
|
|
73
|
+
*/
|
|
74
|
+
export function drawServerFor(options) {
|
|
75
|
+
const where = options.policy.file !== undefined
|
|
76
|
+
? { file: options.policy.file }
|
|
77
|
+
: { dir: options.policy.dir ?? process.cwd() };
|
|
78
|
+
if (options.schemaDir !== undefined)
|
|
79
|
+
where.schemaDir = options.schemaDir;
|
|
80
|
+
const load = loadPolicy(where);
|
|
81
|
+
const env = options.env ?? process.env;
|
|
82
|
+
// Asked FIRST, and answered quietly. A policy with no `supervised-live` class
|
|
83
|
+
// makes no draw at any rate, so an unset secret in this shell is not a fact
|
|
84
|
+
// about that operator's configuration: it is the ordinary state of every
|
|
85
|
+
// daemon that has never used the setting, and a warning printed on every start
|
|
86
|
+
// would be the noise that teaches an operator to stop reading the others. It
|
|
87
|
+
// has to come before the selector because `core/sampler.ts`'s refusals are
|
|
88
|
+
// worded for a caller that already knows a live class is in play ("declares a
|
|
89
|
+
// supervised-live class but names no ...", which would be false here).
|
|
90
|
+
if (load.ok && liveClassesOf(load.policy).length === 0) {
|
|
91
|
+
return {
|
|
92
|
+
ok: false,
|
|
93
|
+
reason: "no-live-class",
|
|
94
|
+
message: `${load.source.filename} declares no supervised-live class, so no draw is ever made and none is served.`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// The availability question is asked through `core/sampler.ts`, so this and
|
|
98
|
+
// the in-process draw agree on what "no usable secret" means and on the words
|
|
99
|
+
// for each way of not having one. The secret itself is read here rather than
|
|
100
|
+
// there because a MAC needs the key and `resolveLiveSelector` returns a
|
|
101
|
+
// closure over it, deliberately.
|
|
102
|
+
const selector = resolveLiveSelector(load, env);
|
|
103
|
+
if (!selector.available) {
|
|
104
|
+
return { ok: false, reason: selector.reason, message: selector.message };
|
|
105
|
+
}
|
|
106
|
+
const secret = env[selector.secretEnv];
|
|
107
|
+
if (typeof secret !== "string" || secret.length === 0) {
|
|
108
|
+
return { ok: false, reason: "secret-unset", message: "the sampling secret is unset in this process" };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
ok: true,
|
|
112
|
+
server: new DrawServer({
|
|
113
|
+
logPath: options.logPath,
|
|
114
|
+
policy: options.policy,
|
|
115
|
+
...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
|
|
116
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
117
|
+
secret,
|
|
118
|
+
}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** The largest question this server will read before hanging up. */
|
|
122
|
+
const QUESTION_LIMIT = 8192;
|
|
123
|
+
function payloadOf(record) {
|
|
124
|
+
const payload = record.payload;
|
|
125
|
+
return typeof payload === "object" && payload !== null
|
|
126
|
+
? payload
|
|
127
|
+
: {};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The class a registered action declared, if the log declares this exact pair.
|
|
131
|
+
*
|
|
132
|
+
* Scans every `task.registered` because the question names no task: the action
|
|
133
|
+
* key is the identifier the whole runtime keys on, and requiring the asker to
|
|
134
|
+
* name a task too would be one more field to get wrong for no check gained. The
|
|
135
|
+
* pair must match on BOTH halves — an action registered with other bytes is not
|
|
136
|
+
* this question's action.
|
|
137
|
+
*/
|
|
138
|
+
function registeredClass(records, actionKey, payloadHash) {
|
|
139
|
+
let found = null;
|
|
140
|
+
for (const record of records) {
|
|
141
|
+
if (record.event !== "task.registered")
|
|
142
|
+
continue;
|
|
143
|
+
const declared = payloadOf(record)["actions"];
|
|
144
|
+
if (!Array.isArray(declared))
|
|
145
|
+
continue;
|
|
146
|
+
for (const entry of declared) {
|
|
147
|
+
if (typeof entry !== "object" || entry === null)
|
|
148
|
+
continue;
|
|
149
|
+
const item = entry;
|
|
150
|
+
if (item["idempotency_key"] !== actionKey)
|
|
151
|
+
continue;
|
|
152
|
+
if (item["payload_hash"] !== payloadHash)
|
|
153
|
+
continue;
|
|
154
|
+
if (typeof item["class"] !== "string")
|
|
155
|
+
continue;
|
|
156
|
+
found = item["class"];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return found;
|
|
160
|
+
}
|
|
161
|
+
/** The question, validated into its typed shape, or `null`. */
|
|
162
|
+
function parseQuestion(line) {
|
|
163
|
+
let parsed;
|
|
164
|
+
try {
|
|
165
|
+
parsed = JSON.parse(line);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
171
|
+
return null;
|
|
172
|
+
const body = parsed;
|
|
173
|
+
if (body["v"] !== DRAW_PROTOCOL_VERSION)
|
|
174
|
+
return null;
|
|
175
|
+
if (typeof body["action_key"] !== "string" || body["action_key"].length === 0)
|
|
176
|
+
return null;
|
|
177
|
+
if (!isHex64(body["payload_hash"]))
|
|
178
|
+
return null;
|
|
179
|
+
if (!isHex64(body["policy_hash"]))
|
|
180
|
+
return null;
|
|
181
|
+
const rate = body["live_rate"];
|
|
182
|
+
if (typeof rate !== "number" || !Number.isFinite(rate) || rate <= 0 || rate > 1)
|
|
183
|
+
return null;
|
|
184
|
+
return {
|
|
185
|
+
v: DRAW_PROTOCOL_VERSION,
|
|
186
|
+
action_key: body["action_key"],
|
|
187
|
+
payload_hash: body["payload_hash"],
|
|
188
|
+
policy_hash: body["policy_hash"],
|
|
189
|
+
live_rate: rate,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* A server that answers live draws for one log, over one owner-only socket.
|
|
194
|
+
*
|
|
195
|
+
* Started and stopped by the daemon loop. Every failure is a refusal to serve,
|
|
196
|
+
* never a throw into the loop: a daemon that could not open a socket must keep
|
|
197
|
+
* doing its job, and every asker fails closed to a human decision, which is
|
|
198
|
+
* exactly what happens today with no daemon at all.
|
|
199
|
+
*/
|
|
200
|
+
export class DrawServer {
|
|
201
|
+
options;
|
|
202
|
+
server = null;
|
|
203
|
+
answered = 0;
|
|
204
|
+
refused = 0;
|
|
205
|
+
constructor(options) {
|
|
206
|
+
this.options = options;
|
|
207
|
+
}
|
|
208
|
+
/** How many questions were answered and refused, for the daemon's report. */
|
|
209
|
+
stats() {
|
|
210
|
+
return { answered: this.answered, refused: this.refused };
|
|
211
|
+
}
|
|
212
|
+
start() {
|
|
213
|
+
const path = drawSocketPathFor(this.options.logPath);
|
|
214
|
+
if (path.length > DRAW_SOCKET_PATH_LIMIT) {
|
|
215
|
+
return {
|
|
216
|
+
ok: false,
|
|
217
|
+
reason: "path-too-long",
|
|
218
|
+
detail: `${path} is ${String(path.length)} bytes, past the ${String(DRAW_SOCKET_PATH_LIMIT)}-byte limit a Unix socket address can carry`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
const dir = drawDirFor(this.options.logPath);
|
|
222
|
+
try {
|
|
223
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
224
|
+
// `mkdirSync`'s mode is subject to umask and a pre-existing directory
|
|
225
|
+
// keeps whatever mode it had, so the mode is asserted rather than asked
|
|
226
|
+
// for. The socket below is 0600 regardless; this is the second lock.
|
|
227
|
+
chmodSync(dir, 0o700);
|
|
228
|
+
const stats = statSync(dir);
|
|
229
|
+
const euid = typeof process.geteuid === "function" ? process.geteuid() : null;
|
|
230
|
+
if (euid === null || stats.uid !== euid) {
|
|
231
|
+
return {
|
|
232
|
+
ok: false,
|
|
233
|
+
reason: "directory-unusable",
|
|
234
|
+
detail: `${dir} is not owned by this user, so a socket in it could not be attributed to this daemon`,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (cause) {
|
|
239
|
+
return {
|
|
240
|
+
ok: false,
|
|
241
|
+
reason: "directory-unusable",
|
|
242
|
+
detail: `${dir} could not be prepared: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// A socket file left by a daemon that was killed. Removing it is safe: a
|
|
246
|
+
// LIVE server holding this path would make the bind below fail with EADDRINUSE
|
|
247
|
+
// only if the file were still there, and a second daemon on one log is
|
|
248
|
+
// already refused by the append lockfile long before it reaches here.
|
|
249
|
+
try {
|
|
250
|
+
rmSync(path, { force: true });
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Nothing to remove, or a path we cannot clear; the bind reports it.
|
|
254
|
+
}
|
|
255
|
+
const server = createServer((socket) => {
|
|
256
|
+
this.serve(socket);
|
|
257
|
+
});
|
|
258
|
+
server.on("error", () => {
|
|
259
|
+
// A listening error after start is a server that has stopped serving.
|
|
260
|
+
// Askers see a socket that will not answer and gate; nothing here throws
|
|
261
|
+
// into the daemon loop.
|
|
262
|
+
});
|
|
263
|
+
try {
|
|
264
|
+
server.listen(path);
|
|
265
|
+
chmodSync(path, 0o600);
|
|
266
|
+
}
|
|
267
|
+
catch (cause) {
|
|
268
|
+
try {
|
|
269
|
+
server.close();
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
// Never listened.
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
ok: false,
|
|
276
|
+
reason: "listen-failed",
|
|
277
|
+
detail: `${path} could not be served: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
// The daemon must be free to exit while this is open.
|
|
281
|
+
server.unref();
|
|
282
|
+
this.server = server;
|
|
283
|
+
return { ok: true, path };
|
|
284
|
+
}
|
|
285
|
+
close() {
|
|
286
|
+
const server = this.server;
|
|
287
|
+
this.server = null;
|
|
288
|
+
if (server === null)
|
|
289
|
+
return;
|
|
290
|
+
try {
|
|
291
|
+
server.close();
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
// Already closed.
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
rmSync(drawSocketPathFor(this.options.logPath), { force: true });
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// A socket file we cannot remove is one the next start clears.
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
serve(socket) {
|
|
304
|
+
let buffer = "";
|
|
305
|
+
let done = false;
|
|
306
|
+
const answer = (body) => {
|
|
307
|
+
if (done)
|
|
308
|
+
return;
|
|
309
|
+
done = true;
|
|
310
|
+
try {
|
|
311
|
+
socket.end(`${JSON.stringify(body)}\n`);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// The asker hung up; nothing to report to.
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const refuse = (detail) => {
|
|
318
|
+
this.refused += 1;
|
|
319
|
+
answer({ ok: false, detail });
|
|
320
|
+
};
|
|
321
|
+
socket.setEncoding("utf8");
|
|
322
|
+
socket.setTimeout(2_000, () => {
|
|
323
|
+
refuse("no question within the server's read timeout");
|
|
324
|
+
socket.destroy();
|
|
325
|
+
});
|
|
326
|
+
socket.on("error", () => {
|
|
327
|
+
done = true;
|
|
328
|
+
});
|
|
329
|
+
socket.on("data", (chunk) => {
|
|
330
|
+
if (done)
|
|
331
|
+
return;
|
|
332
|
+
buffer += chunk;
|
|
333
|
+
if (buffer.length > QUESTION_LIMIT) {
|
|
334
|
+
refuse("the question exceeded this protocol's size limit");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
const newline = buffer.indexOf("\n");
|
|
338
|
+
if (newline < 0)
|
|
339
|
+
return;
|
|
340
|
+
const line = buffer.slice(0, newline);
|
|
341
|
+
// APRV-271. The status question comes first because a draw question can
|
|
342
|
+
// never look like one: it carries no `action_key`, so `parseQuestion`
|
|
343
|
+
// would refuse it, and an operator would be told their daemon was
|
|
344
|
+
// malfunctioning when it had been asked something older builds never
|
|
345
|
+
// defined. Answering it costs no verified read and no MAC.
|
|
346
|
+
if (isSamplingQuery(line)) {
|
|
347
|
+
this.answered += 1;
|
|
348
|
+
answer(this.samplingReport());
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const question = parseQuestion(line);
|
|
352
|
+
if (question === null) {
|
|
353
|
+
refuse("the question was malformed or declared another protocol version");
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
answer(this.decide(question, refuse));
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Answer one question, or refuse it.
|
|
361
|
+
*
|
|
362
|
+
* Returns the answer body; refusals go through `refuse` and this returns
|
|
363
|
+
* `undefined`, which `answer` above ignores because `done` is already set.
|
|
364
|
+
*/
|
|
365
|
+
/** Where this daemon reads its policy from. One spelling, two readers. */
|
|
366
|
+
policyWhere() {
|
|
367
|
+
const where = this.options.policy.file !== undefined
|
|
368
|
+
? { file: this.options.policy.file }
|
|
369
|
+
: { dir: this.options.policy.dir ?? process.cwd() };
|
|
370
|
+
if (this.options.schemaDir !== undefined)
|
|
371
|
+
where.schemaDir = this.options.schemaDir;
|
|
372
|
+
return where;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* This daemon's report on its OWN sampler (APRV-271).
|
|
376
|
+
*
|
|
377
|
+
* Read through `core/sampler.ts` from this process's environment, which is
|
|
378
|
+
* the whole point: the operator exported the secret HERE, and every other
|
|
379
|
+
* process on the machine has had `APPROVAL_*` stripped from it. It carries
|
|
380
|
+
* the variable's NAME and the rate, both of which the policy file already
|
|
381
|
+
* states in the open, and never the value.
|
|
382
|
+
*
|
|
383
|
+
* No verified read, no attestation check and no MAC: this answer decides
|
|
384
|
+
* nothing. `core/live-draw.ts`'s header sets out what a caller may and may
|
|
385
|
+
* not conclude from it.
|
|
386
|
+
*/
|
|
387
|
+
samplingReport() {
|
|
388
|
+
const load = loadPolicy(this.policyWhere());
|
|
389
|
+
const sampler = resolveSampler(load);
|
|
390
|
+
const now = this.options.now ?? (() => new Date().toISOString());
|
|
391
|
+
return {
|
|
392
|
+
v: DRAW_PROTOCOL_VERSION,
|
|
393
|
+
sampling: {
|
|
394
|
+
enabled: sampler.enabled,
|
|
395
|
+
reason: sampler.enabled ? null : sampler.reason,
|
|
396
|
+
secret_env: sampler.secretEnv,
|
|
397
|
+
rate: sampler.rate,
|
|
398
|
+
live_classes: load.ok ? liveClassesOf(load.policy) : [],
|
|
399
|
+
},
|
|
400
|
+
daemon_pid: process.pid,
|
|
401
|
+
answered_at: now(),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
decide(question, refuse) {
|
|
405
|
+
const where = this.policyWhere();
|
|
406
|
+
const load = loadPolicy(where);
|
|
407
|
+
if (!load.ok) {
|
|
408
|
+
refuse(`this daemon cannot load its policy (${load.code}), so it can derive no rate`);
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
const read = readVerifiedRecords(this.options.logPath, this.options.schemaDir === undefined ? {} : { schemaDir: this.options.schemaDir });
|
|
412
|
+
if (!read.ok) {
|
|
413
|
+
refuse(`this daemon's log does not verify (${read.code}), so it will answer nothing`);
|
|
414
|
+
return undefined;
|
|
415
|
+
}
|
|
416
|
+
// The policy this daemon is actually enforcing, by its own attestation
|
|
417
|
+
// check over its own bytes. Never the asker's claim.
|
|
418
|
+
const status = checkAttestation(read.records, load.source.path);
|
|
419
|
+
if (status.status !== "attested") {
|
|
420
|
+
refuse(`this daemon's policy is not attested (${status.status}), so no draw is derivable`);
|
|
421
|
+
return undefined;
|
|
422
|
+
}
|
|
423
|
+
const cls = registeredClass(read.records, question.action_key, question.payload_hash);
|
|
424
|
+
if (cls === null) {
|
|
425
|
+
// The anti-grinding rule. A question about bytes nobody registered is a
|
|
426
|
+
// question about a hypothetical, and answering hypotheticals is what
|
|
427
|
+
// would turn this socket into the oracle the secret exists to deny.
|
|
428
|
+
refuse(`no task.registered in the verified log declares action ${question.action_key} with this payload_hash; a draw is answered only for an action already on the record`);
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
const resolution = resolveClass(load, cls);
|
|
432
|
+
if (resolution.supervision !== "live") {
|
|
433
|
+
refuse(`class ${cls} is not supervised-live under this daemon's policy; there is no fraction to draw`);
|
|
434
|
+
return undefined;
|
|
435
|
+
}
|
|
436
|
+
const rate = resolution.liveRate ?? 1;
|
|
437
|
+
const derived = {
|
|
438
|
+
v: DRAW_PROTOCOL_VERSION,
|
|
439
|
+
action_key: question.action_key,
|
|
440
|
+
payload_hash: question.payload_hash,
|
|
441
|
+
policy_hash: status.sha256,
|
|
442
|
+
live_rate: rate,
|
|
443
|
+
};
|
|
444
|
+
const selected = isSampled(this.options.secret, derived.payload_hash, derived.live_rate);
|
|
445
|
+
const now = this.options.now ?? (() => new Date().toISOString());
|
|
446
|
+
const body = {
|
|
447
|
+
v: DRAW_PROTOCOL_VERSION,
|
|
448
|
+
question: derived,
|
|
449
|
+
selected,
|
|
450
|
+
mac: drawMac(this.options.secret, derived, selected),
|
|
451
|
+
daemon_pid: process.pid,
|
|
452
|
+
answered_at: now(),
|
|
453
|
+
};
|
|
454
|
+
this.answered += 1;
|
|
455
|
+
return body;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=draw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw.js","sourceRoot":"","sources":["../../../src/daemon/draw.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-event git commits — SPEC.md §8's optional hardening (APRV-42).
|
|
3
|
+
*
|
|
4
|
+
* > "Optionally, the log directory is a git repo and the daemon commits per
|
|
5
|
+
* > event with its own identity, giving signed, distributed tamper evidence for
|
|
6
|
+
* > free."
|
|
7
|
+
*
|
|
8
|
+
* The chain in `events.jsonl` already detects mutation and truncation on its
|
|
9
|
+
* own. What a git repository adds is a *second, independent* record of the same
|
|
10
|
+
* bytes: a mutation that is plausible against one layer has to be plausible
|
|
11
|
+
* against the other at the same time, and the second layer is one an operator
|
|
12
|
+
* can clone, mirror, and diff from somewhere the tamperer does not control.
|
|
13
|
+
* Neither layer is trusted to police the other, which is the point of having
|
|
14
|
+
* two: `approval log verify` never consults git, and nothing here ever reads a
|
|
15
|
+
* verdict out of a commit.
|
|
16
|
+
*
|
|
17
|
+
* ## Opt-in, and only for a standalone log deployment
|
|
18
|
+
*
|
|
19
|
+
* This is off unless the operator asks for it, and refuses to turn on unless the
|
|
20
|
+
* log's own directory is a repository *root*. The two layouts do not mix:
|
|
21
|
+
*
|
|
22
|
+
* - **Standalone log deployment.** The log home (`.approval/`, or whatever
|
|
23
|
+
* directory holds the log when it is not under a `log/` folder) is its own git
|
|
24
|
+
* repository, containing the log, the payload store, and nothing else. Enable
|
|
25
|
+
* the opt-in here.
|
|
26
|
+
* - **Nested project layout** — this repository's own dogfood arrangement, where
|
|
27
|
+
* `.approval/` is committed as part of a larger project repo. Perfectly valid,
|
|
28
|
+
* and the opt-in is REFUSED for it.
|
|
29
|
+
*
|
|
30
|
+
* Why refuse the nested case rather than make it work? Because a hash chain does
|
|
31
|
+
* not survive a merge. Two branches that each append independently produce a
|
|
32
|
+
* chain that is corrupt by construction, and no merge strategy repairs the
|
|
33
|
+
* semantics. An outer repository's ordinary history operations — rebase, amend,
|
|
34
|
+
* squash, force-push, `filter-branch` — rewrite the very bytes the evidence is
|
|
35
|
+
* made of, and a daemon committing into someone else's branch would be a second
|
|
36
|
+
* writer to a history the project's humans also write. Evidence that the subject
|
|
37
|
+
* of the investigation can rewrite is not evidence. So the runtime does not try
|
|
38
|
+
* to be clever about it: own-root repository, or no git evidence at all.
|
|
39
|
+
*
|
|
40
|
+
* ## What it does, precisely
|
|
41
|
+
*
|
|
42
|
+
* After every tick in which the log moved, the daemon calls {@link
|
|
43
|
+
* GitEvidenceRecorder.commit} with the verified head it just read. The recorder
|
|
44
|
+
* stages the log file and the payload store, and commits with a message naming
|
|
45
|
+
* the head's `(seq, hash)`. Batching is **one commit per tick**, not literally
|
|
46
|
+
* one per event: ticks are the only moment the daemon has a verified head in
|
|
47
|
+
* hand, and a commit is only meaningful against a head that verified. A tick
|
|
48
|
+
* that observed three appends produces one commit naming the new head and the
|
|
49
|
+
* number of records it covers — the intermediate states are still fully
|
|
50
|
+
* recoverable from the log itself, which is the artifact being witnessed.
|
|
51
|
+
*
|
|
52
|
+
* ## What it deliberately does not do
|
|
53
|
+
*
|
|
54
|
+
* It never pushes, never fetches, never creates or moves a branch by name, never
|
|
55
|
+
* touches a remote, and never writes to any git config outside the single
|
|
56
|
+
* `git commit` invocation (identity is passed with `-c`, per command, so the
|
|
57
|
+
* operator's `user.name` is neither read into the commit nor overwritten on
|
|
58
|
+
* disk). Commits are local, to the log's own repository, authored by the daemon
|
|
59
|
+
* as itself. A failure to commit is a warning, never a stop: git evidence is
|
|
60
|
+
* hardening on top of the chain, and a daemon that halted approvals because a
|
|
61
|
+
* disk was full of git objects would have converted a redundancy into a
|
|
62
|
+
* dependency.
|
|
63
|
+
*/
|
|
64
|
+
import type { LogHead } from "../core/log.js";
|
|
65
|
+
/**
|
|
66
|
+
* The daemon's own git identity. Never the operator's: a commit that says a
|
|
67
|
+
* human made it is a false statement about who wrote the evidence, and the whole
|
|
68
|
+
* value of the second layer is that its authorship is unambiguous.
|
|
69
|
+
*
|
|
70
|
+
* The version is pinned to `package.json` by a test rather than read at runtime,
|
|
71
|
+
* because a module that resolves its own package root differs between the source
|
|
72
|
+
* tree and the build output for no benefit at all.
|
|
73
|
+
*/
|
|
74
|
+
export declare const APPROVALD_VERSION = "0.2.0";
|
|
75
|
+
/** `user.name` on every commit this module makes. */
|
|
76
|
+
export declare const GIT_EVIDENCE_AUTHOR_NAME = "approvald 0.2.0";
|
|
77
|
+
/** `user.email` on every commit: fixed, and deliberately undeliverable. */
|
|
78
|
+
export declare const GIT_EVIDENCE_AUTHOR_EMAIL = "approvald@noreply.approval.md";
|
|
79
|
+
/**
|
|
80
|
+
* Why enabling git evidence was refused. **Frozen union**, additive-only, in the
|
|
81
|
+
* same sense as every other refusal vocabulary in this codebase (SPEC.md §11.1
|
|
82
|
+
* invariant 6: refusals are machine-readable and distinct). An operator's
|
|
83
|
+
* supervisor branches on these to tell "install git" apart from "your layout is
|
|
84
|
+
* wrong", and the repair differs for every one of them.
|
|
85
|
+
*/
|
|
86
|
+
export declare const GIT_EVIDENCE_REFUSAL_CODES: readonly [
|
|
87
|
+
/** No usable `git` on PATH. The daemon runs fine without the opt-in. */
|
|
88
|
+
"git-unavailable",
|
|
89
|
+
/** The directory that would hold the evidence repository does not exist. */
|
|
90
|
+
"log-dir-missing",
|
|
91
|
+
/** It exists and is not a git repository. The repair is `git init` there. */
|
|
92
|
+
"log-dir-not-repo",
|
|
93
|
+
/**
|
|
94
|
+
* It is inside a working tree it does not own — either some outer repository
|
|
95
|
+
* tracks it, or it is a repository whose root is somewhere above. Hash chains
|
|
96
|
+
* do not survive merges and an outer history rewrites evidence.
|
|
97
|
+
*/
|
|
98
|
+
"log-dir-nested"];
|
|
99
|
+
export type GitEvidenceRefusalCode = (typeof GIT_EVIDENCE_REFUSAL_CODES)[number];
|
|
100
|
+
export interface GitEvidenceRefusal {
|
|
101
|
+
ok: false;
|
|
102
|
+
code: GitEvidenceRefusalCode;
|
|
103
|
+
message: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* One line of git-evidence output. Its own frozen shape, reported through the
|
|
107
|
+
* callback the CLI supplies, so that `daemon/daemon.ts`'s event union stays
|
|
108
|
+
* exactly as it was: the hardening layer speaks for itself and the loop's
|
|
109
|
+
* contract is untouched.
|
|
110
|
+
*/
|
|
111
|
+
export type GitEvidenceEvent = {
|
|
112
|
+
event: "git_evidence";
|
|
113
|
+
/** The abbreviated commit this tick produced. */
|
|
114
|
+
commit: string;
|
|
115
|
+
/** The verified head the commit witnesses. */
|
|
116
|
+
seq: number;
|
|
117
|
+
hash: string;
|
|
118
|
+
/**
|
|
119
|
+
* Log lines added since the commit this one builds on — the batch size.
|
|
120
|
+
* The log is append-only, so a line is a record. `null` only when git
|
|
121
|
+
* declined to say, which is a reporting gap and never a correctness one.
|
|
122
|
+
*/
|
|
123
|
+
records: number | null;
|
|
124
|
+
} | {
|
|
125
|
+
event: "git_evidence_failed";
|
|
126
|
+
/** The git invocation that failed, as a bare subcommand name. */
|
|
127
|
+
step: string;
|
|
128
|
+
message: string;
|
|
129
|
+
};
|
|
130
|
+
/** Where git-evidence output goes. Injected, so this module writes to nothing. */
|
|
131
|
+
export type GitEvidenceSink = (event: GitEvidenceEvent) => void;
|
|
132
|
+
/**
|
|
133
|
+
* The hook the daemon calls. One method, taking the verified head of the log it
|
|
134
|
+
* just read, so that the loop's edit is a single line and no scheduling
|
|
135
|
+
* knowledge leaks into this file.
|
|
136
|
+
*/
|
|
137
|
+
export interface GitEvidenceRecorder {
|
|
138
|
+
commit(head: LogHead | null): void;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The directory that must be the evidence repository's root, for a given log.
|
|
142
|
+
*
|
|
143
|
+
* The same rule `payloadStoreDirFor` uses, for the same reason: SPEC.md §9 fixes
|
|
144
|
+
* the log at `<home>/log/events.jsonl` and the payload store at
|
|
145
|
+
* `<home>/payloads/`, so the only directory that contains *both* is `<home>`.
|
|
146
|
+
* Rooting the repository at the log's immediate directory would leave every
|
|
147
|
+
* payload file outside the evidence, which is precisely where a tamperer would
|
|
148
|
+
* then work. When a caller points `--log` somewhere flatter, the log's own
|
|
149
|
+
* directory is the home and the rule still holds.
|
|
150
|
+
*/
|
|
151
|
+
export declare function evidenceRootFor(logPath: string): string;
|
|
152
|
+
export type EnableGitEvidenceResult = {
|
|
153
|
+
ok: true;
|
|
154
|
+
root: string;
|
|
155
|
+
recorder: GitEvidenceRecorder;
|
|
156
|
+
} | GitEvidenceRefusal;
|
|
157
|
+
/**
|
|
158
|
+
* Check every precondition and, when they all hold, build the recorder.
|
|
159
|
+
*
|
|
160
|
+
* Fail closed and fail *loudly*: each refusal is distinct, names the directory
|
|
161
|
+
* it judged, and states the repair. An operator who mistyped `--log` and an
|
|
162
|
+
* operator whose log lives inside a project repository need different sentences,
|
|
163
|
+
* and a single "git evidence unavailable" would have sent both of them looking
|
|
164
|
+
* in the wrong place.
|
|
165
|
+
*/
|
|
166
|
+
export declare function enableGitEvidence(logPath: string, sink: GitEvidenceSink): EnableGitEvidenceResult;
|
|
167
|
+
/**
|
|
168
|
+
* The commit message: the head's `(seq, hash)` on the subject line, so a reader
|
|
169
|
+
* of `git log --oneline` can check a commit against the chain without opening
|
|
170
|
+
* anything, and the batch size in the body so the per-tick batching is visible
|
|
171
|
+
* rather than inferred.
|
|
172
|
+
*/
|
|
173
|
+
export declare function message(head: LogHead, records: number | null): string;
|