project-tiny-context-harness 0.8.17 → 0.11.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 +93 -30
- package/assets/README.md +158 -44
- package/assets/README.zh-CN.md +88 -29
- package/assets/agents/AGENTS_CORE.md +2 -2
- package/assets/context_templates/context.toml +6 -1
- package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_helpers.cs +301 -0
- package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_run.cs +197 -0
- package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_types.cs +215 -0
- package/assets/runtime/windows-job-supervisor/windows_job_process_supervisor.ps1 +117 -0
- package/assets/skills/design-resource-authoring/SKILL.md +6 -3
- package/assets/skills/design-resource-authoring/references/authority-delta-assessment.md +52 -0
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +5 -1
- package/assets/skills/design-system-authoring/SKILL.md +23 -17
- package/assets/skills/design-system-authoring/references/authority-adoption.md +19 -9
- package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +4 -0
- package/assets/skills/long-task-workflow/SKILL.md +6 -6
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +10 -4
- package/assets/skills/long-task-workflow/references/contract-authoring.md +5 -5
- package/assets/skills/long-task-workflow/references/evidence-design.md +14 -3
- package/assets/skills/long-task-workflow/references/source-authoring.md +11 -8
- package/assets/tools/context_rules.json +53 -0
- package/assets/tools/validate_context.py +302 -77
- package/dist/cli.js +2 -1
- package/dist/commands/context-create.d.ts +1 -0
- package/dist/commands/context-create.js +90 -0
- package/dist/commands/context-inspect.d.ts +1 -0
- package/dist/commands/context-inspect.js +98 -0
- package/dist/commands/context-move.d.ts +1 -0
- package/dist/commands/context-move.js +78 -0
- package/dist/commands/context-register.d.ts +1 -0
- package/dist/commands/context-register.js +110 -0
- package/dist/commands/context-transaction.d.ts +1 -0
- package/dist/commands/context-transaction.js +84 -0
- package/dist/commands/context.d.ts +1 -0
- package/dist/commands/context.js +36 -0
- package/dist/commands/design-authority-delta.d.ts +1 -0
- package/dist/commands/design-authority-delta.js +53 -0
- package/dist/commands/design-authority.d.ts +1 -0
- package/dist/commands/design-authority.js +104 -0
- package/dist/commands/design-resource.js +8 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +61 -3
- package/dist/commands/index.js +19 -2
- package/dist/commands/long-task-authoring.js +20 -2
- package/dist/commands/long-task-workdir.d.ts +2 -0
- package/dist/commands/long-task-workdir.js +23 -0
- package/dist/commands/long-task.js +75 -6
- package/dist/commands/route.d.ts +15 -0
- package/dist/commands/route.js +142 -0
- package/dist/index.d.ts +3 -13
- package/dist/index.js +3 -12
- package/dist/lib/cli-exit.d.ts +14 -0
- package/dist/lib/cli-exit.js +19 -0
- package/dist/lib/context-catalog/catalog-default-footprint.d.ts +3 -0
- package/dist/lib/context-catalog/catalog-default-footprint.js +53 -0
- package/dist/lib/context-catalog/catalog-diagnostics.d.ts +9 -0
- package/dist/lib/context-catalog/catalog-diagnostics.js +34 -0
- package/dist/lib/context-catalog/catalog-discovery.d.ts +7 -0
- package/dist/lib/context-catalog/catalog-discovery.js +81 -0
- package/dist/lib/context-catalog/catalog-load.d.ts +8 -0
- package/dist/lib/context-catalog/catalog-load.js +187 -0
- package/dist/lib/context-catalog/catalog-path-validation.d.ts +7 -0
- package/dist/lib/context-catalog/catalog-path-validation.js +62 -0
- package/dist/lib/context-catalog/catalog-paths.d.ts +11 -0
- package/dist/lib/context-catalog/catalog-paths.js +41 -0
- package/dist/lib/context-catalog/catalog-portable-contract.d.ts +15 -0
- package/dist/lib/context-catalog/catalog-portable-contract.js +68 -0
- package/dist/lib/context-catalog/catalog-staged-path-safety.d.ts +1 -0
- package/dist/lib/context-catalog/catalog-staged-path-safety.js +36 -0
- package/dist/lib/context-catalog/catalog-types.d.ts +40 -0
- package/dist/lib/context-catalog/catalog-types.js +1 -0
- package/dist/lib/context-catalog/catalog-validation.d.ts +9 -0
- package/dist/lib/context-catalog/catalog-validation.js +148 -0
- package/dist/lib/context-create/context-create-path.d.ts +2 -0
- package/dist/lib/context-create/context-create-path.js +30 -0
- package/dist/lib/context-create/context-create-template.d.ts +2 -0
- package/dist/lib/context-create/context-create-template.js +95 -0
- package/dist/lib/context-create/context-create-types.d.ts +28 -0
- package/dist/lib/context-create/context-create-types.js +1 -0
- package/dist/lib/context-create/context-create-write.d.ts +1 -0
- package/dist/lib/context-create/context-create-write.js +85 -0
- package/dist/lib/context-create/context-create.d.ts +2 -0
- package/dist/lib/context-create/context-create.js +84 -0
- package/dist/lib/context-default-footprint.d.ts +2 -3
- package/dist/lib/context-default-footprint.js +49 -57
- package/dist/lib/context-doctor/context-doctor-types.d.ts +16 -0
- package/dist/lib/context-doctor/context-doctor-types.js +15 -0
- package/dist/lib/context-doctor/context-doctor.d.ts +2 -0
- package/dist/lib/context-doctor/context-doctor.js +130 -0
- package/dist/lib/context-graph-snapshot.d.ts +5 -0
- package/dist/lib/context-graph-snapshot.js +46 -25
- package/dist/lib/context-inspect/context-inspect-projection.d.ts +9 -0
- package/dist/lib/context-inspect/context-inspect-projection.js +49 -0
- package/dist/lib/context-inspect/context-inspect-render.d.ts +2 -0
- package/dist/lib/context-inspect/context-inspect-render.js +29 -0
- package/dist/lib/context-inspect/context-inspect-types.d.ts +43 -0
- package/dist/lib/context-inspect/context-inspect-types.js +1 -0
- package/dist/lib/context-inspect/context-inspect.d.ts +2 -0
- package/dist/lib/context-inspect/context-inspect.js +104 -0
- package/dist/lib/context-manifest-schema.d.ts +1 -1
- package/dist/lib/context-manifest-schema.js +4 -20
- package/dist/lib/context-markdown/context-markdown-analysis.d.ts +15 -0
- package/dist/lib/context-markdown/context-markdown-analysis.js +245 -0
- package/dist/lib/context-markdown/context-markdown-extract.d.ts +7 -0
- package/dist/lib/context-markdown/context-markdown-extract.js +114 -0
- package/dist/lib/context-markdown/context-markdown-types.d.ts +57 -0
- package/dist/lib/context-markdown/context-markdown-types.js +1 -0
- package/dist/lib/context-move/context-move-input.d.ts +8 -0
- package/dist/lib/context-move/context-move-input.js +17 -0
- package/dist/lib/context-move/context-move-literal-scan.d.ts +20 -0
- package/dist/lib/context-move/context-move-literal-scan.js +213 -0
- package/dist/lib/context-move/context-move-live-validation.d.ts +3 -0
- package/dist/lib/context-move/context-move-live-validation.js +56 -0
- package/dist/lib/context-move/context-move-markdown-plan.d.ts +22 -0
- package/dist/lib/context-move/context-move-markdown-plan.js +39 -0
- package/dist/lib/context-move/context-move-projection.d.ts +3 -0
- package/dist/lib/context-move/context-move-projection.js +11 -0
- package/dist/lib/context-move/context-move-reference-validation.d.ts +11 -0
- package/dist/lib/context-move/context-move-reference-validation.js +64 -0
- package/dist/lib/context-move/context-move-render.d.ts +2 -0
- package/dist/lib/context-move/context-move-render.js +24 -0
- package/dist/lib/context-move/context-move-support.d.ts +10 -0
- package/dist/lib/context-move/context-move-support.js +88 -0
- package/dist/lib/context-move/context-move-transaction-plan.d.ts +24 -0
- package/dist/lib/context-move/context-move-transaction-plan.js +108 -0
- package/dist/lib/context-move/context-move-types.d.ts +74 -0
- package/dist/lib/context-move/context-move-types.js +1 -0
- package/dist/lib/context-move/context-move.d.ts +8 -0
- package/dist/lib/context-move/context-move.js +180 -0
- package/dist/lib/context-mutation/manifest-lossless-patch.d.ts +28 -0
- package/dist/lib/context-mutation/manifest-lossless-patch.js +208 -0
- package/dist/lib/context-mutation/markdown-link-patch.d.ts +34 -0
- package/dist/lib/context-mutation/markdown-link-patch.js +143 -0
- package/dist/lib/context-mutation/markdown-link-spans.d.ts +10 -0
- package/dist/lib/context-mutation/markdown-link-spans.js +179 -0
- package/dist/lib/context-mutation/mutation-cas.d.ts +13 -0
- package/dist/lib/context-mutation/mutation-cas.js +365 -0
- package/dist/lib/context-mutation/mutation-command-support.d.ts +12 -0
- package/dist/lib/context-mutation/mutation-command-support.js +57 -0
- package/dist/lib/context-mutation/mutation-commit.d.ts +12 -0
- package/dist/lib/context-mutation/mutation-commit.js +89 -0
- package/dist/lib/context-mutation/mutation-directories.d.ts +5 -0
- package/dist/lib/context-mutation/mutation-directories.js +56 -0
- package/dist/lib/context-mutation/mutation-file-state.d.ts +14 -0
- package/dist/lib/context-mutation/mutation-file-state.js +137 -0
- package/dist/lib/context-mutation/mutation-journal-file-validation.d.ts +1 -0
- package/dist/lib/context-mutation/mutation-journal-file-validation.js +106 -0
- package/dist/lib/context-mutation/mutation-journal-io.d.ts +5 -0
- package/dist/lib/context-mutation/mutation-journal-io.js +55 -0
- package/dist/lib/context-mutation/mutation-journal-storage.d.ts +18 -0
- package/dist/lib/context-mutation/mutation-journal-storage.js +283 -0
- package/dist/lib/context-mutation/mutation-journal-validation-support.d.ts +16 -0
- package/dist/lib/context-mutation/mutation-journal-validation-support.js +140 -0
- package/dist/lib/context-mutation/mutation-journal-validation.d.ts +3 -0
- package/dist/lib/context-mutation/mutation-journal-validation.js +177 -0
- package/dist/lib/context-mutation/mutation-journal.d.ts +8 -0
- package/dist/lib/context-mutation/mutation-journal.js +111 -0
- package/dist/lib/context-mutation/mutation-live-validation.d.ts +3 -0
- package/dist/lib/context-mutation/mutation-live-validation.js +51 -0
- package/dist/lib/context-mutation/mutation-long-task-guard.d.ts +6 -0
- package/dist/lib/context-mutation/mutation-long-task-guard.js +57 -0
- package/dist/lib/context-mutation/mutation-recovery.d.ts +4 -0
- package/dist/lib/context-mutation/mutation-recovery.js +189 -0
- package/dist/lib/context-mutation/mutation-staged-fs.d.ts +5 -0
- package/dist/lib/context-mutation/mutation-staged-fs.js +56 -0
- package/dist/lib/context-mutation/mutation-types.d.ts +103 -0
- package/dist/lib/context-mutation/mutation-types.js +1 -0
- package/dist/lib/context-register/context-register-input.d.ts +11 -0
- package/dist/lib/context-register/context-register-input.js +43 -0
- package/dist/lib/context-register/context-register-render.d.ts +2 -0
- package/dist/lib/context-register/context-register-render.js +21 -0
- package/dist/lib/context-register/context-register-support.d.ts +6 -0
- package/dist/lib/context-register/context-register-support.js +46 -0
- package/dist/lib/context-register/context-register-types.d.ts +46 -0
- package/dist/lib/context-register/context-register-types.js +1 -0
- package/dist/lib/context-register/context-register.d.ts +8 -0
- package/dist/lib/context-register/context-register.js +155 -0
- package/dist/lib/context-router/context-route-budget.d.ts +15 -0
- package/dist/lib/context-router/context-route-budget.js +14 -0
- package/dist/lib/context-router/context-route-candidates.d.ts +15 -0
- package/dist/lib/context-router/context-route-candidates.js +112 -0
- package/dist/lib/context-router/context-route-order.d.ts +6 -0
- package/dist/lib/context-router/context-route-order.js +53 -0
- package/dist/lib/context-router/context-route-paths.d.ts +16 -0
- package/dist/lib/context-router/context-route-paths.js +109 -0
- package/dist/lib/context-router/context-route-render.d.ts +2 -0
- package/dist/lib/context-router/context-route-render.js +32 -0
- package/dist/lib/context-router/context-route-scan.d.ts +18 -0
- package/dist/lib/context-router/context-route-scan.js +156 -0
- package/dist/lib/context-router/context-route-selection.d.ts +16 -0
- package/dist/lib/context-router/context-route-selection.js +72 -0
- package/dist/lib/context-router/context-route-terms.d.ts +13 -0
- package/dist/lib/context-router/context-route-terms.js +202 -0
- package/dist/lib/context-router/context-route-types.d.ts +101 -0
- package/dist/lib/context-router/context-route-types.js +1 -0
- package/dist/lib/context-router/context-route.d.ts +2 -0
- package/dist/lib/context-router/context-route.js +127 -0
- package/dist/lib/context-units-migration.d.ts +13 -0
- package/dist/lib/context-units-migration.js +217 -0
- package/dist/lib/design-authority-binding.d.ts +7 -0
- package/dist/lib/design-authority-binding.js +96 -0
- package/dist/lib/design-authority-closure.d.ts +3 -0
- package/dist/lib/design-authority-closure.js +201 -0
- package/dist/lib/design-authority-delta-codec-primitives.d.ts +10 -0
- package/dist/lib/design-authority-delta-codec-primitives.js +58 -0
- package/dist/lib/design-authority-delta-codec.d.ts +2 -0
- package/dist/lib/design-authority-delta-codec.js +193 -0
- package/dist/lib/design-authority-delta-types.d.ts +65 -0
- package/dist/lib/design-authority-delta-types.js +6 -0
- package/dist/lib/design-authority-delta-validation.d.ts +2 -0
- package/dist/lib/design-authority-delta-validation.js +16 -0
- package/dist/lib/design-authority-digest.d.ts +8 -0
- package/dist/lib/design-authority-digest.js +36 -0
- package/dist/lib/design-authority-files.d.ts +9 -0
- package/dist/lib/design-authority-files.js +62 -0
- package/dist/lib/design-authority-format.d.ts +2 -0
- package/dist/lib/design-authority-format.js +93 -0
- package/dist/lib/design-authority-links.d.ts +10 -0
- package/dist/lib/design-authority-links.js +137 -0
- package/dist/lib/design-authority-manifest.d.ts +4 -0
- package/dist/lib/design-authority-manifest.js +144 -0
- package/dist/lib/design-authority-tokens.d.ts +9 -0
- package/dist/lib/design-authority-tokens.js +45 -0
- package/dist/lib/design-authority-types.d.ts +80 -0
- package/dist/lib/design-authority-types.js +23 -0
- package/dist/lib/design-md-tool-adapter.d.ts +9 -0
- package/dist/lib/design-md-tool-adapter.js +152 -0
- package/dist/lib/design-md-tool-normalization.d.ts +7 -0
- package/dist/lib/design-md-tool-normalization.js +78 -0
- package/dist/lib/design-md-tool-types.d.ts +99 -0
- package/dist/lib/design-md-tool-types.js +8 -0
- package/dist/lib/design-resource-handoff-input-types.d.ts +1 -1
- package/dist/lib/design-resource-handoff-manifest-projection.js +3 -0
- package/dist/lib/design-resource-handoff-shape.js +14 -2
- package/dist/lib/design-resource-handoff-types.d.ts +3 -0
- package/dist/lib/design-resource-handoff-validation.js +16 -4
- package/dist/lib/design-resource-implementation-feasibility-validation-support.js +1 -1
- package/dist/lib/design-resource-recovery-current.js +22 -0
- package/dist/lib/design-resource-recovery-shape.js +64 -7
- package/dist/lib/design-resource-recovery-types.d.ts +4 -1
- package/dist/lib/design-resource-symbolic-fact-shape.js +7 -1
- package/dist/lib/design-resource-symbolic-fact-types.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-fact-validation.js +15 -3
- package/dist/lib/doctor.d.ts +2 -1
- package/dist/lib/doctor.js +29 -1
- package/dist/lib/fs.js +1 -1
- package/dist/lib/long-task-acceptance-reachability-claims.d.ts +2 -0
- package/dist/lib/long-task-acceptance-reachability-claims.js +279 -0
- package/dist/lib/long-task-acceptance-reachability-design.d.ts +2 -0
- package/dist/lib/long-task-acceptance-reachability-design.js +96 -0
- package/dist/lib/long-task-acceptance-reachability-external.d.ts +9 -0
- package/dist/lib/long-task-acceptance-reachability-external.js +123 -0
- package/dist/lib/long-task-acceptance-reachability-helpers.d.ts +64 -0
- package/dist/lib/long-task-acceptance-reachability-helpers.js +473 -0
- package/dist/lib/long-task-acceptance-reachability-semantic.d.ts +2 -0
- package/dist/lib/long-task-acceptance-reachability-semantic.js +122 -0
- package/dist/lib/long-task-acceptance-reachability-types.d.ts +91 -0
- package/dist/lib/long-task-acceptance-reachability-types.js +1 -0
- package/dist/lib/long-task-acceptance-reachability.d.ts +4 -0
- package/dist/lib/long-task-acceptance-reachability.js +115 -0
- package/dist/lib/long-task-activation-validation.d.ts +6 -0
- package/dist/lib/long-task-activation-validation.js +72 -69
- package/dist/lib/long-task-active-authority-lock-context.d.ts +4 -0
- package/dist/lib/long-task-active-authority-lock-context.js +29 -0
- package/dist/lib/long-task-applicability-identity.d.ts +25 -0
- package/dist/lib/long-task-applicability-identity.js +60 -0
- package/dist/lib/long-task-authoring-preflight-diagnostics.js +8 -0
- package/dist/lib/long-task-authoring-preflight-types.d.ts +2 -0
- package/dist/lib/long-task-authoring-preflight-types.js +9 -0
- package/dist/lib/long-task-authoring-preflight.js +18 -2
- package/dist/lib/long-task-authority-material-diff.js +4 -0
- package/dist/lib/long-task-authority-materials.js +19 -0
- package/dist/lib/long-task-authority-policy.d.ts +3 -0
- package/dist/lib/long-task-authority-policy.js +3 -0
- package/dist/lib/long-task-authority-revision-details.js +2 -1
- package/dist/lib/long-task-authority-types.d.ts +2 -0
- package/dist/lib/long-task-authority.js +2 -0
- package/dist/lib/long-task-check-shape.js +6 -1
- package/dist/lib/long-task-claim-definitions.js +1 -3
- package/dist/lib/long-task-claim-semantic-proof-floor.d.ts +3 -0
- package/dist/lib/long-task-claim-semantic-proof-floor.js +78 -0
- package/dist/lib/long-task-claims.d.ts +0 -18
- package/dist/lib/long-task-claims.js +15 -14
- package/dist/lib/long-task-command-process.js +3 -0
- package/dist/lib/long-task-compact-authoring.js +3 -0
- package/dist/lib/long-task-compact-projections.js +10 -0
- package/dist/lib/long-task-complete-delivery-evidence-types.d.ts +38 -0
- package/dist/lib/long-task-complete-delivery-evidence-types.js +1 -0
- package/dist/lib/long-task-completion-types.d.ts +109 -0
- package/dist/lib/long-task-completion-types.js +1 -0
- package/dist/lib/long-task-conformance-policy.d.ts +2 -1
- package/dist/lib/long-task-conformance-policy.js +11 -4
- package/dist/lib/long-task-context-authority-topology.js +6 -4
- package/dist/lib/long-task-contract-types.d.ts +52 -1
- package/dist/lib/long-task-counterfactual-sandbox.d.ts +7 -1
- package/dist/lib/long-task-counterfactual-sandbox.js +86 -6
- package/dist/lib/long-task-delivery-compiler-preflight.d.ts +24 -0
- package/dist/lib/long-task-delivery-compiler-preflight.js +32 -0
- package/dist/lib/long-task-delivery-compiler.d.ts +1 -0
- package/dist/lib/long-task-delivery-compiler.js +59 -44
- package/dist/lib/long-task-delivery-parser.d.ts +3 -0
- package/dist/lib/long-task-delivery-parser.js +26 -8
- package/dist/lib/long-task-delivery-types.d.ts +2 -0
- package/dist/lib/long-task-delivery-types.js +2 -0
- package/dist/lib/long-task-delivery-validation.d.ts +6 -1
- package/dist/lib/long-task-delivery-validation.js +19 -4
- package/dist/lib/long-task-design-feasibility-binding.d.ts +1 -0
- package/dist/lib/long-task-design-feasibility-binding.js +3 -3
- package/dist/lib/long-task-design-feasibility-source-closure.js +11 -2
- package/dist/lib/long-task-design-obligation.d.ts +50 -0
- package/dist/lib/long-task-design-obligation.js +99 -0
- package/dist/lib/long-task-design-resource-handoff.d.ts +3 -1
- package/dist/lib/long-task-design-resource-handoff.js +36 -12
- package/dist/lib/long-task-design-resource-method-binding.js +12 -0
- package/dist/lib/long-task-effective-external-takeover.d.ts +15 -0
- package/dist/lib/long-task-effective-external-takeover.js +109 -0
- package/dist/lib/long-task-effective-external-ui-takeover.d.ts +5 -0
- package/dist/lib/long-task-effective-external-ui-takeover.js +117 -0
- package/dist/lib/long-task-evidence-capability-codec.js +91 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +62 -14
- package/dist/lib/long-task-evidence-capability-types.d.ts +3 -2
- package/dist/lib/long-task-evidence-v2.d.ts +6 -1
- package/dist/lib/long-task-evidence-v2.js +253 -170
- package/dist/lib/long-task-execution-observation.d.ts +7 -0
- package/dist/lib/long-task-execution-observation.js +21 -4
- package/dist/lib/long-task-expected-authority.d.ts +4 -0
- package/dist/lib/long-task-expected-authority.js +126 -0
- package/dist/lib/long-task-external-confirmation-artifacts.d.ts +9 -0
- package/dist/lib/long-task-external-confirmation-artifacts.js +138 -0
- package/dist/lib/long-task-external-confirmation-attestation.d.ts +20 -0
- package/dist/lib/long-task-external-confirmation-attestation.js +115 -0
- package/dist/lib/long-task-external-confirmation-challenge.d.ts +23 -0
- package/dist/lib/long-task-external-confirmation-challenge.js +164 -0
- package/dist/lib/long-task-external-confirmation-context.d.ts +14 -0
- package/dist/lib/long-task-external-confirmation-context.js +53 -0
- package/dist/lib/long-task-external-confirmation-evaluation.d.ts +11 -0
- package/dist/lib/long-task-external-confirmation-evaluation.js +454 -0
- package/dist/lib/long-task-external-confirmation-expected.d.ts +8 -0
- package/dist/lib/long-task-external-confirmation-expected.js +200 -0
- package/dist/lib/long-task-external-confirmation-identity.d.ts +10 -0
- package/dist/lib/long-task-external-confirmation-identity.js +77 -0
- package/dist/lib/long-task-external-confirmation-plan.d.ts +25 -0
- package/dist/lib/long-task-external-confirmation-plan.js +148 -0
- package/dist/lib/long-task-external-confirmation-preparation.d.ts +4 -0
- package/dist/lib/long-task-external-confirmation-preparation.js +100 -0
- package/dist/lib/long-task-external-confirmation-shape.d.ts +8 -0
- package/dist/lib/long-task-external-confirmation-shape.js +387 -0
- package/dist/lib/long-task-external-confirmation-state.d.ts +10 -0
- package/dist/lib/long-task-external-confirmation-state.js +109 -0
- package/dist/lib/long-task-external-confirmation-types.d.ts +195 -0
- package/dist/lib/long-task-external-confirmation-types.js +1 -0
- package/dist/lib/long-task-final-integrity.d.ts +2 -0
- package/dist/lib/long-task-final-integrity.js +21 -10
- package/dist/lib/long-task-final-v2.d.ts +7 -2
- package/dist/lib/long-task-final-v2.js +179 -55
- package/dist/lib/long-task-finalization-identity.d.ts +27 -0
- package/dist/lib/long-task-finalization-identity.js +58 -0
- package/dist/lib/long-task-finding-context.d.ts +1 -1
- package/dist/lib/long-task-finding-context.js +139 -13
- package/dist/lib/long-task-freshness.d.ts +27 -0
- package/dist/lib/long-task-freshness.js +128 -5
- package/dist/lib/long-task-git.js +3 -3
- package/dist/lib/long-task-material-input-closure.d.ts +3 -0
- package/dist/lib/long-task-material-input-closure.js +92 -0
- package/dist/lib/long-task-obligation-authority-resolution.d.ts +12 -0
- package/dist/lib/long-task-obligation-authority-resolution.js +57 -0
- package/dist/lib/long-task-obligation-semantic-identity.d.ts +16 -0
- package/dist/lib/long-task-obligation-semantic-identity.js +116 -0
- package/dist/lib/long-task-observation-authority.d.ts +11 -0
- package/dist/lib/long-task-observation-authority.js +137 -6
- package/dist/lib/long-task-process-table.d.ts +2 -5
- package/dist/lib/long-task-process-table.js +21 -53
- package/dist/lib/long-task-process-tree.d.ts +0 -1
- package/dist/lib/long-task-process-tree.js +24 -54
- package/dist/lib/long-task-proof-adequacy.d.ts +12 -0
- package/dist/lib/long-task-proof-adequacy.js +57 -0
- package/dist/lib/long-task-proof-capability-floor.d.ts +6 -0
- package/dist/lib/long-task-proof-capability-floor.js +137 -0
- package/dist/lib/long-task-repair-frontier-checks.d.ts +8 -0
- package/dist/lib/long-task-repair-frontier-checks.js +93 -0
- package/dist/lib/long-task-repair-frontier-groups.d.ts +2 -0
- package/dist/lib/long-task-repair-frontier-groups.js +64 -0
- package/dist/lib/long-task-repair-frontier-utils.d.ts +6 -0
- package/dist/lib/long-task-repair-frontier-utils.js +27 -0
- package/dist/lib/long-task-repair-frontier.d.ts +14 -0
- package/dist/lib/long-task-repair-frontier.js +132 -0
- package/dist/lib/long-task-risk.d.ts +3 -2
- package/dist/lib/long-task-risk.js +73 -24
- package/dist/lib/long-task-root-shape.js +148 -8
- package/dist/lib/long-task-runner-freeze.d.ts +2 -1
- package/dist/lib/long-task-runner-freeze.js +23 -8
- package/dist/lib/long-task-runtime-types.d.ts +34 -40
- package/dist/lib/long-task-semantic-assurance-policy.js +2 -11
- package/dist/lib/long-task-semantic-contract-types.d.ts +2 -1
- package/dist/lib/long-task-semantic-drift-migration.js +48 -2
- package/dist/lib/long-task-semantic-fact-binding-types.d.ts +20 -0
- package/dist/lib/long-task-semantic-fact-closure.d.ts +5 -1
- package/dist/lib/long-task-semantic-fact-closure.js +33 -5
- package/dist/lib/long-task-semantic-fact-contract-closure.js +176 -1
- package/dist/lib/long-task-semantic-fact-contract-proofs.js +18 -1
- package/dist/lib/long-task-semantic-fact-input-closure.d.ts +16 -2
- package/dist/lib/long-task-semantic-fact-input-closure.js +138 -15
- package/dist/lib/long-task-semantic-fact-provenance-closure.js +1 -1
- package/dist/lib/long-task-semantic-fact-shape.d.ts +2 -1
- package/dist/lib/long-task-semantic-fact-shape.js +35 -1
- package/dist/lib/long-task-semantic-proof-adequacy.d.ts +2 -0
- package/dist/lib/long-task-semantic-proof-adequacy.js +19 -0
- package/dist/lib/long-task-semantic-proof-profile.d.ts +5 -0
- package/dist/lib/long-task-semantic-proof-profile.js +187 -0
- package/dist/lib/long-task-shape-primitives.d.ts +1 -1
- package/dist/lib/long-task-shape-primitives.js +5 -0
- package/dist/lib/long-task-source-anchors.d.ts +10 -0
- package/dist/lib/long-task-source-anchors.js +102 -0
- package/dist/lib/long-task-source-authority-types.d.ts +46 -0
- package/dist/lib/long-task-source-claim-validation.js +36 -0
- package/dist/lib/long-task-source-conservation-facts.d.ts +8 -0
- package/dist/lib/long-task-source-conservation-facts.js +57 -0
- package/dist/lib/long-task-source-conservation-types.d.ts +34 -0
- package/dist/lib/long-task-source-conservation-types.js +1 -0
- package/dist/lib/long-task-source-conservation.d.ts +7 -0
- package/dist/lib/long-task-source-conservation.js +110 -0
- package/dist/lib/long-task-source-fragments.d.ts +6 -0
- package/dist/lib/long-task-source-fragments.js +219 -0
- package/dist/lib/long-task-source-projection-resolution.d.ts +5 -0
- package/dist/lib/long-task-source-projection-resolution.js +57 -0
- package/dist/lib/long-task-source-projection-validation.d.ts +17 -0
- package/dist/lib/long-task-source-projection-validation.js +154 -0
- package/dist/lib/long-task-source-shape.js +14 -6
- package/dist/lib/long-task-source-supersession.d.ts +5 -0
- package/dist/lib/long-task-source-supersession.js +138 -0
- package/dist/lib/long-task-stage-policy.d.ts +7 -2
- package/dist/lib/long-task-stage-policy.js +67 -23
- package/dist/lib/long-task-state.d.ts +18 -4
- package/dist/lib/long-task-state.js +319 -33
- package/dist/lib/long-task-static-observation-freeze.js +4 -3
- package/dist/lib/long-task-status-projection.d.ts +3 -1
- package/dist/lib/long-task-status-projection.js +44 -13
- package/dist/lib/long-task-status-v2.d.ts +10 -6
- package/dist/lib/long-task-status-v2.js +70 -58
- package/dist/lib/long-task-target-policy.d.ts +8 -3
- package/dist/lib/long-task-target-policy.js +40 -9
- package/dist/lib/long-task-terminal-finalization.d.ts +12 -0
- package/dist/lib/long-task-terminal-finalization.js +190 -0
- package/dist/lib/long-task-ui-design-policy.js +15 -4
- package/dist/lib/long-task-verifier-counterfactuals.d.ts +11 -0
- package/dist/lib/long-task-verifier-counterfactuals.js +96 -0
- package/dist/lib/long-task-verifier-execution.d.ts +9 -0
- package/dist/lib/long-task-verifier-execution.js +67 -0
- package/dist/lib/long-task-verifier-identity.js +16 -5
- package/dist/lib/long-task-verifier-v2.js +52 -65
- package/dist/lib/long-task-windows-job-supervisor-helper.d.ts +1 -0
- package/dist/lib/long-task-windows-job-supervisor-helper.js +104 -0
- package/dist/lib/long-task-windows-job-supervisor-protocol.d.ts +28 -0
- package/dist/lib/long-task-windows-job-supervisor-protocol.js +124 -0
- package/dist/lib/long-task-windows-job-supervisor-result.d.ts +11 -0
- package/dist/lib/long-task-windows-job-supervisor-result.js +152 -0
- package/dist/lib/long-task-windows-job-supervisor.d.ts +2 -0
- package/dist/lib/long-task-windows-job-supervisor.js +126 -0
- package/dist/lib/long-task-workspace-scope.d.ts +1 -0
- package/dist/lib/long-task-workspace-scope.js +4 -1
- package/dist/lib/long-task-workspace.d.ts +1 -0
- package/dist/lib/long-task-workspace.js +10 -0
- package/dist/lib/migrations.js +43 -2
- package/dist/lib/repository-path-safety.d.ts +1 -0
- package/dist/lib/repository-path-safety.js +3 -3
- package/dist/lib/semantic-fact-input-shape.d.ts +7 -2
- package/dist/lib/semantic-fact-input-shape.js +25 -1
- package/dist/lib/semantic-fact-inventory-types.d.ts +8 -2
- package/dist/lib/semantic-fact-policy-census.d.ts +1 -1
- package/dist/lib/semantic-fact-policy-census.js +5 -2
- package/dist/lib/semantic-fact-policy.d.ts +1 -1
- package/dist/lib/semantic-fact-policy.js +2 -2
- package/dist/lib/semantic-fact-proof-shape.d.ts +1 -1
- package/dist/lib/semantic-fact-property-shape.d.ts +1 -1
- package/dist/lib/validators.d.ts +3 -0
- package/dist/lib/validators.js +45 -157
- package/dist/public-api-core.d.ts +12 -0
- package/dist/public-api-core.js +12 -0
- package/dist/public-api-long-task.d.ts +10 -0
- package/dist/public-api-long-task.js +10 -0
- package/dist/public-types.d.ts +5 -1
- package/dist/schemas/design-authority-delta-assessment-v1.schema.json +191 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +166 -2
- package/dist/schemas/long-task-external-confirmation-record-v1.schema.json +155 -0
- package/dist/schemas/long-task-external-confirmation-record-v2.schema.json +209 -0
- package/migrations/README.md +99 -0
- package/package.json +7 -5
- package/source-mappings.yaml +18 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
2
|
+
export function markdownDestinationSpans(content) {
|
|
3
|
+
const tree = fromMarkdown(content);
|
|
4
|
+
const spans = [];
|
|
5
|
+
walk(tree, content, spans);
|
|
6
|
+
return spans.sort((left, right) => left.start - right.start);
|
|
7
|
+
}
|
|
8
|
+
function walk(node, content, spans) {
|
|
9
|
+
if (node.type === "link" || node.type === "image") {
|
|
10
|
+
const located = locateInlineDestination(content, node);
|
|
11
|
+
if (located)
|
|
12
|
+
spans.push({
|
|
13
|
+
...located,
|
|
14
|
+
kind: node.type === "link" ? "inline" : "image",
|
|
15
|
+
...lineColumn(content, located.start),
|
|
16
|
+
});
|
|
17
|
+
if (node.type === "link")
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
else if (node.type === "definition") {
|
|
21
|
+
const located = locateDefinitionDestination(content, node);
|
|
22
|
+
if (located)
|
|
23
|
+
spans.push({
|
|
24
|
+
...located,
|
|
25
|
+
kind: "definition",
|
|
26
|
+
...lineColumn(content, located.start),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else if (node.type === "text" || node.type === "html") {
|
|
30
|
+
const start = node.position?.start.offset;
|
|
31
|
+
const end = node.position?.end.offset;
|
|
32
|
+
if (start !== undefined && end !== undefined)
|
|
33
|
+
for (const located of locateLocalAngles(content, start, end))
|
|
34
|
+
spans.push({
|
|
35
|
+
...located,
|
|
36
|
+
kind: "angle",
|
|
37
|
+
...lineColumn(content, located.start),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (!("children" in node))
|
|
41
|
+
return;
|
|
42
|
+
for (const child of node.children)
|
|
43
|
+
walk(child, content, spans);
|
|
44
|
+
}
|
|
45
|
+
function locateInlineDestination(content, node) {
|
|
46
|
+
const bounds = nodeBounds(node);
|
|
47
|
+
if (!bounds)
|
|
48
|
+
return null;
|
|
49
|
+
const raw = content.slice(bounds.start, bounds.end);
|
|
50
|
+
const labelStart = raw.indexOf("[");
|
|
51
|
+
if (labelStart < 0)
|
|
52
|
+
return null;
|
|
53
|
+
const labelEnd = closingBracket(raw, labelStart);
|
|
54
|
+
if (labelEnd < 0)
|
|
55
|
+
return null;
|
|
56
|
+
let cursor = skipWhitespace(raw, labelEnd + 1);
|
|
57
|
+
if (raw[cursor] !== "(")
|
|
58
|
+
return null;
|
|
59
|
+
cursor = skipWhitespace(raw, cursor + 1);
|
|
60
|
+
return destinationAt(content, raw, bounds.start, cursor, ")");
|
|
61
|
+
}
|
|
62
|
+
function locateDefinitionDestination(content, node) {
|
|
63
|
+
const bounds = nodeBounds(node);
|
|
64
|
+
if (!bounds)
|
|
65
|
+
return null;
|
|
66
|
+
const raw = content.slice(bounds.start, bounds.end);
|
|
67
|
+
const labelStart = raw.indexOf("[");
|
|
68
|
+
if (labelStart < 0)
|
|
69
|
+
return null;
|
|
70
|
+
const labelEnd = closingBracket(raw, labelStart);
|
|
71
|
+
if (labelEnd < 0)
|
|
72
|
+
return null;
|
|
73
|
+
let cursor = skipWhitespace(raw, labelEnd + 1);
|
|
74
|
+
if (raw[cursor] !== ":")
|
|
75
|
+
return null;
|
|
76
|
+
cursor = skipWhitespace(raw, cursor + 1);
|
|
77
|
+
return destinationAt(content, raw, bounds.start, cursor, "line");
|
|
78
|
+
}
|
|
79
|
+
function destinationAt(content, raw, absoluteStart, cursor, terminator) {
|
|
80
|
+
if (raw[cursor] === "<") {
|
|
81
|
+
const end = unescapedIndex(raw, ">", cursor + 1);
|
|
82
|
+
return end < 0
|
|
83
|
+
? null
|
|
84
|
+
: located(content, absoluteStart + cursor + 1, absoluteStart + end);
|
|
85
|
+
}
|
|
86
|
+
const start = cursor;
|
|
87
|
+
let depth = 0;
|
|
88
|
+
while (cursor < raw.length) {
|
|
89
|
+
const character = raw[cursor];
|
|
90
|
+
if (character === "\\") {
|
|
91
|
+
cursor += 2;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (character === "(" && terminator === ")")
|
|
95
|
+
depth += 1;
|
|
96
|
+
else if (character === ")" && terminator === ")") {
|
|
97
|
+
if (depth === 0)
|
|
98
|
+
break;
|
|
99
|
+
depth -= 1;
|
|
100
|
+
}
|
|
101
|
+
else if (/\s/u.test(character) && depth === 0)
|
|
102
|
+
break;
|
|
103
|
+
cursor += 1;
|
|
104
|
+
}
|
|
105
|
+
return located(content, absoluteStart + start, absoluteStart + cursor);
|
|
106
|
+
}
|
|
107
|
+
function locateLocalAngles(content, start, end) {
|
|
108
|
+
const result = [];
|
|
109
|
+
for (let cursor = start; cursor < end; cursor += 1) {
|
|
110
|
+
if (content[cursor] !== "<")
|
|
111
|
+
continue;
|
|
112
|
+
const close = content.indexOf(">", cursor + 1);
|
|
113
|
+
if (close < 0 || close >= end)
|
|
114
|
+
break;
|
|
115
|
+
const candidate = content.slice(cursor + 1, close);
|
|
116
|
+
if (looksLikeLocalAngle(candidate))
|
|
117
|
+
result.push(located(content, cursor + 1, close));
|
|
118
|
+
cursor = close;
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
function located(content, start, end) {
|
|
123
|
+
return { destination: content.slice(start, end), start, end };
|
|
124
|
+
}
|
|
125
|
+
function closingBracket(raw, start) {
|
|
126
|
+
let depth = 0;
|
|
127
|
+
for (let cursor = start; cursor < raw.length; cursor += 1) {
|
|
128
|
+
if (raw[cursor] === "\\") {
|
|
129
|
+
cursor += 1;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (raw[cursor] === "[")
|
|
133
|
+
depth += 1;
|
|
134
|
+
else if (raw[cursor] === "]") {
|
|
135
|
+
depth -= 1;
|
|
136
|
+
if (depth === 0)
|
|
137
|
+
return cursor;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return -1;
|
|
141
|
+
}
|
|
142
|
+
function unescapedIndex(raw, character, start) {
|
|
143
|
+
for (let cursor = start; cursor < raw.length; cursor += 1) {
|
|
144
|
+
if (raw[cursor] === "\\")
|
|
145
|
+
cursor += 1;
|
|
146
|
+
else if (raw[cursor] === character)
|
|
147
|
+
return cursor;
|
|
148
|
+
}
|
|
149
|
+
return -1;
|
|
150
|
+
}
|
|
151
|
+
function skipWhitespace(raw, start) {
|
|
152
|
+
let cursor = start;
|
|
153
|
+
while (cursor < raw.length && /\s/u.test(raw[cursor]))
|
|
154
|
+
cursor += 1;
|
|
155
|
+
return cursor;
|
|
156
|
+
}
|
|
157
|
+
function nodeBounds(node) {
|
|
158
|
+
const start = node.position?.start.offset;
|
|
159
|
+
const end = node.position?.end.offset;
|
|
160
|
+
return start === undefined || end === undefined ? null : { start, end };
|
|
161
|
+
}
|
|
162
|
+
function lineColumn(content, offset) {
|
|
163
|
+
const prefix = content.slice(0, offset);
|
|
164
|
+
const lines = prefix.split(/\r\n?|\n/u);
|
|
165
|
+
return {
|
|
166
|
+
line: lines.length,
|
|
167
|
+
column: Array.from(lines.at(-1) ?? "").length + 1,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function looksLikeLocalAngle(value) {
|
|
171
|
+
if (!value || Array.from(value).some((point) => /\s/u.test(point)))
|
|
172
|
+
return false;
|
|
173
|
+
return (value.startsWith(".") ||
|
|
174
|
+
value.startsWith("/") ||
|
|
175
|
+
value.startsWith("project_context") ||
|
|
176
|
+
value.includes("/") ||
|
|
177
|
+
value.includes("\\") ||
|
|
178
|
+
value.toLowerCase().endsWith(".md"));
|
|
179
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MutationFileChange, MutationRecordedFileState, MutationTemporaryState } from "./mutation-types.js";
|
|
2
|
+
export { absentMutationFileState, assertMutationChangesContentState, assertMutationChangesCurrent, captureMutationFileState, mutationFileStateFromBytes, } from "./mutation-file-state.js";
|
|
3
|
+
type MutationSide = "before" | "after";
|
|
4
|
+
type MutationDisposition = MutationSide | "conflict";
|
|
5
|
+
export type MutationBeforeSecondCas = (change: MutationFileChange) => Promise<void>;
|
|
6
|
+
export type MutationAfterTemporaryCreated = (change: MutationFileChange, side: MutationSide) => Promise<void>;
|
|
7
|
+
export declare function mutationTemporaryPath(target: string, transactionId: string, index: number): string;
|
|
8
|
+
export declare function stageMutationTemporary(repository: string, change: MutationFileChange, side?: MutationSide, afterCreated?: MutationAfterTemporaryCreated): Promise<MutationTemporaryState | null>;
|
|
9
|
+
export declare function prepareMutationTemporaryForRecovery(repository: string, change: MutationFileChange, side: MutationSide, beforeSecondCas?: MutationBeforeSecondCas, afterCreated?: MutationAfterTemporaryCreated): Promise<MutationTemporaryState | null>;
|
|
10
|
+
export declare function applyMutationChangeForward(repository: string, change: MutationFileChange, beforeSecondCas?: MutationBeforeSecondCas): Promise<MutationRecordedFileState>;
|
|
11
|
+
export declare function applyMutationChangeBackward(repository: string, change: MutationFileChange, beforeSecondCas?: MutationBeforeSecondCas): Promise<MutationRecordedFileState>;
|
|
12
|
+
export declare function mutationChangeDisposition(repository: string, change: MutationFileChange): Promise<MutationDisposition>;
|
|
13
|
+
export declare function cleanupMutationTemporary(repository: string, change: MutationFileChange): Promise<void>;
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { chmod, link, lstat, open, rename, unlink } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { assertSafeRepositoryFilePath, resolveInsideRepository, } from "../repository-path-safety.js";
|
|
4
|
+
import { sha256Hex } from "../strict-codec.js";
|
|
5
|
+
import { captureMutationFileState, mutationPhysicalPath, mutationRecordedFileState, sameMutationRecordedState, } from "./mutation-file-state.js";
|
|
6
|
+
export { absentMutationFileState, assertMutationChangesContentState, assertMutationChangesCurrent, captureMutationFileState, mutationFileStateFromBytes, } from "./mutation-file-state.js";
|
|
7
|
+
export function mutationTemporaryPath(target, transactionId, index) {
|
|
8
|
+
const parent = path.posix.dirname(target);
|
|
9
|
+
const name = path.posix.basename(target);
|
|
10
|
+
return `${parent}/.${name}.ty-context-mutation-${transactionId.slice(0, 16)}-${index}.tmp`;
|
|
11
|
+
}
|
|
12
|
+
export async function stageMutationTemporary(repository, change, side = "after", afterCreated) {
|
|
13
|
+
const state = change[side];
|
|
14
|
+
if (!state.exists)
|
|
15
|
+
return null;
|
|
16
|
+
if (!change.temporary_path)
|
|
17
|
+
invalid(`temporary_path_missing:${change.path}`);
|
|
18
|
+
const temporary = await assertSafeRepositoryFilePath(repository, change.temporary_path, "context_mutation_temporary", { destinationMayBeAbsent: true, allowHardlinks: true });
|
|
19
|
+
if (temporary.status) {
|
|
20
|
+
const current = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
21
|
+
if (change.temporary_state?.side === side &&
|
|
22
|
+
sameMutationRecordedState(current, change.temporary_state.state))
|
|
23
|
+
return change.temporary_state;
|
|
24
|
+
invalid(`temporary_collision:${change.temporary_path}`);
|
|
25
|
+
}
|
|
26
|
+
const handle = await open(temporary.absolute, "wx", state.mode ?? 0o666);
|
|
27
|
+
try {
|
|
28
|
+
await handle.writeFile(stateBytes(state));
|
|
29
|
+
await handle.sync();
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await handle.close();
|
|
33
|
+
}
|
|
34
|
+
if (state.mode !== null)
|
|
35
|
+
await chmod(temporary.absolute, state.mode);
|
|
36
|
+
await afterCreated?.(change, side);
|
|
37
|
+
const captured = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
38
|
+
if (!samePayload(captured, state) || captured.identity?.nlink !== "1")
|
|
39
|
+
invalid(`temporary_readback_mismatch:${change.temporary_path}`);
|
|
40
|
+
return { side, state: mutationRecordedFileState(captured) };
|
|
41
|
+
}
|
|
42
|
+
export async function prepareMutationTemporaryForRecovery(repository, change, side, beforeSecondCas, afterCreated) {
|
|
43
|
+
const desired = change[side];
|
|
44
|
+
if (!change.temporary_path)
|
|
45
|
+
invalid(`temporary_path_missing:${change.path}`);
|
|
46
|
+
const temporary = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
47
|
+
if (temporary.exists) {
|
|
48
|
+
if (desired.exists &&
|
|
49
|
+
change.temporary_state?.side === side &&
|
|
50
|
+
sameMutationRecordedState(temporary, change.temporary_state.state))
|
|
51
|
+
return change.temporary_state;
|
|
52
|
+
if (desired.exists &&
|
|
53
|
+
change.temporary_state?.side === side &&
|
|
54
|
+
isOwnedDeletionRemainder(temporary, change.temporary_state.state))
|
|
55
|
+
return change.temporary_state;
|
|
56
|
+
await removeOwnedTemporary(repository, change, temporary);
|
|
57
|
+
}
|
|
58
|
+
if (desired.exists)
|
|
59
|
+
return stageMutationTemporary(repository, change, side, afterCreated);
|
|
60
|
+
return stageDeletionTombstone(repository, change, side, beforeSecondCas, afterCreated);
|
|
61
|
+
}
|
|
62
|
+
export async function applyMutationChangeForward(repository, change, beforeSecondCas) {
|
|
63
|
+
return applyMutationState(repository, change, "before", "after", beforeSecondCas);
|
|
64
|
+
}
|
|
65
|
+
export async function applyMutationChangeBackward(repository, change, beforeSecondCas) {
|
|
66
|
+
return applyMutationState(repository, change, "after", "before", beforeSecondCas);
|
|
67
|
+
}
|
|
68
|
+
export async function mutationChangeDisposition(repository, change) {
|
|
69
|
+
await assertNoUnrecordedTemporary(repository, change);
|
|
70
|
+
const current = await captureMutationFileState(repository, mutationPhysicalPath(change), {
|
|
71
|
+
allow_hardlinks: true,
|
|
72
|
+
});
|
|
73
|
+
if (matchesRecordedSide(current, change, "before"))
|
|
74
|
+
return "before";
|
|
75
|
+
if (matchesRecordedSide(current, change, "after"))
|
|
76
|
+
return "after";
|
|
77
|
+
return ((await ownedTemporaryTransition(repository, change, current)) ?? "conflict");
|
|
78
|
+
}
|
|
79
|
+
export async function cleanupMutationTemporary(repository, change) {
|
|
80
|
+
if (!change.temporary_path)
|
|
81
|
+
return;
|
|
82
|
+
const absolute = resolveInsideRepository(repository, change.temporary_path, "context_mutation_temporary_cleanup");
|
|
83
|
+
const status = await lstat(absolute).catch((error) => {
|
|
84
|
+
if (error.code === "ENOENT")
|
|
85
|
+
return null;
|
|
86
|
+
throw error;
|
|
87
|
+
});
|
|
88
|
+
if (!status)
|
|
89
|
+
return;
|
|
90
|
+
const current = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
91
|
+
await removeOwnedTemporary(repository, change, current);
|
|
92
|
+
}
|
|
93
|
+
async function applyMutationState(repository, change, expectedSide, desiredSide, beforeSecondCas) {
|
|
94
|
+
let disposition = await mutationChangeDisposition(repository, change);
|
|
95
|
+
if (disposition === desiredSide)
|
|
96
|
+
return captureDesiredEndpoint(repository, change, desiredSide);
|
|
97
|
+
if (disposition !== expectedSide)
|
|
98
|
+
invalid(`recovery_conflict:${change.path}`);
|
|
99
|
+
const desired = change[desiredSide];
|
|
100
|
+
const target = await assertSafeRepositoryFilePath(repository, mutationPhysicalPath(change), "context_mutation_commit_target", { destinationMayBeAbsent: true, allowHardlinks: !desired.exists });
|
|
101
|
+
if (desired.exists)
|
|
102
|
+
await assertTemporaryReady(repository, change, desiredSide);
|
|
103
|
+
else
|
|
104
|
+
await assertDeletionTombstoneReady(repository, change, expectedSide);
|
|
105
|
+
// This second cooperative CAS closes changes made during staging and path
|
|
106
|
+
// acquisition. Publication remains a narrow rename/link/unlink window, not
|
|
107
|
+
// a claim of hostile-writer filesystem atomicity.
|
|
108
|
+
if (desired.exists)
|
|
109
|
+
await beforeSecondCas?.(change);
|
|
110
|
+
disposition = await mutationChangeDisposition(repository, change);
|
|
111
|
+
if (disposition === desiredSide)
|
|
112
|
+
return captureDesiredEndpoint(repository, change, desiredSide);
|
|
113
|
+
if (disposition !== expectedSide)
|
|
114
|
+
invalid(`second_cas_conflict:${change.path}`);
|
|
115
|
+
if (!desired.exists) {
|
|
116
|
+
if (!target.status)
|
|
117
|
+
invalid(`deletion_target_missing:${change.path}`);
|
|
118
|
+
await unlink(target.absolute);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const temporary = resolveInsideRepository(repository, change.temporary_path, "context_mutation_commit_temporary");
|
|
122
|
+
if (change[expectedSide].exists)
|
|
123
|
+
await rename(temporary, target.absolute);
|
|
124
|
+
else {
|
|
125
|
+
try {
|
|
126
|
+
await link(temporary, target.absolute);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (error.code === "EEXIST")
|
|
130
|
+
invalid(`destination_collision:${change.path}`);
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
await unlink(temporary);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
await syncParentDirectory(path.dirname(target.absolute));
|
|
137
|
+
return captureDesiredEndpoint(repository, change, desiredSide);
|
|
138
|
+
}
|
|
139
|
+
async function captureDesiredEndpoint(repository, change, side) {
|
|
140
|
+
const current = await captureMutationFileState(repository, mutationPhysicalPath(change), {
|
|
141
|
+
allow_hardlinks: true,
|
|
142
|
+
});
|
|
143
|
+
const desired = change[side];
|
|
144
|
+
if (!samePayload(current, desired))
|
|
145
|
+
invalid(`post_commit_readback_mismatch:${change.path}`);
|
|
146
|
+
const transition = await ownedTemporaryTransition(repository, change, current);
|
|
147
|
+
const recorded = side === "before" ? change.published_before : change.published_after;
|
|
148
|
+
if (transition !== side &&
|
|
149
|
+
!(recorded && sameMutationRecordedState(current, recorded)) &&
|
|
150
|
+
!(desired.exists && sameMutationRecordedState(current, desired)))
|
|
151
|
+
invalid(`post_commit_identity_mismatch:${change.path}`);
|
|
152
|
+
return mutationRecordedFileState(current);
|
|
153
|
+
}
|
|
154
|
+
async function assertTemporaryReady(repository, change, side) {
|
|
155
|
+
if (!change.temporary_path || change.temporary_state?.side !== side)
|
|
156
|
+
invalid(`temporary_state_missing:${change.path}`);
|
|
157
|
+
const temporary = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
158
|
+
if (!((sameMutationRecordedState(temporary, change.temporary_state.state) &&
|
|
159
|
+
temporary.identity?.nlink === "1") ||
|
|
160
|
+
isOwnedDeletionRemainder(temporary, change.temporary_state.state)))
|
|
161
|
+
invalid(`temporary_identity_changed:${change.temporary_path}`);
|
|
162
|
+
}
|
|
163
|
+
function matchesRecordedSide(current, change, side) {
|
|
164
|
+
const semantic = change[side];
|
|
165
|
+
const published = side === "before" ? change.published_before : change.published_after;
|
|
166
|
+
if (published && sameMutationRecordedState(current, published))
|
|
167
|
+
return true;
|
|
168
|
+
if (semantic.exists)
|
|
169
|
+
return sameMutationRecordedState(current, semantic);
|
|
170
|
+
if (side !== "before")
|
|
171
|
+
return false;
|
|
172
|
+
const oppositePublished = change.published_after;
|
|
173
|
+
return (oppositePublished === null && sameMutationRecordedState(current, semantic));
|
|
174
|
+
}
|
|
175
|
+
async function ownedTemporaryTransition(repository, change, current) {
|
|
176
|
+
const prepared = change.temporary_state;
|
|
177
|
+
if (!prepared || !change.temporary_path)
|
|
178
|
+
return null;
|
|
179
|
+
const temporary = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
180
|
+
if (prepared.state.identity?.nlink === "2")
|
|
181
|
+
return ownedDeletionTombstoneTransition(current, temporary, prepared);
|
|
182
|
+
if (!current.exists ||
|
|
183
|
+
!samePayload(current, change[prepared.side]) ||
|
|
184
|
+
!sameFileObject(current, prepared.state))
|
|
185
|
+
return null;
|
|
186
|
+
if (!temporary.exists)
|
|
187
|
+
return current.identity?.nlink === "1" ? prepared.side : null;
|
|
188
|
+
if (current.identity?.nlink === "2" &&
|
|
189
|
+
temporary.identity?.nlink === "2" &&
|
|
190
|
+
samePayload(temporary, change[prepared.side]) &&
|
|
191
|
+
sameFileObject(current, temporary))
|
|
192
|
+
return prepared.side;
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
function ownedDeletionTombstoneTransition(current, temporary, prepared) {
|
|
196
|
+
if (current.exists &&
|
|
197
|
+
temporary.exists &&
|
|
198
|
+
sameMutationRecordedState(current, prepared.state) &&
|
|
199
|
+
sameMutationRecordedState(temporary, prepared.state))
|
|
200
|
+
return prepared.side;
|
|
201
|
+
if (!current.exists &&
|
|
202
|
+
temporary.exists &&
|
|
203
|
+
isOwnedDeletionRemainder(temporary, prepared.state))
|
|
204
|
+
return oppositeSide(prepared.side);
|
|
205
|
+
if (current.exists &&
|
|
206
|
+
!temporary.exists &&
|
|
207
|
+
isOwnedDeletionRemainder(current, prepared.state))
|
|
208
|
+
return prepared.side;
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
async function removeOwnedTemporary(repository, change, temporary) {
|
|
212
|
+
if (!change.temporary_path || !change.temporary_state)
|
|
213
|
+
invalid(`temporary_identity_unrecorded:${change.temporary_path ?? change.path}`);
|
|
214
|
+
const exact = sameMutationRecordedState(temporary, change.temporary_state.state);
|
|
215
|
+
let linkedPair = false;
|
|
216
|
+
if (!exact && temporary.identity?.nlink === "2") {
|
|
217
|
+
const target = await captureMutationFileState(repository, mutationPhysicalPath(change), { allow_hardlinks: true });
|
|
218
|
+
linkedPair =
|
|
219
|
+
target.identity?.nlink === "2" &&
|
|
220
|
+
sameFileObject(target, temporary) &&
|
|
221
|
+
samePayload(temporary, change[change.temporary_state.side]) &&
|
|
222
|
+
(await ownedTemporaryTransition(repository, change, target)) ===
|
|
223
|
+
change.temporary_state.side;
|
|
224
|
+
}
|
|
225
|
+
const deletionRemainder = !exact &&
|
|
226
|
+
change.temporary_state.state.identity?.nlink === "2" &&
|
|
227
|
+
isOwnedDeletionRemainder(temporary, change.temporary_state.state) &&
|
|
228
|
+
!(await captureMutationFileState(repository, mutationPhysicalPath(change), {
|
|
229
|
+
allow_hardlinks: true,
|
|
230
|
+
})).exists;
|
|
231
|
+
if (!exact && !linkedPair && !deletionRemainder)
|
|
232
|
+
invalid(`temporary_identity_changed:${change.temporary_path}`);
|
|
233
|
+
const absolute = resolveInsideRepository(repository, change.temporary_path, "context_mutation_temporary_cleanup");
|
|
234
|
+
await unlink(absolute);
|
|
235
|
+
await syncParentDirectory(path.dirname(absolute));
|
|
236
|
+
}
|
|
237
|
+
function samePayload(current, expected) {
|
|
238
|
+
return (current.exists === expected.exists &&
|
|
239
|
+
current.sha256 === expected.sha256 &&
|
|
240
|
+
current.mode === expected.mode);
|
|
241
|
+
}
|
|
242
|
+
function sameFileObject(current, expected) {
|
|
243
|
+
const left = current.identity;
|
|
244
|
+
const right = expected.identity;
|
|
245
|
+
return (left !== null &&
|
|
246
|
+
right !== null &&
|
|
247
|
+
left.dev === right.dev &&
|
|
248
|
+
left.ino === right.ino &&
|
|
249
|
+
left.size === right.size &&
|
|
250
|
+
left.mtime_ns === right.mtime_ns);
|
|
251
|
+
}
|
|
252
|
+
async function stageDeletionTombstone(repository, change, desiredSide, beforeSecondCas, afterCreated) {
|
|
253
|
+
const expectedSide = oppositeSide(desiredSide);
|
|
254
|
+
if (!change[expectedSide].exists || change[desiredSide].exists)
|
|
255
|
+
invalid(`deletion_transition_invalid:${change.path}`);
|
|
256
|
+
let disposition = await mutationChangeDisposition(repository, change);
|
|
257
|
+
if (disposition !== expectedSide)
|
|
258
|
+
invalid(`recovery_conflict:${change.path}`);
|
|
259
|
+
await beforeSecondCas?.(change);
|
|
260
|
+
disposition = await mutationChangeDisposition(repository, change);
|
|
261
|
+
if (disposition !== expectedSide)
|
|
262
|
+
invalid(`second_cas_conflict:${change.path}`);
|
|
263
|
+
const beforeLink = await captureMutationFileState(repository, mutationPhysicalPath(change));
|
|
264
|
+
if ((await mutationChangeDisposition(repository, change)) !== expectedSide)
|
|
265
|
+
invalid(`second_cas_conflict:${change.path}`);
|
|
266
|
+
const target = await assertSafeRepositoryFilePath(repository, mutationPhysicalPath(change), "context_mutation_deletion_target", { destinationMayBeAbsent: false });
|
|
267
|
+
const temporary = await assertSafeRepositoryFilePath(repository, change.temporary_path, "context_mutation_deletion_tombstone", { destinationMayBeAbsent: true, allowHardlinks: true });
|
|
268
|
+
if (!target.status)
|
|
269
|
+
invalid(`deletion_target_missing:${change.path}`);
|
|
270
|
+
if (temporary.status)
|
|
271
|
+
invalid(`temporary_collision:${change.temporary_path}`);
|
|
272
|
+
try {
|
|
273
|
+
await link(target.absolute, temporary.absolute);
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
if (error.code === "EEXIST")
|
|
277
|
+
invalid(`temporary_collision:${change.temporary_path}`);
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
await afterCreated?.(change, expectedSide);
|
|
281
|
+
const [targetState, temporaryState] = await Promise.all([
|
|
282
|
+
captureMutationFileState(repository, mutationPhysicalPath(change), {
|
|
283
|
+
allow_hardlinks: true,
|
|
284
|
+
}),
|
|
285
|
+
captureMutationFileState(repository, change.temporary_path, {
|
|
286
|
+
allow_hardlinks: true,
|
|
287
|
+
}),
|
|
288
|
+
]);
|
|
289
|
+
if (targetState.identity?.nlink !== "2" ||
|
|
290
|
+
temporaryState.identity?.nlink !== "2" ||
|
|
291
|
+
!sameMutationRecordedState(targetState, temporaryState) ||
|
|
292
|
+
!samePayload(targetState, change[expectedSide]) ||
|
|
293
|
+
!sameFileObject(targetState, beforeLink))
|
|
294
|
+
invalid(`deletion_tombstone_readback_mismatch:${change.path}`);
|
|
295
|
+
await syncParentDirectory(path.dirname(temporary.absolute));
|
|
296
|
+
return {
|
|
297
|
+
side: expectedSide,
|
|
298
|
+
state: mutationRecordedFileState(temporaryState),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
async function assertDeletionTombstoneReady(repository, change, expectedSide) {
|
|
302
|
+
const prepared = change.temporary_state;
|
|
303
|
+
if (!change.temporary_path ||
|
|
304
|
+
!prepared ||
|
|
305
|
+
prepared.side !== expectedSide ||
|
|
306
|
+
prepared.state.identity?.nlink !== "2")
|
|
307
|
+
invalid(`deletion_tombstone_missing:${change.path}`);
|
|
308
|
+
const [target, temporary] = await Promise.all([
|
|
309
|
+
captureMutationFileState(repository, mutationPhysicalPath(change), {
|
|
310
|
+
allow_hardlinks: true,
|
|
311
|
+
}),
|
|
312
|
+
captureMutationFileState(repository, change.temporary_path, {
|
|
313
|
+
allow_hardlinks: true,
|
|
314
|
+
}),
|
|
315
|
+
]);
|
|
316
|
+
if (!sameMutationRecordedState(target, prepared.state) ||
|
|
317
|
+
!sameMutationRecordedState(temporary, prepared.state))
|
|
318
|
+
invalid(`deletion_tombstone_identity_changed:${change.path}`);
|
|
319
|
+
}
|
|
320
|
+
async function assertNoUnrecordedTemporary(repository, change) {
|
|
321
|
+
if (!change.temporary_path || change.temporary_state)
|
|
322
|
+
return;
|
|
323
|
+
const temporary = await captureMutationFileState(repository, change.temporary_path, { allow_hardlinks: true });
|
|
324
|
+
if (temporary.exists)
|
|
325
|
+
invalid(`temporary_identity_unrecorded:${change.temporary_path}:manual_recovery_required_restore_exact_path_state_and_remove_only_the_verified_orphan`);
|
|
326
|
+
}
|
|
327
|
+
function isOwnedDeletionRemainder(current, recorded) {
|
|
328
|
+
return (current.exists &&
|
|
329
|
+
current.identity?.nlink === "1" &&
|
|
330
|
+
recorded.identity?.nlink === "2" &&
|
|
331
|
+
current.sha256 === recorded.sha256 &&
|
|
332
|
+
current.mode === recorded.mode &&
|
|
333
|
+
sameFileObject(current, recorded));
|
|
334
|
+
}
|
|
335
|
+
function oppositeSide(side) {
|
|
336
|
+
return side === "before" ? "after" : "before";
|
|
337
|
+
}
|
|
338
|
+
async function syncParentDirectory(directory) {
|
|
339
|
+
let handle;
|
|
340
|
+
try {
|
|
341
|
+
handle = await open(directory, "r");
|
|
342
|
+
await handle.sync();
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
const code = error.code;
|
|
346
|
+
if (process.platform === "win32" &&
|
|
347
|
+
["EACCES", "EINVAL", "EPERM"].includes(code ?? ""))
|
|
348
|
+
return;
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
finally {
|
|
352
|
+
await handle?.close();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function stateBytes(state) {
|
|
356
|
+
if (!state.exists || state.bytes_base64 === null || state.sha256 === null)
|
|
357
|
+
invalid("file_state_bytes_missing");
|
|
358
|
+
const bytes = Buffer.from(state.bytes_base64, "base64");
|
|
359
|
+
if (sha256Hex(bytes) !== state.sha256)
|
|
360
|
+
invalid("file_state_digest_mismatch");
|
|
361
|
+
return bytes;
|
|
362
|
+
}
|
|
363
|
+
function invalid(reason) {
|
|
364
|
+
throw new Error(`context_mutation_invalid:${reason}`);
|
|
365
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ContextCatalog } from "../context-catalog/catalog-types.js";
|
|
2
|
+
export declare function assertNoUnfinishedContextMutation(repository: string): Promise<void>;
|
|
3
|
+
export declare function loadMutationCatalog(repository: string, fileOverrides?: ReadonlyMap<string, Uint8Array | null>, directoryOverrides?: ReadonlySet<string>): Promise<ContextCatalog>;
|
|
4
|
+
export declare function assertMutationCatalogValid(catalog: ContextCatalog, prefix: string): void;
|
|
5
|
+
export declare function mutationStateBytes(state: {
|
|
6
|
+
bytes_base64: string | null;
|
|
7
|
+
}): Buffer;
|
|
8
|
+
export declare function decodeMutationUtf8(bytes: Uint8Array, file: string): string;
|
|
9
|
+
export declare function sameMutationArray(left: string[], right: string[]): boolean;
|
|
10
|
+
export declare function mutationCatalogFailure(messageText: string, cause?: unknown): never;
|
|
11
|
+
export declare function mutationIoFailure(messageText: string, cause?: unknown): never;
|
|
12
|
+
export declare function mutationMessage(error: unknown): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CLI_EXIT_CODES, CliCommandError } from "../cli-exit.js";
|
|
2
|
+
import { catalogErrors } from "../context-catalog/catalog-diagnostics.js";
|
|
3
|
+
import { loadContextCatalog } from "../context-catalog/catalog-load.js";
|
|
4
|
+
import { readContextMutationJournal } from "./mutation-journal.js";
|
|
5
|
+
export async function assertNoUnfinishedContextMutation(repository) {
|
|
6
|
+
let journal;
|
|
7
|
+
try {
|
|
8
|
+
journal = await readContextMutationJournal(repository);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
mutationIoFailure(`unable to inspect Context mutation journal: ${mutationMessage(error)}`, error);
|
|
12
|
+
}
|
|
13
|
+
if (journal)
|
|
14
|
+
mutationIoFailure(`unfinished Context mutation ${journal.transaction_id} exists; run ty-context context transaction status and then rollback or complete`);
|
|
15
|
+
}
|
|
16
|
+
export async function loadMutationCatalog(repository, fileOverrides, directoryOverrides) {
|
|
17
|
+
try {
|
|
18
|
+
return await loadContextCatalog(repository, {
|
|
19
|
+
file_overrides: fileOverrides,
|
|
20
|
+
directory_overrides: directoryOverrides,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
mutationIoFailure(`unable to load Context Catalog: ${mutationMessage(error)}`, error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function assertMutationCatalogValid(catalog, prefix) {
|
|
28
|
+
const errors = catalogErrors(catalog.diagnostics);
|
|
29
|
+
if (errors.length)
|
|
30
|
+
mutationCatalogFailure(`${prefix}: ${errors.join("; ")}`);
|
|
31
|
+
}
|
|
32
|
+
export function mutationStateBytes(state) {
|
|
33
|
+
if (state.bytes_base64 === null)
|
|
34
|
+
mutationIoFailure("mutation snapshot bytes are missing");
|
|
35
|
+
return Buffer.from(state.bytes_base64, "base64");
|
|
36
|
+
}
|
|
37
|
+
export function decodeMutationUtf8(bytes, file) {
|
|
38
|
+
try {
|
|
39
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
mutationCatalogFailure(`${file} must be valid UTF-8`, error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function sameMutationArray(left, right) {
|
|
46
|
+
return (left.length === right.length &&
|
|
47
|
+
left.every((value, index) => value === right[index]));
|
|
48
|
+
}
|
|
49
|
+
export function mutationCatalogFailure(messageText, cause) {
|
|
50
|
+
throw new CliCommandError(CLI_EXIT_CODES.catalog, messageText, { cause });
|
|
51
|
+
}
|
|
52
|
+
export function mutationIoFailure(messageText, cause) {
|
|
53
|
+
throw new CliCommandError(CLI_EXIT_CODES.io, messageText, { cause });
|
|
54
|
+
}
|
|
55
|
+
export function mutationMessage(error) {
|
|
56
|
+
return error instanceof Error ? error.message : String(error);
|
|
57
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type MutationBeforeSecondCas } from "./mutation-cas.js";
|
|
2
|
+
import type { ContextMutationJournal, ContextMutationPlan } from "./mutation-types.js";
|
|
3
|
+
export type MutationFaultPoint = "journal_created" | "prepared" | "before_validation" | `temporary_created_before_identity:${string}` | `published_before_journal:${string}` | `applied:${string}`;
|
|
4
|
+
export type MutationBarrier = (point: MutationFaultPoint, change?: ContextMutationJournal["files"][number]) => Promise<void>;
|
|
5
|
+
export interface ExecuteContextMutationOptions {
|
|
6
|
+
fault_after?: MutationFaultPoint;
|
|
7
|
+
before_second_cas?: MutationBeforeSecondCas;
|
|
8
|
+
barrier?: MutationBarrier;
|
|
9
|
+
}
|
|
10
|
+
export declare function executeContextMutationPlan(repository: string, plan: ContextMutationPlan, options?: ExecuteContextMutationOptions): Promise<void>;
|
|
11
|
+
export declare function finishContextMutation(repository: string, journal: ContextMutationJournal): Promise<void>;
|
|
12
|
+
export declare function cleanupContextMutationTemporaries(repository: string, journal: ContextMutationJournal): Promise<void>;
|