approval-md 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +629 -559
- package/SPEC.md +99 -24
- package/dist/src/adapters/agentmail.d.ts +426 -0
- package/dist/src/adapters/agentmail.js +2 -2
- package/dist/src/adapters/conformance.d.ts +149 -0
- package/dist/src/adapters/contract.d.ts +628 -0
- package/dist/src/adapters/contract.js +110 -16
- package/dist/src/adapters/contract.js.map +1 -1
- package/dist/src/adapters/email.d.ts +324 -0
- package/dist/src/adapters/env-passphrase.d.ts +93 -0
- package/dist/src/adapters/public.d.ts +11 -0
- package/dist/src/adapters/public.js +11 -0
- package/dist/src/adapters/public.js.map +1 -0
- package/dist/src/adapters/registry.d.ts +59 -0
- package/dist/src/adapters/registry.js +2 -1
- package/dist/src/adapters/registry.js.map +1 -1
- package/dist/src/adapters/smtp.d.ts +213 -0
- package/dist/src/adapters/vault-provider.d.ts +114 -0
- package/dist/src/adapters/vault-provider.js +3 -3
- package/dist/src/adapters/zzz.d.ts +66 -0
- package/dist/src/adapters/zzz.js +299 -0
- package/dist/src/adapters/zzz.js.map +1 -0
- package/dist/src/channels/batch.d.ts +109 -0
- package/dist/src/channels/cli.d.ts +193 -0
- package/dist/src/channels/conformance.d.ts +92 -0
- package/dist/src/channels/contract.d.ts +656 -0
- package/dist/src/channels/contract.js +200 -7
- package/dist/src/channels/contract.js.map +1 -1
- package/dist/src/channels/payload-view.d.ts +35 -0
- package/dist/src/channels/render-queue.d.ts +149 -0
- package/dist/src/channels/tagging.d.ts +196 -0
- package/dist/src/channels/telegram.d.ts +1944 -0
- package/dist/src/channels/telegram.js +218 -23
- package/dist/src/channels/telegram.js.map +1 -1
- package/dist/src/channels/web.d.ts +350 -0
- package/dist/src/channels/web.js +17 -0
- package/dist/src/channels/web.js.map +1 -1
- package/dist/src/cli/adapter.d.ts +90 -0
- package/dist/src/cli/adapter.js +25 -15
- package/dist/src/cli/adapter.js.map +1 -1
- package/dist/src/cli/amend.d.ts +59 -0
- package/dist/src/cli/amend.js +214 -30
- package/dist/src/cli/amend.js.map +1 -1
- package/dist/src/cli/args.d.ts +43 -0
- package/dist/src/cli/attest.d.ts +50 -0
- package/dist/src/cli/attest.js +134 -7
- package/dist/src/cli/attest.js.map +1 -1
- package/dist/src/cli/audit-card.d.ts +62 -0
- package/dist/src/cli/audit.d.ts +59 -0
- package/dist/src/cli/channel-telegram.d.ts +879 -0
- package/dist/src/cli/channel-telegram.js +311 -13
- package/dist/src/cli/channel-telegram.js.map +1 -1
- package/dist/src/cli/channel-web.d.ts +131 -0
- package/dist/src/cli/channel.d.ts +80 -0
- package/dist/src/cli/channel.js +9 -0
- package/dist/src/cli/channel.js.map +1 -1
- package/dist/src/cli/checkpoint-tap.d.ts +169 -0
- package/dist/src/cli/codex-bridge.d.ts +819 -0
- package/dist/src/cli/codex-bridge.js +1607 -0
- package/dist/src/cli/codex-bridge.js.map +1 -0
- package/dist/src/cli/codex.d.ts +2 -0
- package/dist/src/cli/codex.js +469 -0
- package/dist/src/cli/codex.js.map +1 -0
- package/dist/src/cli/coverage.d.ts +61 -0
- package/dist/src/cli/daemon.d.ts +120 -0
- package/dist/src/cli/daemon.js +4 -1
- package/dist/src/cli/daemon.js.map +1 -1
- package/dist/src/cli/doctor.d.ts +129 -0
- package/dist/src/cli/doctor.js +586 -17
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/env.d.ts +65 -0
- package/dist/src/cli/execute.d.ts +202 -0
- package/dist/src/cli/execute.js +25 -2
- package/dist/src/cli/execute.js.map +1 -1
- package/dist/src/cli/exit-codes.d.ts +73 -0
- package/dist/src/cli/feedback.d.ts +60 -0
- package/dist/src/cli/gate-window.d.ts +40 -0
- package/dist/src/cli/gate.d.ts +68 -0
- package/dist/src/cli/git-scope.d.ts +190 -0
- package/dist/src/cli/gloss-attach.d.ts +85 -0
- package/dist/src/cli/gloss-codex-child.d.ts +9 -0
- package/dist/src/cli/gloss-codex.d.ts +24 -0
- package/dist/src/cli/gloss-options.d.ts +42 -0
- package/dist/src/cli/gloss.d.ts +265 -0
- package/dist/src/cli/help.d.ts +107 -0
- package/dist/src/cli/help.js +320 -93
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hook-codex.d.ts +126 -0
- package/dist/src/cli/hook-codex.js +226 -0
- package/dist/src/cli/hook-codex.js.map +1 -0
- package/dist/src/cli/hook.d.ts +787 -0
- package/dist/src/cli/hook.js +1235 -181
- package/dist/src/cli/hook.js.map +1 -1
- package/dist/src/cli/import.d.ts +35 -0
- package/dist/src/cli/import.js +1 -1
- package/dist/src/cli/import.js.map +1 -1
- package/dist/src/cli/init.d.ts +84 -0
- package/dist/src/cli/init.js +2 -2
- package/dist/src/cli/init.js.map +1 -1
- package/dist/src/cli/instructions.d.ts +23 -0
- package/dist/src/cli/journal.d.ts +41 -0
- package/dist/src/cli/log-advance.d.ts +287 -0
- package/dist/src/cli/log-advance.js +102 -11
- package/dist/src/cli/log-advance.js.map +1 -1
- package/dist/src/cli/log-anchor.d.ts +176 -0
- package/dist/src/cli/log-checkpoint.d.ts +22 -0
- package/dist/src/cli/log-sync.d.ts +243 -0
- package/dist/src/cli/log-verbs.d.ts +16 -0
- package/dist/src/cli/log-verbs.js +7 -1
- package/dist/src/cli/log-verbs.js.map +1 -1
- package/dist/src/cli/long-help.d.ts +70 -0
- package/dist/src/cli/main.d.ts +77 -0
- package/dist/src/cli/main.js +159 -7
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/mcp.d.ts +52 -0
- package/dist/src/cli/paths.d.ts +56 -0
- package/dist/src/cli/payload.d.ts +58 -0
- package/dist/src/cli/policy-apply.d.ts +195 -0
- package/dist/src/cli/policy-apply.js +573 -0
- package/dist/src/cli/policy-apply.js.map +1 -0
- package/dist/src/cli/policy.d.ts +43 -0
- package/dist/src/cli/policy.js +14 -1
- package/dist/src/cli/policy.js.map +1 -1
- package/dist/src/cli/preflight.d.ts +501 -0
- package/dist/src/cli/preflight.js +689 -45
- package/dist/src/cli/preflight.js.map +1 -1
- package/dist/src/cli/progress.d.ts +78 -0
- package/dist/src/cli/prompt.d.ts +209 -0
- package/dist/src/cli/quickstart.d.ts +46 -0
- package/dist/src/cli/quickstart.js +297 -0
- package/dist/src/cli/quickstart.js.map +1 -0
- package/dist/src/cli/records.d.ts +34 -0
- package/dist/src/cli/render.d.ts +22 -0
- package/dist/src/cli/sandbox.d.ts +51 -0
- package/dist/src/cli/sandbox.js +17 -1
- package/dist/src/cli/sandbox.js.map +1 -1
- package/dist/src/cli/scaffold.d.ts +79 -0
- package/dist/src/cli/scaffold.js +1 -1
- package/dist/src/cli/setup-adapter.d.ts +137 -0
- package/dist/src/cli/setup-adapter.js +38 -4
- package/dist/src/cli/setup-adapter.js.map +1 -1
- package/dist/src/cli/setup-channel.d.ts +126 -0
- package/dist/src/cli/setup-channel.js +28 -1
- package/dist/src/cli/setup-channel.js.map +1 -1
- package/dist/src/cli/setup-checkpoint.d.ts +57 -0
- package/dist/src/cli/setup-common.d.ts +277 -0
- package/dist/src/cli/setup-common.js +3 -2
- package/dist/src/cli/setup-common.js.map +1 -1
- package/dist/src/cli/setup-flow.d.ts +287 -0
- package/dist/src/cli/setup-service.d.ts +96 -0
- package/dist/src/cli/setup.d.ts +204 -0
- package/dist/src/cli/setup.js +94 -2
- package/dist/src/cli/setup.js.map +1 -1
- package/dist/src/cli/style.d.ts +320 -0
- package/dist/src/cli/token.d.ts +39 -0
- package/dist/src/cli/up.d.ts +155 -0
- package/dist/src/cli/up.js +119 -53
- package/dist/src/cli/up.js.map +1 -1
- package/dist/src/cli/usage.d.ts +37 -0
- package/dist/src/cli/values.d.ts +40 -0
- package/dist/src/cli/values.js +3 -4
- package/dist/src/cli/values.js.map +1 -1
- package/dist/src/cli/vault.d.ts +59 -0
- package/dist/src/cli/vault.js +2 -2
- package/dist/src/cli/vault.js.map +1 -1
- package/dist/src/cli/verb-registry.d.ts +76 -0
- package/dist/src/cli/verb-registry.js +344 -11
- package/dist/src/cli/verb-registry.js.map +1 -1
- package/dist/src/cli/wordmark.d.ts +31 -0
- package/dist/src/cli/wordmark.js +2 -2
- package/dist/src/codex/broker.d.ts +229 -0
- package/dist/src/codex/broker.js +548 -0
- package/dist/src/codex/broker.js.map +1 -0
- package/dist/src/codex/doctor.d.ts +13 -0
- package/dist/src/codex/doctor.js +41 -0
- package/dist/src/codex/doctor.js.map +1 -0
- package/dist/src/codex/manifest.d.ts +49 -0
- package/dist/src/codex/manifest.js +103 -0
- package/dist/src/codex/manifest.js.map +1 -0
- package/dist/src/codex/runner.d.ts +178 -0
- package/dist/src/codex/runner.js +231 -0
- package/dist/src/codex/runner.js.map +1 -0
- package/dist/src/codex/serve.d.ts +56 -0
- package/dist/src/codex/serve.js +98 -0
- package/dist/src/codex/serve.js.map +1 -0
- package/dist/src/codex/templates.d.ts +41 -0
- package/dist/src/codex/templates.js +319 -0
- package/dist/src/codex/templates.js.map +1 -0
- package/dist/src/codex/trust.d.ts +19 -0
- package/dist/src/codex/trust.js +183 -0
- package/dist/src/codex/trust.js.map +1 -0
- package/dist/src/codex/workspace-commit.d.ts +219 -0
- package/dist/src/codex/workspace-commit.js +549 -0
- package/dist/src/codex/workspace-commit.js.map +1 -0
- package/dist/src/codex/workspace-plan.d.ts +131 -0
- package/dist/src/codex/workspace-plan.js +561 -0
- package/dist/src/codex/workspace-plan.js.map +1 -0
- package/dist/src/core/actor.d.ts +2 -0
- package/dist/src/core/actor.js +5 -0
- package/dist/src/core/actor.js.map +1 -0
- package/dist/src/core/advance-cycle.d.ts +221 -0
- package/dist/src/core/advance-cycle.js +66 -2
- package/dist/src/core/advance-cycle.js.map +1 -1
- package/dist/src/core/agents-md.d.ts +278 -0
- package/dist/src/core/agents-md.js +33 -31
- package/dist/src/core/agents-md.js.map +1 -1
- package/dist/src/core/apply-patch.d.ts +49 -0
- package/dist/src/core/apply-patch.js +266 -0
- package/dist/src/core/apply-patch.js.map +1 -0
- package/dist/src/core/attest.d.ts +635 -0
- package/dist/src/core/attest.js +326 -4
- package/dist/src/core/attest.js.map +1 -1
- package/dist/src/core/audit.d.ts +510 -0
- package/dist/src/core/audit.js +13 -0
- package/dist/src/core/audit.js.map +1 -1
- package/dist/src/core/budgets.d.ts +238 -0
- package/dist/src/core/channel-owner.d.ts +213 -0
- package/dist/src/core/channel-owner.js +358 -0
- package/dist/src/core/channel-owner.js.map +1 -0
- package/dist/src/core/checkpoint.d.ts +500 -0
- package/dist/src/core/child-env.d.ts +88 -0
- package/dist/src/core/clock.d.ts +52 -0
- package/dist/src/core/command-class.d.ts +697 -0
- package/dist/src/core/command-class.js +713 -25
- package/dist/src/core/command-class.js.map +1 -1
- package/dist/src/core/commit-guard.d.ts +272 -0
- package/dist/src/core/commit-guard.js +424 -0
- package/dist/src/core/commit-guard.js.map +1 -0
- package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
- package/dist/src/core/coverage-sources/gh.d.ts +48 -0
- package/dist/src/core/coverage-sources/git.d.ts +101 -0
- package/dist/src/core/coverage.d.ts +217 -0
- package/dist/src/core/credential-spec.d.ts +72 -0
- package/dist/src/core/daemon-actor.d.ts +45 -0
- package/dist/src/core/daemon-actor.js +54 -0
- package/dist/src/core/daemon-actor.js.map +1 -0
- package/dist/src/core/dark-session.d.ts +432 -0
- package/dist/src/core/dark-session.js +266 -82
- package/dist/src/core/dark-session.js.map +1 -1
- package/dist/src/core/decision-refusal.d.ts +206 -0
- package/dist/src/core/decision-refusal.js +24 -2
- package/dist/src/core/decision-refusal.js.map +1 -1
- package/dist/src/core/env-file.d.ts +455 -0
- package/dist/src/core/env-file.js +60 -1
- package/dist/src/core/env-file.js.map +1 -1
- package/dist/src/core/execute.d.ts +871 -0
- package/dist/src/core/execute.js +59 -8
- package/dist/src/core/execute.js.map +1 -1
- package/dist/src/core/frontmatter.d.ts +78 -0
- package/dist/src/core/gate-window.d.ts +312 -0
- package/dist/src/core/gate.d.ts +1449 -0
- package/dist/src/core/gate.js +149 -14
- package/dist/src/core/gate.js.map +1 -1
- package/dist/src/core/gesture-refusal.d.ts +166 -0
- package/dist/src/core/gesture-refusal.js +188 -0
- package/dist/src/core/gesture-refusal.js.map +1 -0
- package/dist/src/core/git-run.d.ts +73 -0
- package/dist/src/core/harness-version.d.ts +157 -0
- package/dist/src/core/harness-version.js +4 -1
- package/dist/src/core/harness-version.js.map +1 -1
- package/dist/src/core/harness-wait.d.ts +55 -0
- package/dist/src/core/head-retry.d.ts +107 -0
- package/dist/src/core/instance.d.ts +310 -0
- package/dist/src/core/instance.js +113 -0
- package/dist/src/core/instance.js.map +1 -1
- package/dist/src/core/intake-limits.d.ts +247 -0
- package/dist/src/core/jcs.d.ts +52 -0
- package/dist/src/core/journal.d.ts +144 -0
- package/dist/src/core/live-draw.d.ts +436 -0
- package/dist/src/core/log-reconcile.d.ts +89 -0
- package/dist/src/core/log-subscribe.d.ts +36 -0
- package/dist/src/core/log-subscribe.js +162 -0
- package/dist/src/core/log-subscribe.js.map +1 -0
- package/dist/src/core/log.d.ts +316 -0
- package/dist/src/core/log.js.map +1 -1
- package/dist/src/core/loop.d.ts +274 -0
- package/dist/src/core/loop.js +11 -0
- package/dist/src/core/loop.js.map +1 -1
- package/dist/src/core/md-fence.d.ts +41 -0
- package/dist/src/core/money.d.ts +147 -0
- package/dist/src/core/payload-census.d.ts +74 -0
- package/dist/src/core/payload-store.d.ts +175 -0
- package/dist/src/core/payload.d.ts +71 -0
- package/dist/src/core/policy-diff.d.ts +292 -0
- package/dist/src/core/policy-diff.js +27 -4
- package/dist/src/core/policy-diff.js.map +1 -1
- package/dist/src/core/policy-expectations.d.ts +199 -0
- package/dist/src/core/policy-explain.d.ts +160 -0
- package/dist/src/core/policy-explain.js +63 -3
- package/dist/src/core/policy-explain.js.map +1 -1
- package/dist/src/core/policy-load.d.ts +567 -0
- package/dist/src/core/policy-load.js +36 -6
- package/dist/src/core/policy-load.js.map +1 -1
- package/dist/src/core/policy-match.d.ts +324 -0
- package/dist/src/core/policy-match.js +72 -9
- package/dist/src/core/policy-match.js.map +1 -1
- package/dist/src/core/policy-proposal.d.ts +317 -0
- package/dist/src/core/policy-proposal.js +102 -2
- package/dist/src/core/policy-proposal.js.map +1 -1
- package/dist/src/core/prompt-layout.d.ts +221 -0
- package/dist/src/core/protected-path-guard.d.ts +566 -0
- package/dist/src/core/protected-path-guard.js +848 -55
- package/dist/src/core/protected-path-guard.js.map +1 -1
- package/dist/src/core/question-preempted.d.ts +141 -0
- package/dist/src/core/question-preempted.js +152 -0
- package/dist/src/core/question-preempted.js.map +1 -0
- package/dist/src/core/read-scope.d.ts +172 -0
- package/dist/src/core/read-scope.js +252 -0
- package/dist/src/core/read-scope.js.map +1 -0
- package/dist/src/core/registration.d.ts +25 -0
- package/dist/src/core/reindex.d.ts +99 -0
- package/dist/src/core/sampler.d.ts +313 -0
- package/dist/src/core/sandbox.d.ts +371 -0
- package/dist/src/core/sandbox.js +190 -1
- package/dist/src/core/sandbox.js.map +1 -1
- package/dist/src/core/seal.d.ts +165 -0
- package/dist/src/core/sender-identity.d.ts +476 -0
- package/dist/src/core/sender-identity.js +572 -0
- package/dist/src/core/sender-identity.js.map +1 -0
- package/dist/src/core/shlex.d.ts +102 -0
- package/dist/src/core/shlex.js +159 -0
- package/dist/src/core/shlex.js.map +1 -0
- package/dist/src/core/state.d.ts +505 -0
- package/dist/src/core/task-file.d.ts +185 -0
- package/dist/src/core/telegram-config.d.ts +93 -0
- package/dist/src/core/token.d.ts +409 -0
- package/dist/src/core/token.js +21 -38
- package/dist/src/core/token.js.map +1 -1
- package/dist/src/core/validate.d.ts +138 -0
- package/dist/src/core/values.d.ts +147 -0
- package/dist/src/core/values.js +36 -1
- package/dist/src/core/values.js.map +1 -1
- package/dist/src/core/vault.d.ts +291 -0
- package/dist/src/core/verified-snapshot.d.ts +204 -0
- package/dist/src/core/verify.d.ts +336 -0
- package/dist/src/core/version.d.ts +8 -0
- package/dist/src/core/wysiwys.d.ts +370 -0
- package/dist/src/daemon/advance-child.d.ts +39 -0
- package/dist/src/daemon/advance.d.ts +476 -0
- package/dist/src/daemon/advance.js +25 -4
- package/dist/src/daemon/advance.js.map +1 -1
- package/dist/src/daemon/audit.d.ts +87 -0
- package/dist/src/daemon/daemon.d.ts +1180 -0
- package/dist/src/daemon/daemon.js +9 -0
- package/dist/src/daemon/daemon.js.map +1 -1
- package/dist/src/daemon/dark-session.d.ts +64 -0
- package/dist/src/daemon/draw-child.d.ts +36 -0
- package/dist/src/daemon/draw.d.ts +154 -0
- package/dist/src/daemon/git-evidence.d.ts +173 -0
- package/dist/src/daemon/git-evidence.js +1 -1
- package/dist/src/daemon/projection.d.ts +180 -0
- package/dist/src/daemon/prune.d.ts +207 -0
- package/dist/src/mcp/http.d.ts +113 -0
- package/dist/src/mcp/server.d.ts +265 -0
- package/dist/src/mcp/server.js +17 -1
- package/dist/src/mcp/server.js.map +1 -1
- package/docs/adapter-api.md +106 -0
- package/docs/cli-reference.md +1316 -63
- package/docs/codex-enforced-session.md +103 -0
- package/docs/codex-workspace-broker.md +118 -0
- package/package.json +14 -2
- package/schema/codex-instance.schema.json +82 -0
- package/schema/event.schema.json +539 -9
- package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
- package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
- package/schema/fixtures/event/invalid/approval-granted-sender-hashed-false.json +20 -0
- package/schema/fixtures/event/invalid/approval-granted-sender-hashed-raw-id.json +20 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-human-actor.json +16 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-no-actor-no-sender.json +15 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-unknown-gesture.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-agent-actor.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-no-question-id.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-unknown-source.json +15 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-absolute-path.json +14 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-agent-actor.json +14 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-missing-path.json +13 -0
- package/schema/fixtures/event/valid/approval-granted-sender-hashed.json +20 -0
- package/schema/fixtures/event/valid/audit-gesture-refused-review-note.json +21 -0
- package/schema/fixtures/event/valid/audit-gesture-refused-sender-key-unavailable.json +19 -0
- package/schema/fixtures/event/valid/audit-gesture-refused.json +19 -0
- package/schema/fixtures/event/valid/audit-question-preempted-no-verdict.json +16 -0
- package/schema/fixtures/event/valid/audit-question-preempted.json +20 -0
- package/schema/fixtures/event/valid/gate-path-signed-off.json +14 -0
- package/schema/fixtures/event/valid/harness-kind-claude-code.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-codex.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-cursor.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-grok.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-muse.json +23 -0
- package/schema/fixtures/policy/invalid/senders-half-keyed.json +20 -0
- package/schema/fixtures/policy/valid/canonical.json +1 -1
- package/schema/fixtures/policy/valid/senders-keyed.json +24 -0
- package/schema/fixtures/policy-md/valid/canonical.md +1 -1
- package/schema/fixtures/policy-md/valid/with-values.md +5 -7
- package/schema/fixtures/values/invalid/class-shaped.json +1 -1
- package/schema/fixtures/values/invalid/duplicate-entry.json +1 -1
- package/schema/fixtures/values/invalid/non-string-item.json +1 -1
- package/schema/fixtures/values/invalid/over-cap.json +1 -1
- package/schema/fixtures/values/invalid/unknown-key.json +1 -1
- package/schema/fixtures/values/invalid/version-float.json +1 -0
- package/schema/fixtures/values/invalid/version-integer.json +1 -0
- package/schema/fixtures/values/invalid/version-wrong-string.json +1 -0
- package/schema/fixtures/values/valid/empty-lists.json +2 -3
- package/schema/fixtures/values/valid/full.json +5 -7
- package/schema/fixtures/values/valid/minimal.json +1 -1
- package/schema/fixtures/values-md/invalid/schema-invalid.md +5 -3
- package/schema/fixtures/values-md/invalid/two-blocks.md +3 -3
- package/schema/fixtures/values-md/invalid/unterminated.md +2 -2
- package/schema/fixtures/values-md/invalid/version-1.md +69 -0
- package/schema/fixtures/values-md/invalid/version-unquoted.md +64 -0
- package/schema/fixtures/values-md/invalid/yaml-error.md +2 -2
- package/schema/fixtures/values-md/valid/absent.md +1 -1
- package/schema/fixtures/values-md/valid/with-values.md +5 -7
- package/schema/policy.schema.json +75 -3
- package/schema/values.schema.json +7 -11
- package/templates/codex/README.md +9 -0
- package/schema/fixtures/values/invalid/version-string.json +0 -1
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The open window (amended SPEC.md §5.2, APRV-214): a human-only, time-boxed
|
|
3
|
+
* suspension of the harness gate's POLICY, so the gate can be debugged from
|
|
4
|
+
* inside a session it would otherwise refuse everything to.
|
|
5
|
+
*
|
|
6
|
+
* ## Why this exists
|
|
7
|
+
*
|
|
8
|
+
* `cli/hook.ts` fails closed on every axis, which is right, and which means the
|
|
9
|
+
* moment the gate itself is broken (an unattested policy, a drifted
|
|
10
|
+
* attestation, a hung daemon, a dark channel) every command a session issues
|
|
11
|
+
* dies, including the ones a person would use to repair it. The only escape
|
|
12
|
+
* before this was hand-editing the hook out of `.claude/settings.json`: an
|
|
13
|
+
* ungated session nobody records, which is the exact failure this project
|
|
14
|
+
* exists to prevent.
|
|
15
|
+
*
|
|
16
|
+
* ## Where the state lives, and why it lives there
|
|
17
|
+
*
|
|
18
|
+
* In the log, as `gate.opened` / `gate.closed`, and NOWHERE else. The
|
|
19
|
+
* `.approval/env` precedent (`cli/init.ts`) states the rule this follows: a
|
|
20
|
+
* file the runtime reads on its own authority lets anything able to write that
|
|
21
|
+
* file act as the human. A window flag in a dotfile would be exactly that, and
|
|
22
|
+
* an agent that can write files is the party the window is a bypass for.
|
|
23
|
+
*
|
|
24
|
+
* The consequence is deliberate and is the property that keeps this safe: a log
|
|
25
|
+
* the hook cannot read, or cannot verify, yields NO window and the hook denies
|
|
26
|
+
* as it always did. The window suspends the policy; it never suspends the log.
|
|
27
|
+
*
|
|
28
|
+
* ## What is derived rather than written
|
|
29
|
+
*
|
|
30
|
+
* Nothing is appended when a window lapses. A reader derives the window from
|
|
31
|
+
* the latest `gate.opened`: it is open when no `gate.closed` names its seq and
|
|
32
|
+
* the moment of asking is before its expiry. Expiry is `ts` plus `duration`,
|
|
33
|
+
* both of which are on the record, and the runtime authored the `ts` at the
|
|
34
|
+
* write boundary (`core/clock.ts`), so an opener cannot author the length of
|
|
35
|
+
* their own window. `expires_at` rides along for a human reading the log; a
|
|
36
|
+
* record claiming one BEYOND `ts + duration` reads as the shorter of the two,
|
|
37
|
+
* and a duration over {@link MAX_WINDOW_MS} is clamped at read time as well as
|
|
38
|
+
* refused at write time. Every path through this file resolves an ambiguity by
|
|
39
|
+
* shortening the window, never by lengthening it.
|
|
40
|
+
*
|
|
41
|
+
* ## What this module does not do
|
|
42
|
+
*
|
|
43
|
+
* It does not decide anything about a command. The hook classifies inside an
|
|
44
|
+
* open window exactly as it does outside one, still denies `log.mutate`, still
|
|
45
|
+
* denies every class the policy reserves to human hands, and still denies a
|
|
46
|
+
* command the classifier cannot read. All this module offers is the derived
|
|
47
|
+
* window and the three appends, each through `core/log.ts`'s `appendEvent` with
|
|
48
|
+
* a compare-and-append precondition (§11.1 invariant 5).
|
|
49
|
+
*
|
|
50
|
+
* `core/gate.ts`'s `startHarnessExecution` is deliberately NOT reused for the
|
|
51
|
+
* bypass record: it refuses on an unattested policy, on manual, on the loop
|
|
52
|
+
* floor and on budget, which are the very things being bypassed. What is reused
|
|
53
|
+
* is the mechanism, `appendEvent` with `expectedHead` under a head-moved retry.
|
|
54
|
+
*/
|
|
55
|
+
import { type ClockOptions } from "./clock.js";
|
|
56
|
+
import { type HarnessProvenance } from "./harness-version.js";
|
|
57
|
+
import { type AppendError, type AppendOptions, type EventRecord } from "./log.js";
|
|
58
|
+
/** What an open window suspends. One value at v0.1, matching the schema enum. */
|
|
59
|
+
export declare const GATE_WINDOW_SCOPE = "hook";
|
|
60
|
+
/** The duration `approval gate open` uses when none is asked for. */
|
|
61
|
+
export declare const DEFAULT_WINDOW = "30m";
|
|
62
|
+
/**
|
|
63
|
+
* The longest window anyone may open, enforced at BOTH ends: `openWindow`
|
|
64
|
+
* refuses a longer one, and {@link openGateWindow} clamps a record claiming one
|
|
65
|
+
* so that a hand-written `gate.opened` buys no more time than the ceremony
|
|
66
|
+
* would have granted.
|
|
67
|
+
*
|
|
68
|
+
* A day, because the window's purpose is one debugging session and because a
|
|
69
|
+
* bypass that outlives the person's attention is a bypass nobody is watching.
|
|
70
|
+
*/
|
|
71
|
+
export declare const MAX_WINDOW_MS: number;
|
|
72
|
+
/**
|
|
73
|
+
* The verb-level refusal codes of the open window. **Frozen union**, in the
|
|
74
|
+
* same sense as `GATE_REFUSAL_CODES`, `EXECUTION_REFUSAL_CODES`,
|
|
75
|
+
* `AUDIT_REFUSAL_CODES`, `DARK_SESSION_CODES` and `HOOK_DENY_CODES`: a caller
|
|
76
|
+
* branches on these, so members are added and never repurposed (SPEC.md §11.1
|
|
77
|
+
* invariant 6, which this makes the sixth such union).
|
|
78
|
+
*
|
|
79
|
+
* Every one of them appends nothing.
|
|
80
|
+
*/
|
|
81
|
+
export declare const GATE_WINDOW_REFUSAL_CODES: readonly [
|
|
82
|
+
/**
|
|
83
|
+
* The actor is not `human:`-prefixed. Opening a window is the one act that
|
|
84
|
+
* suspends the policy, so an agent able to perform it could authorize its own
|
|
85
|
+
* next command. Refused here in code, and again in `event.schema.json`.
|
|
86
|
+
*/
|
|
87
|
+
"actor-not-human",
|
|
88
|
+
/** No reason was given. A bypass nobody stated a reason for cannot be reviewed. */
|
|
89
|
+
"gate-reason-required",
|
|
90
|
+
/**
|
|
91
|
+
* The duration is over {@link MAX_WINDOW_MS}, zero, negative, or unreadable.
|
|
92
|
+
* One code for the family because the repair is one sentence: ask for a
|
|
93
|
+
* shorter window, spelled the way SPEC.md §5.2 spells durations.
|
|
94
|
+
*/
|
|
95
|
+
"gate-duration-too-long",
|
|
96
|
+
/** A window is already open. Close it, or wait for it to lapse. */
|
|
97
|
+
"gate-already-open",
|
|
98
|
+
/**
|
|
99
|
+
* No window is open. `close` says so rather than appending a record that
|
|
100
|
+
* closes nothing, and a bypass asked for with no window behind it at all says
|
|
101
|
+
* so rather than recording a bypass nothing authorized.
|
|
102
|
+
*/
|
|
103
|
+
"gate-not-open",
|
|
104
|
+
/**
|
|
105
|
+
* The window a caller DECIDED under is gone by the time the bypass is
|
|
106
|
+
* recorded (APRV-294).
|
|
107
|
+
*
|
|
108
|
+
* Distinct from `gate-not-open`, and the difference is the fact each states.
|
|
109
|
+
* That one says there was no window to begin with, which is the ordinary
|
|
110
|
+
* closed gate. This one says a window stood when the verdict was formed and
|
|
111
|
+
* does not stand at the append: a human closed it, it lapsed, or a later
|
|
112
|
+
* `gate.opened` superseded the one the caller named. The refusal names the
|
|
113
|
+
* `gate.closed` seq that ended it, or the expiry it ran past, so a reviewer
|
|
114
|
+
* holding the log alone can place the boundary.
|
|
115
|
+
*
|
|
116
|
+
* The repair is a retry, and it is a retry of an ordinary gated tool call:
|
|
117
|
+
* nothing is appended here, nothing ran, and the next invocation derives the
|
|
118
|
+
* window from its own read and is answered by the policy where there is none.
|
|
119
|
+
* A refusal on this path is therefore not a failed execution and accrues no
|
|
120
|
+
* loop-safety streak (SPEC.md §10.2), because no execution was started for it.
|
|
121
|
+
*/
|
|
122
|
+
"gate-window-closed",
|
|
123
|
+
/**
|
|
124
|
+
* Stdin is not a terminal (or `--json` was asked for). The ceremony is a
|
|
125
|
+
* person typing a word, and a prompt a pipe could answer is a ceremony a
|
|
126
|
+
* harness shell tool can perform.
|
|
127
|
+
*/
|
|
128
|
+
"gate-stdin-not-tty",
|
|
129
|
+
/** The typed confirmation was not exactly `understood`. Includes EOF. */
|
|
130
|
+
"gate-confirmation-mismatch",
|
|
131
|
+
/** The log could not be opened. */
|
|
132
|
+
"log-unreadable",
|
|
133
|
+
/** The log's last line is truncated: a crashed write, repaired by a human. */
|
|
134
|
+
"log-torn-tail",
|
|
135
|
+
/** The chain does not verify, so no window may be derived from it. */
|
|
136
|
+
"log-corrupt",
|
|
137
|
+
/** The append itself was refused; `append` carries the writer's own code. */
|
|
138
|
+
"append-failed"];
|
|
139
|
+
export type GateWindowRefusalCode = (typeof GATE_WINDOW_REFUSAL_CODES)[number];
|
|
140
|
+
/** A refusal from this module. Nothing was appended. */
|
|
141
|
+
export interface GateWindowRefusal {
|
|
142
|
+
ok: false;
|
|
143
|
+
code: GateWindowRefusalCode;
|
|
144
|
+
message: string;
|
|
145
|
+
/** The underlying writer error, when `code` is `append-failed`. */
|
|
146
|
+
append?: AppendError;
|
|
147
|
+
}
|
|
148
|
+
/** An open window, as derived from the log. */
|
|
149
|
+
export interface OpenWindow {
|
|
150
|
+
/** The `seq` of the `gate.opened` record. Every bypass names it. */
|
|
151
|
+
seq: number;
|
|
152
|
+
/** The runtime-stamped instant the window opened. */
|
|
153
|
+
openedAt: string;
|
|
154
|
+
/** The human who opened it. */
|
|
155
|
+
openedBy: string;
|
|
156
|
+
/** Why, in their words. */
|
|
157
|
+
reason: string;
|
|
158
|
+
/** The effective length, after the {@link MAX_WINDOW_MS} clamp. */
|
|
159
|
+
durationMs: number;
|
|
160
|
+
/** The effective expiry: the earlier of `ts + duration` and the claim. */
|
|
161
|
+
expiresAt: string;
|
|
162
|
+
/** How many `gate.bypassed` records name this window so far. */
|
|
163
|
+
bypassCount: number;
|
|
164
|
+
}
|
|
165
|
+
/** A successful append, with the window the caller may now report. */
|
|
166
|
+
export interface GateWindowResult {
|
|
167
|
+
ok: true;
|
|
168
|
+
record: EventRecord;
|
|
169
|
+
window: OpenWindow;
|
|
170
|
+
}
|
|
171
|
+
/** A successful close: the record, and the window it ended. */
|
|
172
|
+
export interface GateCloseResult {
|
|
173
|
+
ok: true;
|
|
174
|
+
record: EventRecord;
|
|
175
|
+
closed: OpenWindow;
|
|
176
|
+
}
|
|
177
|
+
/** Options every write here accepts: the injected clock, plus append tuning. */
|
|
178
|
+
export interface GateWindowOptions extends ClockOptions {
|
|
179
|
+
schemaDir?: string;
|
|
180
|
+
append?: AppendOptions;
|
|
181
|
+
/** Lowers the head-moved attempt bound; never raises it. */
|
|
182
|
+
retryOnHeadMoved?: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The window open at `now`, or `null`.
|
|
186
|
+
*
|
|
187
|
+
* Pure over the records it is given, so every caller (the hook, the CLI verb,
|
|
188
|
+
* `approval status`) derives the same fact from the same log and none of them
|
|
189
|
+
* reads a clock of its own.
|
|
190
|
+
*
|
|
191
|
+
* Only the LATEST `gate.opened` is considered. An older one that was never
|
|
192
|
+
* closed is not a second window: the ceremony refuses to open a second while
|
|
193
|
+
* one stands, so an unclosed older record is either lapsed or superseded, and
|
|
194
|
+
* treating it as live would let a stale record outlive the window a human
|
|
195
|
+
* actually opened.
|
|
196
|
+
*
|
|
197
|
+
* Every ambiguity resolves closed. An unreadable duration, a missing reason, a
|
|
198
|
+
* `ts` that does not parse: each yields `null` rather than a window nobody can
|
|
199
|
+
* state the bounds of.
|
|
200
|
+
*/
|
|
201
|
+
export declare function openGateWindow(records: readonly EventRecord[], now?: Date | number): OpenWindow | null;
|
|
202
|
+
/** Milliseconds left on a window at `now`, floored at zero. */
|
|
203
|
+
export declare function remainingMs(window: OpenWindow, now?: Date | number): number;
|
|
204
|
+
/** What `approval gate open` asks for, already parsed by its caller. */
|
|
205
|
+
export interface OpenWindowInput {
|
|
206
|
+
/** The duration as typed (`30m`), recorded verbatim on the event. */
|
|
207
|
+
durationText: string;
|
|
208
|
+
/** The same duration in milliseconds, as the caller parsed it. */
|
|
209
|
+
durationMs: number;
|
|
210
|
+
/** Why the window is being opened. */
|
|
211
|
+
reason: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Append `gate.opened`, after establishing that the actor is a human, the
|
|
215
|
+
* duration is inside the cap, and no window is already open.
|
|
216
|
+
*
|
|
217
|
+
* One `tick()` supplies BOTH the record's `ts` and its `expires_at`, so the two
|
|
218
|
+
* cannot disagree by a scheduling delay and the derived expiry is exactly the
|
|
219
|
+
* claimed one on a record this runtime wrote.
|
|
220
|
+
*/
|
|
221
|
+
export declare function openWindow(logPath: string, input: OpenWindowInput, actor: string, options?: GateWindowOptions): GateWindowResult | GateWindowRefusal;
|
|
222
|
+
/**
|
|
223
|
+
* Append `gate.closed` for whatever window stands.
|
|
224
|
+
*
|
|
225
|
+
* No confirmation anywhere on this path: closing only ever TIGHTENS, and a
|
|
226
|
+
* ceremony guarding the safe direction is a ceremony people learn to type past.
|
|
227
|
+
*/
|
|
228
|
+
export declare function closeWindow(logPath: string, actor: string, options?: GateWindowOptions & {
|
|
229
|
+
note?: string;
|
|
230
|
+
}): GateCloseResult | GateWindowRefusal;
|
|
231
|
+
/** One gated tool call the hook is about to allow because a window is open. */
|
|
232
|
+
export interface GateBypassInput {
|
|
233
|
+
/** The harness tool the call came through. */
|
|
234
|
+
tool: string;
|
|
235
|
+
/** The one-line headline, already truncated to the hook's `SUMMARY_LIMIT`. */
|
|
236
|
+
summary: string;
|
|
237
|
+
/** The classes the command resolved to. At least one. */
|
|
238
|
+
classes: readonly string[];
|
|
239
|
+
/** The `payload_hash` of the binding bytes. */
|
|
240
|
+
payloadHash: string;
|
|
241
|
+
sessionId?: string;
|
|
242
|
+
toolUseId?: string;
|
|
243
|
+
cwd?: string;
|
|
244
|
+
/**
|
|
245
|
+
* Which harness binary is printing the allow, and at what version (APRV-227).
|
|
246
|
+
*
|
|
247
|
+
* Derived by the hook process from its own event and its own PATH and handed
|
|
248
|
+
* in here; copied into the payload verbatim when present, omitted entirely
|
|
249
|
+
* when absent. Nothing reads it back — the window was authorized by a human's
|
|
250
|
+
* `gate.opened` and this pair moves no part of that (SPEC.md §11.1 invariant
|
|
251
|
+
* 4, and `core/harness-version.ts`'s header). What it does is let a reviewer
|
|
252
|
+
* of a bypass see which binary was standing in front of the gate at the time,
|
|
253
|
+
* which on this path is the record a human actually goes back and reads.
|
|
254
|
+
*/
|
|
255
|
+
harness?: HarnessProvenance;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The window verdict a caller already reached, handed to the append that
|
|
259
|
+
* records it (APRV-294).
|
|
260
|
+
*
|
|
261
|
+
* ## Why the append takes the caller's read
|
|
262
|
+
*
|
|
263
|
+
* On 2026-09-07 two hook invocations disagreed about one window inside a
|
|
264
|
+
* minute: the first decided "open" from its own verified read and took the
|
|
265
|
+
* bypass path, and the append re-read, derived no window from the fresher
|
|
266
|
+
* bytes, and refused `gate-not-open`. Both reads were honest and the pair was
|
|
267
|
+
* not: the verdict was formed on one view of the log and acted on another, and
|
|
268
|
+
* the refusal named a state ("no window is open") that had never been true for
|
|
269
|
+
* the invocation being refused.
|
|
270
|
+
*
|
|
271
|
+
* So the decision travels with the write. `read` is the verified read the
|
|
272
|
+
* caller derived its window from, used by the FIRST append attempt, which makes
|
|
273
|
+
* the decision and the record one read rather than two. `openedSeq` is the
|
|
274
|
+
* window that decision named, and it outlives the seed: a `head-moved` retry
|
|
275
|
+
* re-reads (it must — the head it would chain onto has moved), and the window
|
|
276
|
+
* it then derives is compared against this seq, so a window that ended in
|
|
277
|
+
* between refuses {@link GATE_WINDOW_REFUSAL_CODES}'s `gate-window-closed`
|
|
278
|
+
* naming what ended it rather than the bare `gate-not-open`.
|
|
279
|
+
*
|
|
280
|
+
* Nothing here reads unverified bytes as verified: `read` is the caller's own
|
|
281
|
+
* verified read, and every retry past the first performs its own (§11.1
|
|
282
|
+
* invariant 1).
|
|
283
|
+
*/
|
|
284
|
+
export interface GateBypassDecision {
|
|
285
|
+
/** The `seq` of the `gate.opened` the caller's verdict was decided under. */
|
|
286
|
+
openedSeq: number;
|
|
287
|
+
/** The verified read that verdict was formed on. The first attempt uses it. */
|
|
288
|
+
read?: {
|
|
289
|
+
records: readonly EventRecord[];
|
|
290
|
+
head: {
|
|
291
|
+
seq: number;
|
|
292
|
+
hash: string;
|
|
293
|
+
} | null;
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Record a bypassed tool call, BEFORE its allow is printed.
|
|
298
|
+
*
|
|
299
|
+
* The order is record-then-allow for the same reason `recordUnattended`'s is
|
|
300
|
+
* (§11.1 invariant 8): a bypassed command that ran and left no record is the
|
|
301
|
+
* one state this whole feature must not be able to reach, so an append failure
|
|
302
|
+
* is the caller's deny.
|
|
303
|
+
*
|
|
304
|
+
* The window is re-derived on every attempt past the first. A head that moved
|
|
305
|
+
* says the read was stale, so the next attempt re-reads, re-derives, and appends
|
|
306
|
+
* against the head it saw; a window that lapsed or was closed refuses rather
|
|
307
|
+
* than recording a bypass nothing authorized. Which refusal depends on what the
|
|
308
|
+
* caller stated: with a {@link GateBypassDecision} in hand the refusal is
|
|
309
|
+
* `gate-window-closed` and names the record or the expiry that ended the window,
|
|
310
|
+
* and with none it is the historical `gate-not-open`.
|
|
311
|
+
*/
|
|
312
|
+
export declare function recordGateBypass(logPath: string, input: GateBypassInput, actor: string, options?: GateWindowOptions, decided?: GateBypassDecision): GateWindowResult | GateWindowRefusal;
|