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 @@
|
|
|
1
|
+
{"version":3,"file":"head-retry.js","sourceRoot":"","sources":["../../../src/core/head-retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAIH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAkBrC,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,MAAqB;IAC/C,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,YAAY,CAAC;AAC/F,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,KAAyB,EAAE,OAAO,GAAG,mBAAmB;IACjF,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IACjF,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAA0B,QAAgB,EAAE,KAAc;IACrF,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC;IACrB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,GAAG,QAAQ,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QACzD,MAAM,GAAG,KAAK,EAAE,CAAC;IACnB,CAAC;IACD,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAA0B,MAAS,EAAE,QAAgB;IACrE,MAAM,IAAI,GAAG,KAAK,MAAM,CAAC,QAAQ,CAAC,WAChC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAC5B,uIAAuI,CAAC;IACxI,6EAA6E;IAC7E,2EAA2E;IAC3E,oEAAoE;IACpE,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,gBAAgB,GAAG,IAAI,EAAE,EAAO,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which gate instance this process is talking about (APRV-178).
|
|
3
|
+
*
|
|
4
|
+
* Everything else in this runtime is directory-scoped already: the policy is
|
|
5
|
+
* the `APPROVAL.md` beside the working directory, the log is that directory's
|
|
6
|
+
* `.approval/log/events.jsonl`, the vault and `.approval/env` sit next to it.
|
|
7
|
+
* Two checkouts on one machine are two gates, and nothing they hold is shared.
|
|
8
|
+
*
|
|
9
|
+
* The OS keystore was the exception, and it cost a live incident: the item
|
|
10
|
+
* names were three fixed strings, so a demo instance provisioned in another
|
|
11
|
+
* directory stored its bot token over the production instance's item and then
|
|
12
|
+
* read the production token back. Both gates then long-polled ONE bot, the
|
|
13
|
+
* `getUpdates` offsets fought, and a human's approval tap was consumed by the
|
|
14
|
+
* listener that had not asked for it. A keystore is machine-global; the names
|
|
15
|
+
* put into it have to carry the scoping the filesystem gave everything else.
|
|
16
|
+
*
|
|
17
|
+
* ## What the identity is
|
|
18
|
+
*
|
|
19
|
+
* The absolute path of the instance's `.approval` directory, hashed. Not the
|
|
20
|
+
* repository root (a gate may be configured with `--log` somewhere else), not
|
|
21
|
+
* a random id written into a file (a file the operator can copy is an identity
|
|
22
|
+
* that travels, which is the bug), and not the log path itself (a `--log` that
|
|
23
|
+
* names the same instance's log by a different but equivalent spelling should
|
|
24
|
+
* not mint a second identity, and `envFilePathFor` already normalises the two
|
|
25
|
+
* spellings this runtime supports).
|
|
26
|
+
*
|
|
27
|
+
* Symlinks are deliberately NOT resolved. `realpathSync` would touch the
|
|
28
|
+
* filesystem, so the identity of an instance would depend on whether its
|
|
29
|
+
* directory currently exists — and `approval setup` must be able to name the
|
|
30
|
+
* item it is about to create before anything is on disk. Two paths that reach
|
|
31
|
+
* one directory by different routes are therefore two identities; that is the
|
|
32
|
+
* safe direction of the error (two names, no sharing) rather than the unsafe
|
|
33
|
+
* one.
|
|
34
|
+
*
|
|
35
|
+
* ## What the names look like
|
|
36
|
+
*
|
|
37
|
+
* ```
|
|
38
|
+
* approval-tg-token-3f2a9c11
|
|
39
|
+
* approval-vault-passphrase-3f2a9c11
|
|
40
|
+
* approval-sampling-secret-3f2a9c11
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Eight hex digits: long enough that two instances on one machine will not
|
|
44
|
+
* collide by accident, short enough that an operator reading
|
|
45
|
+
* `keychain:approval-tg-token-3f2a9c11` in `.approval/env` and the same suffix
|
|
46
|
+
* in `approval doctor` can compare them at a glance. The suffix is not a
|
|
47
|
+
* secret and is not derived from one — it is a hash of a directory path, which
|
|
48
|
+
* `.approval/env` already carries in the open.
|
|
49
|
+
*/
|
|
50
|
+
import { createHash } from "node:crypto";
|
|
51
|
+
import { dirname } from "node:path";
|
|
52
|
+
import { NON_RESOLVING_RUNNER, envFilePathFor, resolveEnvironment, } from "./env-file.js";
|
|
53
|
+
/**
|
|
54
|
+
* The unscoped item names this project used before APRV-178.
|
|
55
|
+
*
|
|
56
|
+
* Kept, and kept named, for two reasons: an instance provisioned before the
|
|
57
|
+
* change still has its token under one of them, and the migration path is to
|
|
58
|
+
* READ them as a fallback and say so out loud, never to silently adopt them.
|
|
59
|
+
*/
|
|
60
|
+
export const LEGACY_SERVICE_TELEGRAM_TOKEN = "approval-tg-token";
|
|
61
|
+
export const LEGACY_SERVICE_VAULT_PASSPHRASE = "approval-vault-passphrase";
|
|
62
|
+
export const LEGACY_SERVICE_SAMPLING_SECRET = "approval-sampling-secret";
|
|
63
|
+
/** Every unscoped name, for the "is this the legacy one?" test. */
|
|
64
|
+
export const LEGACY_SERVICES = [
|
|
65
|
+
LEGACY_SERVICE_TELEGRAM_TOKEN,
|
|
66
|
+
LEGACY_SERVICE_VAULT_PASSPHRASE,
|
|
67
|
+
LEGACY_SERVICE_SAMPLING_SECRET,
|
|
68
|
+
];
|
|
69
|
+
/** How many hex digits of the digest a scoped name carries. */
|
|
70
|
+
export const INSTANCE_ID_LENGTH = 8;
|
|
71
|
+
/** A scoped name is a legacy base plus exactly that many hex digits. */
|
|
72
|
+
const SCOPED_SUFFIX = new RegExp(`^-[0-9a-f]{${String(INSTANCE_ID_LENGTH)}}$`, "u");
|
|
73
|
+
/**
|
|
74
|
+
* The `.approval` directory this log path belongs to, absolute as given.
|
|
75
|
+
*
|
|
76
|
+
* `envFilePathFor` already answers "which instance is this log in", by walking
|
|
77
|
+
* up out of `log/` when it is there; the env file's own directory IS the
|
|
78
|
+
* instance home, so this is that answer with the filename removed rather than
|
|
79
|
+
* a second rule that could disagree with it.
|
|
80
|
+
*/
|
|
81
|
+
export function instanceHomeFor(logPath) {
|
|
82
|
+
return dirname(envFilePathFor(logPath));
|
|
83
|
+
}
|
|
84
|
+
/** The instance's short identity: {@link INSTANCE_ID_LENGTH} hex digits. */
|
|
85
|
+
export function instanceIdFor(logPath) {
|
|
86
|
+
return createHash("sha256")
|
|
87
|
+
.update(instanceHomeFor(logPath), "utf8")
|
|
88
|
+
.digest("hex")
|
|
89
|
+
.slice(0, INSTANCE_ID_LENGTH);
|
|
90
|
+
}
|
|
91
|
+
/** The keystore item name `base` takes in the instance owning `logPath`. */
|
|
92
|
+
export function scopedService(base, logPath) {
|
|
93
|
+
return `${base}-${instanceIdFor(logPath)}`;
|
|
94
|
+
}
|
|
95
|
+
export function scopeOfService(service, logPath) {
|
|
96
|
+
for (const base of LEGACY_SERVICES) {
|
|
97
|
+
if (service === base)
|
|
98
|
+
return "legacy";
|
|
99
|
+
if (service.startsWith(base)) {
|
|
100
|
+
const suffix = service.slice(base.length);
|
|
101
|
+
if (!SCOPED_SUFFIX.test(suffix))
|
|
102
|
+
continue;
|
|
103
|
+
return suffix === `-${instanceIdFor(logPath)}` ? "mine" : "other-instance";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return "unknown";
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Export provenance (APRV-278)
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
/**
|
|
112
|
+
* The variable `approval env`'s export block uses to say what it exported.
|
|
113
|
+
*
|
|
114
|
+
* ## The bug this exists to close
|
|
115
|
+
*
|
|
116
|
+
* The bleed rule below reads no values, on purpose: it runs inside `approval
|
|
117
|
+
* doctor` and `approval up`, neither of which may pop a keystore-unlock dialog
|
|
118
|
+
* to produce a diagnostic (`NON_RESOLVING_RUNNER`). So it saw "this variable is
|
|
119
|
+
* exported, and the file has a line for it" and reported that the value in use
|
|
120
|
+
* was not the one the instance configured. It could not know that. The
|
|
121
|
+
* documented start ritual is
|
|
122
|
+
*
|
|
123
|
+
* ```sh
|
|
124
|
+
* eval "$(approval env)"
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* which exports THIS instance's own values from THIS instance's own file, and
|
|
128
|
+
* leaves behind exactly the state the rule was calling an incident: exported,
|
|
129
|
+
* with a file line naming a source. Observed on 2026-09-06 in the primary,
|
|
130
|
+
* where `unset APPROVAL_SAMPLING_SECRET && eval "$(approval env)" && approval
|
|
131
|
+
* up` printed the finding for the variable the eval had just resolved from the
|
|
132
|
+
* gate's own keychain item. A check that asserts a fact it never tested is
|
|
133
|
+
* worse than no check: it teaches the operator to skip the line.
|
|
134
|
+
*
|
|
135
|
+
* ## What is exported, and why it is value-free
|
|
136
|
+
*
|
|
137
|
+
* ```
|
|
138
|
+
* APPROVAL_ENV_PROVENANCE=1:3f2a9c11:<64 hex>:APPROVAL_TG_TOKEN,APPROVAL_TG_CHAT
|
|
139
|
+
* │ │ │ └ the NAMES it exported from the file
|
|
140
|
+
* │ │ └ sha256 of the env file bytes it read
|
|
141
|
+
* │ └ the instance whose file that was
|
|
142
|
+
* └ the format version
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* Four colon-separated fields; the names are shell variable names, which cannot
|
|
146
|
+
* contain a colon or a comma, so the shape needs no escaping. Every field is a
|
|
147
|
+
* NAME, an id or a digest: the same three kinds of thing `.approval/env` already
|
|
148
|
+
* carries in the open, and none of them is a value. The rule stays as value-free
|
|
149
|
+
* after this change as it was before it, which is the point — a check that had
|
|
150
|
+
* to read the secret to decide whether to complain about the secret would be a
|
|
151
|
+
* worse trade than the false positive.
|
|
152
|
+
*
|
|
153
|
+
* ## What it does NOT weaken
|
|
154
|
+
*
|
|
155
|
+
* Invariant 7 (no verb loads `.approval/env` implicitly) is untouched: this
|
|
156
|
+
* variable reaches a shell only when a human evaluates `approval env`'s output,
|
|
157
|
+
* exactly like every other line in that block, and no verb gains the ability to
|
|
158
|
+
* read the file for its values. And it cannot launder a foreign export, because
|
|
159
|
+
* `approval env` lists only the names it resolved FROM THE FILE. A value that
|
|
160
|
+
* was already in the environment is re-exported by that block for fidelity, and
|
|
161
|
+
* deliberately left out of this list, so a bled variable stays reported however
|
|
162
|
+
* many times the ritual is run over it.
|
|
163
|
+
*
|
|
164
|
+
* Trusting the variable is safe in the only direction that matters. Anything
|
|
165
|
+
* able to set it in this process's environment could already set the credential
|
|
166
|
+
* variables themselves, so it buys an attacker nothing; and being wrong here
|
|
167
|
+
* silences a WARNING rather than opening a gate. The reverse default — believing
|
|
168
|
+
* the exported value is foreign — is the bug being fixed.
|
|
169
|
+
*/
|
|
170
|
+
export const ENV_PROVENANCE_VAR = "APPROVAL_ENV_PROVENANCE";
|
|
171
|
+
/** The only format version this build writes, and the only one it reads. */
|
|
172
|
+
export const ENV_PROVENANCE_VERSION = "1";
|
|
173
|
+
const PROVENANCE_INSTANCE_ID = new RegExp(`^[0-9a-f]{${String(INSTANCE_ID_LENGTH)}}$`, "u");
|
|
174
|
+
const PROVENANCE_DIGEST = /^[0-9a-f]{64}$/u;
|
|
175
|
+
const PROVENANCE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
176
|
+
/**
|
|
177
|
+
* The value for {@link ENV_PROVENANCE_VAR}, for an export block that resolved
|
|
178
|
+
* `names` out of the file `digest` identifies.
|
|
179
|
+
*/
|
|
180
|
+
export function formatEnvProvenance(logPath, digest, names) {
|
|
181
|
+
return [ENV_PROVENANCE_VERSION, instanceIdFor(logPath), digest, [...names].join(",")].join(":");
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Read the claim back, or `null` for anything this build does not recognise.
|
|
185
|
+
*
|
|
186
|
+
* Strict on every field, and `null` rather than a partial answer: a malformed
|
|
187
|
+
* claim is an unverified one, an unverified one earns no credit, and no credit
|
|
188
|
+
* means the finding is still reported. That is the fail-closed direction (the
|
|
189
|
+
* check stays loud) for a value whose whole job is to make the check quieter.
|
|
190
|
+
*/
|
|
191
|
+
export function parseEnvProvenance(raw) {
|
|
192
|
+
if (raw === undefined)
|
|
193
|
+
return null;
|
|
194
|
+
const fields = raw.split(":");
|
|
195
|
+
if (fields.length !== 4)
|
|
196
|
+
return null;
|
|
197
|
+
const [version, instanceId, digest, joined] = fields;
|
|
198
|
+
if (version !== ENV_PROVENANCE_VERSION)
|
|
199
|
+
return null;
|
|
200
|
+
if (!PROVENANCE_INSTANCE_ID.test(instanceId))
|
|
201
|
+
return null;
|
|
202
|
+
if (!PROVENANCE_DIGEST.test(digest))
|
|
203
|
+
return null;
|
|
204
|
+
const names = joined.length === 0 ? [] : joined.split(",");
|
|
205
|
+
if (names.some((name) => !PROVENANCE_NAME.test(name)))
|
|
206
|
+
return null;
|
|
207
|
+
return { instanceId, digest, names: new Set(names) };
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* What is wrong with WHOSE credentials this instance is using (APRV-178).
|
|
211
|
+
*
|
|
212
|
+
* Answered from names alone. No keystore is consulted ({@link
|
|
213
|
+
* NON_RESOLVING_RUNNER}), so this may be called from `approval doctor` and from
|
|
214
|
+
* `approval up`'s start-up without either of them blocking on an unlock dialog.
|
|
215
|
+
* No value is read, compared or printed on any path: the inputs are a service
|
|
216
|
+
* name, a scheme, a variable name, and (since APRV-278) an instance id, a file
|
|
217
|
+
* digest and a list of variable names out of {@link ENV_PROVENANCE_VAR} — all of
|
|
218
|
+
* which `.approval/env` and `approval env --check` carry in the open. The
|
|
219
|
+
* exported VALUES this reports on are still never read, compared or printed.
|
|
220
|
+
*
|
|
221
|
+
* A file this runtime cannot read at all produces no findings rather than a
|
|
222
|
+
* guess; `approval env --check` and doctor's `environment` row are what report
|
|
223
|
+
* an unreadable or wrong-moded file, and saying it twice in different words is
|
|
224
|
+
* how two commands come to disagree.
|
|
225
|
+
*/
|
|
226
|
+
export function instanceFindings(logPath, load, ambientEnv = process.env) {
|
|
227
|
+
const resolved = resolveEnvironment(load, envFilePathFor(logPath), NON_RESOLVING_RUNNER, ambientEnv);
|
|
228
|
+
return resolved.ok
|
|
229
|
+
? findingsFor(logPath, resolved.variables, {
|
|
230
|
+
ambientEnv,
|
|
231
|
+
// The digest of the file THIS call read, which is what the provenance
|
|
232
|
+
// claim is checked against: an env file edited since the operator's
|
|
233
|
+
// `eval` earns no credit for the export it no longer describes.
|
|
234
|
+
envFileDigest: resolved.digest,
|
|
235
|
+
})
|
|
236
|
+
: [];
|
|
237
|
+
}
|
|
238
|
+
function provenanceView(logPath, context) {
|
|
239
|
+
const claim = parseEnvProvenance(context.ambientEnv?.[ENV_PROVENANCE_VAR]);
|
|
240
|
+
if (claim === null) {
|
|
241
|
+
return { claimsThisInstance: false, claimsThisFile: false, names: new Set() };
|
|
242
|
+
}
|
|
243
|
+
const claimsThisInstance = claim.instanceId === instanceIdFor(logPath);
|
|
244
|
+
return {
|
|
245
|
+
claimsThisInstance,
|
|
246
|
+
// An unknown digest is not a match: the rule may only vouch for what it has
|
|
247
|
+
// verified, and "the caller did not tell me" is not verification.
|
|
248
|
+
claimsThisFile: claimsThisInstance &&
|
|
249
|
+
context.envFileDigest !== undefined &&
|
|
250
|
+
claim.digest === context.envFileDigest,
|
|
251
|
+
names: claim.names,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The exported names this instance's OWN current `approval env` vouches for
|
|
256
|
+
* (APRV-278).
|
|
257
|
+
*
|
|
258
|
+
* Empty unless {@link ENV_PROVENANCE_VAR} parses, names this instance, and
|
|
259
|
+
* matches the env file as it now reads. `approval env --check` and the finding
|
|
260
|
+
* rule below both answer "is this export the documented ritual's?" from this one
|
|
261
|
+
* function, because two spellings of that question are two chances for `approval
|
|
262
|
+
* env --check` and `approval up` to say different things about one shell.
|
|
263
|
+
*/
|
|
264
|
+
export function ownEnvExports(logPath, context = {}) {
|
|
265
|
+
const view = provenanceView(logPath, context);
|
|
266
|
+
return view.claimsThisFile ? view.names : new Set();
|
|
267
|
+
}
|
|
268
|
+
/** The name-only rules, over an already-resolved variable set. */
|
|
269
|
+
export function findingsFor(logPath, variables, context = {}) {
|
|
270
|
+
const home = instanceHomeFor(logPath);
|
|
271
|
+
const { claimsThisInstance, claimsThisFile, names } = provenanceView(logPath, context);
|
|
272
|
+
const findings = [];
|
|
273
|
+
for (const variable of variables) {
|
|
274
|
+
const source = variable.fileSource;
|
|
275
|
+
if (source === undefined)
|
|
276
|
+
continue;
|
|
277
|
+
if (variable.status === "set-in-environment") {
|
|
278
|
+
const claimed = names.has(variable.name);
|
|
279
|
+
// The documented ritual: this instance's own `approval env`, run against
|
|
280
|
+
// the file as it now reads, exported this name out of it. The exported
|
|
281
|
+
// value IS the one the file configures, so there is nothing to report.
|
|
282
|
+
if (claimsThisFile && claimed)
|
|
283
|
+
continue;
|
|
284
|
+
findings.push({
|
|
285
|
+
kind: "ambient-bleed",
|
|
286
|
+
variable: variable.name,
|
|
287
|
+
detail: claimsThisInstance && claimed
|
|
288
|
+
? // This instance's own export, but of some other version of the
|
|
289
|
+
// file. Which version is not knowable from here, so the finding
|
|
290
|
+
// says only that, and does not claim the value is a stranger's.
|
|
291
|
+
`${variable.name} was exported by an \`approval env\` run this process cannot match to ${home}'s env file as it now reads, so line ${String(source.line)} as it now reads was not consulted`
|
|
292
|
+
: `${variable.name} was exported before this process started and is not this instance's own \`approval env\` export; line ${String(source.line)} of ${home}'s env file was not consulted`,
|
|
293
|
+
});
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const service = source.service;
|
|
297
|
+
if (service === undefined)
|
|
298
|
+
continue;
|
|
299
|
+
const scope = scopeOfService(service, logPath);
|
|
300
|
+
if (scope === "other-instance") {
|
|
301
|
+
findings.push({
|
|
302
|
+
kind: "foreign-instance",
|
|
303
|
+
variable: variable.name,
|
|
304
|
+
service,
|
|
305
|
+
detail: `${variable.name} names ${service}, whose scope suffix is not this instance's (${instanceIdFor(logPath)}, ${home}): two gates on this machine are pointed at one credential`,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
else if (scope === "legacy") {
|
|
309
|
+
findings.push({
|
|
310
|
+
kind: "legacy-shared",
|
|
311
|
+
variable: variable.name,
|
|
312
|
+
service,
|
|
313
|
+
detail: `${variable.name} names ${service}, the unscoped item name every gate on this machine resolves to the same value`,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return findings;
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=instance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../../src/core/instance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,kBAAkB,GAEnB,MAAM,eAAe,CAAC;AAGvB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC;AACjE,MAAM,CAAC,MAAM,+BAA+B,GAAG,2BAA2B,CAAC;AAC3E,MAAM,CAAC,MAAM,8BAA8B,GAAG,0BAA0B,CAAC;AAEzE,mEAAmE;AACnE,MAAM,CAAC,MAAM,eAAe,GAAsB;IAChD,6BAA6B;IAC7B,+BAA+B;IAC/B,8BAA8B;CAC/B,CAAC;AAEF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,wEAAwE;AACxE,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,cAAc,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;SACxC,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;AAClC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IACzD,OAAO,GAAG,IAAI,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;AAC7C,CAAC;AAmBD,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,OAAe;IAC7D,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;QACtC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS;YAC1C,OAAO,MAAM,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAE5D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,MAAM,sBAAsB,GAAG,IAAI,MAAM,CAAC,aAAa,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5F,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAC5C,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAYpD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,MAAc,EACd,KAAwB;IAExB,OAAO,CAAC,sBAAsB,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAuB;IACxD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,MAA0C,CAAC;IACzF,IAAI,OAAO,KAAK,sBAAsB;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;AACvD,CAAC;AAqCD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,IAAsB,EACtB,UAAU,GAAsB,OAAO,CAAC,GAAG;IAE3C,MAAM,QAAQ,GAAG,kBAAkB,CACjC,IAAI,EACJ,cAAc,CAAC,OAAO,CAAC,EACvB,oBAAoB,EACpB,UAAU,CACX,CAAC;IACF,OAAO,QAAQ,CAAC,EAAE;QAChB,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,EAAE;YACvC,UAAU;YACV,sEAAsE;YACtE,oEAAoE;YACpE,gEAAgE;YAChE,aAAa,EAAE,QAAQ,CAAC,MAAM;SAC/B,CAAC;QACJ,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AA0BD,SAAS,cAAc,CAAC,OAAe,EAAE,OAAwB;IAC/D,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,GAAG,EAAU,EAAE,CAAC;IACxF,CAAC;IACD,MAAM,kBAAkB,GAAG,KAAK,CAAC,UAAU,KAAK,aAAa,CAAC,OAAO,CAAC,CAAC;IACvE,OAAO;QACL,kBAAkB;QAClB,4EAA4E;QAC5E,kEAAkE;QAClE,cAAc,EACZ,kBAAkB;YAClB,OAAO,CAAC,aAAa,KAAK,SAAS;YACnC,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,aAAa;QACxC,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,OAAO,GAAoB,EAAE;IAE7B,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;AAC9D,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,SAAsC,EACtC,OAAO,GAAoB,EAAE;IAE7B,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEvF,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;QACnC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QAEnC,IAAI,QAAQ,CAAC,MAAM,KAAK,oBAAoB,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACzC,yEAAyE;YACzE,uEAAuE;YACvE,uEAAuE;YACvE,IAAI,cAAc,IAAI,OAAO;gBAAE,SAAS;YACxC,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,MAAM,EACJ,kBAAkB,IAAI,OAAO;oBAC3B,CAAC,CAAC,+DAA+D;wBAC/D,gEAAgE;wBAChE,gEAAgE;wBAChE,GAAG,QAAQ,CAAC,IAAI,yEAAyE,IAAI,wCAAwC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC;oBAC9L,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,0GAA0G,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,+BAA+B;aAC9L,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,IAAI,KAAK,KAAK,gBAAgB,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,kBAAkB;gBACxB,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,OAAO;gBACP,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,UAAU,OAAO,gDAAgD,aAAa,CAAC,OAAO,CAAC,KAAK,IAAI,4DAA4D;aACrL,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,OAAO;gBACP,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,UAAU,OAAO,gFAAgF;aAC1H,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|