approval-md 0.1.0 → 0.3.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/README.md +629 -559
- package/SPEC.md +99 -24
- package/dist/src/adapters/agentmail.d.ts +426 -0
- package/dist/src/adapters/agentmail.js +2 -2
- package/dist/src/adapters/conformance.d.ts +149 -0
- package/dist/src/adapters/contract.d.ts +628 -0
- package/dist/src/adapters/contract.js +110 -16
- package/dist/src/adapters/contract.js.map +1 -1
- package/dist/src/adapters/email.d.ts +324 -0
- package/dist/src/adapters/env-passphrase.d.ts +93 -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 +2 -1
- package/dist/src/adapters/registry.js.map +1 -1
- package/dist/src/adapters/smtp.d.ts +213 -0
- package/dist/src/adapters/vault-provider.d.ts +114 -0
- package/dist/src/adapters/vault-provider.js +3 -3
- 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/cli.d.ts +193 -0
- package/dist/src/channels/conformance.d.ts +92 -0
- package/dist/src/channels/contract.d.ts +656 -0
- package/dist/src/channels/contract.js +200 -7
- package/dist/src/channels/contract.js.map +1 -1
- package/dist/src/channels/payload-view.d.ts +35 -0
- package/dist/src/channels/render-queue.d.ts +149 -0
- package/dist/src/channels/tagging.d.ts +196 -0
- package/dist/src/channels/telegram.d.ts +1944 -0
- package/dist/src/channels/telegram.js +218 -23
- package/dist/src/channels/telegram.js.map +1 -1
- package/dist/src/channels/web.d.ts +350 -0
- package/dist/src/channels/web.js +17 -0
- package/dist/src/channels/web.js.map +1 -1
- package/dist/src/cli/adapter.d.ts +90 -0
- package/dist/src/cli/adapter.js +25 -15
- package/dist/src/cli/adapter.js.map +1 -1
- package/dist/src/cli/amend.d.ts +59 -0
- package/dist/src/cli/amend.js +214 -30
- package/dist/src/cli/amend.js.map +1 -1
- package/dist/src/cli/args.d.ts +43 -0
- package/dist/src/cli/attest.d.ts +50 -0
- package/dist/src/cli/attest.js +134 -7
- package/dist/src/cli/attest.js.map +1 -1
- package/dist/src/cli/audit-card.d.ts +62 -0
- package/dist/src/cli/audit.d.ts +59 -0
- package/dist/src/cli/channel-telegram.d.ts +879 -0
- package/dist/src/cli/channel-telegram.js +311 -13
- package/dist/src/cli/channel-telegram.js.map +1 -1
- package/dist/src/cli/channel-web.d.ts +131 -0
- package/dist/src/cli/channel.d.ts +80 -0
- package/dist/src/cli/channel.js +9 -0
- package/dist/src/cli/channel.js.map +1 -1
- package/dist/src/cli/checkpoint-tap.d.ts +169 -0
- package/dist/src/cli/codex-bridge.d.ts +819 -0
- package/dist/src/cli/codex-bridge.js +1607 -0
- package/dist/src/cli/codex-bridge.js.map +1 -0
- package/dist/src/cli/codex.d.ts +2 -0
- package/dist/src/cli/codex.js +469 -0
- package/dist/src/cli/codex.js.map +1 -0
- package/dist/src/cli/coverage.d.ts +61 -0
- package/dist/src/cli/daemon.d.ts +120 -0
- package/dist/src/cli/daemon.js +4 -1
- package/dist/src/cli/daemon.js.map +1 -1
- package/dist/src/cli/doctor.d.ts +129 -0
- package/dist/src/cli/doctor.js +586 -17
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/env.d.ts +65 -0
- package/dist/src/cli/execute.d.ts +202 -0
- package/dist/src/cli/execute.js +25 -2
- package/dist/src/cli/execute.js.map +1 -1
- package/dist/src/cli/exit-codes.d.ts +73 -0
- package/dist/src/cli/feedback.d.ts +60 -0
- package/dist/src/cli/gate-window.d.ts +40 -0
- package/dist/src/cli/gate.d.ts +68 -0
- package/dist/src/cli/git-scope.d.ts +190 -0
- package/dist/src/cli/gloss-attach.d.ts +85 -0
- package/dist/src/cli/gloss-codex-child.d.ts +9 -0
- package/dist/src/cli/gloss-codex.d.ts +24 -0
- package/dist/src/cli/gloss-options.d.ts +42 -0
- package/dist/src/cli/gloss.d.ts +265 -0
- package/dist/src/cli/help.d.ts +107 -0
- package/dist/src/cli/help.js +320 -93
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hook-codex.d.ts +126 -0
- package/dist/src/cli/hook-codex.js +226 -0
- package/dist/src/cli/hook-codex.js.map +1 -0
- package/dist/src/cli/hook.d.ts +787 -0
- package/dist/src/cli/hook.js +1235 -181
- package/dist/src/cli/hook.js.map +1 -1
- package/dist/src/cli/import.d.ts +35 -0
- package/dist/src/cli/import.js +1 -1
- package/dist/src/cli/import.js.map +1 -1
- package/dist/src/cli/init.d.ts +84 -0
- package/dist/src/cli/init.js +2 -2
- package/dist/src/cli/init.js.map +1 -1
- package/dist/src/cli/instructions.d.ts +23 -0
- package/dist/src/cli/journal.d.ts +41 -0
- package/dist/src/cli/log-advance.d.ts +287 -0
- package/dist/src/cli/log-advance.js +102 -11
- package/dist/src/cli/log-advance.js.map +1 -1
- package/dist/src/cli/log-anchor.d.ts +176 -0
- package/dist/src/cli/log-checkpoint.d.ts +22 -0
- package/dist/src/cli/log-sync.d.ts +243 -0
- package/dist/src/cli/log-verbs.d.ts +16 -0
- package/dist/src/cli/log-verbs.js +7 -1
- package/dist/src/cli/log-verbs.js.map +1 -1
- package/dist/src/cli/long-help.d.ts +70 -0
- package/dist/src/cli/main.d.ts +77 -0
- package/dist/src/cli/main.js +159 -7
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/mcp.d.ts +52 -0
- package/dist/src/cli/paths.d.ts +56 -0
- package/dist/src/cli/payload.d.ts +58 -0
- package/dist/src/cli/policy-apply.d.ts +195 -0
- package/dist/src/cli/policy-apply.js +573 -0
- package/dist/src/cli/policy-apply.js.map +1 -0
- package/dist/src/cli/policy.d.ts +43 -0
- package/dist/src/cli/policy.js +14 -1
- package/dist/src/cli/policy.js.map +1 -1
- package/dist/src/cli/preflight.d.ts +501 -0
- package/dist/src/cli/preflight.js +689 -45
- package/dist/src/cli/preflight.js.map +1 -1
- package/dist/src/cli/progress.d.ts +78 -0
- package/dist/src/cli/prompt.d.ts +209 -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/render.d.ts +22 -0
- package/dist/src/cli/sandbox.d.ts +51 -0
- package/dist/src/cli/sandbox.js +17 -1
- package/dist/src/cli/sandbox.js.map +1 -1
- package/dist/src/cli/scaffold.d.ts +79 -0
- package/dist/src/cli/scaffold.js +1 -1
- package/dist/src/cli/setup-adapter.d.ts +137 -0
- package/dist/src/cli/setup-adapter.js +38 -4
- package/dist/src/cli/setup-adapter.js.map +1 -1
- package/dist/src/cli/setup-channel.d.ts +126 -0
- package/dist/src/cli/setup-channel.js +28 -1
- package/dist/src/cli/setup-channel.js.map +1 -1
- package/dist/src/cli/setup-checkpoint.d.ts +57 -0
- package/dist/src/cli/setup-common.d.ts +277 -0
- package/dist/src/cli/setup-common.js +3 -2
- package/dist/src/cli/setup-common.js.map +1 -1
- package/dist/src/cli/setup-flow.d.ts +287 -0
- package/dist/src/cli/setup-service.d.ts +96 -0
- package/dist/src/cli/setup.d.ts +204 -0
- package/dist/src/cli/setup.js +94 -2
- package/dist/src/cli/setup.js.map +1 -1
- package/dist/src/cli/style.d.ts +320 -0
- package/dist/src/cli/token.d.ts +39 -0
- package/dist/src/cli/up.d.ts +155 -0
- package/dist/src/cli/up.js +119 -53
- package/dist/src/cli/up.js.map +1 -1
- package/dist/src/cli/usage.d.ts +37 -0
- package/dist/src/cli/values.d.ts +40 -0
- package/dist/src/cli/values.js +3 -4
- package/dist/src/cli/values.js.map +1 -1
- package/dist/src/cli/vault.d.ts +59 -0
- package/dist/src/cli/vault.js +2 -2
- package/dist/src/cli/vault.js.map +1 -1
- package/dist/src/cli/verb-registry.d.ts +76 -0
- package/dist/src/cli/verb-registry.js +344 -11
- package/dist/src/cli/verb-registry.js.map +1 -1
- package/dist/src/cli/wordmark.d.ts +31 -0
- package/dist/src/cli/wordmark.js +2 -2
- package/dist/src/codex/broker.d.ts +229 -0
- package/dist/src/codex/broker.js +548 -0
- package/dist/src/codex/broker.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/runner.d.ts +178 -0
- package/dist/src/codex/runner.js +231 -0
- package/dist/src/codex/runner.js.map +1 -0
- package/dist/src/codex/serve.d.ts +56 -0
- package/dist/src/codex/serve.js +98 -0
- package/dist/src/codex/serve.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-commit.d.ts +219 -0
- package/dist/src/codex/workspace-commit.js +549 -0
- package/dist/src/codex/workspace-commit.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 +221 -0
- package/dist/src/core/advance-cycle.js +66 -2
- package/dist/src/core/advance-cycle.js.map +1 -1
- package/dist/src/core/agents-md.d.ts +278 -0
- package/dist/src/core/agents-md.js +33 -31
- package/dist/src/core/agents-md.js.map +1 -1
- 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 +635 -0
- package/dist/src/core/attest.js +326 -4
- package/dist/src/core/attest.js.map +1 -1
- package/dist/src/core/audit.d.ts +510 -0
- package/dist/src/core/audit.js +13 -0
- package/dist/src/core/audit.js.map +1 -1
- package/dist/src/core/budgets.d.ts +238 -0
- package/dist/src/core/channel-owner.d.ts +213 -0
- package/dist/src/core/channel-owner.js +358 -0
- package/dist/src/core/channel-owner.js.map +1 -0
- package/dist/src/core/checkpoint.d.ts +500 -0
- package/dist/src/core/child-env.d.ts +88 -0
- package/dist/src/core/clock.d.ts +52 -0
- package/dist/src/core/command-class.d.ts +697 -0
- package/dist/src/core/command-class.js +713 -25
- package/dist/src/core/command-class.js.map +1 -1
- package/dist/src/core/commit-guard.d.ts +272 -0
- package/dist/src/core/commit-guard.js +424 -0
- package/dist/src/core/commit-guard.js.map +1 -0
- package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
- package/dist/src/core/coverage-sources/gh.d.ts +48 -0
- package/dist/src/core/coverage-sources/git.d.ts +101 -0
- package/dist/src/core/coverage.d.ts +217 -0
- package/dist/src/core/credential-spec.d.ts +72 -0
- package/dist/src/core/daemon-actor.d.ts +45 -0
- package/dist/src/core/daemon-actor.js +54 -0
- package/dist/src/core/daemon-actor.js.map +1 -0
- package/dist/src/core/dark-session.d.ts +432 -0
- package/dist/src/core/dark-session.js +266 -82
- package/dist/src/core/dark-session.js.map +1 -1
- package/dist/src/core/decision-refusal.d.ts +206 -0
- package/dist/src/core/decision-refusal.js +24 -2
- package/dist/src/core/decision-refusal.js.map +1 -1
- package/dist/src/core/env-file.d.ts +455 -0
- package/dist/src/core/env-file.js +60 -1
- package/dist/src/core/env-file.js.map +1 -1
- package/dist/src/core/execute.d.ts +871 -0
- package/dist/src/core/execute.js +59 -8
- package/dist/src/core/execute.js.map +1 -1
- package/dist/src/core/frontmatter.d.ts +78 -0
- package/dist/src/core/gate-window.d.ts +312 -0
- package/dist/src/core/gate.d.ts +1449 -0
- package/dist/src/core/gate.js +149 -14
- package/dist/src/core/gate.js.map +1 -1
- package/dist/src/core/gesture-refusal.d.ts +166 -0
- package/dist/src/core/gesture-refusal.js +188 -0
- package/dist/src/core/gesture-refusal.js.map +1 -0
- package/dist/src/core/git-run.d.ts +73 -0
- package/dist/src/core/harness-version.d.ts +157 -0
- package/dist/src/core/harness-version.js +4 -1
- package/dist/src/core/harness-version.js.map +1 -1
- package/dist/src/core/harness-wait.d.ts +55 -0
- package/dist/src/core/head-retry.d.ts +107 -0
- package/dist/src/core/instance.d.ts +310 -0
- package/dist/src/core/instance.js +113 -0
- package/dist/src/core/instance.js.map +1 -1
- package/dist/src/core/intake-limits.d.ts +247 -0
- package/dist/src/core/jcs.d.ts +52 -0
- package/dist/src/core/journal.d.ts +144 -0
- package/dist/src/core/live-draw.d.ts +436 -0
- package/dist/src/core/log-reconcile.d.ts +89 -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 +316 -0
- package/dist/src/core/log.js.map +1 -1
- package/dist/src/core/loop.d.ts +274 -0
- package/dist/src/core/loop.js +11 -0
- package/dist/src/core/loop.js.map +1 -1
- package/dist/src/core/md-fence.d.ts +41 -0
- package/dist/src/core/money.d.ts +147 -0
- package/dist/src/core/payload-census.d.ts +74 -0
- package/dist/src/core/payload-store.d.ts +175 -0
- package/dist/src/core/payload.d.ts +71 -0
- package/dist/src/core/policy-diff.d.ts +292 -0
- package/dist/src/core/policy-diff.js +27 -4
- package/dist/src/core/policy-diff.js.map +1 -1
- package/dist/src/core/policy-expectations.d.ts +199 -0
- package/dist/src/core/policy-explain.d.ts +160 -0
- package/dist/src/core/policy-explain.js +63 -3
- package/dist/src/core/policy-explain.js.map +1 -1
- package/dist/src/core/policy-load.d.ts +567 -0
- package/dist/src/core/policy-load.js +36 -6
- package/dist/src/core/policy-load.js.map +1 -1
- package/dist/src/core/policy-match.d.ts +324 -0
- package/dist/src/core/policy-match.js +72 -9
- package/dist/src/core/policy-match.js.map +1 -1
- package/dist/src/core/policy-proposal.d.ts +317 -0
- package/dist/src/core/policy-proposal.js +102 -2
- package/dist/src/core/policy-proposal.js.map +1 -1
- package/dist/src/core/prompt-layout.d.ts +221 -0
- package/dist/src/core/protected-path-guard.d.ts +566 -0
- package/dist/src/core/protected-path-guard.js +848 -55
- package/dist/src/core/protected-path-guard.js.map +1 -1
- package/dist/src/core/question-preempted.d.ts +141 -0
- package/dist/src/core/question-preempted.js +152 -0
- package/dist/src/core/question-preempted.js.map +1 -0
- package/dist/src/core/read-scope.d.ts +172 -0
- package/dist/src/core/read-scope.js +252 -0
- package/dist/src/core/read-scope.js.map +1 -0
- package/dist/src/core/registration.d.ts +25 -0
- package/dist/src/core/reindex.d.ts +99 -0
- package/dist/src/core/sampler.d.ts +313 -0
- package/dist/src/core/sandbox.d.ts +371 -0
- package/dist/src/core/sandbox.js +190 -1
- package/dist/src/core/sandbox.js.map +1 -1
- package/dist/src/core/seal.d.ts +165 -0
- package/dist/src/core/sender-identity.d.ts +476 -0
- package/dist/src/core/sender-identity.js +572 -0
- package/dist/src/core/sender-identity.js.map +1 -0
- package/dist/src/core/shlex.d.ts +102 -0
- package/dist/src/core/shlex.js +159 -0
- package/dist/src/core/shlex.js.map +1 -0
- package/dist/src/core/state.d.ts +505 -0
- package/dist/src/core/task-file.d.ts +185 -0
- package/dist/src/core/telegram-config.d.ts +93 -0
- package/dist/src/core/token.d.ts +409 -0
- package/dist/src/core/token.js +21 -38
- package/dist/src/core/token.js.map +1 -1
- package/dist/src/core/validate.d.ts +138 -0
- package/dist/src/core/values.d.ts +147 -0
- package/dist/src/core/values.js +36 -1
- package/dist/src/core/values.js.map +1 -1
- package/dist/src/core/vault.d.ts +291 -0
- package/dist/src/core/verified-snapshot.d.ts +204 -0
- package/dist/src/core/verify.d.ts +336 -0
- package/dist/src/core/version.d.ts +8 -0
- package/dist/src/core/wysiwys.d.ts +370 -0
- package/dist/src/daemon/advance-child.d.ts +39 -0
- package/dist/src/daemon/advance.d.ts +476 -0
- package/dist/src/daemon/advance.js +25 -4
- package/dist/src/daemon/advance.js.map +1 -1
- package/dist/src/daemon/audit.d.ts +87 -0
- package/dist/src/daemon/daemon.d.ts +1180 -0
- package/dist/src/daemon/daemon.js +9 -0
- package/dist/src/daemon/daemon.js.map +1 -1
- package/dist/src/daemon/dark-session.d.ts +64 -0
- package/dist/src/daemon/draw-child.d.ts +36 -0
- package/dist/src/daemon/draw.d.ts +154 -0
- package/dist/src/daemon/git-evidence.d.ts +173 -0
- package/dist/src/daemon/git-evidence.js +1 -1
- package/dist/src/daemon/projection.d.ts +180 -0
- package/dist/src/daemon/prune.d.ts +207 -0
- package/dist/src/mcp/http.d.ts +113 -0
- package/dist/src/mcp/server.d.ts +265 -0
- package/dist/src/mcp/server.js +17 -1
- package/dist/src/mcp/server.js.map +1 -1
- package/docs/adapter-api.md +106 -0
- package/docs/cli-reference.md +1316 -63
- package/docs/codex-enforced-session.md +103 -0
- package/docs/codex-workspace-broker.md +118 -0
- package/package.json +14 -2
- package/schema/codex-instance.schema.json +82 -0
- package/schema/event.schema.json +539 -9
- 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/event/invalid/approval-granted-sender-hashed-false.json +20 -0
- package/schema/fixtures/event/invalid/approval-granted-sender-hashed-raw-id.json +20 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-human-actor.json +16 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-no-actor-no-sender.json +15 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-unknown-gesture.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-agent-actor.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-no-question-id.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-unknown-source.json +15 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-absolute-path.json +14 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-agent-actor.json +14 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-missing-path.json +13 -0
- package/schema/fixtures/event/valid/approval-granted-sender-hashed.json +20 -0
- package/schema/fixtures/event/valid/audit-gesture-refused-review-note.json +21 -0
- package/schema/fixtures/event/valid/audit-gesture-refused-sender-key-unavailable.json +19 -0
- package/schema/fixtures/event/valid/audit-gesture-refused.json +19 -0
- package/schema/fixtures/event/valid/audit-question-preempted-no-verdict.json +16 -0
- package/schema/fixtures/event/valid/audit-question-preempted.json +20 -0
- package/schema/fixtures/event/valid/gate-path-signed-off.json +14 -0
- package/schema/fixtures/event/valid/harness-kind-claude-code.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-codex.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-cursor.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-grok.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-muse.json +23 -0
- package/schema/fixtures/policy/invalid/senders-half-keyed.json +20 -0
- package/schema/fixtures/policy/valid/canonical.json +1 -1
- package/schema/fixtures/policy/valid/senders-keyed.json +24 -0
- package/schema/fixtures/policy-md/valid/canonical.md +1 -1
- package/schema/fixtures/policy-md/valid/with-values.md +5 -7
- package/schema/fixtures/values/invalid/class-shaped.json +1 -1
- package/schema/fixtures/values/invalid/duplicate-entry.json +1 -1
- package/schema/fixtures/values/invalid/non-string-item.json +1 -1
- package/schema/fixtures/values/invalid/over-cap.json +1 -1
- package/schema/fixtures/values/invalid/unknown-key.json +1 -1
- package/schema/fixtures/values/invalid/version-float.json +1 -0
- package/schema/fixtures/values/invalid/version-integer.json +1 -0
- package/schema/fixtures/values/invalid/version-wrong-string.json +1 -0
- package/schema/fixtures/values/valid/empty-lists.json +2 -3
- package/schema/fixtures/values/valid/full.json +5 -7
- package/schema/fixtures/values/valid/minimal.json +1 -1
- package/schema/fixtures/values-md/invalid/schema-invalid.md +5 -3
- package/schema/fixtures/values-md/invalid/two-blocks.md +3 -3
- package/schema/fixtures/values-md/invalid/unterminated.md +2 -2
- package/schema/fixtures/values-md/invalid/version-1.md +69 -0
- package/schema/fixtures/values-md/invalid/version-unquoted.md +64 -0
- package/schema/fixtures/values-md/invalid/yaml-error.md +2 -2
- package/schema/fixtures/values-md/valid/absent.md +1 -1
- package/schema/fixtures/values-md/valid/with-values.md +5 -7
- package/schema/policy.schema.json +75 -3
- package/schema/values.schema.json +7 -11
- package/templates/codex/README.md +9 -0
- package/schema/fixtures/values/invalid/version-string.json +0 -1
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `approval quickstart` (APRV-309): one human ceremony for a small, operative
|
|
3
|
+
* policy. The command is terminal-only, displays the exact bytes it will
|
|
4
|
+
* attest, and leaves any interrupted setup unattested.
|
|
5
|
+
*/
|
|
6
|
+
import { spawn } from "node:child_process";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { isAbsolute, join, resolve as resolvePathSegments } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { appendAttestation, HUMAN_ACTOR_ENV, policyBytesHash } from "../core/attest.js";
|
|
11
|
+
import { SECRET_ENV_PREFIXES } from "../core/child-env.js";
|
|
12
|
+
import { defaultSourceRunner, envFilePathFor, resolveEnvironment, upsertEnvFileEntries, } from "../core/env-file.js";
|
|
13
|
+
import { loadPolicy, loadPolicyText } from "../core/policy-load.js";
|
|
14
|
+
import { parseFlags, boolFlag, stringFlag } from "./args.js";
|
|
15
|
+
import { EXIT_INTEGRITY, EXIT_IO, EXIT_OK, EXIT_TORN_TAIL, EXIT_USAGE } from "./exit-codes.js";
|
|
16
|
+
import { QUICKSTART_HELP } from "./help.js";
|
|
17
|
+
import { commandInit } from "./init.js";
|
|
18
|
+
import { DEFAULT_LOG_PATH } from "./paths.js";
|
|
19
|
+
import { askUntil, createPrompter } from "./prompt.js";
|
|
20
|
+
import { commandSetupChannel } from "./setup-channel.js";
|
|
21
|
+
import { identityFromAnswer } from "./setup.js";
|
|
22
|
+
import { usageErrorText } from "./usage.js";
|
|
23
|
+
const FLAGS = {
|
|
24
|
+
"--dir": "string",
|
|
25
|
+
"--api-base": "string",
|
|
26
|
+
"--json": "boolean",
|
|
27
|
+
"--help": "boolean",
|
|
28
|
+
"-h": "boolean",
|
|
29
|
+
};
|
|
30
|
+
export const QUICKSTART_CLASSES = [
|
|
31
|
+
{ pattern: "communicate.*", label: "send a message or email" },
|
|
32
|
+
{ pattern: "financial.*", label: "spend money" },
|
|
33
|
+
{ pattern: "files.delete.*", label: "delete files" },
|
|
34
|
+
{ pattern: "public.*", label: "post publicly" },
|
|
35
|
+
{ pattern: "vcs.push.main", label: "push to main" },
|
|
36
|
+
];
|
|
37
|
+
const DOCTOR_TIMEOUT_MS = 20_000;
|
|
38
|
+
const DOCTOR_OUTPUT_LIMIT_BYTES = 256 * 1024;
|
|
39
|
+
function absolute(value, cwd) {
|
|
40
|
+
return isAbsolute(value) ? value : resolvePathSegments(cwd, value);
|
|
41
|
+
}
|
|
42
|
+
function refusal(streams, message) {
|
|
43
|
+
streams.err(usageErrorText(message, QUICKSTART_HELP));
|
|
44
|
+
return EXIT_USAGE;
|
|
45
|
+
}
|
|
46
|
+
function shellQuote(value) {
|
|
47
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
48
|
+
}
|
|
49
|
+
function nonInteractive(streams, json) {
|
|
50
|
+
const message = "quickstart needs a human at a terminal and has no JSON mode. Non-interactive equivalent: run `approval init`, write and review APPROVAL.md, run `approval setup identity`, optionally run `approval setup channel telegram`, then run `approval policy attest --as human:<id>`.";
|
|
51
|
+
if (json)
|
|
52
|
+
streams.err(`${JSON.stringify({ error: { code: "usage", message } })}\n`);
|
|
53
|
+
else
|
|
54
|
+
streams.err(usageErrorText(message, QUICKSTART_HELP));
|
|
55
|
+
return EXIT_USAGE;
|
|
56
|
+
}
|
|
57
|
+
function channelAnswer(answer) {
|
|
58
|
+
switch (answer.trim().toLowerCase()) {
|
|
59
|
+
case "1":
|
|
60
|
+
case "terminal":
|
|
61
|
+
case "cli":
|
|
62
|
+
return { ok: true, value: "cli" };
|
|
63
|
+
case "2":
|
|
64
|
+
case "telegram":
|
|
65
|
+
return { ok: true, value: "telegram" };
|
|
66
|
+
default:
|
|
67
|
+
return { ok: false, reason: "choose 1 for this terminal or 2 for Telegram" };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function classesAnswer(answer) {
|
|
71
|
+
const typed = answer.trim().toLowerCase();
|
|
72
|
+
if (typed.length === 0 || typed === "all") {
|
|
73
|
+
return { ok: true, value: QUICKSTART_CLASSES.map((entry) => entry.pattern) };
|
|
74
|
+
}
|
|
75
|
+
if (typed === "none")
|
|
76
|
+
return { ok: true, value: [] };
|
|
77
|
+
const indexes = typed.split(",").map((part) => Number(part.trim()));
|
|
78
|
+
if (indexes.some((index) => !Number.isInteger(index) || index < 1 || index > QUICKSTART_CLASSES.length)) {
|
|
79
|
+
return { ok: false, reason: "enter comma-separated numbers 1-5, all, none, or press Enter for all" };
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
ok: true,
|
|
83
|
+
value: [...new Set(indexes)].map((index) => QUICKSTART_CLASSES[index - 1]?.pattern),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function quickstartIdentity(answer) {
|
|
87
|
+
const parsed = identityFromAnswer(answer);
|
|
88
|
+
if (!parsed.ok)
|
|
89
|
+
return parsed;
|
|
90
|
+
const humanId = parsed.value.slice("human:".length);
|
|
91
|
+
return /^[a-z0-9][a-z0-9_-]*$/u.test(humanId)
|
|
92
|
+
? parsed
|
|
93
|
+
: { ok: false, reason: "the id must start with a lowercase letter or digit and contain only lowercase letters, digits, _ or -" };
|
|
94
|
+
}
|
|
95
|
+
export function renderSoloPolicy(humanId, channel, patterns) {
|
|
96
|
+
const rules = patterns
|
|
97
|
+
.map((pattern) => ` ${pattern}:\n autonomy: manual\n approvers: [${humanId}]`)
|
|
98
|
+
.join("\n");
|
|
99
|
+
const channelBlock = channel === "telegram"
|
|
100
|
+
? "\nchannels:\n telegram:\n chat_id_env: APPROVAL_TG_CHAT\n token_env: APPROVAL_TG_TOKEN\n"
|
|
101
|
+
: "";
|
|
102
|
+
return `# Approval Policy\n\nThis is a solo policy. The selected class families ask the person below.\nOther classified reversible actions use the autonomous default. Runtime safety\nfloors and unclassified-command refusals still apply.\n\n\`\`\`yaml approval-policy\nversion: "0.1"\n\ndefaults:\n autonomy: autonomous # Tighten to manual to make every unnamed class ask.\n channel: ${channel}\n approval_ttl: 24h\n on_expiry: reject\n\napprovers:\n ${humanId}:\n channels: [${channel}]\n\nclasses:\n${rules.length === 0 ? " {}" : rules}\n${channelBlock}\`\`\`\n\nNo audit block means retrospective sampling is off. Add one only through a\nhuman-reviewed policy amendment; see \`approval policy amend --help\`.\n`;
|
|
103
|
+
}
|
|
104
|
+
function appendBounded(current, chunk, limit) {
|
|
105
|
+
const remaining = limit - Buffer.byteLength(current);
|
|
106
|
+
if (remaining <= 0)
|
|
107
|
+
return { text: current, overflow: true };
|
|
108
|
+
const bytes = Buffer.from(chunk);
|
|
109
|
+
if (bytes.byteLength <= remaining)
|
|
110
|
+
return { text: current + chunk, overflow: false };
|
|
111
|
+
return { text: current + bytes.subarray(0, remaining).toString("utf8"), overflow: true };
|
|
112
|
+
}
|
|
113
|
+
export function runQuickstartDoctor(dir, actor, resolvedEnv, apiBase, options = {}) {
|
|
114
|
+
return new Promise((resolve) => {
|
|
115
|
+
const env = { ...process.env };
|
|
116
|
+
// The check must not borrow identity or credentials from another instance.
|
|
117
|
+
// Only values explicitly resolved from this quickstart's source map return.
|
|
118
|
+
for (const name of Object.keys(env)) {
|
|
119
|
+
if (SECRET_ENV_PREFIXES.some((prefix) => name.startsWith(prefix)))
|
|
120
|
+
delete env[name];
|
|
121
|
+
}
|
|
122
|
+
Object.assign(env, resolvedEnv, { [HUMAN_ACTOR_ENV]: actor });
|
|
123
|
+
const cliEntry = fileURLToPath(new URL("./main.js", import.meta.url));
|
|
124
|
+
const childArgs = [cliEntry, "doctor", "--json", "--dir", dir];
|
|
125
|
+
if (apiBase !== null)
|
|
126
|
+
childArgs.push("--api-base", apiBase);
|
|
127
|
+
const child = (options.spawnChild ?? spawn)(process.execPath, childArgs, {
|
|
128
|
+
cwd: dir,
|
|
129
|
+
env,
|
|
130
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
131
|
+
});
|
|
132
|
+
let stdout = "";
|
|
133
|
+
let stderr = "";
|
|
134
|
+
let settled = false;
|
|
135
|
+
const outputLimit = options.outputLimitBytes ?? DOCTOR_OUTPUT_LIMIT_BYTES;
|
|
136
|
+
const finish = (result) => {
|
|
137
|
+
if (settled)
|
|
138
|
+
return;
|
|
139
|
+
settled = true;
|
|
140
|
+
clearTimeout(timer);
|
|
141
|
+
resolve(result);
|
|
142
|
+
};
|
|
143
|
+
const abortForOutput = () => {
|
|
144
|
+
child.kill("SIGTERM");
|
|
145
|
+
finish({ code: EXIT_IO, stdout, stderr: `${stderr}approval doctor output exceeded ${String(outputLimit)} bytes and was stopped\n` });
|
|
146
|
+
};
|
|
147
|
+
child.stdout.setEncoding("utf8");
|
|
148
|
+
child.stderr.setEncoding("utf8");
|
|
149
|
+
child.stdout.on("data", (text) => {
|
|
150
|
+
const next = appendBounded(stdout, text, outputLimit);
|
|
151
|
+
stdout = next.text;
|
|
152
|
+
if (next.overflow)
|
|
153
|
+
abortForOutput();
|
|
154
|
+
});
|
|
155
|
+
child.stderr.on("data", (text) => {
|
|
156
|
+
const next = appendBounded(stderr, text, outputLimit);
|
|
157
|
+
stderr = next.text;
|
|
158
|
+
if (next.overflow)
|
|
159
|
+
abortForOutput();
|
|
160
|
+
});
|
|
161
|
+
child.once("error", (cause) => finish({ code: EXIT_IO, stdout, stderr: `${stderr}${cause.message}\n` }));
|
|
162
|
+
child.once("close", (code) => finish({ code: code ?? EXIT_IO, stdout, stderr }));
|
|
163
|
+
const timer = setTimeout(() => {
|
|
164
|
+
child.kill("SIGTERM");
|
|
165
|
+
finish({ code: EXIT_IO, stdout, stderr: `${stderr}approval doctor exceeded ${String(options.timeoutMs ?? DOCTOR_TIMEOUT_MS)}ms and was stopped\n` });
|
|
166
|
+
}, options.timeoutMs ?? DOCTOR_TIMEOUT_MS);
|
|
167
|
+
timer.unref();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function doctorPreflight(run) {
|
|
171
|
+
if (run.code === EXIT_OK)
|
|
172
|
+
return { ok: true };
|
|
173
|
+
if (run.code === EXIT_INTEGRITY) {
|
|
174
|
+
try {
|
|
175
|
+
const report = JSON.parse(run.stdout);
|
|
176
|
+
const failed = report.checks?.filter((check) => check.status === "fail") ?? [];
|
|
177
|
+
if (failed.length === 1 &&
|
|
178
|
+
failed[0]?.check === "attestation" &&
|
|
179
|
+
typeof failed[0].detail === "string" &&
|
|
180
|
+
failed[0].detail.includes("has never been attested"))
|
|
181
|
+
return { ok: true };
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// The diagnostic's malformed output is reported below with its exit.
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
ok: false,
|
|
189
|
+
code: run.code,
|
|
190
|
+
message: `approval doctor preflight reported a setup problem; the policy remains unattested:\n${run.stderr}${run.stdout}`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export async function commandQuickstart(argv, streams, cwd, deps = {}) {
|
|
194
|
+
const json = argv.includes("--json");
|
|
195
|
+
const parsed = parseFlags(argv, FLAGS);
|
|
196
|
+
if (!parsed.ok)
|
|
197
|
+
return refusal(streams, parsed.message);
|
|
198
|
+
if (boolFlag(parsed.flags, "--help") || boolFlag(parsed.flags, "-h")) {
|
|
199
|
+
streams.out(`${QUICKSTART_HELP}\n`);
|
|
200
|
+
return EXIT_OK;
|
|
201
|
+
}
|
|
202
|
+
if (parsed.positionals.length > 0)
|
|
203
|
+
return refusal(streams, `unexpected argument ${JSON.stringify(parsed.positionals[0])}`);
|
|
204
|
+
const prompter = deps.prompter === undefined ? createPrompter(streams) : deps.prompter;
|
|
205
|
+
if (json || prompter === null)
|
|
206
|
+
return nonInteractive(streams, json);
|
|
207
|
+
const dirFlag = stringFlag(parsed.flags, "--dir");
|
|
208
|
+
const dir = dirFlag === null ? cwd : absolute(dirFlag, cwd);
|
|
209
|
+
const apiBase = stringFlag(parsed.flags, "--api-base");
|
|
210
|
+
if (existsSync(join(dir, "APPROVAL.md")) ||
|
|
211
|
+
existsSync(join(dir, "APPROVALS.md")) ||
|
|
212
|
+
existsSync(join(dir, ".approval"))) {
|
|
213
|
+
streams.err(`approval: setup artifacts already exist in ${dir}; quickstart only initializes a fresh instance and changed nothing\n`);
|
|
214
|
+
return EXIT_IO;
|
|
215
|
+
}
|
|
216
|
+
streams.out("approval quickstart — three decisions to make a solo gate operative.\n\n");
|
|
217
|
+
const identity = askUntil(streams, prompter, "1/3 your name (for human:<id>): ", quickstartIdentity);
|
|
218
|
+
if (!identity.ok)
|
|
219
|
+
return refusal(streams, "no valid human identity was entered; nothing was written");
|
|
220
|
+
const actor = identity.value;
|
|
221
|
+
const humanId = actor.slice("human:".length);
|
|
222
|
+
const channel = askUntil(streams, prompter, "2/3 button location (1 terminal, 2 Telegram): ", channelAnswer);
|
|
223
|
+
if (!channel.ok)
|
|
224
|
+
return refusal(streams, "no channel was chosen; nothing was written");
|
|
225
|
+
streams.out(`${QUICKSTART_CLASSES.map((entry, index) => ` ${String(index + 1)}. ${entry.label}`).join("\n")}\n`);
|
|
226
|
+
const selected = askUntil(streams, prompter, "3/3 always ask (numbers, Enter for all): ", classesAnswer);
|
|
227
|
+
if (!selected.ok)
|
|
228
|
+
return refusal(streams, "no valid checklist was entered; nothing was written");
|
|
229
|
+
const policy = renderSoloPolicy(humanId, channel.value, selected.value);
|
|
230
|
+
const loaded = loadPolicyText(join(dir, "APPROVAL.md"), policy);
|
|
231
|
+
if (!loaded.ok) {
|
|
232
|
+
streams.err(`approval: generated policy failed validation: ${loaded.message}\n`);
|
|
233
|
+
return EXIT_IO;
|
|
234
|
+
}
|
|
235
|
+
let initOut = "";
|
|
236
|
+
let initErr = "";
|
|
237
|
+
const initCode = commandInit([], { out: (text) => { initOut += text; }, err: (text) => { initErr += text; } }, dir, { policyText: policy });
|
|
238
|
+
if (initCode !== EXIT_OK) {
|
|
239
|
+
streams.err(`${initErr}${initOut}`);
|
|
240
|
+
return initCode;
|
|
241
|
+
}
|
|
242
|
+
const envPath = envFilePathFor(join(dir, DEFAULT_LOG_PATH));
|
|
243
|
+
const envWrite = upsertEnvFileEntries(envPath, [{ key: HUMAN_ACTOR_ENV, value: actor }]);
|
|
244
|
+
if (!envWrite.ok) {
|
|
245
|
+
streams.err(`approval: ${envWrite.message}\n`);
|
|
246
|
+
return EXIT_IO;
|
|
247
|
+
}
|
|
248
|
+
if (channel.value === "telegram") {
|
|
249
|
+
const setupArgs = ["telegram", "--as", actor, "--dir", dir];
|
|
250
|
+
if (apiBase !== null)
|
|
251
|
+
setupArgs.push("--api-base", apiBase);
|
|
252
|
+
const setupCode = await commandSetupChannel(setupArgs, streams, dir, { ...deps.setup, prompter });
|
|
253
|
+
if (setupCode !== EXIT_OK)
|
|
254
|
+
return setupCode;
|
|
255
|
+
}
|
|
256
|
+
const onDisk = loadPolicy({ dir });
|
|
257
|
+
if (!onDisk.ok) {
|
|
258
|
+
streams.err(`approval: generated policy could not be reloaded for preflight: ${onDisk.message}\n`);
|
|
259
|
+
return EXIT_IO;
|
|
260
|
+
}
|
|
261
|
+
const resolution = resolveEnvironment(onDisk, envPath, deps.sourceRunner ?? defaultSourceRunner, {});
|
|
262
|
+
if (!resolution.ok) {
|
|
263
|
+
streams.err(`approval: quickstart environment could not be resolved: ${resolution.message}\n`);
|
|
264
|
+
return EXIT_IO;
|
|
265
|
+
}
|
|
266
|
+
const resolvedEnv = {};
|
|
267
|
+
for (const variable of resolution.variables) {
|
|
268
|
+
if (variable.value !== undefined)
|
|
269
|
+
resolvedEnv[variable.name] = variable.value;
|
|
270
|
+
else if (variable.declared) {
|
|
271
|
+
streams.err(`approval: ${variable.name} could not be resolved from this instance (${variable.source}); the policy remains unattested\n`);
|
|
272
|
+
return EXIT_IO;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const doctor = await (deps.doctor ?? runQuickstartDoctor)(dir, actor, resolvedEnv, apiBase);
|
|
276
|
+
const preflight = doctorPreflight(doctor);
|
|
277
|
+
if (!preflight.ok) {
|
|
278
|
+
streams.err(preflight.message);
|
|
279
|
+
return preflight.code;
|
|
280
|
+
}
|
|
281
|
+
streams.out(`\nReview the exact policy that will become operative:\n\n${policy}\n`);
|
|
282
|
+
const understood = askUntil(streams, prompter, "type understood to attest these exact bytes: ", (answer) => answer.trim() === "understood"
|
|
283
|
+
? { ok: true, value: true }
|
|
284
|
+
: { ok: false, reason: "type understood exactly, or Ctrl-D to leave the policy unattested" });
|
|
285
|
+
if (!understood.ok)
|
|
286
|
+
return refusal(streams, "policy left unattested");
|
|
287
|
+
const attestation = appendAttestation(join(dir, DEFAULT_LOG_PATH), join(dir, "APPROVAL.md"), actor, { expectedSha256: policyBytesHash(Buffer.from(policy, "utf8")) });
|
|
288
|
+
if (!attestation.ok) {
|
|
289
|
+
streams.err(`approval: ${attestation.error.message}\n`);
|
|
290
|
+
return attestation.error.code === "corrupt-tail" ? EXIT_TORN_TAIL : EXIT_IO;
|
|
291
|
+
}
|
|
292
|
+
streams.out(`ready: ${String(selected.value.length)} selected class families ask ${actor} on ${channel.value}; other classified reversible actions use the autonomous default\n`);
|
|
293
|
+
streams.out(`activate: eval "$(approval env --dir ${shellQuote(dir)})"\n`);
|
|
294
|
+
streams.out("try: approval hook classify -- curl -X POST https://api.example.com/apply\n");
|
|
295
|
+
return EXIT_OK;
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=quickstart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.js","sourceRoot":"","sources":["../../../src/cli/quickstart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading stored lines back out of the log, for `tail` and `export`.
|
|
3
|
+
*
|
|
4
|
+
* Read-only in the strictest sense: this module opens the file once for
|
|
5
|
+
* reading and returns the *stored bytes* of each complete line. It never
|
|
6
|
+
* re-serializes, never normalizes, never repairs. `export` is required to be
|
|
7
|
+
* byte-faithful, and the cheapest way to guarantee that is never to have a
|
|
8
|
+
* parsed object on the write path at all.
|
|
9
|
+
*
|
|
10
|
+
* Called only after {@link verify} has passed over the same file, so `count` is
|
|
11
|
+
* the number of complete lines verification vouched for. If the file no longer
|
|
12
|
+
* has that many lines, something is writing underneath us; that is reported as
|
|
13
|
+
* an I/O condition rather than papered over.
|
|
14
|
+
*/
|
|
15
|
+
export type ReadResult = {
|
|
16
|
+
ok: true;
|
|
17
|
+
lines: string[];
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
message: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The first `count` complete (newline-terminated) lines of the log, exactly as
|
|
24
|
+
* stored, without their terminators.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readCompleteLines(logPath: string, count: number): ReadResult;
|
|
27
|
+
/** Parse stored lines back into records for `--json` output. */
|
|
28
|
+
export declare function parseLines(logPath: string, lines: string[]): {
|
|
29
|
+
ok: true;
|
|
30
|
+
records: unknown[];
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `approval render` — regenerate `.approval/QUEUE.md` from the log (SPEC.md
|
|
3
|
+
* §9.1, §10.1).
|
|
4
|
+
*
|
|
5
|
+
* As everywhere else in this CLI, no logic lives here. The projection is
|
|
6
|
+
* `channels/render-queue.ts`; this file splits argv, resolves paths, reads the
|
|
7
|
+
* clock **once at the edge** and hands the instant to core, and maps a result
|
|
8
|
+
* onto the frozen exit table.
|
|
9
|
+
*
|
|
10
|
+
* The clock is the point worth stating. The renderer is a pure function of
|
|
11
|
+
* (verified log, policy, `now`), which is what makes an identical log render to
|
|
12
|
+
* identical bytes. That property survives only if exactly one place reads a real
|
|
13
|
+
* clock, and this is it.
|
|
14
|
+
*
|
|
15
|
+
* `render` writes one file and never the log. A corrupt log refuses (exit 1)
|
|
16
|
+
* rather than producing a queue: a projection of a log that does not verify
|
|
17
|
+
* would be a screenshot of something nobody should be reading.
|
|
18
|
+
*/
|
|
19
|
+
import type { Streams } from "./main.js";
|
|
20
|
+
/** SPEC.md §9.1: where the queue projection lives. */
|
|
21
|
+
export declare const DEFAULT_QUEUE_PATH = ".approval/QUEUE.md";
|
|
22
|
+
export declare function commandRender(argv: string[], streams: Streams, cwd: string): number;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `approval sandbox` — run a command with no way out to the network (APRV-193).
|
|
3
|
+
*
|
|
4
|
+
* ## Why a verb, when `approval run` already sandboxes
|
|
5
|
+
*
|
|
6
|
+
* `approval run` covers the actions the gate SEES: it holds a grant or it does
|
|
7
|
+
* not, it appends `execution.started`, and since APRV-193 it puts an ungranted
|
|
8
|
+
* child in a room with no doors. It does not cover the commands the harness
|
|
9
|
+
* runs on its own — `npm test`, `node scripts/whatever.mjs` — which the hook
|
|
10
|
+
* classifies `files.write.workspace`, allows, and then never touches again,
|
|
11
|
+
* because the hook DECIDES and the harness EXECUTES. Those are the commands that
|
|
12
|
+
* run code an agent wrote a minute ago, and they are the whole of the
|
|
13
|
+
* laundering hole this task exists to close.
|
|
14
|
+
*
|
|
15
|
+
* The hook cannot close it: a `PreToolUse` verdict is allow or deny, and it
|
|
16
|
+
* cannot rewrite the command into a wrapper. So the wrapper is a verb the
|
|
17
|
+
* command is written with, `approval sandbox -- npm test`, and two things make
|
|
18
|
+
* that more than a convention an agent could simply not type:
|
|
19
|
+
*
|
|
20
|
+
* 1. `core/command-class.ts` classifies the wrapper as its INNER argv, so
|
|
21
|
+
* running something safely is no longer punished with `hook-unclassified`
|
|
22
|
+
* (before this task, `sandbox-exec …` was denied while the bare command was
|
|
23
|
+
* allowed — the hook actively penalised the safe spelling), and the wrapper
|
|
24
|
+
* cannot launder anything either, because the class the hook resolves is the
|
|
25
|
+
* inner command's own.
|
|
26
|
+
* 2. `APPROVAL_HOOK_REQUIRE_SANDBOX=1` makes the hook DENY an allowed-class
|
|
27
|
+
* exec that is not written this way, with a message naming the spelling that
|
|
28
|
+
* works. It is off by default and turning it on can only ever refuse more,
|
|
29
|
+
* which is why an environment variable is an acceptable home for it.
|
|
30
|
+
*
|
|
31
|
+
* ## What it does
|
|
32
|
+
*
|
|
33
|
+
* Builds the profile (`core/sandbox.ts`), scrubs the credential-bearing
|
|
34
|
+
* variables out of the child's environment (`core/child-env.ts`, APRV-205),
|
|
35
|
+
* spawns, and exits with the child's own exit code. It appends NOTHING: this
|
|
36
|
+
* verb removes a capability, it does not authorize anything, and a log entry
|
|
37
|
+
* per `npm test` would be the transparency log inheriting a database's problem
|
|
38
|
+
* (SPEC.md §2, and the reason gate-routed editing was rejected on this task).
|
|
39
|
+
*
|
|
40
|
+
* ## What it fails at, stated plainly
|
|
41
|
+
*
|
|
42
|
+
* An agent HARNESS cannot run under this. `claude` and `cursor-agent` talk to a
|
|
43
|
+
* model over the network, and this verb denies exactly that, so
|
|
44
|
+
* `approval sandbox -- claude` is a session that cannot think. Sandboxing a
|
|
45
|
+
* whole session needs an egress allowlist reaching one host, which Seatbelt
|
|
46
|
+
* cannot express by hostname and which the prior art (Claude Code's own sandbox
|
|
47
|
+
* mode) solves with a local proxy. That is a follow-up, and until it exists the
|
|
48
|
+
* unit this verb protects is the COMMAND rather than the session.
|
|
49
|
+
*/
|
|
50
|
+
import type { Streams } from "./main.js";
|
|
51
|
+
export declare function commandSandbox(argv: string[], streams: Streams, cwd: string): number;
|
package/dist/src/cli/sandbox.js
CHANGED
|
@@ -50,11 +50,13 @@
|
|
|
50
50
|
import { spawnSync } from "node:child_process";
|
|
51
51
|
import { rmSync } from "node:fs";
|
|
52
52
|
import { constants as osConstants } from "node:os";
|
|
53
|
+
import { dirname } from "node:path";
|
|
53
54
|
import { childEnvironment } from "../core/child-env.js";
|
|
54
55
|
import { loadPolicy } from "../core/policy-load.js";
|
|
55
56
|
import { credentialPathsFor, detectSandbox, resolveExecutable, wrapForSandbox, } from "../core/sandbox.js";
|
|
56
57
|
import { passphraseEnvFor } from "../core/vault.js";
|
|
57
58
|
import { parseFlags, boolFlag, stringFlag } from "./args.js";
|
|
59
|
+
import { resolveReadRoots } from "./hook.js";
|
|
58
60
|
import { EXIT_OK, EXIT_USAGE } from "./exit-codes.js";
|
|
59
61
|
import { SANDBOX_HELP } from "./help.js";
|
|
60
62
|
import { DEFAULT_LOG_PATH } from "./paths.js";
|
|
@@ -63,6 +65,7 @@ import { usageErrorText } from "./usage.js";
|
|
|
63
65
|
const EXIT_COMMAND_NOT_RUN = 127;
|
|
64
66
|
const FLAGS = {
|
|
65
67
|
"--allow-loopback": "boolean",
|
|
68
|
+
"--read-jail": "boolean",
|
|
66
69
|
"--log": "string",
|
|
67
70
|
"--long": "boolean",
|
|
68
71
|
"--help": "boolean",
|
|
@@ -107,7 +110,8 @@ export function commandSandbox(argv, streams, cwd) {
|
|
|
107
110
|
return EXIT_COMMAND_NOT_RUN;
|
|
108
111
|
}
|
|
109
112
|
const logPath = stringFlag(parsed.flags, "--log") ?? DEFAULT_LOG_PATH;
|
|
110
|
-
const
|
|
113
|
+
const policy = loadPolicy({ dir: cwd });
|
|
114
|
+
const child = childEnvironment({ passphraseEnv: passphraseEnvFor(policy) });
|
|
111
115
|
const resolved = resolveExecutable(command, child.env);
|
|
112
116
|
if (resolved === null) {
|
|
113
117
|
// Resolved HERE rather than left to the wrapper: `sandbox-exec` execs
|
|
@@ -116,9 +120,21 @@ export function commandSandbox(argv, streams, cwd) {
|
|
|
116
120
|
streams.err(`approval: ${JSON.stringify(command)} is not on PATH; the command was NOT run.\n`);
|
|
117
121
|
return EXIT_COMMAND_NOT_RUN;
|
|
118
122
|
}
|
|
123
|
+
// APRV-347. The read jail, from the same two sources `approval run` reads it
|
|
124
|
+
// from: the policy declaring a `read_scope` block turns it on for every
|
|
125
|
+
// command this verb wraps, and `--read-jail` turns it on for one command
|
|
126
|
+
// whether the policy declares one or not. There is no flag that turns it OFF
|
|
127
|
+
// where the policy asked for it — a flag an agent can pass must only ever be
|
|
128
|
+
// able to make the room smaller.
|
|
129
|
+
const declared = policy.ok ? policy.policy.read_scope : undefined;
|
|
130
|
+
const wantJail = declared !== undefined || boolFlag(parsed.flags, "--read-jail");
|
|
131
|
+
const readJail = wantJail
|
|
132
|
+
? resolveReadRoots(cwd, policy.ok ? dirname(policy.source.path) : cwd, declared?.roots)
|
|
133
|
+
: [];
|
|
119
134
|
const wrapped = wrapForSandbox(detection.mechanism, resolved, childArgv.slice(1), {
|
|
120
135
|
loopback: boolFlag(parsed.flags, "--allow-loopback"),
|
|
121
136
|
denyRead: credentialPathsFor(logPath),
|
|
137
|
+
...(readJail.length === 0 ? {} : { allowRead: readJail }),
|
|
122
138
|
});
|
|
123
139
|
try {
|
|
124
140
|
const result = spawnSync(wrapped.command, wrapped.args, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../src/cli/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../src/cli/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bytes `approval init` scaffolds, and the one-line rationale for each.
|
|
3
|
+
*
|
|
4
|
+
* These constants live apart from both `init.ts` and `help.ts` because both
|
|
5
|
+
* need them: the verb writes them and the help text quotes them, and a help text
|
|
6
|
+
* that quoted a stale copy would be the second-worst kind of documentation — the
|
|
7
|
+
* confident kind. One definition, two readers, no cycle.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* SPEC.md §5.1's canonical example, byte for byte.
|
|
11
|
+
*
|
|
12
|
+
* This constant and `schema/fixtures/policy-md/valid/canonical.md` are the same
|
|
13
|
+
* bytes, and `tests/cli-init.test.ts` asserts it: the fixture is frozen (every
|
|
14
|
+
* policy-loading test descends from it) and the spec section it transcribes is
|
|
15
|
+
* what a reader compares the scaffolded file against. A copy that drifted from
|
|
16
|
+
* either would hand a new user a policy the documentation does not describe.
|
|
17
|
+
*
|
|
18
|
+
* It is embedded here rather than read from `schema/` because the published
|
|
19
|
+
* package ships the CLI and the spec, not the test fixtures, and a scaffolding
|
|
20
|
+
* verb that fails on an installed copy is a verb that only ever worked in this
|
|
21
|
+
* checkout.
|
|
22
|
+
*
|
|
23
|
+
* The closing sentence is not in SPEC.md §5.1's fence — it is the fixture's own
|
|
24
|
+
* trailing prose, kept because it says the one thing a first-time reader of this
|
|
25
|
+
* file needs to know: the prose is not the policy.
|
|
26
|
+
*/
|
|
27
|
+
export declare const CANONICAL_POLICY = "# Approval Policy\n\nAgents working in this project handle my life admin. Anything that leaves\nthe machine gets declared, and the classes below say what I sign off on.\n\n```yaml approval-policy\nversion: \"0.1\"\n\ndefaults:\n autonomy: manual # unknown/undeclared classes require sign-off\n channel: telegram\n approval_ttl: 24h # pending requests expire\n on_expiry: reject\n\napprovers:\n alice:\n channels: [telegram, cli]\n\nclasses:\n read.*: { autonomy: autonomous }\n files.write.workspace: { autonomy: autonomous }\n calendar.write.own: { autonomy: supervised-retro }\n communicate.email.draft: { autonomy: autonomous }\n communicate.email.external:\n autonomy: manual\n approvers: [alice]\n financial.spend:\n autonomy: manual\n approvers: [alice]\n limits: { per_action_usd: 25, daily_usd: 100 }\n public.post: { autonomy: manual }\n data.delete: { autonomy: manual }\n account.auth: { autonomy: manual }\n\nbudgets:\n global: { daily_usd: 100, daily_actions: 200 }\n\naudit:\n supervised_sample_rate: 0.10 # fraction of supervised actions escalated\n # for retrospective human review\n\nchannels:\n telegram:\n chat_id_env: APPROVAL_TG_CHAT\n token_env: APPROVAL_TG_TOKEN\n web:\n port: 4680\n```\n\nEverything after the block is prose again and is ignored by the parser.\n";
|
|
28
|
+
/**
|
|
29
|
+
* The comment the merged `.gitignore` lines live under.
|
|
30
|
+
*
|
|
31
|
+
* A marker rather than a bare append, so a second `init` can tell its own lines
|
|
32
|
+
* from the operator's and add only what is missing, and so a human reading the
|
|
33
|
+
* file knows which lines they are allowed to delete.
|
|
34
|
+
*/
|
|
35
|
+
export declare const GITIGNORE_MARKER = "# approval.md";
|
|
36
|
+
/**
|
|
37
|
+
* The ignore lines, and why each one is there.
|
|
38
|
+
*
|
|
39
|
+
* - `.approval/*.sqlite` — the index is a projection (SPEC.md §9.2). It rebuilds
|
|
40
|
+
* from the log with `approval reindex`; committing it would put a cache in the
|
|
41
|
+
* history of the thing it caches.
|
|
42
|
+
* - `.approval/vault.enc` — the encrypted credential store (M7). Encrypted or
|
|
43
|
+
* not, the vault is the one file in the layout whose contents are secrets, and
|
|
44
|
+
* secrets do not go in a repository.
|
|
45
|
+
* - `.approval/env` — the environment source map (APRV-73). Usually it holds
|
|
46
|
+
* only keychain service names, and it is ignored anyway: the format permits a
|
|
47
|
+
* plaintext literal, an operator will eventually paste one in, and the day
|
|
48
|
+
* they do must not be the day a bot token lands in a commit. Ignoring it also
|
|
49
|
+
* states the intent — the environment is per-machine, not per-repository.
|
|
50
|
+
* - `.approval/keys/` — the per-request X25519 private keys of sealed token
|
|
51
|
+
* delivery (APRV-105). Per-machine by construction: the whole design is that
|
|
52
|
+
* the log, which IS shared, carries only ciphertext, and a key committed to a
|
|
53
|
+
* shared history would hand every reader of that history the ability to open
|
|
54
|
+
* an unspent token inside its TTL. Written whether or not a policy has opted
|
|
55
|
+
* into `token_delivery: sealed`, because the line an operator needs is the one
|
|
56
|
+
* that is already there on the day they turn the knob.
|
|
57
|
+
* - `.approval/**\/*.tmp-*` — the atomic-write temp files. Both writers that
|
|
58
|
+
* rename into place (`channels/render-queue.ts`, `core/payload-store.ts`) name
|
|
59
|
+
* their temp `.<basename>.tmp-<pid>-<counter>`, so this pattern is written to
|
|
60
|
+
* match what those two actually produce, at both levels of the tree. A crashed
|
|
61
|
+
* write leaves one behind; nobody should be asked to review it.
|
|
62
|
+
*
|
|
63
|
+
* - `.approval-journal/` — the ungated free-text channel of `approval journal`
|
|
64
|
+
* (APRV-195). Ignored rather than tracked because it is not truth and not
|
|
65
|
+
* evidence: the log is the record of what happened and it is committed, while
|
|
66
|
+
* the journal is what an agent said about working here, which the operator
|
|
67
|
+
* reads locally. Committing it would also turn an outlet into a publication,
|
|
68
|
+
* and an agent writing for a public repository is an agent writing for an
|
|
69
|
+
* audience — the pressure this channel exists to be free of. An operator who
|
|
70
|
+
* wants the history keeps it by deleting the line.
|
|
71
|
+
*
|
|
72
|
+
* `.approval/log/` is deliberately absent: the log is the truth and belongs in
|
|
73
|
+
* the history. So is `.approval/payloads/`, which holds the bytes each approval
|
|
74
|
+
* bound to — evidence defaults to tracked, and the next steps `init` prints say
|
|
75
|
+
* so, along with the one line that reverses the choice.
|
|
76
|
+
*/
|
|
77
|
+
export declare const GITIGNORE_ENTRIES: readonly string[];
|
|
78
|
+
/** The same entries, indented for the help text so the two cannot disagree. */
|
|
79
|
+
export declare const GITIGNORE_ENTRY_LINES: string;
|
package/dist/src/cli/scaffold.js
CHANGED
|
@@ -45,7 +45,7 @@ approvers:
|
|
|
45
45
|
classes:
|
|
46
46
|
read.*: { autonomy: autonomous }
|
|
47
47
|
files.write.workspace: { autonomy: autonomous }
|
|
48
|
-
calendar.write.own: { autonomy: supervised }
|
|
48
|
+
calendar.write.own: { autonomy: supervised-retro }
|
|
49
49
|
communicate.email.draft: { autonomy: autonomous }
|
|
50
50
|
communicate.email.external:
|
|
51
51
|
autonomy: manual
|