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,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The durable half of the Codex workspace broker (APRV-325.2).
|
|
3
|
+
*
|
|
4
|
+
* `workspace-plan.ts` decides what a change IS; this module is the only place
|
|
5
|
+
* that makes one happen. It exists because POSIX gives no atomic multi-file
|
|
6
|
+
* rename: four `rename(2)` calls are four separate instants, and a crash
|
|
7
|
+
* between the second and the third leaves a workspace that is neither the state
|
|
8
|
+
* the human approved nor the state they started from.
|
|
9
|
+
*
|
|
10
|
+
* ## The three states, and the one this module refuses to invent
|
|
11
|
+
*
|
|
12
|
+
* A committed transaction is `after`. An untouched one is `before`. Anything
|
|
13
|
+
* else is `mixed`, and mixed is reported as mixed. The classification is made
|
|
14
|
+
* by READING the filesystem back against the journal's recorded digests, never
|
|
15
|
+
* from what the applying code believes it did: a `rename` that returned zero
|
|
16
|
+
* and a `rename` whose effect a crash lost look identical from inside the
|
|
17
|
+
* process that called it, and only the bytes on disk can tell them apart. That
|
|
18
|
+
* is why {@link inspectWorkspaceState} runs after a successful apply as well as
|
|
19
|
+
* after a failed one, and why a mixed result reaches the log as
|
|
20
|
+
* `execution.indeterminate` with reason `workspace-commit-unknown` rather than
|
|
21
|
+
* as a failure (SPEC.md §8's closed reason set, extended by this task).
|
|
22
|
+
*
|
|
23
|
+
* ## Ordering, and why the journal is written before anything moves
|
|
24
|
+
*
|
|
25
|
+
* 1. Stage every new byte and every preimage into a directory on the SAME
|
|
26
|
+
* filesystem as the workspace, and `fsync` each file and then the directory.
|
|
27
|
+
* Nothing in the workspace has changed yet, so a crash here is `before`.
|
|
28
|
+
* 2. Write the journal — the plan's payload hash, every endpoint, and the
|
|
29
|
+
* before/after digest of each — and `fsync` it and its directory. This is
|
|
30
|
+
* the instant after which a crash is RECOVERABLE rather than merely
|
|
31
|
+
* undecidable: a journal on disk names what the workspace was and what it
|
|
32
|
+
* was becoming, so a later reader can prove which of the two it is in.
|
|
33
|
+
* 3. Apply, in a fixed order, then `fsync` every touched parent directory.
|
|
34
|
+
* 4. Read the endpoints back. Only an all-`after` reading removes the journal
|
|
35
|
+
* as a success; an all-`before` reading removes it as an untaken
|
|
36
|
+
* transaction; a mixed reading LEAVES IT for a person.
|
|
37
|
+
*
|
|
38
|
+
* ## Custody is claimed only as far as the platform proves it
|
|
39
|
+
*
|
|
40
|
+
* {@link acquireWorkspaceCustody} takes an `O_CREAT | O_EXCL` lock, which
|
|
41
|
+
* excludes other cooperating brokers and nothing else, and then asks POSIX
|
|
42
|
+
* ownership and mode whether any other principal can write the endpoints it is
|
|
43
|
+
* about to touch. It reports `os-exclusive` only when both hold, `advisory`
|
|
44
|
+
* otherwise, and it always reports `acl-unproven`, because ownership and mode
|
|
45
|
+
* do not speak about ACLs (the same honesty `codex/trust.ts` already keeps). A
|
|
46
|
+
* caller that needs the strong answer asks for it and is refused when the host
|
|
47
|
+
* cannot give it; nothing here silently downgrades.
|
|
48
|
+
*/
|
|
49
|
+
import { createHash } from "node:crypto";
|
|
50
|
+
import { closeSync, constants, fstatSync, fsyncSync, mkdirSync, openSync, readFileSync, readSync, renameSync, rmSync, statSync, unlinkSync, writeSync, } from "node:fs";
|
|
51
|
+
import { dirname, join, resolve } from "node:path";
|
|
52
|
+
import { canonicalize } from "../core/jcs.js";
|
|
53
|
+
export const WORKSPACE_COMMIT_VERSION = "approval.codex.workspace-commit.v1";
|
|
54
|
+
/**
|
|
55
|
+
* The one directory name inside a workspace root that a proposal may never
|
|
56
|
+
* name (the broker refuses an endpoint under it before the planner ever reads
|
|
57
|
+
* a preimage). Staging has to share a filesystem with the workspace for
|
|
58
|
+
* `rename` to be atomic, so it lives inside it; reserving the name is what
|
|
59
|
+
* stops a proposal from staging over its own transaction.
|
|
60
|
+
*/
|
|
61
|
+
export const WORKSPACE_TXN_DIR = ".approval-codex-txn";
|
|
62
|
+
/** The lockfile, beside the staging directory and under the same reservation. */
|
|
63
|
+
export const WORKSPACE_LOCK_FILE = ".approval-codex-lock";
|
|
64
|
+
const JOURNAL_FILE = "journal.json";
|
|
65
|
+
function fsyncDir(path) {
|
|
66
|
+
let fd = null;
|
|
67
|
+
try {
|
|
68
|
+
fd = openSync(path, constants.O_RDONLY);
|
|
69
|
+
fsyncSync(fd);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// A filesystem that refuses to fsync a directory handle (some network and
|
|
73
|
+
// virtual filesystems do) is reported by the readback, not guessed at here.
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
if (fd !== null)
|
|
77
|
+
closeSync(fd);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function writeDurable(path, bytes) {
|
|
81
|
+
const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, 0o600);
|
|
82
|
+
try {
|
|
83
|
+
let written = 0;
|
|
84
|
+
while (written < bytes.byteLength) {
|
|
85
|
+
written += writeSync(fd, bytes, written, bytes.byteLength - written);
|
|
86
|
+
}
|
|
87
|
+
fsyncSync(fd);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
closeSync(fd);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Is `path` writable by a principal other than this process's effective user,
|
|
95
|
+
* as far as POSIX ownership and mode can say?
|
|
96
|
+
*
|
|
97
|
+
* `null` means the question could not be asked (the path could not be stated),
|
|
98
|
+
* which is not the same as "no" and is never read as one.
|
|
99
|
+
*/
|
|
100
|
+
function foreignWritable(path) {
|
|
101
|
+
try {
|
|
102
|
+
const stats = statSync(path);
|
|
103
|
+
if ((stats.mode & 0o022) !== 0)
|
|
104
|
+
return true;
|
|
105
|
+
return stats.uid !== process.getuid?.();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Take the workspace lock and report how much exclusion it bought.
|
|
113
|
+
*
|
|
114
|
+
* The lock is `O_CREAT | O_EXCL` on a reserved name, which is the strongest
|
|
115
|
+
* primitive available to a process with no privilege: it excludes every other
|
|
116
|
+
* broker that respects it and no one else. Whether anything else CAN write is a
|
|
117
|
+
* separate question, asked of POSIX afterwards, and answered conservatively.
|
|
118
|
+
*/
|
|
119
|
+
export function acquireWorkspaceCustody(root, touchedDirectories) {
|
|
120
|
+
const lockPath = join(root, WORKSPACE_LOCK_FILE);
|
|
121
|
+
const txnDir = join(root, WORKSPACE_TXN_DIR);
|
|
122
|
+
let lockFd;
|
|
123
|
+
try {
|
|
124
|
+
lockFd = openSync(lockPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, 0o600);
|
|
125
|
+
}
|
|
126
|
+
catch (cause) {
|
|
127
|
+
const code = cause.code;
|
|
128
|
+
if (code === "EEXIST") {
|
|
129
|
+
return {
|
|
130
|
+
ok: false,
|
|
131
|
+
code: "custody-contended",
|
|
132
|
+
message: `another workspace transaction holds ${lockPath}; no operation was attempted`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
code: "custody-unavailable",
|
|
138
|
+
message: `workspace lock ${lockPath} could not be created: ${String(code ?? cause)}`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
closeSync(lockFd);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// The lock is the file's existence, not the descriptor.
|
|
146
|
+
}
|
|
147
|
+
const findings = ["acl-unproven"];
|
|
148
|
+
let exclusive = true;
|
|
149
|
+
for (const directory of [root, ...touchedDirectories]) {
|
|
150
|
+
const foreign = foreignWritable(directory);
|
|
151
|
+
if (foreign === null) {
|
|
152
|
+
findings.push(`custody-unreadable:${directory}`);
|
|
153
|
+
exclusive = false;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (foreign) {
|
|
157
|
+
findings.push(`foreign-writable:${directory}`);
|
|
158
|
+
exclusive = false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
mkdirSync(txnDir, { mode: 0o700 });
|
|
163
|
+
}
|
|
164
|
+
catch (cause) {
|
|
165
|
+
try {
|
|
166
|
+
unlinkSync(lockPath);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Best effort: the failure below is the one that matters.
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
ok: false,
|
|
173
|
+
code: "custody-unavailable",
|
|
174
|
+
message: `staging directory ${txnDir} could not be created: ${String(cause.code ?? cause)}`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
fsyncDir(root);
|
|
178
|
+
return {
|
|
179
|
+
ok: true,
|
|
180
|
+
custody: {
|
|
181
|
+
report: { kind: exclusive ? "os-exclusive" : "advisory", findings },
|
|
182
|
+
root,
|
|
183
|
+
txnDir,
|
|
184
|
+
release: () => {
|
|
185
|
+
try {
|
|
186
|
+
rmSync(txnDir, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Leaving staging behind is visible to recovery and to a person.
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
unlinkSync(lockPath);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Same.
|
|
196
|
+
}
|
|
197
|
+
fsyncDir(root);
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function sha256(bytes) {
|
|
203
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The endpoints one planned operation owns, in the shape recovery reads.
|
|
207
|
+
*
|
|
208
|
+
* A move owns two, and the second one's `before` is deliberately `null`: the
|
|
209
|
+
* planner refuses a move whose destination exists, so "absent" is the state the
|
|
210
|
+
* transaction started from and the state a rollback must restore.
|
|
211
|
+
*/
|
|
212
|
+
export function journalEndpointsOf(operation) {
|
|
213
|
+
switch (operation.kind) {
|
|
214
|
+
case "create":
|
|
215
|
+
return [{ path: operation.path, before_sha256: null, after_sha256: operation.after.sha256 }];
|
|
216
|
+
case "replace":
|
|
217
|
+
return [{
|
|
218
|
+
path: operation.path,
|
|
219
|
+
before_sha256: operation.before.sha256,
|
|
220
|
+
after_sha256: operation.after.sha256,
|
|
221
|
+
}];
|
|
222
|
+
case "delete":
|
|
223
|
+
return [{ path: operation.path, before_sha256: operation.before.sha256, after_sha256: null }];
|
|
224
|
+
case "move":
|
|
225
|
+
return [
|
|
226
|
+
{ path: operation.from, before_sha256: operation.before.sha256, after_sha256: null },
|
|
227
|
+
{ path: operation.to, before_sha256: null, after_sha256: operation.before.sha256 },
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function newBytesOf(operation) {
|
|
232
|
+
if (operation.kind === "create" || operation.kind === "replace") {
|
|
233
|
+
return Buffer.from(operation.after.base64, "base64");
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
function preimageBytesOf(operation) {
|
|
238
|
+
if (operation.kind === "create")
|
|
239
|
+
return null;
|
|
240
|
+
return Buffer.from(operation.before.base64, "base64");
|
|
241
|
+
}
|
|
242
|
+
/** Every parent directory a transaction will write into, absolute and deduplicated. */
|
|
243
|
+
export function touchedDirectories(plan) {
|
|
244
|
+
const seen = new Set();
|
|
245
|
+
for (const operation of plan.payload.operations) {
|
|
246
|
+
for (const endpoint of journalEndpointsOf(operation)) {
|
|
247
|
+
seen.add(dirname(resolve(plan.payload.root, endpoint.path)));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return [...seen].sort();
|
|
251
|
+
}
|
|
252
|
+
const MAX_READBACK_BYTES = 1_048_576;
|
|
253
|
+
/**
|
|
254
|
+
* The digest of a regular single-link file, `null` when it is absent, and
|
|
255
|
+
* `undefined` when the question could not be answered.
|
|
256
|
+
*
|
|
257
|
+
* `O_NOFOLLOW` and the `nlink` test are the planner's rules, repeated here
|
|
258
|
+
* because a readback that followed a symlink planted between the apply and the
|
|
259
|
+
* inspection would report someone else's bytes as this transaction's outcome.
|
|
260
|
+
*/
|
|
261
|
+
function readbackDigest(path) {
|
|
262
|
+
let fd = null;
|
|
263
|
+
try {
|
|
264
|
+
fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
265
|
+
}
|
|
266
|
+
catch (cause) {
|
|
267
|
+
const code = cause.code;
|
|
268
|
+
if (code === "ENOENT")
|
|
269
|
+
return null;
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
try {
|
|
273
|
+
const stats = fstatSync(fd, { bigint: true });
|
|
274
|
+
if (!stats.isFile() || stats.nlink !== 1n)
|
|
275
|
+
return undefined;
|
|
276
|
+
if (stats.size > BigInt(MAX_READBACK_BYTES))
|
|
277
|
+
return undefined;
|
|
278
|
+
const buffer = Buffer.alloc(Number(stats.size));
|
|
279
|
+
let length = 0;
|
|
280
|
+
while (length < buffer.byteLength) {
|
|
281
|
+
const count = readSync(fd, buffer, length, buffer.byteLength - length, length);
|
|
282
|
+
if (count === 0)
|
|
283
|
+
break;
|
|
284
|
+
length += count;
|
|
285
|
+
}
|
|
286
|
+
if (length !== buffer.byteLength)
|
|
287
|
+
return undefined;
|
|
288
|
+
return sha256(buffer);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
finally {
|
|
294
|
+
closeSync(fd);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function endpointState(root, endpoint) {
|
|
298
|
+
const digest = readbackDigest(resolve(root, endpoint.path));
|
|
299
|
+
if (digest === undefined)
|
|
300
|
+
return "unreadable";
|
|
301
|
+
const isAfter = digest === endpoint.after_sha256;
|
|
302
|
+
const isBefore = digest === endpoint.before_sha256;
|
|
303
|
+
// `before` wins a tie, and a tie is real: a replace whose new bytes equal its
|
|
304
|
+
// old bytes is both, and calling it `before` can only under-claim.
|
|
305
|
+
if (isBefore)
|
|
306
|
+
return "before";
|
|
307
|
+
if (isAfter)
|
|
308
|
+
return "after";
|
|
309
|
+
return "other";
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Classify the workspace against a journal by reading it.
|
|
313
|
+
*
|
|
314
|
+
* `mixed` is the honest answer for anything that is not uniformly one state,
|
|
315
|
+
* INCLUDING a single unreadable endpoint: "I could not look" and "it is half
|
|
316
|
+
* done" are both "nobody knows", and collapsing the first into `before` would
|
|
317
|
+
* be the runtime deciding an effect did not happen.
|
|
318
|
+
*/
|
|
319
|
+
export function inspectWorkspaceState(journal) {
|
|
320
|
+
const endpoints = [];
|
|
321
|
+
for (const operation of journal.operations) {
|
|
322
|
+
for (const endpoint of operation.endpoints) {
|
|
323
|
+
endpoints.push({ path: endpoint.path, state: endpointState(journal.root, endpoint) });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const every = (state) => endpoints.every((entry) => entry.state === state);
|
|
327
|
+
if (endpoints.length > 0 && every("after"))
|
|
328
|
+
return { state: "after", endpoints };
|
|
329
|
+
if (endpoints.length === 0 || every("before"))
|
|
330
|
+
return { state: "before", endpoints };
|
|
331
|
+
return { state: "mixed", endpoints };
|
|
332
|
+
}
|
|
333
|
+
function journalPath(txnDir) {
|
|
334
|
+
return join(txnDir, JOURNAL_FILE);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Stage, journal, apply, read back.
|
|
338
|
+
*
|
|
339
|
+
* The caller holds custody (and therefore the staging directory) and keeps it
|
|
340
|
+
* until this returns. A `stage-failed` result is the one result that guarantees
|
|
341
|
+
* the workspace is untouched by construction rather than by inspection: nothing
|
|
342
|
+
* visible has been attempted when it fires.
|
|
343
|
+
*/
|
|
344
|
+
export function commitWorkspacePlan(plan, custody, options = {}) {
|
|
345
|
+
const { root, txnDir } = custody;
|
|
346
|
+
const operations = [];
|
|
347
|
+
// --- Phase 1: stage. Nothing in the workspace changes. ------------------
|
|
348
|
+
try {
|
|
349
|
+
for (let index = 0; index < plan.payload.operations.length; index += 1) {
|
|
350
|
+
const operation = plan.payload.operations[index];
|
|
351
|
+
const newBytes = newBytesOf(operation);
|
|
352
|
+
const preimage = preimageBytesOf(operation);
|
|
353
|
+
const staged = newBytes === null ? null : `new-${String(index)}`;
|
|
354
|
+
const saved = preimage === null ? null : `old-${String(index)}`;
|
|
355
|
+
if (staged !== null && newBytes !== null)
|
|
356
|
+
writeDurable(join(txnDir, staged), newBytes);
|
|
357
|
+
if (saved !== null && preimage !== null)
|
|
358
|
+
writeDurable(join(txnDir, saved), preimage);
|
|
359
|
+
operations.push({
|
|
360
|
+
index,
|
|
361
|
+
kind: operation.kind,
|
|
362
|
+
endpoints: journalEndpointsOf(operation),
|
|
363
|
+
staged,
|
|
364
|
+
preimage: saved,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
fsyncDir(txnDir);
|
|
368
|
+
}
|
|
369
|
+
catch (cause) {
|
|
370
|
+
return {
|
|
371
|
+
ok: false,
|
|
372
|
+
code: "stage-failed",
|
|
373
|
+
message: `workspace staging failed before any mutation: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
const journal = {
|
|
377
|
+
version: WORKSPACE_COMMIT_VERSION,
|
|
378
|
+
root,
|
|
379
|
+
payload_hash: plan.payload_hash,
|
|
380
|
+
custody: custody.report.kind,
|
|
381
|
+
operations,
|
|
382
|
+
};
|
|
383
|
+
// --- Phase 2: the journal, durable, before anything moves. --------------
|
|
384
|
+
try {
|
|
385
|
+
writeDurable(journalPath(txnDir), Buffer.from(canonicalize(journal), "utf8"));
|
|
386
|
+
fsyncDir(txnDir);
|
|
387
|
+
}
|
|
388
|
+
catch (cause) {
|
|
389
|
+
return {
|
|
390
|
+
ok: false,
|
|
391
|
+
code: "stage-failed",
|
|
392
|
+
message: `workspace journal could not be made durable before any mutation: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
// --- Phase 3: apply. From here the answer comes from reading. -----------
|
|
396
|
+
let failure;
|
|
397
|
+
try {
|
|
398
|
+
options.onStep?.(0);
|
|
399
|
+
for (const entry of operations) {
|
|
400
|
+
const operation = plan.payload.operations[entry.index];
|
|
401
|
+
applyOne(root, txnDir, operation, entry);
|
|
402
|
+
options.onStep?.(entry.index + 1);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch (cause) {
|
|
406
|
+
failure = cause instanceof Error ? cause.message : String(cause);
|
|
407
|
+
}
|
|
408
|
+
for (const directory of touchedDirectories(plan))
|
|
409
|
+
fsyncDir(directory);
|
|
410
|
+
// --- Phase 4: a failed apply tries to undo itself, and is then read. ----
|
|
411
|
+
if (failure !== undefined) {
|
|
412
|
+
try {
|
|
413
|
+
rollback(root, txnDir, operations);
|
|
414
|
+
}
|
|
415
|
+
catch (cause) {
|
|
416
|
+
failure = `${failure}; rollback also failed: ${cause instanceof Error ? cause.message : String(cause)}`;
|
|
417
|
+
}
|
|
418
|
+
for (const directory of touchedDirectories(plan))
|
|
419
|
+
fsyncDir(directory);
|
|
420
|
+
}
|
|
421
|
+
const inspection = inspectWorkspaceState(journal);
|
|
422
|
+
const retained = inspection.state === "mixed";
|
|
423
|
+
if (!retained) {
|
|
424
|
+
try {
|
|
425
|
+
unlinkSync(journalPath(txnDir));
|
|
426
|
+
fsyncDir(txnDir);
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
// Recovery reads a journal beside a settled workspace as settled.
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return {
|
|
433
|
+
ok: true,
|
|
434
|
+
outcome: {
|
|
435
|
+
state: inspection.state,
|
|
436
|
+
inspection,
|
|
437
|
+
journal,
|
|
438
|
+
journalRetained: retained,
|
|
439
|
+
...(failure === undefined ? {} : { failure }),
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function applyOne(root, txnDir, operation, entry) {
|
|
444
|
+
switch (operation.kind) {
|
|
445
|
+
case "create":
|
|
446
|
+
case "replace":
|
|
447
|
+
renameSync(join(txnDir, entry.staged), resolve(root, operation.path));
|
|
448
|
+
return;
|
|
449
|
+
case "delete":
|
|
450
|
+
unlinkSync(resolve(root, operation.path));
|
|
451
|
+
return;
|
|
452
|
+
case "move":
|
|
453
|
+
renameSync(resolve(root, operation.from), resolve(root, operation.to));
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Put every endpoint back the way the journal says it was, from the staged
|
|
459
|
+
* preimages.
|
|
460
|
+
*
|
|
461
|
+
* Best effort by construction: it is attempted, and then the workspace is READ.
|
|
462
|
+
* A rollback that half worked produces `mixed` from the inspection, which is
|
|
463
|
+
* the same answer a rollback that was never attempted would produce, and that
|
|
464
|
+
* is deliberate — the classification must not depend on what this function
|
|
465
|
+
* thinks it achieved.
|
|
466
|
+
*/
|
|
467
|
+
function rollback(root, txnDir, operations) {
|
|
468
|
+
const problems = [];
|
|
469
|
+
for (let index = operations.length - 1; index >= 0; index -= 1) {
|
|
470
|
+
const entry = operations[index];
|
|
471
|
+
try {
|
|
472
|
+
for (let slot = 0; slot < entry.endpoints.length; slot += 1) {
|
|
473
|
+
const endpoint = entry.endpoints[slot];
|
|
474
|
+
const target = resolve(root, endpoint.path);
|
|
475
|
+
if (endpoint.before_sha256 === null) {
|
|
476
|
+
try {
|
|
477
|
+
unlinkSync(target);
|
|
478
|
+
}
|
|
479
|
+
catch (cause) {
|
|
480
|
+
if (cause.code !== "ENOENT")
|
|
481
|
+
throw cause;
|
|
482
|
+
}
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
if (readbackDigest(target) === endpoint.before_sha256)
|
|
486
|
+
continue;
|
|
487
|
+
if (entry.preimage === null)
|
|
488
|
+
continue;
|
|
489
|
+
const restored = join(txnDir, `restore-${String(index)}-${String(slot)}`);
|
|
490
|
+
writeDurable(restored, readFileSync(join(txnDir, entry.preimage)));
|
|
491
|
+
renameSync(restored, target);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
catch (cause) {
|
|
495
|
+
problems.push(cause instanceof Error ? cause.message : String(cause));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
if (problems.length > 0)
|
|
499
|
+
throw new Error(problems.join("; "));
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Read a workspace's retained journal and say which of the three states it is
|
|
503
|
+
* in. It CHANGES NOTHING in the workspace.
|
|
504
|
+
*
|
|
505
|
+
* That is the whole contract, and the restraint is the point: a recovery that
|
|
506
|
+
* rolled a mixed workspace forward would be guessing which half of it the
|
|
507
|
+
* human approved, and a recovery that rolled one back would be deleting the
|
|
508
|
+
* half that already committed. Both are the runtime inventing a fact. A proven
|
|
509
|
+
* `before` or `after` needs no repair by definition, so there is nothing left
|
|
510
|
+
* for this function to do but say so and let the operator clear the staging
|
|
511
|
+
* directory.
|
|
512
|
+
*/
|
|
513
|
+
export function recoverWorkspaceCommit(root) {
|
|
514
|
+
const path = journalPath(join(root, WORKSPACE_TXN_DIR));
|
|
515
|
+
let raw;
|
|
516
|
+
try {
|
|
517
|
+
raw = readFileSync(path, "utf8");
|
|
518
|
+
}
|
|
519
|
+
catch (cause) {
|
|
520
|
+
if (cause.code === "ENOENT") {
|
|
521
|
+
return { ok: true, state: "none", message: `no workspace transaction journal at ${path}` };
|
|
522
|
+
}
|
|
523
|
+
return {
|
|
524
|
+
ok: false,
|
|
525
|
+
code: "journal-unreadable",
|
|
526
|
+
message: `workspace transaction journal ${path} could not be read: ${String(cause.code ?? cause)}`,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
let journal;
|
|
530
|
+
try {
|
|
531
|
+
const parsed = JSON.parse(raw);
|
|
532
|
+
if (typeof parsed !== "object" || parsed === null ||
|
|
533
|
+
parsed.version !== WORKSPACE_COMMIT_VERSION ||
|
|
534
|
+
!Array.isArray(parsed.operations)) {
|
|
535
|
+
return { ok: false, code: "journal-unreadable", message: `${path} is not a v1 workspace transaction journal` };
|
|
536
|
+
}
|
|
537
|
+
journal = parsed;
|
|
538
|
+
}
|
|
539
|
+
catch (cause) {
|
|
540
|
+
return {
|
|
541
|
+
ok: false,
|
|
542
|
+
code: "journal-unreadable",
|
|
543
|
+
message: `${path} is not parseable JSON: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
const inspection = inspectWorkspaceState(journal);
|
|
547
|
+
return { ok: true, state: inspection.state, inspection, journal };
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=workspace-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-commit.js","sourceRoot":"","sources":["../../../src/codex/workspace-commit.ts"],"names":[],"mappings":"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"}
|