approval-md 0.0.1 → 0.1.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 +909 -4
- package/SPEC.md +445 -32
- package/cli.js +29 -3
- package/dist/src/adapters/agentmail.js +1200 -0
- package/dist/src/adapters/agentmail.js.map +1 -0
- package/dist/src/adapters/conformance.js +461 -0
- package/dist/src/adapters/conformance.js.map +1 -0
- package/dist/src/adapters/contract.js +941 -0
- package/dist/src/adapters/contract.js.map +1 -0
- package/dist/src/adapters/email.js +749 -0
- package/dist/src/adapters/email.js.map +1 -0
- package/dist/src/adapters/env-passphrase.js +132 -0
- package/dist/src/adapters/env-passphrase.js.map +1 -0
- package/dist/src/adapters/registry.js +76 -0
- package/dist/src/adapters/registry.js.map +1 -0
- package/dist/src/adapters/smtp.js +499 -0
- package/dist/src/adapters/smtp.js.map +1 -0
- package/dist/src/adapters/vault-provider.js +161 -0
- package/dist/src/adapters/vault-provider.js.map +1 -0
- package/dist/src/channels/batch.js +121 -0
- package/dist/src/channels/batch.js.map +1 -0
- package/dist/src/channels/cli.js +468 -0
- package/dist/src/channels/cli.js.map +1 -0
- package/dist/src/channels/conformance.js +445 -0
- package/dist/src/channels/conformance.js.map +1 -0
- package/dist/src/channels/contract.js +494 -0
- package/dist/src/channels/contract.js.map +1 -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.js +564 -0
- package/dist/src/channels/render-queue.js.map +1 -0
- package/dist/src/channels/tagging.js +723 -0
- package/dist/src/channels/tagging.js.map +1 -0
- package/dist/src/channels/telegram.js +3190 -0
- package/dist/src/channels/telegram.js.map +1 -0
- package/dist/src/channels/web.js +903 -0
- package/dist/src/channels/web.js.map +1 -0
- package/dist/src/cli/adapter.js +278 -0
- package/dist/src/cli/adapter.js.map +1 -0
- package/dist/src/cli/amend.js +2171 -0
- package/dist/src/cli/amend.js.map +1 -0
- package/dist/src/cli/args.js +86 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/attest.js +307 -0
- package/dist/src/cli/attest.js.map +1 -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.js +460 -0
- package/dist/src/cli/audit.js.map +1 -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.js +357 -0
- package/dist/src/cli/channel-web.js.map +1 -0
- package/dist/src/cli/channel.js +438 -0
- package/dist/src/cli/channel.js.map +1 -0
- package/dist/src/cli/checkpoint-tap.js +238 -0
- package/dist/src/cli/checkpoint-tap.js.map +1 -0
- package/dist/src/cli/coverage.js +343 -0
- package/dist/src/cli/coverage.js.map +1 -0
- package/dist/src/cli/daemon.js +631 -0
- package/dist/src/cli/daemon.js.map +1 -0
- package/dist/src/cli/doctor.js +2648 -0
- package/dist/src/cli/doctor.js.map +1 -0
- package/dist/src/cli/env.js +302 -0
- package/dist/src/cli/env.js.map +1 -0
- package/dist/src/cli/execute.js +1682 -0
- package/dist/src/cli/execute.js.map +1 -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.js +205 -0
- package/dist/src/cli/feedback.js.map +1 -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.js +557 -0
- package/dist/src/cli/gate.js.map +1 -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.js +107 -0
- package/dist/src/cli/gloss-attach.js.map +1 -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.js +255 -0
- package/dist/src/cli/gloss-codex.js.map +1 -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.js +362 -0
- package/dist/src/cli/gloss.js.map +1 -0
- package/dist/src/cli/help.js +2217 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/hook.js +2743 -0
- package/dist/src/cli/hook.js.map +1 -0
- package/dist/src/cli/import.js +175 -0
- package/dist/src/cli/import.js.map +1 -0
- package/dist/src/cli/init.js +336 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/cli/instructions.js +262 -0
- package/dist/src/cli/instructions.js.map +1 -0
- package/dist/src/cli/journal.js +238 -0
- package/dist/src/cli/journal.js.map +1 -0
- package/dist/src/cli/log-advance.js +749 -0
- package/dist/src/cli/log-advance.js.map +1 -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.js +128 -0
- package/dist/src/cli/log-checkpoint.js.map +1 -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.js +354 -0
- package/dist/src/cli/log-verbs.js.map +1 -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.js +1056 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/mcp.js +306 -0
- package/dist/src/cli/mcp.js.map +1 -0
- package/dist/src/cli/paths.js +79 -0
- package/dist/src/cli/paths.js.map +1 -0
- package/dist/src/cli/payload.js +253 -0
- package/dist/src/cli/payload.js.map +1 -0
- package/dist/src/cli/policy.js +229 -0
- package/dist/src/cli/policy.js.map +1 -0
- package/dist/src/cli/preflight.js +888 -0
- package/dist/src/cli/preflight.js.map +1 -0
- package/dist/src/cli/progress.js +112 -0
- package/dist/src/cli/progress.js.map +1 -0
- package/dist/src/cli/prompt.js +312 -0
- package/dist/src/cli/prompt.js.map +1 -0
- package/dist/src/cli/records.js +66 -0
- package/dist/src/cli/records.js.map +1 -0
- package/dist/src/cli/render.js +132 -0
- package/dist/src/cli/render.js.map +1 -0
- package/dist/src/cli/sandbox.js +150 -0
- package/dist/src/cli/sandbox.js.map +1 -0
- package/dist/src/cli/scaffold.js +137 -0
- package/dist/src/cli/scaffold.js.map +1 -0
- package/dist/src/cli/setup-adapter.js +475 -0
- package/dist/src/cli/setup-adapter.js.map +1 -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.js +196 -0
- package/dist/src/cli/setup-checkpoint.js.map +1 -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.js +476 -0
- package/dist/src/cli/setup-flow.js.map +1 -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.js +473 -0
- package/dist/src/cli/setup.js.map +1 -0
- package/dist/src/cli/style.js +469 -0
- package/dist/src/cli/style.js.map +1 -0
- package/dist/src/cli/token.js +274 -0
- package/dist/src/cli/token.js.map +1 -0
- package/dist/src/cli/up.js +847 -0
- package/dist/src/cli/up.js.map +1 -0
- package/dist/src/cli/usage.js +91 -0
- package/dist/src/cli/usage.js.map +1 -0
- package/dist/src/cli/values.js +189 -0
- package/dist/src/cli/values.js.map +1 -0
- package/dist/src/cli/vault.js +362 -0
- package/dist/src/cli/vault.js.map +1 -0
- package/dist/src/cli/verb-registry.js +2173 -0
- package/dist/src/cli/verb-registry.js.map +1 -0
- package/dist/src/cli/wordmark.js +52 -0
- package/dist/src/cli/wordmark.js.map +1 -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.js +747 -0
- package/dist/src/core/agents-md.js.map +1 -0
- package/dist/src/core/attest.js +577 -0
- package/dist/src/core/attest.js.map +1 -0
- package/dist/src/core/audit.js +882 -0
- package/dist/src/core/audit.js.map +1 -0
- package/dist/src/core/budgets.js +449 -0
- package/dist/src/core/budgets.js.map +1 -0
- package/dist/src/core/checkpoint.js +738 -0
- package/dist/src/core/checkpoint.js.map +1 -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.js +43 -0
- package/dist/src/core/clock.js.map +1 -0
- package/dist/src/core/command-class.js +2321 -0
- package/dist/src/core/command-class.js.map +1 -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.js +136 -0
- package/dist/src/core/coverage-sources/gh.js.map +1 -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.js +337 -0
- package/dist/src/core/coverage.js.map +1 -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.js +714 -0
- package/dist/src/core/dark-session.js.map +1 -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.js +837 -0
- package/dist/src/core/env-file.js.map +1 -0
- package/dist/src/core/execute.js +1233 -0
- package/dist/src/core/execute.js.map +1 -0
- package/dist/src/core/frontmatter.js +100 -0
- package/dist/src/core/frontmatter.js.map +1 -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.js +2947 -0
- package/dist/src/core/gate.js.map +1 -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.js +210 -0
- package/dist/src/core/harness-version.js.map +1 -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.js +121 -0
- package/dist/src/core/head-retry.js.map +1 -0
- package/dist/src/core/instance.js +319 -0
- package/dist/src/core/instance.js.map +1 -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.js +132 -0
- package/dist/src/core/jcs.js.map +1 -0
- package/dist/src/core/journal.js +200 -0
- package/dist/src/core/journal.js.map +1 -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.js +136 -0
- package/dist/src/core/log-reconcile.js.map +1 -0
- package/dist/src/core/log.js +546 -0
- package/dist/src/core/log.js.map +1 -0
- package/dist/src/core/loop.js +476 -0
- package/dist/src/core/loop.js.map +1 -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.js +195 -0
- package/dist/src/core/money.js.map +1 -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.js +340 -0
- package/dist/src/core/payload-store.js.map +1 -0
- package/dist/src/core/payload.js +80 -0
- package/dist/src/core/payload.js.map +1 -0
- package/dist/src/core/policy-diff.js +565 -0
- package/dist/src/core/policy-diff.js.map +1 -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.js +230 -0
- package/dist/src/core/policy-explain.js.map +1 -0
- package/dist/src/core/policy-load.js +524 -0
- package/dist/src/core/policy-load.js.map +1 -0
- package/dist/src/core/policy-match.js +467 -0
- package/dist/src/core/policy-match.js.map +1 -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.js +422 -0
- package/dist/src/core/prompt-layout.js.map +1 -0
- package/dist/src/core/protected-path-guard.js +1087 -0
- package/dist/src/core/protected-path-guard.js.map +1 -0
- package/dist/src/core/registration.js +39 -0
- package/dist/src/core/registration.js.map +1 -0
- package/dist/src/core/reindex.js +336 -0
- package/dist/src/core/reindex.js.map +1 -0
- package/dist/src/core/sampler.js +388 -0
- package/dist/src/core/sampler.js.map +1 -0
- package/dist/src/core/sandbox.js +424 -0
- package/dist/src/core/sandbox.js.map +1 -0
- package/dist/src/core/seal.js +290 -0
- package/dist/src/core/seal.js.map +1 -0
- package/dist/src/core/state.js +1009 -0
- package/dist/src/core/state.js.map +1 -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.js +114 -0
- package/dist/src/core/telegram-config.js.map +1 -0
- package/dist/src/core/token.js +578 -0
- package/dist/src/core/token.js.map +1 -0
- package/dist/src/core/validate.js +0 -0
- package/dist/src/core/validate.js.map +1 -0
- package/dist/src/core/values.js +153 -0
- package/dist/src/core/values.js.map +1 -0
- package/dist/src/core/vault.js +612 -0
- package/dist/src/core/vault.js.map +1 -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.js +549 -0
- package/dist/src/core/verify.js.map +1 -0
- package/dist/src/core/version.js +9 -0
- package/dist/src/core/version.js.map +1 -0
- package/dist/src/core/wysiwys.js +728 -0
- package/dist/src/core/wysiwys.js.map +1 -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.js +849 -0
- package/dist/src/daemon/advance.js.map +1 -0
- package/dist/src/daemon/audit.js +90 -0
- package/dist/src/daemon/audit.js.map +1 -0
- package/dist/src/daemon/daemon.js +1988 -0
- package/dist/src/daemon/daemon.js.map +1 -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.js +132 -0
- package/dist/src/daemon/draw-child.js.map +1 -0
- package/dist/src/daemon/draw.js +458 -0
- package/dist/src/daemon/draw.js.map +1 -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.js +233 -0
- package/dist/src/daemon/projection.js.map +1 -0
- package/dist/src/daemon/prune.js +376 -0
- package/dist/src/daemon/prune.js.map +1 -0
- package/dist/src/mcp/http.js +343 -0
- package/dist/src/mcp/http.js.map +1 -0
- package/dist/src/mcp/server.js +594 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/docs/cli-reference.md +5363 -0
- package/package.json +43 -4
- package/schema/.gitkeep +0 -0
- package/schema/LICENSE +117 -0
- package/schema/envelope.schema.json +137 -0
- package/schema/event.schema.json +1810 -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 +481 -0
- package/schema/sample-record.schema.json +26 -0
- package/schema/values.schema.json +55 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The checkpoint tap: custody, the offer, the prompt text, the signature
|
|
3
|
+
* (APRV-257, the delivery half of APRV-220).
|
|
4
|
+
*
|
|
5
|
+
* APRV-220 built the record and gave a human exactly one way to sign one:
|
|
6
|
+
* `approval log checkpoint` at a terminal, remembered. This file is what makes
|
|
7
|
+
* it happen without the remembering, and it is deliberately the ONLY file
|
|
8
|
+
* between a channel and a signature.
|
|
9
|
+
*
|
|
10
|
+
* ## Why custody lives here now
|
|
11
|
+
*
|
|
12
|
+
* `core/checkpoint.ts` takes the private key as a value and reads it from
|
|
13
|
+
* nowhere, so that one file decides where a checkpoint key may come from. Until
|
|
14
|
+
* this task that file was `cli/log-checkpoint.ts`, because the terminal verb was
|
|
15
|
+
* the only caller. It is not any more: the Telegram listener and the CLI channel
|
|
16
|
+
* both sign now. So the decision moved here rather than being copied, and
|
|
17
|
+
* `cli/log-checkpoint.ts` calls {@link resolveCheckpointKey} like everyone else.
|
|
18
|
+
* There is still exactly one place to read to learn every way a key can reach a
|
|
19
|
+
* signature, which was the whole property.
|
|
20
|
+
*
|
|
21
|
+
* Two sources, in this order, unchanged from APRV-220:
|
|
22
|
+
*
|
|
23
|
+
* 1. `--key-file <path>`, for a key an operator keeps outside the vault.
|
|
24
|
+
* 2. The credential vault, under `approval.checkpoint.key`. Encrypted at rest
|
|
25
|
+
* under the passphrase `vault.passphrase_env` names, which
|
|
26
|
+
* `core/child-env.ts` strips from every child this runtime spawns
|
|
27
|
+
* (APRV-205), behind a file whose reading classifies `account.credential`.
|
|
28
|
+
*
|
|
29
|
+
* There is no `--key` flag and no environment variable holding the key.
|
|
30
|
+
*
|
|
31
|
+
* ## Why an agent-launched process cannot reach any of this
|
|
32
|
+
*
|
|
33
|
+
* Three independent locks, and the tap adds none of its own — it inherits all
|
|
34
|
+
* three, which is why the tap can be built at all:
|
|
35
|
+
*
|
|
36
|
+
* 1. **Classification.** `approval log checkpoint` and `approval setup
|
|
37
|
+
* checkpoint` classify `policy.core` in `core/command-class.ts`, which the
|
|
38
|
+
* reference policy holds `human-only`, so the Claude Code hook denies both
|
|
39
|
+
* with `hook-class-human-only` before a process starts.
|
|
40
|
+
* 2. **The passphrase.** `core/child-env.ts` strips `vault.passphrase_env` from
|
|
41
|
+
* every child this runtime spawns, so a process an agent launched cannot
|
|
42
|
+
* open the vault even if it ran this code.
|
|
43
|
+
* 3. **The launch.** The listener holds the passphrase because a HUMAN
|
|
44
|
+
* exported it into the shell they started `approval up` in. Nothing an agent
|
|
45
|
+
* can do puts it into a process the agent controls.
|
|
46
|
+
*
|
|
47
|
+
* `tests/checkpoint-tap.test.ts` proves the first two and proves the third
|
|
48
|
+
* structurally: the hook's module graph never reaches this file.
|
|
49
|
+
*
|
|
50
|
+
* ## What the human is shown is what gets signed
|
|
51
|
+
*
|
|
52
|
+
* The offer carries a `(seq, hash)`; the prompt prints it; the signature covers
|
|
53
|
+
* it. The head may have moved several times over between the prompt and the tap
|
|
54
|
+
* — a phone is in a pocket and a daemon is not — and
|
|
55
|
+
* {@link ../core/checkpoint.js appendCheckpointAt} signs the head that was on
|
|
56
|
+
* the screen, checking first that this chain still carries those bytes at that
|
|
57
|
+
* seq. APRV-220's verify rule (a checkpoint signs any seq below its own) exists
|
|
58
|
+
* precisely so this is a legal record rather than a clever one.
|
|
59
|
+
*/
|
|
60
|
+
import { readFileSync } from "node:fs";
|
|
61
|
+
import { isAbsolute, resolve } from "node:path";
|
|
62
|
+
import { appendCheckpointAt, checkpointDue, checkpointPolicyOf, CHECKPOINT_KEY_CREDENTIAL, } from "../core/checkpoint.js";
|
|
63
|
+
import { readVerifiedRecords } from "../core/state.js";
|
|
64
|
+
import { loadPolicy } from "../core/policy-load.js";
|
|
65
|
+
import { getCredential, passphraseEnvFor, passphraseFrom, vaultPathFor } from "../core/vault.js";
|
|
66
|
+
/** Why no key could be had. One code: the repair is the message, not a branch. */
|
|
67
|
+
export const CHECKPOINT_KEY_REFUSAL = "checkpoint-key-unreadable";
|
|
68
|
+
function absolute(path, cwd) {
|
|
69
|
+
return isAbsolute(path) ? path : resolve(cwd, path);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The private key, or a refusal naming which source failed and how to fix it.
|
|
73
|
+
*
|
|
74
|
+
* Moved verbatim from `cli/log-checkpoint.ts` (APRV-257) so that the terminal
|
|
75
|
+
* verb, the Telegram listener and the CLI channel share one answer to "where
|
|
76
|
+
* may a checkpoint key come from". The sentences are unchanged: an operator who
|
|
77
|
+
* has seen this refusal once should not meet it in new words on another
|
|
78
|
+
* surface.
|
|
79
|
+
*/
|
|
80
|
+
export function resolveCheckpointKey(keyFile, logPath, vaultFlag, policyWhere, cwd,
|
|
81
|
+
/**
|
|
82
|
+
* Where the passphrase is read from. `process.env` in production.
|
|
83
|
+
*
|
|
84
|
+
* A seam and not a back door, and the same one `setup adapter` carries: it
|
|
85
|
+
* goes through {@link passphraseFrom}, which is the function `approval vault
|
|
86
|
+
* set` uses, and it never resolves `.approval/env` (SPEC.md §11.1 invariant
|
|
87
|
+
* 7). Injectable so a suite can prove the vault path without mutating an
|
|
88
|
+
* environment every other test in the process shares.
|
|
89
|
+
*/
|
|
90
|
+
env) {
|
|
91
|
+
if (keyFile !== null) {
|
|
92
|
+
const path = absolute(keyFile, cwd);
|
|
93
|
+
let text;
|
|
94
|
+
try {
|
|
95
|
+
text = readFileSync(path, "utf8").trim();
|
|
96
|
+
}
|
|
97
|
+
catch (cause) {
|
|
98
|
+
return {
|
|
99
|
+
ok: false,
|
|
100
|
+
code: CHECKPOINT_KEY_REFUSAL,
|
|
101
|
+
message: `--key-file ${path} could not be read (${cause instanceof Error ? cause.message : String(cause)}); nothing was appended`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (text.length === 0) {
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
code: CHECKPOINT_KEY_REFUSAL,
|
|
108
|
+
message: `--key-file ${path} is empty; a checkpoint key is a base64 PKCS#8 Ed25519 private key on one line. Nothing was appended`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return { ok: true, privateKey: text };
|
|
112
|
+
}
|
|
113
|
+
const vaultPath = vaultFlag === null ? vaultPathFor(logPath) : absolute(vaultFlag, cwd);
|
|
114
|
+
const passphraseEnv = passphraseEnvFor(loadPolicy(policyWhere));
|
|
115
|
+
const passphrase = passphraseFrom(passphraseEnv, env ?? process.env);
|
|
116
|
+
if (passphrase === null) {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
code: CHECKPOINT_KEY_REFUSAL,
|
|
120
|
+
message: `${passphraseEnv} is unset or empty, so the vault holding ${CHECKPOINT_KEY_CREDENTIAL} could not be opened. The passphrase is read from that variable and from nowhere else; there is no --passphrase flag. Nothing was appended`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const credential = getCredential(vaultPath, passphrase, CHECKPOINT_KEY_CREDENTIAL);
|
|
124
|
+
if (!credential.ok) {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
code: CHECKPOINT_KEY_REFUSAL,
|
|
128
|
+
message: `the checkpoint signing key could not be read from ${vaultPath} (${credential.code}: ${credential.message}). Mint one with \`approval setup checkpoint\`, or pass --key-file. Nothing was appended`,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return { ok: true, privateKey: credential.value };
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// The offer
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* The checkpoint this log is owed, or `null`.
|
|
138
|
+
*
|
|
139
|
+
* Reads the policy first and gives up the moment it names no cadence, so a
|
|
140
|
+
* dispatch cycle on a gate that has never turned checkpoints on pays one policy
|
|
141
|
+
* load and no log walk. Everything after that is
|
|
142
|
+
* {@link ../core/checkpoint.js checkpointDue} over verified records, which is
|
|
143
|
+
* the same call the daemon's warning and doctor's row make: three surfaces,
|
|
144
|
+
* one rule, no arrangement in which they disagree.
|
|
145
|
+
*
|
|
146
|
+
* A log that does not verify produces no offer and no complaint. A chain that
|
|
147
|
+
* is not fit to be read is not fit to be signed either, and the surfaces that
|
|
148
|
+
* exist to shout about a bad chain — `approval log verify`, the daemon's
|
|
149
|
+
* re-proof, doctor's `log` row — are already shouting.
|
|
150
|
+
*/
|
|
151
|
+
export function checkpointOfferFor(tap, now) {
|
|
152
|
+
const configured = checkpointPolicyOf(tap.policy, tap.schemaDir);
|
|
153
|
+
if (configured.checkpointEveryMs === null || configured.publicKeys.length === 0)
|
|
154
|
+
return null;
|
|
155
|
+
const read = readVerifiedRecords(tap.logPath, tap.schemaDir === undefined ? {} : { schemaDir: tap.schemaDir });
|
|
156
|
+
if (!read.ok)
|
|
157
|
+
return null;
|
|
158
|
+
return checkpointDue({
|
|
159
|
+
records: read.records,
|
|
160
|
+
publicKeys: configured.publicKeys,
|
|
161
|
+
checkpointEveryMs: configured.checkpointEveryMs,
|
|
162
|
+
...(now === undefined ? {} : { now }),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* What a human reads before they tap, on every channel.
|
|
167
|
+
*
|
|
168
|
+
* One text for every surface, because the thing being consented to is identical
|
|
169
|
+
* and a phone that phrased it differently from a terminal would be two claims
|
|
170
|
+
* about one gesture. The `(seq, hash)` is first and whole: it is the entire
|
|
171
|
+
* content of the signature, and an approver who cannot see what they are
|
|
172
|
+
* signing is not approving anything.
|
|
173
|
+
*
|
|
174
|
+
* The last line is the one that keeps this honest. Declining costs nothing —
|
|
175
|
+
* there is no path in this runtime from a checkpoint that is due to a refusal
|
|
176
|
+
* of anything — and a prompt that implied otherwise would be manufacturing
|
|
177
|
+
* pressure for a signature.
|
|
178
|
+
*/
|
|
179
|
+
export function checkpointPromptLines(offer) {
|
|
180
|
+
return [
|
|
181
|
+
`CHECKPOINT DUE — sign the log head at seq ${String(offer.head.seq)}?`,
|
|
182
|
+
`head seq ${String(offer.head.seq)} ${offer.head.hash}`,
|
|
183
|
+
offer.since === null
|
|
184
|
+
? "This log has never been checkpointed."
|
|
185
|
+
: `The newest checkpoint is at seq ${String(offer.since)}.`,
|
|
186
|
+
offer.warning,
|
|
187
|
+
"Signing appends one log.checkpoint saying that a key no agent process holds saw this head. It authorizes nothing, spends nothing, and decides no request.",
|
|
188
|
+
"The head may move before you tap. What is signed is the head named above, which is the one you are looking at.",
|
|
189
|
+
"Not signing is not a refusal of anything: a checkpoint that is owed is a warning at every layer and never a reason to hold up an action.",
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Sign one head and append the record, on the machine the channel runs on.
|
|
194
|
+
*
|
|
195
|
+
* `head` is the `(seq, hash)` that was on the screen, handed back by the
|
|
196
|
+
* channel unchanged. It is a head rather than the whole offer on purpose: by
|
|
197
|
+
* tap time the offer's cadence arithmetic is hours stale and nothing should be
|
|
198
|
+
* tempted to read it, while the head is the one part that must survive
|
|
199
|
+
* verbatim.
|
|
200
|
+
*
|
|
201
|
+
* The key is resolved at TAP time and not at offer time, and that ordering is
|
|
202
|
+
* the point: a prompt sitting on a phone for an hour holds no key material
|
|
203
|
+
* anywhere, and a listener whose vault the operator has since re-keyed refuses
|
|
204
|
+
* the tap with a sentence rather than signing with something stale.
|
|
205
|
+
*/
|
|
206
|
+
export function signCheckpointOffer(tap, head, actor, channel, cwd) {
|
|
207
|
+
const key = resolveCheckpointKey(tap.keyFile, tap.logPath, tap.vault, tap.policy, cwd);
|
|
208
|
+
if (!key.ok)
|
|
209
|
+
return key;
|
|
210
|
+
const appended = appendCheckpointAt(tap.logPath, key.privateKey, actor, head, {
|
|
211
|
+
channel,
|
|
212
|
+
...(tap.schemaDir === undefined ? {} : { schemaDir: tap.schemaDir }),
|
|
213
|
+
});
|
|
214
|
+
if (!appended.ok)
|
|
215
|
+
return { ok: false, code: appended.code, message: appended.message };
|
|
216
|
+
return {
|
|
217
|
+
ok: true,
|
|
218
|
+
seq: appended.record.seq,
|
|
219
|
+
signed: { seq: appended.head.seq, hash: appended.head.hash },
|
|
220
|
+
fingerprint: appended.fingerprint,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/** What a channel says on the message it just edited, once a tap has landed. */
|
|
224
|
+
export function checkpointSignedLines(result) {
|
|
225
|
+
if (!result.ok) {
|
|
226
|
+
return [
|
|
227
|
+
"NOT CHECKPOINTED",
|
|
228
|
+
`${result.code}: ${result.message}`,
|
|
229
|
+
"Nothing was appended. The log is unchanged and no verdict anywhere depends on this.",
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
return [
|
|
233
|
+
"CHECKPOINTED",
|
|
234
|
+
`log.checkpoint at seq ${String(result.seq)}, signing head seq ${String(result.signed.seq)} ${result.signed.hash}`,
|
|
235
|
+
`key ${result.fingerprint}`,
|
|
236
|
+
];
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=checkpoint-tap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-tap.js","sourceRoot":"","sources":["../../../src/cli/checkpoint-tap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `approval coverage` — observed side effects, joined to the verified log
|
|
3
|
+
* (APRV-245, SPEC.md §10.1).
|
|
4
|
+
*
|
|
5
|
+
* ## What it answers
|
|
6
|
+
*
|
|
7
|
+
* "Here is everything the witnesses outside this runtime say happened, and here
|
|
8
|
+
* is what the log says about each one." Nothing more: the join is
|
|
9
|
+
* `core/coverage.ts`, the witnesses are `core/coverage-sources/`, and this file
|
|
10
|
+
* is argument parsing, source selection, and the rendering of a table.
|
|
11
|
+
*
|
|
12
|
+
* ## Why it exits 0 with gaps
|
|
13
|
+
*
|
|
14
|
+
* Because it is INFORMATIONAL, on exactly SPEC.md §10.1's rule for the APRV-145
|
|
15
|
+
* harness-start coverage in `approval status`: a coverage measurement is not an
|
|
16
|
+
* integrity verdict, and a control an operator learns to silence is worse than
|
|
17
|
+
* one that reports beside the verdict. A gap here is a question ("was this
|
|
18
|
+
* effect ever declared?"), and questions with legitimate answers must not fail
|
|
19
|
+
* a build. The two codes it can still emit are the filesystem's: 2 for a usage
|
|
20
|
+
* error and 4 for a log this process could not read, plus 3 for a torn tail,
|
|
21
|
+
* because a log it could not read is a report it did not make.
|
|
22
|
+
*
|
|
23
|
+
* ## Why a source that cannot be reached is not a gap
|
|
24
|
+
*
|
|
25
|
+
* A source reports `available: false` with a reason, and its effects are absent
|
|
26
|
+
* rather than uncovered. "`gh` is not on PATH" and "`gh` saw nothing" are
|
|
27
|
+
* different facts, and a report that flattened them would let a broken tool read
|
|
28
|
+
* as a clean bill of health. Every unavailable source prints its reason on its
|
|
29
|
+
* own line.
|
|
30
|
+
*
|
|
31
|
+
* ## Writes nothing, reads only verified records
|
|
32
|
+
*
|
|
33
|
+
* The log is read through `readVerifiedRecords` (SPEC.md §11.1 invariant 1) and
|
|
34
|
+
* nothing here appends, renders, or caches. Running it changes no state any
|
|
35
|
+
* later verdict depends on, which is what lets it be safe to run on a timer.
|
|
36
|
+
*/
|
|
37
|
+
import { isAbsolute, resolve as resolvePathSegments } from "node:path";
|
|
38
|
+
import { observeAdapter } from "../core/coverage-sources/adapter.js";
|
|
39
|
+
import { observeGh } from "../core/coverage-sources/gh.js";
|
|
40
|
+
import { DEFAULT_TRUNK_REF, defaultRange, observeGit, } from "../core/coverage-sources/git.js";
|
|
41
|
+
import { coverageReport } from "../core/coverage.js";
|
|
42
|
+
import { loadPolicy, parseDuration } from "../core/policy-load.js";
|
|
43
|
+
import { readVerifiedRecords } from "../core/state.js";
|
|
44
|
+
import { passphraseEnvFor, vaultPathFor } from "../core/vault.js";
|
|
45
|
+
import { agentmailAdapter } from "../adapters/agentmail.js";
|
|
46
|
+
import { vaultCredentialProvider } from "../adapters/vault-provider.js";
|
|
47
|
+
import { boolFlag, parseFlags, stringFlag } from "./args.js";
|
|
48
|
+
import { EXIT_IO, EXIT_OK, EXIT_TORN_TAIL, EXIT_USAGE } from "./exit-codes.js";
|
|
49
|
+
import { repoRoot } from "./git-scope.js";
|
|
50
|
+
import { COVERAGE_HELP } from "./help.js";
|
|
51
|
+
import { DEFAULT_LOG_PATH, preflightLog, resolvePath } from "./paths.js";
|
|
52
|
+
import { style, table } from "./style.js";
|
|
53
|
+
import { usageErrorText } from "./usage.js";
|
|
54
|
+
const FLAGS = {
|
|
55
|
+
"--base": "string",
|
|
56
|
+
"--head": "string",
|
|
57
|
+
"--since": "string",
|
|
58
|
+
"--until": "string",
|
|
59
|
+
"--source": "string",
|
|
60
|
+
"--log": "string",
|
|
61
|
+
"--policy": "string",
|
|
62
|
+
"--dir": "string",
|
|
63
|
+
"--vault": "string",
|
|
64
|
+
"--json": "boolean",
|
|
65
|
+
"--help": "boolean",
|
|
66
|
+
"-h": "boolean",
|
|
67
|
+
};
|
|
68
|
+
/** The sources this verb knows how to ask. */
|
|
69
|
+
const KNOWN_SOURCES = ["git", "gh", "agentmail"];
|
|
70
|
+
/** The default set. `agentmail` is opt-in because it opens a vault. */
|
|
71
|
+
const DEFAULT_SOURCES = ["git", "gh"];
|
|
72
|
+
/** The adapter window when `--since` is not given. */
|
|
73
|
+
const DEFAULT_SINCE = "7d";
|
|
74
|
+
function absolute(value, cwd) {
|
|
75
|
+
return isAbsolute(value) ? value : resolvePathSegments(cwd, value);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Where policy lives, from `--policy` / `--dir`, with the CLI's cwd default.
|
|
79
|
+
*
|
|
80
|
+
* The same four lines `cli/execute.ts` gives `status`, spelled again rather than
|
|
81
|
+
* imported: that copy is module-private, and importing it would pull the whole
|
|
82
|
+
* execution module (the appender, the child spawner, the token reader) into a
|
|
83
|
+
* verb whose entire promise is that it writes nothing. The behaviour is pinned
|
|
84
|
+
* by the CLI suites on both sides, so a drift would show up as a test failure
|
|
85
|
+
* rather than as a quietly different discovery order.
|
|
86
|
+
*/
|
|
87
|
+
function policyLocation(flags, cwd) {
|
|
88
|
+
const policyFlag = stringFlag(flags, "--policy");
|
|
89
|
+
const dirFlag = stringFlag(flags, "--dir");
|
|
90
|
+
if (policyFlag !== null)
|
|
91
|
+
return { file: absolute(policyFlag, cwd) };
|
|
92
|
+
return { dir: dirFlag === null ? cwd : absolute(dirFlag, cwd) };
|
|
93
|
+
}
|
|
94
|
+
function usageError(streams, json, message) {
|
|
95
|
+
if (json)
|
|
96
|
+
streams.err(`${JSON.stringify({ error: { code: "usage", message } })}\n`);
|
|
97
|
+
else
|
|
98
|
+
streams.err(usageErrorText(message, COVERAGE_HELP));
|
|
99
|
+
return EXIT_USAGE;
|
|
100
|
+
}
|
|
101
|
+
function ioError(streams, json, message) {
|
|
102
|
+
if (json)
|
|
103
|
+
streams.err(`${JSON.stringify({ error: { code: "io", message } })}\n`);
|
|
104
|
+
else
|
|
105
|
+
streams.err(`approval: ${message}\n`);
|
|
106
|
+
return EXIT_IO;
|
|
107
|
+
}
|
|
108
|
+
function emitJson(streams, value) {
|
|
109
|
+
streams.out(`${JSON.stringify(value)}\n`);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The evidence column, as one short string a reader can act on.
|
|
113
|
+
*
|
|
114
|
+
* The qualifier says how the record was found, so that a weaker match is never
|
|
115
|
+
* read as a stronger one and the strongest is not read as the ordinary one.
|
|
116
|
+
* `(id)` is APRV-251's: the record names this exact effect by the provider's own
|
|
117
|
+
* identifier, which is a different claim from "a record of this class sits in
|
|
118
|
+
* this effect's window" and prints as one.
|
|
119
|
+
*/
|
|
120
|
+
export function evidenceText(entry) {
|
|
121
|
+
const evidence = entry.evidence;
|
|
122
|
+
if (evidence === null)
|
|
123
|
+
return "none";
|
|
124
|
+
if ("verdict" in evidence)
|
|
125
|
+
return evidence.verdict;
|
|
126
|
+
const qualifier = entry.match === "family" ? " (family)" : entry.match === "provider-ref" ? " (id)" : "";
|
|
127
|
+
return `seq ${String(evidence.seq)} ${evidence.event}${qualifier}`;
|
|
128
|
+
}
|
|
129
|
+
/** The coverage line one source prints, in the shape the help promises. */
|
|
130
|
+
export function coverageLine(source) {
|
|
131
|
+
if (!source.available) {
|
|
132
|
+
return `${source.name}: unavailable (${source.reason ?? "no reason given"})`;
|
|
133
|
+
}
|
|
134
|
+
const qualifier = source.reason === null ? "" : ` — ${source.reason}`;
|
|
135
|
+
return `${source.name}: ${String(source.covered)} of ${String(source.observed)} effect(s) carry evidence${qualifier}`;
|
|
136
|
+
}
|
|
137
|
+
export async function commandCoverage(argv, streams, cwd) {
|
|
138
|
+
const json = argv.includes("--json");
|
|
139
|
+
const parsed = parseFlags(argv, FLAGS);
|
|
140
|
+
if (!parsed.ok)
|
|
141
|
+
return usageError(streams, json, parsed.message);
|
|
142
|
+
if (boolFlag(parsed.flags, "--help") || boolFlag(parsed.flags, "-h")) {
|
|
143
|
+
streams.out(`${COVERAGE_HELP}\n`);
|
|
144
|
+
return EXIT_OK;
|
|
145
|
+
}
|
|
146
|
+
const extra = parsed.positionals[0];
|
|
147
|
+
if (extra !== undefined) {
|
|
148
|
+
return usageError(streams, json, `unexpected argument ${JSON.stringify(extra)}`);
|
|
149
|
+
}
|
|
150
|
+
const flags = parsed.flags;
|
|
151
|
+
// --- the sources ------------------------------------------------------
|
|
152
|
+
const requested = stringFlag(flags, "--source");
|
|
153
|
+
let sources = [...DEFAULT_SOURCES];
|
|
154
|
+
if (requested !== null) {
|
|
155
|
+
const named = requested
|
|
156
|
+
.split(",")
|
|
157
|
+
.map((word) => word.trim())
|
|
158
|
+
.filter((word) => word.length > 0);
|
|
159
|
+
if (named.length === 0) {
|
|
160
|
+
return usageError(streams, json, "--source was given no source names");
|
|
161
|
+
}
|
|
162
|
+
for (const name of named) {
|
|
163
|
+
if (!KNOWN_SOURCES.includes(name)) {
|
|
164
|
+
return usageError(streams, json, `unknown source ${JSON.stringify(name)}; the sources are ${KNOWN_SOURCES.join(", ")}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
sources = [...new Set(named)];
|
|
168
|
+
}
|
|
169
|
+
// --- the adapter window ----------------------------------------------
|
|
170
|
+
const sinceText = stringFlag(flags, "--since") ?? DEFAULT_SINCE;
|
|
171
|
+
const sinceMs = parseDuration(sinceText);
|
|
172
|
+
if (sinceMs === null) {
|
|
173
|
+
return usageError(streams, json, `--since ${JSON.stringify(sinceText)} is not a duration (e.g. 7d, 24h, 90m)`);
|
|
174
|
+
}
|
|
175
|
+
const untilText = stringFlag(flags, "--until");
|
|
176
|
+
// The one clock read in this verb, and it reaches only the window a source is
|
|
177
|
+
// ASKED about. Nothing derived from it is written anywhere.
|
|
178
|
+
const untilAt = untilText === null ? Date.now() : Date.parse(untilText);
|
|
179
|
+
if (Number.isNaN(untilAt)) {
|
|
180
|
+
return usageError(streams, json, `--until ${JSON.stringify(untilText ?? "")} is not an RFC 3339 instant`);
|
|
181
|
+
}
|
|
182
|
+
const window = {
|
|
183
|
+
since: new Date(untilAt - sinceMs).toISOString(),
|
|
184
|
+
until: new Date(untilAt).toISOString(),
|
|
185
|
+
};
|
|
186
|
+
// --- the log ----------------------------------------------------------
|
|
187
|
+
const logPath = resolvePath(stringFlag(flags, "--log"), DEFAULT_LOG_PATH, cwd);
|
|
188
|
+
const check = preflightLog(logPath);
|
|
189
|
+
if (!check.ok)
|
|
190
|
+
return ioError(streams, json, check.message);
|
|
191
|
+
const read = readVerifiedRecords(logPath);
|
|
192
|
+
if (!read.ok) {
|
|
193
|
+
if (read.code === "log-unreadable")
|
|
194
|
+
return ioError(streams, json, read.message);
|
|
195
|
+
if (read.code === "log-torn-tail") {
|
|
196
|
+
if (json) {
|
|
197
|
+
streams.err(`${JSON.stringify({ error: { code: read.code, message: read.message } })}\n`);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
streams.err(`approval: ${read.message}\n`);
|
|
201
|
+
}
|
|
202
|
+
return EXIT_TORN_TAIL;
|
|
203
|
+
}
|
|
204
|
+
// A corrupt chain is reported and the run stops: this verb reads only
|
|
205
|
+
// VERIFIED records (SPEC.md §11.1 invariant 1), so a chain that does not
|
|
206
|
+
// verify leaves it with nothing it is allowed to join against.
|
|
207
|
+
if (json) {
|
|
208
|
+
streams.err(`${JSON.stringify({ error: { code: read.code, message: read.message } })}\n`);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
streams.err(`approval: ${read.message}\n`);
|
|
212
|
+
}
|
|
213
|
+
return EXIT_IO;
|
|
214
|
+
}
|
|
215
|
+
const records = read.records;
|
|
216
|
+
const location = policyLocation(flags, cwd);
|
|
217
|
+
const load = loadPolicy(location.file === undefined ? { dir: location.dir ?? cwd } : { file: location.file });
|
|
218
|
+
const protectedPaths = load.ok ? (load.policy.protected_paths ?? []) : [];
|
|
219
|
+
// --- the commit range -------------------------------------------------
|
|
220
|
+
const root = repoRoot(cwd) ?? cwd;
|
|
221
|
+
const baseFlag = stringFlag(flags, "--base");
|
|
222
|
+
const headFlag = stringFlag(flags, "--head");
|
|
223
|
+
const fallback = baseFlag === null ? defaultRange(root, DEFAULT_TRUNK_REF) : null;
|
|
224
|
+
const base = baseFlag ?? fallback?.base ?? "HEAD~20";
|
|
225
|
+
const head = headFlag ?? "HEAD";
|
|
226
|
+
// --- ask each source --------------------------------------------------
|
|
227
|
+
const observations = [];
|
|
228
|
+
for (const name of sources) {
|
|
229
|
+
if (name === "git") {
|
|
230
|
+
const seen = observeGit(root, {
|
|
231
|
+
base,
|
|
232
|
+
head,
|
|
233
|
+
policyProtectedPaths: protectedPaths,
|
|
234
|
+
});
|
|
235
|
+
const note = fallback?.note;
|
|
236
|
+
observations.push(note === undefined
|
|
237
|
+
? seen
|
|
238
|
+
: { ...seen, reason: seen.reason === undefined ? note : `${note}; ${seen.reason}` });
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (name === "gh") {
|
|
242
|
+
observations.push(observeGh(root, window));
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
observations.push(await observeAgentmailSource(flags, cwd, logPath, window));
|
|
246
|
+
}
|
|
247
|
+
// --- the join ---------------------------------------------------------
|
|
248
|
+
const all = observations.flatMap((observation) => observation.effects);
|
|
249
|
+
const report = coverageReport(all, records);
|
|
250
|
+
const byEffect = new Map();
|
|
251
|
+
for (const entry of report.entries)
|
|
252
|
+
byEffect.set(`${entry.effect.source}${entry.effect.id}`, entry);
|
|
253
|
+
const rendered = observations.map((observation) => {
|
|
254
|
+
const entries = observation.effects.flatMap((effect) => {
|
|
255
|
+
const entry = byEffect.get(`${effect.source}${effect.id}`);
|
|
256
|
+
return entry === undefined ? [] : [entry];
|
|
257
|
+
});
|
|
258
|
+
return {
|
|
259
|
+
name: observation.name,
|
|
260
|
+
available: observation.available,
|
|
261
|
+
reason: observation.reason ?? null,
|
|
262
|
+
entries,
|
|
263
|
+
observed: entries.length,
|
|
264
|
+
covered: entries.filter((entry) => entry.evidence !== null).length,
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
if (json) {
|
|
268
|
+
emitJson(streams, {
|
|
269
|
+
ok: true,
|
|
270
|
+
window: { base, head, since: window.since, until: window.until },
|
|
271
|
+
sources: rendered.map((source) => ({
|
|
272
|
+
name: source.name,
|
|
273
|
+
available: source.available,
|
|
274
|
+
reason: source.reason,
|
|
275
|
+
effects: source.entries.map((entry) => ({
|
|
276
|
+
id: entry.effect.id,
|
|
277
|
+
class: entry.effect.class,
|
|
278
|
+
at: entry.effect.at,
|
|
279
|
+
actor_hint: entry.effect.actorHint,
|
|
280
|
+
detail: entry.effect.detail,
|
|
281
|
+
path: entry.effect.path ?? null,
|
|
282
|
+
match: entry.match,
|
|
283
|
+
evidence: entry.evidence === null
|
|
284
|
+
? null
|
|
285
|
+
: "verdict" in entry.evidence
|
|
286
|
+
? { seq: null, event: null, verdict: entry.evidence.verdict }
|
|
287
|
+
: { seq: entry.evidence.seq, event: entry.evidence.event, verdict: null },
|
|
288
|
+
})),
|
|
289
|
+
covered: source.covered,
|
|
290
|
+
observed: source.observed,
|
|
291
|
+
})),
|
|
292
|
+
});
|
|
293
|
+
return EXIT_OK;
|
|
294
|
+
}
|
|
295
|
+
const st = style({ json });
|
|
296
|
+
const rows = rendered.flatMap((source) => source.entries.map((entry) => [
|
|
297
|
+
source.name,
|
|
298
|
+
entry.effect.id.length > 20 ? `${entry.effect.id.slice(0, 19)}…` : entry.effect.id,
|
|
299
|
+
entry.effect.class,
|
|
300
|
+
entry.evidence === null
|
|
301
|
+
? { text: "none", role: "warn" }
|
|
302
|
+
: { text: evidenceText(entry), role: "value" },
|
|
303
|
+
]));
|
|
304
|
+
if (rows.length > 0) {
|
|
305
|
+
streams.out(`${table(st, rows, { header: ["source", "effect", "class", "evidence"] })}\n`);
|
|
306
|
+
}
|
|
307
|
+
streams.out(`range ${base}..${head}, adapter window ${window.since} .. ${window.until}\n`);
|
|
308
|
+
for (const source of rendered)
|
|
309
|
+
streams.out(`${coverageLine(source)}\n`);
|
|
310
|
+
streams.out(`${st.muted("informational: exit 0 with or without gaps. A gap is a question, not a verdict — docs/cli-reference.md#coverage")}\n`);
|
|
311
|
+
return EXIT_OK;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* The AgentMail source, with the credential provider built exactly as
|
|
315
|
+
* `approval setup adapter agentmail` builds its probe's.
|
|
316
|
+
*
|
|
317
|
+
* `passphraseEnv` comes from the policy and `envFilePath` is deliberately NOT
|
|
318
|
+
* supplied. The `.approval/env` passphrase fallback is legitimate only inside a
|
|
319
|
+
* consumed-token window (APRV-168): its whole argument is that a human granted
|
|
320
|
+
* THIS action and the token is the authority. A reporting verb holds no token,
|
|
321
|
+
* so it reads the passphrase from the shell environment or it reports that it
|
|
322
|
+
* could not, which is SPEC.md §11.1 invariant 7 applied to a read.
|
|
323
|
+
*
|
|
324
|
+
* A vault that will not open is reported as an unavailable SOURCE with the
|
|
325
|
+
* reason, never as an exit code: the other sources still have answers, and a
|
|
326
|
+
* coverage report that refused to print because one provider was unreachable
|
|
327
|
+
* would be a report people stop running.
|
|
328
|
+
*/
|
|
329
|
+
async function observeAgentmailSource(flags, cwd, logPath, window) {
|
|
330
|
+
const location = policyLocation(flags, cwd);
|
|
331
|
+
const load = loadPolicy(location.file === undefined ? { dir: location.dir ?? cwd } : { file: location.file });
|
|
332
|
+
const passphraseEnv = passphraseEnvFor(load);
|
|
333
|
+
const vaultFlag = stringFlag(flags, "--vault");
|
|
334
|
+
const vaultPath = vaultFlag === null ? vaultPathFor(logPath) : absolute(vaultFlag, cwd);
|
|
335
|
+
const credentials = vaultCredentialProvider({ vaultPath }, { passphraseEnv });
|
|
336
|
+
// No `secrets` list, and deliberately: this verb never reads the vault's
|
|
337
|
+
// values itself, so the only party that knows what to scrub is the adapter,
|
|
338
|
+
// whose own configuration reader redacts before it returns. Assembling a
|
|
339
|
+
// secret corpus here would mean opening the vault a second time in the one
|
|
340
|
+
// verb that has no business holding what is in it.
|
|
341
|
+
return await observeAdapter(agentmailAdapter(), window, credentials);
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../../src/cli/coverage.ts"],"names":[],"mappings":"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"}
|