@cleocode/core 2026.10.3 → 2026.10.5-rc.ci.672
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/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +7 -37
- package/dist/bootstrap.js.map +1 -1
- package/dist/build-provenance.json +2 -2
- package/dist/caamp/adapter.d.ts.map +1 -1
- package/dist/caamp/adapter.js +5 -2
- package/dist/caamp/adapter.js.map +1 -1
- package/dist/changesets/parse-frontmatter.d.ts +1 -1
- package/dist/changesets/parse-frontmatter.d.ts.map +1 -1
- package/dist/changesets/parse-frontmatter.js +2 -1
- package/dist/changesets/parse-frontmatter.js.map +1 -1
- package/dist/changesets/parser.d.ts +1 -1
- package/dist/changesets/parser.d.ts.map +1 -1
- package/dist/changesets/parser.js +2 -1
- package/dist/changesets/parser.js.map +1 -1
- package/dist/changesets/writer.d.ts +8 -1
- package/dist/changesets/writer.d.ts.map +1 -1
- package/dist/changesets/writer.js +56 -5
- package/dist/changesets/writer.js.map +1 -1
- package/dist/cloud/keys.d.ts +9 -0
- package/dist/cloud/keys.d.ts.map +1 -1
- package/dist/cloud/keys.js +11 -0
- package/dist/cloud/keys.js.map +1 -1
- package/dist/cloud/nexus-attach.d.ts +17 -0
- package/dist/cloud/nexus-attach.d.ts.map +1 -1
- package/dist/cloud/nexus-attach.js +30 -9
- package/dist/cloud/nexus-attach.js.map +1 -1
- package/dist/cloud/nexus-auth.d.ts +7 -1
- package/dist/cloud/nexus-auth.d.ts.map +1 -1
- package/dist/cloud/nexus-auth.js +7 -1
- package/dist/cloud/nexus-auth.js.map +1 -1
- package/dist/cloud/nexus-cloud-activity.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-activity.js +2 -1
- package/dist/cloud/nexus-cloud-activity.js.map +1 -1
- package/dist/cloud/nexus-cloud-conflicts.d.ts +48 -0
- package/dist/cloud/nexus-cloud-conflicts.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-conflicts.js +68 -0
- package/dist/cloud/nexus-cloud-conflicts.js.map +1 -0
- package/dist/cloud/nexus-cloud-status.d.ts +42 -6
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-status.js +233 -19
- package/dist/cloud/nexus-cloud-status.js.map +1 -1
- package/dist/cloud/nexus-cloud.d.ts +18 -1
- package/dist/cloud/nexus-cloud.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud.js +56 -2
- package/dist/cloud/nexus-cloud.js.map +1 -1
- package/dist/cloud/nexus-credentials.d.ts +1 -1
- package/dist/cloud/nexus-credentials.d.ts.map +1 -1
- package/dist/cloud/nexus-credentials.js +1 -1
- package/dist/cloud/nexus-credentials.js.map +1 -1
- package/dist/cloud/nexus-enrol.d.ts +10 -1
- package/dist/cloud/nexus-enrol.d.ts.map +1 -1
- package/dist/cloud/nexus-enrol.js +47 -3
- package/dist/cloud/nexus-enrol.js.map +1 -1
- package/dist/cloud/nexus-first-run.d.ts +146 -0
- package/dist/cloud/nexus-first-run.d.ts.map +1 -0
- package/dist/cloud/nexus-first-run.js +358 -0
- package/dist/cloud/nexus-first-run.js.map +1 -0
- package/dist/cloud/nexus-link.d.ts +35 -4
- package/dist/cloud/nexus-link.d.ts.map +1 -1
- package/dist/cloud/nexus-link.js +172 -7
- package/dist/cloud/nexus-link.js.map +1 -1
- package/dist/cloud/nexus-presence-refresh.d.ts +65 -0
- package/dist/cloud/nexus-presence-refresh.d.ts.map +1 -0
- package/dist/cloud/nexus-presence-refresh.js +122 -0
- package/dist/cloud/nexus-presence-refresh.js.map +1 -0
- package/dist/cloud/nexus-project-history.d.ts +54 -0
- package/dist/cloud/nexus-project-history.d.ts.map +1 -0
- package/dist/cloud/nexus-project-history.js +108 -0
- package/dist/cloud/nexus-project-history.js.map +1 -0
- package/dist/cloud/nexus-project-names.d.ts +173 -0
- package/dist/cloud/nexus-project-names.d.ts.map +1 -0
- package/dist/cloud/nexus-project-names.js +314 -0
- package/dist/cloud/nexus-project-names.js.map +1 -0
- package/dist/cloud/nexus-vault-keys.d.ts +33 -2
- package/dist/cloud/nexus-vault-keys.d.ts.map +1 -1
- package/dist/cloud/nexus-vault-keys.js +144 -18
- package/dist/cloud/nexus-vault-keys.js.map +1 -1
- package/dist/cloud/nexus-vault.d.ts +7 -3
- package/dist/cloud/nexus-vault.d.ts.map +1 -1
- package/dist/cloud/nexus-vault.js +176 -29
- package/dist/cloud/nexus-vault.js.map +1 -1
- package/dist/cloud/presence.d.ts +1 -1
- package/dist/cloud/presence.d.ts.map +1 -1
- package/dist/cloud/presence.js +1 -1
- package/dist/cloud/presence.js.map +1 -1
- package/dist/cloud/projects.d.ts +7 -4
- package/dist/cloud/projects.d.ts.map +1 -1
- package/dist/cloud/projects.js +10 -1
- package/dist/cloud/projects.js.map +1 -1
- package/dist/cloud/signing.d.ts +14 -0
- package/dist/cloud/signing.d.ts.map +1 -1
- package/dist/cloud/signing.js +9 -0
- package/dist/cloud/signing.js.map +1 -1
- package/dist/conduit/cloud-endpoint.d.ts +96 -0
- package/dist/conduit/cloud-endpoint.d.ts.map +1 -0
- package/dist/conduit/cloud-endpoint.js +191 -0
- package/dist/conduit/cloud-endpoint.js.map +1 -0
- package/dist/conduit/conduit-client.d.ts.map +1 -1
- package/dist/conduit/conduit-client.js +2 -1
- package/dist/conduit/conduit-client.js.map +1 -1
- package/dist/conduit/factory.d.ts +4 -0
- package/dist/conduit/factory.d.ts.map +1 -1
- package/dist/conduit/factory.js +7 -1
- package/dist/conduit/factory.js.map +1 -1
- package/dist/conduit/http-transport.d.ts +12 -7
- package/dist/conduit/http-transport.d.ts.map +1 -1
- package/dist/conduit/http-transport.js +18 -11
- package/dist/conduit/http-transport.js.map +1 -1
- package/dist/conduit/index.d.ts +3 -1
- package/dist/conduit/index.d.ts.map +1 -1
- package/dist/conduit/index.js +3 -1
- package/dist/conduit/index.js.map +1 -1
- package/dist/conduit/sse-transport.d.ts +5 -1
- package/dist/conduit/sse-transport.d.ts.map +1 -1
- package/dist/conduit/sse-transport.js +10 -2
- package/dist/conduit/sse-transport.js.map +1 -1
- package/dist/config/registry.js +1 -1
- package/dist/config/registry.js.map +1 -1
- package/dist/core-paths.d.ts +13 -0
- package/dist/core-paths.d.ts.map +1 -0
- package/dist/core-paths.js +13 -0
- package/dist/core-paths.js.map +1 -0
- package/dist/decide/bench/source.js +1 -1
- package/dist/decide/bench/source.js.map +1 -1
- package/dist/decide/client.d.ts +1 -1
- package/dist/decide/client.d.ts.map +1 -1
- package/dist/decide/client.js +1 -1
- package/dist/decide/client.js.map +1 -1
- package/dist/decide/credentials.d.ts +1 -1
- package/dist/decide/credentials.d.ts.map +1 -1
- package/dist/decide/credentials.js +1 -1
- package/dist/decide/credentials.js.map +1 -1
- package/dist/decide/jev-wire.d.ts +1 -1
- package/dist/decide/jev-wire.d.ts.map +1 -1
- package/dist/decide/jev-wire.js +1 -1
- package/dist/decide/jev-wire.js.map +1 -1
- package/dist/decide/operations.d.ts +1 -1
- package/dist/decide/operations.d.ts.map +1 -1
- package/dist/decide/operations.js +1 -1
- package/dist/decide/operations.js.map +1 -1
- package/dist/decide/providers.d.ts +1 -1
- package/dist/decide/providers.d.ts.map +1 -1
- package/dist/decide/providers.js +1 -1
- package/dist/decide/providers.js.map +1 -1
- package/dist/decide/wizard.d.ts.map +1 -1
- package/dist/decide/wizard.js +1 -1
- package/dist/decide/wizard.js.map +1 -1
- package/dist/dispatch/config-domain-handler.d.ts +1 -1
- package/dist/dispatch/config-domain-handler.d.ts.map +1 -1
- package/dist/dispatch/config-domain-handler.js +1 -1
- package/dist/dispatch/config-domain-handler.js.map +1 -1
- package/dist/dispatch/contracts/derive-output-contract.d.ts +1 -1
- package/dist/dispatch/contracts/derive-output-contract.d.ts.map +1 -1
- package/dist/dispatch/contracts/derive-output-contract.js +2 -1
- package/dist/dispatch/contracts/derive-output-contract.js.map +1 -1
- package/dist/dispatch/contracts/ensures-schema.d.ts +1 -1
- package/dist/dispatch/contracts/ensures-schema.d.ts.map +1 -1
- package/dist/dispatch/contracts/ensures-schema.js +1 -1
- package/dist/dispatch/contracts/ensures-schema.js.map +1 -1
- package/dist/dispatch/contracts/input-contracts.d.ts +1 -1
- package/dist/dispatch/contracts/input-contracts.d.ts.map +1 -1
- package/dist/dispatch/contracts/input-contracts.js +3 -1
- package/dist/dispatch/contracts/input-contracts.js.map +1 -1
- package/dist/dispatch/contracts/output-contracts.d.ts +2 -1
- package/dist/dispatch/contracts/output-contracts.d.ts.map +1 -1
- package/dist/dispatch/contracts/output-contracts.js +1 -1
- package/dist/dispatch/contracts/output-contracts.js.map +1 -1
- package/dist/dispatch/describe-operation.d.ts +1 -1
- package/dist/dispatch/describe-operation.d.ts.map +1 -1
- package/dist/dispatch/describe-operation.js +1 -1
- package/dist/dispatch/describe-operation.js.map +1 -1
- package/dist/dispatch/mvi-projection.d.ts +1 -1
- package/dist/dispatch/mvi-projection.d.ts.map +1 -1
- package/dist/dispatch/mvi-projection.js +1 -1
- package/dist/dispatch/mvi-projection.js.map +1 -1
- package/dist/docs/display-alias.js +1 -1
- package/dist/docs/display-alias.js.map +1 -1
- package/dist/docs/docs-update.d.ts +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +2 -1
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/export-document.js +14 -58410
- package/dist/docs/export-document.js.map +3 -3
- package/dist/docs/publish-pr.js +1 -1
- package/dist/docs/publish-pr.js.map +1 -1
- package/dist/docs/supersede.js +1 -1
- package/dist/docs/supersede.js.map +1 -1
- package/dist/docs/validate-body.d.ts +1 -1
- package/dist/docs/validate-body.d.ts.map +1 -1
- package/dist/docs/validate-body.js +1 -1
- package/dist/docs/validate-body.js.map +1 -1
- package/dist/docs/writer-registry.js +1 -1
- package/dist/docs/writer-registry.js.map +1 -1
- package/dist/doctor/acceptance-drift.js +1 -1
- package/dist/doctor/acceptance-drift.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts +7 -10
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +11 -15
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/doctor/invariant-audit.js +1 -1
- package/dist/doctor/invariant-audit.js.map +1 -1
- package/dist/doctor/malformed-task-ids.js +1 -1
- package/dist/doctor/malformed-task-ids.js.map +1 -1
- package/dist/doctor/migrations.d.ts +18 -0
- package/dist/doctor/migrations.d.ts.map +1 -1
- package/dist/doctor/migrations.js +54 -2
- package/dist/doctor/migrations.js.map +1 -1
- package/dist/doctor/row-identity-refill.d.ts +43 -0
- package/dist/doctor/row-identity-refill.d.ts.map +1 -0
- package/dist/doctor/row-identity-refill.js +186 -0
- package/dist/doctor/row-identity-refill.js.map +1 -0
- package/dist/doctor/superseded-store.d.ts.map +1 -1
- package/dist/doctor/superseded-store.js +51 -2
- package/dist/doctor/superseded-store.js.map +1 -1
- package/dist/doctor/sync-repair.d.ts +39 -0
- package/dist/doctor/sync-repair.d.ts.map +1 -0
- package/dist/doctor/sync-repair.js +71 -0
- package/dist/doctor/sync-repair.js.map +1 -0
- package/dist/doctor/sync-triggers.d.ts +63 -4
- package/dist/doctor/sync-triggers.d.ts.map +1 -1
- package/dist/doctor/sync-triggers.js +352 -9
- package/dist/doctor/sync-triggers.js.map +1 -1
- package/dist/doctor/twin-collapse.js +1 -1
- package/dist/doctor/twin-collapse.js.map +1 -1
- package/dist/engine/engine-ops.d.ts.map +1 -1
- package/dist/engine/engine-ops.js +7 -1
- package/dist/engine/engine-ops.js.map +1 -1
- package/dist/engine-result.d.ts +1 -1
- package/dist/engine-result.d.ts.map +1 -1
- package/dist/engine-result.js +1 -1
- package/dist/engine-result.js.map +1 -1
- package/dist/error-catalog.js +1 -1
- package/dist/error-catalog.js.map +1 -1
- package/dist/error-registry.d.ts +1 -1
- package/dist/error-registry.d.ts.map +1 -1
- package/dist/error-registry.js +1 -1
- package/dist/error-registry.js.map +1 -1
- package/dist/errors-to-engine.d.ts +20 -0
- package/dist/errors-to-engine.d.ts.map +1 -1
- package/dist/errors-to-engine.js +37 -0
- package/dist/errors-to-engine.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/gc/janitor.d.ts +23 -4
- package/dist/gc/janitor.d.ts.map +1 -1
- package/dist/gc/janitor.js +71 -11
- package/dist/gc/janitor.js.map +1 -1
- package/dist/goal/continuation.d.ts +1 -1
- package/dist/goal/continuation.d.ts.map +1 -1
- package/dist/goal/continuation.js +1 -1
- package/dist/goal/continuation.js.map +1 -1
- package/dist/goal/judge.d.ts.map +1 -1
- package/dist/goal/judge.js +2 -1
- package/dist/goal/judge.js.map +1 -1
- package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/session-hooks.js +1 -1
- package/dist/hooks/handlers/session-hooks.js.map +1 -1
- package/dist/init/engine-ops.js +1 -1
- package/dist/init/engine-ops.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +22 -37
- package/dist/init.js.map +1 -1
- package/dist/inject/index.js +1 -1
- package/dist/inject/index.js.map +1 -1
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +13 -0
- package/dist/injection.js.map +1 -1
- package/dist/internal.d.ts +4 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +7 -4
- package/dist/internal.js.map +1 -1
- package/dist/issue/create.js +1 -1
- package/dist/issue/create.js.map +1 -1
- package/dist/json-schema-validator.js +1 -1
- package/dist/json-schema-validator.js.map +1 -1
- package/dist/lifecycle/index.d.ts +2 -23
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +5 -112
- package/dist/lifecycle/index.js.map +1 -1
- package/dist/lifecycle/kind-requirements.d.ts +1 -1
- package/dist/lifecycle/kind-requirements.d.ts.map +1 -1
- package/dist/lifecycle/kind-requirements.js +1 -1
- package/dist/lifecycle/kind-requirements.js.map +1 -1
- package/dist/lifecycle/pipeline.js +1 -1
- package/dist/lifecycle/pipeline.js.map +1 -1
- package/dist/lifecycle/resume.js +2 -2
- package/dist/lifecycle/resume.js.map +1 -1
- package/dist/lifecycle/state-machine.js +1 -1
- package/dist/lifecycle/state-machine.js.map +1 -1
- package/dist/lifecycle/status.d.ts +46 -0
- package/dist/lifecycle/status.d.ts.map +1 -0
- package/dist/lifecycle/status.js +147 -0
- package/dist/lifecycle/status.js.map +1 -0
- package/dist/lifecycle/verification/satisfies-validator.js +1 -1
- package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
- package/dist/llm/catalog-seeder.d.ts +1 -1
- package/dist/llm/catalog-seeder.d.ts.map +1 -1
- package/dist/llm/catalog-seeder.js +1 -1
- package/dist/llm/catalog-seeder.js.map +1 -1
- package/dist/llm/cli-ops.d.ts +1 -2
- package/dist/llm/cli-ops.d.ts.map +1 -1
- package/dist/llm/cli-ops.js +2 -1
- package/dist/llm/cli-ops.js.map +1 -1
- package/dist/llm/conversation.d.ts.map +1 -1
- package/dist/llm/conversation.js +15 -4
- package/dist/llm/conversation.js.map +1 -1
- package/dist/llm/credential-seeders/claude-code-seeder.js +1 -1
- package/dist/llm/credential-seeders/claude-code-seeder.js.map +1 -1
- package/dist/llm/credential-seeders/cleo-pkce-seeder.js +1 -1
- package/dist/llm/credential-seeders/cleo-pkce-seeder.js.map +1 -1
- package/dist/llm/credential-writeback.js +1 -1
- package/dist/llm/credential-writeback.js.map +1 -1
- package/dist/llm/entity-ops.d.ts +1 -1
- package/dist/llm/entity-ops.d.ts.map +1 -1
- package/dist/llm/entity-ops.js +2 -1
- package/dist/llm/entity-ops.js.map +1 -1
- package/dist/llm/llm-queue-admit.d.ts +1 -1
- package/dist/llm/llm-queue-admit.d.ts.map +1 -1
- package/dist/llm/llm-queue-admit.js +2 -1
- package/dist/llm/llm-queue-admit.js.map +1 -1
- package/dist/llm/onboarding/login-engine.js +1 -1
- package/dist/llm/onboarding/login-engine.js.map +1 -1
- package/dist/llm/pi/pi-errors.d.ts +1 -1
- package/dist/llm/pi/pi-errors.d.ts.map +1 -1
- package/dist/llm/pi/pi-errors.js +1 -1
- package/dist/llm/pi/pi-errors.js.map +1 -1
- package/dist/llm/plugin-facade.d.ts.map +1 -1
- package/dist/llm/plugin-facade.js +14 -93651
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/system-key.d.ts +1 -1
- package/dist/llm/system-key.d.ts.map +1 -1
- package/dist/llm/system-key.js +1 -1
- package/dist/llm/system-key.js.map +1 -1
- package/dist/llm/system-of-use-registry.d.ts +1 -1
- package/dist/llm/system-of-use-registry.d.ts.map +1 -1
- package/dist/llm/system-of-use-registry.js +1 -1
- package/dist/llm/system-of-use-registry.js.map +1 -1
- package/dist/llm/system-resolver.js +1 -1
- package/dist/llm/system-resolver.js.map +1 -1
- package/dist/llm/transports/bedrock.d.ts +1 -0
- package/dist/llm/transports/bedrock.d.ts.map +1 -1
- package/dist/llm/transports/bedrock.js +30 -12
- package/dist/llm/transports/bedrock.js.map +1 -1
- package/dist/memory/brain-host.d.ts +71 -0
- package/dist/memory/brain-host.d.ts.map +1 -0
- package/dist/memory/brain-host.js +84 -0
- package/dist/memory/brain-host.js.map +1 -0
- package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
- package/dist/memory/brain-writer-handlers.js +24 -7
- package/dist/memory/brain-writer-handlers.js.map +1 -1
- package/dist/memory/brain-writer-thread.d.ts +66 -6
- package/dist/memory/brain-writer-thread.d.ts.map +1 -1
- package/dist/memory/brain-writer-thread.js +67 -10
- package/dist/memory/brain-writer-thread.js.map +1 -1
- package/dist/memory/brain-writer-worker.js +7 -0
- package/dist/memory/brain-writer-worker.js.map +1 -1
- package/dist/memory/decision-contradiction.d.ts.map +1 -1
- package/dist/memory/decision-contradiction.js +10 -5
- package/dist/memory/decision-contradiction.js.map +1 -1
- package/dist/memory/decisions.js +2 -1
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/dialectic-evaluator.d.ts.map +1 -1
- package/dist/memory/dialectic-evaluator.js +4 -1
- package/dist/memory/dialectic-evaluator.js.map +1 -1
- package/dist/memory/embedding-backfill.d.ts +70 -0
- package/dist/memory/embedding-backfill.d.ts.map +1 -0
- package/dist/memory/embedding-backfill.js +110 -0
- package/dist/memory/embedding-backfill.js.map +1 -0
- package/dist/memory/index.js +1 -1
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/manifest-identity.js +1 -1
- package/dist/memory/manifest-identity.js.map +1 -1
- package/dist/memory/retrieval/observe.d.ts +23 -0
- package/dist/memory/retrieval/observe.d.ts.map +1 -1
- package/dist/memory/retrieval/observe.js +82 -36
- package/dist/memory/retrieval/observe.js.map +1 -1
- package/dist/memory/transcript-extractor.d.ts.map +1 -1
- package/dist/memory/transcript-extractor.js +3 -2
- package/dist/memory/transcript-extractor.js.map +1 -1
- package/dist/metrics/model-provider-registry.d.ts.map +1 -1
- package/dist/metrics/model-provider-registry.js +6 -0
- package/dist/metrics/model-provider-registry.js.map +1 -1
- package/dist/metrics/token-service.d.ts +33 -0
- package/dist/metrics/token-service.d.ts.map +1 -1
- package/dist/metrics/token-service.js +35 -0
- package/dist/metrics/token-service.js.map +1 -1
- package/dist/migration/index.js +1 -1
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/manual/T10165-backfill-adr-index.js +1 -1
- package/dist/migration/manual/T10165-backfill-adr-index.js.map +1 -1
- package/dist/nexus/api-contracts.d.ts.map +1 -1
- package/dist/nexus/api-contracts.js +27 -11
- package/dist/nexus/api-contracts.js.map +1 -1
- package/dist/nexus/api-extractors/http-extractor.d.ts +2 -2
- package/dist/nexus/api-extractors/http-extractor.d.ts.map +1 -1
- package/dist/nexus/api-extractors/http-extractor.js +3 -3
- package/dist/nexus/api-extractors/http-extractor.js.map +1 -1
- package/dist/nexus/assessment-projection.d.ts +1 -1
- package/dist/nexus/assessment-projection.d.ts.map +1 -1
- package/dist/nexus/assessment-projection.js +1 -1
- package/dist/nexus/assessment-projection.js.map +1 -1
- package/dist/nexus/clusters.js +1 -1
- package/dist/nexus/clusters.js.map +1 -1
- package/dist/nexus/deps.d.ts +1 -1
- package/dist/nexus/deps.d.ts.map +1 -1
- package/dist/nexus/deps.js +1 -1
- package/dist/nexus/deps.js.map +1 -1
- package/dist/nexus/diff.d.ts +1 -1
- package/dist/nexus/diff.d.ts.map +1 -1
- package/dist/nexus/diff.js +3 -2
- package/dist/nexus/diff.js.map +1 -1
- package/dist/nexus/fleet-status.d.ts +1 -1
- package/dist/nexus/fleet-status.d.ts.map +1 -1
- package/dist/nexus/fleet-status.js +1 -1
- package/dist/nexus/fleet-status.js.map +1 -1
- package/dist/nexus/flows.js +1 -1
- package/dist/nexus/flows.js.map +1 -1
- package/dist/nexus/identity.d.ts +8 -0
- package/dist/nexus/identity.d.ts.map +1 -1
- package/dist/nexus/identity.js +17 -1
- package/dist/nexus/identity.js.map +1 -1
- package/dist/nexus/index.d.ts +1 -1
- package/dist/nexus/index.d.ts.map +1 -1
- package/dist/nexus/index.js +2 -2
- package/dist/nexus/index.js.map +1 -1
- package/dist/nexus/nexus-bridge.d.ts.map +1 -1
- package/dist/nexus/nexus-bridge.js +5 -5
- package/dist/nexus/nexus-bridge.js.map +1 -1
- package/dist/nexus/permissions.d.ts +1 -1
- package/dist/nexus/permissions.d.ts.map +1 -1
- package/dist/nexus/permissions.js +1 -1
- package/dist/nexus/permissions.js.map +1 -1
- package/dist/nexus/query-dsl.js +1 -1
- package/dist/nexus/query-dsl.js.map +1 -1
- package/dist/nexus/query.d.ts +1 -2
- package/dist/nexus/query.d.ts.map +1 -1
- package/dist/nexus/query.js +1 -1
- package/dist/nexus/query.js.map +1 -1
- package/dist/nexus/registry-errors.js +1 -1
- package/dist/nexus/registry-errors.js.map +1 -1
- package/dist/nexus/registry.d.ts +23 -1
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +77 -2
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/workspace.js +1 -1
- package/dist/nexus/workspace.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +2 -1
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/query-ops.js +1 -1
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestrate/spawn-ops.js +1 -1
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/atomicity.d.ts +1 -1
- package/dist/orchestration/atomicity.d.ts.map +1 -1
- package/dist/orchestration/atomicity.js +1 -1
- package/dist/orchestration/atomicity.js.map +1 -1
- package/dist/orchestration/classify.js +1 -1
- package/dist/orchestration/classify.js.map +1 -1
- package/dist/orchestration/index.js +1 -1
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/parallel.js +1 -1
- package/dist/orchestration/parallel.js.map +1 -1
- package/dist/orchestration/protocol-validators.d.ts +1 -1
- package/dist/orchestration/protocol-validators.d.ts.map +1 -1
- package/dist/orchestration/protocol-validators.js +1 -1
- package/dist/orchestration/protocol-validators.js.map +1 -1
- package/dist/orchestration/skill-ops.js +1 -1
- package/dist/orchestration/skill-ops.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts +9 -0
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +13 -2
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/spawn.js +1 -1
- package/dist/orchestration/spawn.js.map +1 -1
- package/dist/paths.d.ts +3 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +4 -2
- package/dist/paths.js.map +1 -1
- package/dist/phases/deps.js +1 -1
- package/dist/phases/deps.js.map +1 -1
- package/dist/phases/index.js +1 -1
- package/dist/phases/index.js.map +1 -1
- package/dist/project-lifecycle.js +3 -3
- package/dist/project-lifecycle.js.map +1 -1
- package/dist/project-scope.js +1 -1
- package/dist/project-scope.js.map +1 -1
- package/dist/project-tombstone.js +1 -1
- package/dist/project-tombstone.js.map +1 -1
- package/dist/registrations.d.ts +30 -0
- package/dist/registrations.d.ts.map +1 -0
- package/dist/registrations.js +30 -0
- package/dist/registrations.js.map +1 -0
- package/dist/release/changesets-aggregator.js +1 -1
- package/dist/release/changesets-aggregator.js.map +1 -1
- package/dist/release/ci-evidence.d.ts +68 -2
- package/dist/release/ci-evidence.d.ts.map +1 -1
- package/dist/release/ci-evidence.js +203 -39
- package/dist/release/ci-evidence.js.map +1 -1
- package/dist/release/invariants/archive-reason-invariant.d.ts +1 -1
- package/dist/release/invariants/archive-reason-invariant.d.ts.map +1 -1
- package/dist/release/invariants/archive-reason-invariant.js +1 -1
- package/dist/release/invariants/archive-reason-invariant.js.map +1 -1
- package/dist/release/invariants/registry.d.ts +1 -1
- package/dist/release/invariants/registry.d.ts.map +1 -1
- package/dist/release/invariants/registry.js +1 -1
- package/dist/release/invariants/registry.js.map +1 -1
- package/dist/release/open.d.ts +4 -7
- package/dist/release/open.d.ts.map +1 -1
- package/dist/release/open.js +62 -24
- package/dist/release/open.js.map +1 -1
- package/dist/release/plan.d.ts +1 -2
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +4 -1
- package/dist/release/plan.js.map +1 -1
- package/dist/release/pr-evidence.d.ts +1 -1
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +2 -2
- package/dist/release/pr-evidence.js.map +1 -1
- package/dist/release/preflight-skip.d.ts +74 -10
- package/dist/release/preflight-skip.d.ts.map +1 -1
- package/dist/release/preflight-skip.js +254 -47
- package/dist/release/preflight-skip.js.map +1 -1
- package/dist/release/reconcile.d.ts +1 -1
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +19 -3
- package/dist/release/reconcile.js.map +1 -1
- package/dist/release/version-bump.d.ts +1 -1
- package/dist/release/version-bump.d.ts.map +1 -1
- package/dist/release/version-bump.js +1 -1
- package/dist/release/version-bump.js.map +1 -1
- package/dist/render/colors.js +1 -19
- package/dist/render/colors.js.map +1 -1
- package/dist/render/tasks/colors.js +1 -1
- package/dist/render/tasks/colors.js.map +1 -1
- package/dist/resources/admission-ledger.d.ts +587 -0
- package/dist/resources/admission-ledger.d.ts.map +1 -0
- package/dist/resources/admission-ledger.js +1401 -0
- package/dist/resources/admission-ledger.js.map +1 -0
- package/dist/resources/backend.d.ts +37 -1
- package/dist/resources/backend.d.ts.map +1 -1
- package/dist/resources/backend.js +1 -1
- package/dist/resources/darwin-backend.d.ts +152 -26
- package/dist/resources/darwin-backend.d.ts.map +1 -1
- package/dist/resources/darwin-backend.js +217 -34
- package/dist/resources/darwin-backend.js.map +1 -1
- package/dist/resources/governor.d.ts +36 -27
- package/dist/resources/governor.d.ts.map +1 -1
- package/dist/resources/governor.js +144 -49
- package/dist/resources/governor.js.map +1 -1
- package/dist/resources/heavy-command-hook-delivery.d.ts +144 -0
- package/dist/resources/heavy-command-hook-delivery.d.ts.map +1 -0
- package/dist/resources/heavy-command-hook-delivery.js +204 -0
- package/dist/resources/heavy-command-hook-delivery.js.map +1 -0
- package/dist/resources/heavy-command.d.ts +69 -0
- package/dist/resources/heavy-command.d.ts.map +1 -1
- package/dist/resources/heavy-command.js +479 -7
- package/dist/resources/heavy-command.js.map +1 -1
- package/dist/resources/pressure-gate.d.ts +148 -0
- package/dist/resources/pressure-gate.d.ts.map +1 -0
- package/dist/resources/pressure-gate.js +273 -0
- package/dist/resources/pressure-gate.js.map +1 -0
- package/dist/resources/run-admission.d.ts +33 -45
- package/dist/resources/run-admission.d.ts.map +1 -1
- package/dist/resources/run-admission.js +50 -118
- package/dist/resources/run-admission.js.map +1 -1
- package/dist/resources/run-class.d.ts +60 -4
- package/dist/resources/run-class.d.ts.map +1 -1
- package/dist/resources/run-class.js +474 -6
- package/dist/resources/run-class.js.map +1 -1
- package/dist/resources/run-governed.d.ts +43 -11
- package/dist/resources/run-governed.d.ts.map +1 -1
- package/dist/resources/run-governed.js +139 -99
- package/dist/resources/run-governed.js.map +1 -1
- package/dist/resources/slot-holder.d.ts +12 -4
- package/dist/resources/slot-holder.d.ts.map +1 -1
- package/dist/resources/slot-holder.js +19 -14
- package/dist/resources/slot-holder.js.map +1 -1
- package/dist/resources/spawn-wrapper.js +1 -1
- package/dist/resources/spawn-wrapper.js.map +1 -1
- package/dist/resources/supervisor-admit.d.ts +1 -1
- package/dist/resources/supervisor-admit.d.ts.map +1 -1
- package/dist/resources/supervisor-admit.js +2 -1
- package/dist/resources/supervisor-admit.js.map +1 -1
- package/dist/routing/build-command-groups.d.ts +1 -1
- package/dist/routing/build-command-groups.d.ts.map +1 -1
- package/dist/routing/build-command-groups.js +4 -1
- package/dist/routing/build-command-groups.js.map +1 -1
- package/dist/runtime/openapi/generate-openapi.d.ts +1 -1
- package/dist/runtime/openapi/generate-openapi.d.ts.map +1 -1
- package/dist/runtime/openapi/generate-openapi.js +1 -1
- package/dist/runtime/openapi/generate-openapi.js.map +1 -1
- package/dist/sagas/index.d.ts +3 -1
- package/dist/sagas/index.d.ts.map +1 -1
- package/dist/sagas/index.js +2 -5
- package/dist/sagas/index.js.map +1 -1
- package/dist/scaffold/ensure-skills.d.ts.map +1 -1
- package/dist/scaffold/ensure-skills.js +58 -2
- package/dist/scaffold/ensure-skills.js.map +1 -1
- package/dist/scaffold/project-identity.js +1 -1
- package/dist/scaffold/project-identity.js.map +1 -1
- package/dist/sdk/validator-attest.d.ts +1 -1
- package/dist/sdk/validator-attest.d.ts.map +1 -1
- package/dist/sdk/validator-attest.js +1 -1
- package/dist/sdk/validator-attest.js.map +1 -1
- package/dist/sdk/validator-reject.d.ts +1 -1
- package/dist/sdk/validator-reject.d.ts.map +1 -1
- package/dist/sdk/validator-reject.js +1 -1
- package/dist/sdk/validator-reject.js.map +1 -1
- package/dist/security/input-sanitization.js +2 -1
- package/dist/security/input-sanitization.js.map +1 -1
- package/dist/security/override-cap.js +1 -1
- package/dist/security/override-cap.js.map +1 -1
- package/dist/security/owner-override-auth.js +1 -1
- package/dist/security/owner-override-auth.js.map +1 -1
- package/dist/security/shared-evidence-tracker.js +1 -1
- package/dist/security/shared-evidence-tracker.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +35 -93136
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sentient/daemon.d.ts.map +1 -1
- package/dist/sentient/daemon.js +3 -0
- package/dist/sentient/daemon.js.map +1 -1
- package/dist/sentient/tick.d.ts +7 -0
- package/dist/sentient/tick.d.ts.map +1 -1
- package/dist/sentient/tick.js +11 -0
- package/dist/sentient/tick.js.map +1 -1
- package/dist/sequence/index.js +1 -1
- package/dist/sequence/index.js.map +1 -1
- package/dist/session/engine-ops.d.ts +3 -45
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +63 -112
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/session/status-op.d.ts +40 -0
- package/dist/session/status-op.d.ts.map +1 -0
- package/dist/session/status-op.js +71 -0
- package/dist/session/status-op.js.map +1 -0
- package/dist/session/task-current.d.ts +31 -0
- package/dist/session/task-current.d.ts.map +1 -0
- package/dist/session/task-current.js +59 -0
- package/dist/session/task-current.js.map +1 -0
- package/dist/sessions/assumptions.d.ts +1 -1
- package/dist/sessions/assumptions.d.ts.map +1 -1
- package/dist/sessions/assumptions.js +1 -1
- package/dist/sessions/assumptions.js.map +1 -1
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +11 -0
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/context-inject.js +1 -1
- package/dist/sessions/context-inject.js.map +1 -1
- package/dist/sessions/decisions.d.ts +1 -1
- package/dist/sessions/decisions.d.ts.map +1 -1
- package/dist/sessions/decisions.js +1 -1
- package/dist/sessions/decisions.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +2 -1
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/handoff.js +1 -1
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/sessions/index.d.ts +1 -2
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +3 -2
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-drift.js +1 -1
- package/dist/sessions/session-drift.js.map +1 -1
- package/dist/sessions/session-end-snapshot-entry.d.ts +4 -0
- package/dist/sessions/session-end-snapshot-entry.d.ts.map +1 -1
- package/dist/sessions/session-end-snapshot-entry.js +11 -0
- package/dist/sessions/session-end-snapshot-entry.js.map +1 -1
- package/dist/sessions/session-end-snapshot.d.ts.map +1 -1
- package/dist/sessions/session-end-snapshot.js +4 -0
- package/dist/sessions/session-end-snapshot.js.map +1 -1
- package/dist/sessions/session-enforcement.js +1 -1
- package/dist/sessions/session-enforcement.js.map +1 -1
- package/dist/sessions/session-show.d.ts +1 -2
- package/dist/sessions/session-show.d.ts.map +1 -1
- package/dist/sessions/session-show.js +1 -1
- package/dist/sessions/session-show.js.map +1 -1
- package/dist/sessions/session-stats.js +1 -1
- package/dist/sessions/session-stats.js.map +1 -1
- package/dist/sessions/session-suspend.d.ts +1 -2
- package/dist/sessions/session-suspend.d.ts.map +1 -1
- package/dist/sessions/session-suspend.js +1 -1
- package/dist/sessions/session-suspend.js.map +1 -1
- package/dist/sessions/session-switch.js +1 -1
- package/dist/sessions/session-switch.js.map +1 -1
- package/dist/sessions/snapshot.js +1 -1
- package/dist/sessions/snapshot.js.map +1 -1
- package/dist/sessions/terminal-identity.d.ts +1 -1
- package/dist/sessions/terminal-identity.d.ts.map +1 -1
- package/dist/sessions/terminal-identity.js +1 -1
- package/dist/sessions/terminal-identity.js.map +1 -1
- package/dist/setup/sections/integrations.d.ts.map +1 -1
- package/dist/setup/sections/integrations.js +9 -0
- package/dist/setup/sections/integrations.js.map +1 -1
- package/dist/setup/sections/models-roles.js +1 -1
- package/dist/setup/sections/models-roles.js.map +1 -1
- package/dist/setup/sections/verification.d.ts.map +1 -1
- package/dist/setup/sections/verification.js +8 -2
- package/dist/setup/sections/verification.js.map +1 -1
- package/dist/shutdown.d.ts +24 -0
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +30 -1
- package/dist/shutdown.js.map +1 -1
- package/dist/skills/agents/install.d.ts +46 -6
- package/dist/skills/agents/install.d.ts.map +1 -1
- package/dist/skills/agents/install.js +86 -17
- package/dist/skills/agents/install.js.map +1 -1
- package/dist/skills/injection/subagent.js +1 -1
- package/dist/skills/injection/subagent.js.map +1 -1
- package/dist/skills/manifests/research.d.ts.map +1 -1
- package/dist/skills/manifests/research.js +2 -1
- package/dist/skills/manifests/research.js.map +1 -1
- package/dist/skills/orchestrator/spawn.js +1 -1
- package/dist/skills/orchestrator/spawn.js.map +1 -1
- package/dist/skills/orchestrator/validator.js +1 -1
- package/dist/skills/orchestrator/validator.js.map +1 -1
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/snapshot/index.js +13 -0
- package/dist/snapshot/index.js.map +1 -1
- package/dist/spawn/agent-identity.js +1 -1
- package/dist/spawn/agent-identity.js.map +1 -1
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +2 -1
- package/dist/stats/index.js.map +1 -1
- package/dist/store/agent-install.d.ts.map +1 -1
- package/dist/store/agent-install.js +2 -1
- package/dist/store/agent-install.js.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts +1 -0
- package/dist/store/agent-registry-accessor.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.js +3 -1
- package/dist/store/agent-registry-accessor.js.map +1 -1
- package/dist/store/atomic.js +1 -1
- package/dist/store/atomic.js.map +1 -1
- package/dist/store/attachment-store.js +1 -1
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/audit-log-schema.d.ts +645 -0
- package/dist/store/audit-log-schema.d.ts.map +1 -0
- package/dist/store/audit-log-schema.js +30 -0
- package/dist/store/audit-log-schema.js.map +1 -0
- package/dist/store/background-ops.d.ts +26 -0
- package/dist/store/background-ops.d.ts.map +1 -1
- package/dist/store/background-ops.js +46 -0
- package/dist/store/background-ops.js.map +1 -1
- package/dist/store/backup-recover.d.ts +36 -1
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +99 -1
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/backup-verify.d.ts +1 -1
- package/dist/store/backup-verify.d.ts.map +1 -1
- package/dist/store/backup-verify.js +6 -1
- package/dist/store/backup-verify.js.map +1 -1
- package/dist/store/backup.js +1 -1
- package/dist/store/backup.js.map +1 -1
- package/dist/store/conduit-sqlite.d.ts.map +1 -1
- package/dist/store/conduit-sqlite.js +2 -26
- package/dist/store/conduit-sqlite.js.map +1 -1
- package/dist/store/converters.js +1 -1
- package/dist/store/converters.js.map +1 -1
- package/dist/store/db-helpers.js +1 -1
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dependency-cycles.js +1 -1
- package/dist/store/dependency-cycles.js.map +1 -1
- package/dist/store/display-id-alias.d.ts +2 -2
- package/dist/store/display-id-alias.d.ts.map +1 -1
- package/dist/store/display-id-alias.js +5 -28
- package/dist/store/display-id-alias.js.map +1 -1
- package/dist/store/drizzle-node-sqlite.d.ts +56 -0
- package/dist/store/drizzle-node-sqlite.d.ts.map +1 -0
- package/dist/store/drizzle-node-sqlite.js +87 -0
- package/dist/store/drizzle-node-sqlite.js.map +1 -0
- package/dist/store/dual-scope-db.d.ts +26 -33
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +416 -122
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/abort-events.d.ts +134 -0
- package/dist/store/exodus/abort-events.d.ts.map +1 -1
- package/dist/store/exodus/abort-events.js +201 -0
- package/dist/store/exodus/abort-events.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts +7 -0
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +156 -118
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +36 -0
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +102 -27
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/prior-recoveries.d.ts +75 -0
- package/dist/store/exodus/prior-recoveries.d.ts.map +1 -0
- package/dist/store/exodus/prior-recoveries.js +122 -0
- package/dist/store/exodus/prior-recoveries.js.map +1 -0
- package/dist/store/exodus/reconcile.d.ts.map +1 -1
- package/dist/store/exodus/reconcile.js +188 -24
- package/dist/store/exodus/reconcile.js.map +1 -1
- package/dist/store/exodus/runtime-targets.d.ts +3 -3
- package/dist/store/exodus/runtime-targets.js +3 -3
- package/dist/store/exodus/task-id-collision-sql.d.ts +52 -0
- package/dist/store/exodus/task-id-collision-sql.d.ts.map +1 -0
- package/dist/store/exodus/task-id-collision-sql.js +97 -0
- package/dist/store/exodus/task-id-collision-sql.js.map +1 -0
- package/dist/store/exodus/task-id-remap.d.ts +113 -0
- package/dist/store/exodus/task-id-remap.d.ts.map +1 -0
- package/dist/store/exodus/task-id-remap.js +301 -0
- package/dist/store/exodus/task-id-remap.js.map +1 -0
- package/dist/store/exodus/verify-migration.js +1 -1
- package/dist/store/exodus/verify-migration.js.map +1 -1
- package/dist/store/exodus/write-guard.d.ts +136 -0
- package/dist/store/exodus/write-guard.d.ts.map +1 -0
- package/dist/store/exodus/write-guard.js +289 -0
- package/dist/store/exodus/write-guard.js.map +1 -0
- package/dist/store/identity-share.d.ts +31 -0
- package/dist/store/identity-share.d.ts.map +1 -0
- package/dist/store/identity-share.js +54 -0
- package/dist/store/identity-share.js.map +1 -0
- package/dist/store/import-remap.js +1 -1
- package/dist/store/import-remap.js.map +1 -1
- package/dist/store/import-sort.js +1 -1
- package/dist/store/import-sort.js.map +1 -1
- package/dist/store/json.js +1 -1
- package/dist/store/json.js.map +1 -1
- package/dist/store/legacy-tasks-lineage.js +3 -3
- package/dist/store/legacy-tasks-lineage.js.map +1 -1
- package/dist/store/lock.d.ts +17 -0
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +18 -1
- package/dist/store/lock.js.map +1 -1
- package/dist/store/memory-sqlite.d.ts.map +1 -1
- package/dist/store/memory-sqlite.js +2 -25
- package/dist/store/memory-sqlite.js.map +1 -1
- package/dist/store/migration-files.d.ts +30 -0
- package/dist/store/migration-files.d.ts.map +1 -0
- package/dist/store/migration-files.js +59 -0
- package/dist/store/migration-files.js.map +1 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +14 -14
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-runner.d.ts.map +1 -1
- package/dist/store/migration-runner.js +2 -2
- package/dist/store/migration-runner.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +290 -355
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +4 -2
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/pid-alive.d.ts +15 -0
- package/dist/store/pid-alive.d.ts.map +1 -0
- package/dist/store/pid-alive.js +24 -0
- package/dist/store/pid-alive.js.map +1 -0
- package/dist/store/portable-bundle-scan.d.ts +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +1 -1
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts +10 -1
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +10 -1
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/recover-malformed-db.d.ts +1 -1
- package/dist/store/recover-malformed-db.d.ts.map +1 -1
- package/dist/store/recover-malformed-db.js +1 -1
- package/dist/store/recover-malformed-db.js.map +1 -1
- package/dist/store/repair-malformed-dbs.d.ts +1 -1
- package/dist/store/repair-malformed-dbs.d.ts.map +1 -1
- package/dist/store/repair-malformed-dbs.js +1 -1
- package/dist/store/repair-malformed-dbs.js.map +1 -1
- package/dist/store/restore-marker.d.ts +89 -0
- package/dist/store/restore-marker.d.ts.map +1 -0
- package/dist/store/restore-marker.js +197 -0
- package/dist/store/restore-marker.js.map +1 -0
- package/dist/store/restore-store.d.ts +85 -0
- package/dist/store/restore-store.d.ts.map +1 -0
- package/dist/store/restore-store.js +391 -0
- package/dist/store/restore-store.js.map +1 -0
- package/dist/store/row-identity.d.ts +123 -1
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +454 -80
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/schema/agent-registry-schema.d.ts +1 -1
- package/dist/store/schema/agent-registry-schema.d.ts.map +1 -1
- package/dist/store/schema/agent-registry-schema.js +5 -1
- package/dist/store/schema/agent-registry-schema.js.map +1 -1
- package/dist/store/schema/cleo-global/agent-registry.d.ts +1 -1
- package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/agent-registry.js +9 -5
- package/dist/store/schema/cleo-global/agent-registry.js.map +1 -1
- package/dist/store/schema/cleo-global/models-catalog.js +1 -1
- package/dist/store/schema/cleo-global/models-catalog.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.js +1 -1
- package/dist/store/schema/cleo-global/nexus.js.map +1 -1
- package/dist/store/schema/cleo-project/provenance-commits.d.ts +1 -1
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts +1 -1
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/provenance-orphans.js +9 -2
- package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -1
- package/dist/store/schema/cleo-project/provenance-rest.d.ts +1 -1
- package/dist/store/schema/cleo-project/provenance-rest.js +1 -1
- package/dist/store/schema/cleo-project/provenance-rest.js.map +1 -1
- package/dist/store/schema/cleo-shared/brain.js +1 -1
- package/dist/store/schema/cleo-shared/brain.js.map +1 -1
- package/dist/store/schema/memory-schema.d.ts +1 -1
- package/dist/store/schema/memory-schema.d.ts.map +1 -1
- package/dist/store/schema/memory-schema.js +1 -1
- package/dist/store/schema/memory-schema.js.map +1 -1
- package/dist/store/schema/nexus-schema.js +1 -1
- package/dist/store/schema/nexus-schema.js.map +1 -1
- package/dist/store/service-host-matcher.d.ts +1 -1
- package/dist/store/service-host-matcher.d.ts.map +1 -1
- package/dist/store/service-host-matcher.js +1 -1
- package/dist/store/service-host-matcher.js.map +1 -1
- package/dist/store/service-oauth.js +1 -1
- package/dist/store/service-oauth.js.map +1 -1
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +7 -1
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/sqlite-backup.d.ts +1 -1
- package/dist/store/sqlite-backup.d.ts.map +1 -1
- package/dist/store/sqlite-backup.js +1 -1
- package/dist/store/sqlite-backup.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +52 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +95 -22
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite-native.d.ts.map +1 -1
- package/dist/store/sqlite-native.js +9 -9
- package/dist/store/sqlite-native.js.map +1 -1
- package/dist/store/sqlite-pragmas.d.ts +12 -5
- package/dist/store/sqlite-pragmas.d.ts.map +1 -1
- package/dist/store/sqlite-pragmas.js +13 -2
- package/dist/store/sqlite-pragmas.js.map +1 -1
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +7 -32
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/status-registry.d.ts +1 -1
- package/dist/store/status-registry.d.ts.map +1 -1
- package/dist/store/status-registry.js +1 -1
- package/dist/store/status-registry.js.map +1 -1
- package/dist/store/sync/apply/applier.d.ts +119 -0
- package/dist/store/sync/apply/applier.d.ts.map +1 -0
- package/dist/store/sync/apply/applier.js +1239 -0
- package/dist/store/sync/apply/applier.js.map +1 -0
- package/dist/store/sync/apply/fk.d.ts +47 -0
- package/dist/store/sync/apply/fk.d.ts.map +1 -0
- package/dist/store/sync/apply/fk.js +89 -0
- package/dist/store/sync/apply/fk.js.map +1 -0
- package/dist/store/sync/apply/footprints.d.ts +60 -0
- package/dist/store/sync/apply/footprints.d.ts.map +1 -0
- package/dist/store/sync/apply/footprints.js +235 -0
- package/dist/store/sync/apply/footprints.js.map +1 -0
- package/dist/store/sync/apply/frame.d.ts +80 -0
- package/dist/store/sync/apply/frame.d.ts.map +1 -0
- package/dist/store/sync/apply/frame.js +127 -0
- package/dist/store/sync/apply/frame.js.map +1 -0
- package/dist/store/sync/apply/index.d.ts +11 -0
- package/dist/store/sync/apply/index.d.ts.map +1 -0
- package/dist/store/sync/apply/index.js +11 -0
- package/dist/store/sync/apply/index.js.map +1 -0
- package/dist/store/sync/apply/parent-delete.d.ts +38 -0
- package/dist/store/sync/apply/parent-delete.d.ts.map +1 -0
- package/dist/store/sync/apply/parent-delete.js +41 -0
- package/dist/store/sync/apply/parent-delete.js.map +1 -0
- package/dist/store/sync/apply/post-apply.d.ts +67 -0
- package/dist/store/sync/apply/post-apply.d.ts.map +1 -0
- package/dist/store/sync/apply/post-apply.js +118 -0
- package/dist/store/sync/apply/post-apply.js.map +1 -0
- package/dist/store/sync/apply/refs.d.ts +60 -0
- package/dist/store/sync/apply/refs.d.ts.map +1 -0
- package/dist/store/sync/apply/refs.js +90 -0
- package/dist/store/sync/apply/refs.js.map +1 -0
- package/dist/store/sync/apply/write-api.d.ts +195 -0
- package/dist/store/sync/apply/write-api.d.ts.map +1 -0
- package/dist/store/sync/apply/write-api.js +416 -0
- package/dist/store/sync/apply/write-api.js.map +1 -0
- package/dist/store/sync/apply-intent.d.ts +117 -0
- package/dist/store/sync/apply-intent.d.ts.map +1 -0
- package/dist/store/sync/apply-intent.js +225 -0
- package/dist/store/sync/apply-intent.js.map +1 -0
- package/dist/store/sync/capture.d.ts +32 -2
- package/dist/store/sync/capture.d.ts.map +1 -1
- package/dist/store/sync/capture.js +47 -13
- package/dist/store/sync/capture.js.map +1 -1
- package/dist/store/sync/conflicts.d.ts +81 -0
- package/dist/store/sync/conflicts.d.ts.map +1 -0
- package/dist/store/sync/conflicts.js +98 -0
- package/dist/store/sync/conflicts.js.map +1 -0
- package/dist/store/sync/field-leave.d.ts +146 -0
- package/dist/store/sync/field-leave.d.ts.map +1 -0
- package/dist/store/sync/field-leave.js +241 -0
- package/dist/store/sync/field-leave.js.map +1 -0
- package/dist/store/sync/flags.d.ts +119 -0
- package/dist/store/sync/flags.d.ts.map +1 -1
- package/dist/store/sync/flags.js +360 -0
- package/dist/store/sync/flags.js.map +1 -1
- package/dist/store/sync/held.d.ts +197 -0
- package/dist/store/sync/held.d.ts.map +1 -0
- package/dist/store/sync/held.js +314 -0
- package/dist/store/sync/held.js.map +1 -0
- package/dist/store/sync/identity-fill.d.ts.map +1 -1
- package/dist/store/sync/identity-fill.js +10 -2
- package/dist/store/sync/identity-fill.js.map +1 -1
- package/dist/store/sync/inbox.d.ts +114 -0
- package/dist/store/sync/inbox.d.ts.map +1 -0
- package/dist/store/sync/inbox.js +222 -0
- package/dist/store/sync/inbox.js.map +1 -0
- package/dist/store/sync/inherit.d.ts +36 -0
- package/dist/store/sync/inherit.d.ts.map +1 -0
- package/dist/store/sync/inherit.js +38 -0
- package/dist/store/sync/inherit.js.map +1 -0
- package/dist/store/sync/merge/engine.d.ts +114 -0
- package/dist/store/sync/merge/engine.d.ts.map +1 -0
- package/dist/store/sync/merge/engine.js +698 -0
- package/dist/store/sync/merge/engine.js.map +1 -0
- package/dist/store/sync/merge/index.d.ts +11 -0
- package/dist/store/sync/merge/index.d.ts.map +1 -0
- package/dist/store/sync/merge/index.js +11 -0
- package/dist/store/sync/merge/index.js.map +1 -0
- package/dist/store/sync/merge/rules.d.ts +91 -0
- package/dist/store/sync/merge/rules.d.ts.map +1 -0
- package/dist/store/sync/merge/rules.js +151 -0
- package/dist/store/sync/merge/rules.js.map +1 -0
- package/dist/store/sync/merge/types.d.ts +206 -0
- package/dist/store/sync/merge/types.d.ts.map +1 -0
- package/dist/store/sync/merge/types.js +15 -0
- package/dist/store/sync/merge/types.js.map +1 -0
- package/dist/store/sync/migration-hooks.d.ts +47 -0
- package/dist/store/sync/migration-hooks.d.ts.map +1 -0
- package/dist/store/sync/migration-hooks.js +74 -0
- package/dist/store/sync/migration-hooks.js.map +1 -0
- package/dist/store/sync/netting.d.ts +5 -0
- package/dist/store/sync/netting.d.ts.map +1 -1
- package/dist/store/sync/netting.js +29 -2
- package/dist/store/sync/netting.js.map +1 -1
- package/dist/store/sync/remap.d.ts +72 -0
- package/dist/store/sync/remap.d.ts.map +1 -0
- package/dist/store/sync/remap.js +209 -0
- package/dist/store/sync/remap.js.map +1 -0
- package/dist/store/sync/repair.d.ts +180 -0
- package/dist/store/sync/repair.d.ts.map +1 -0
- package/dist/store/sync/repair.js +499 -0
- package/dist/store/sync/repair.js.map +1 -0
- package/dist/store/sync/replica-registry.d.ts +54 -0
- package/dist/store/sync/replica-registry.d.ts.map +1 -1
- package/dist/store/sync/replica-registry.js +72 -2
- package/dist/store/sync/replica-registry.js.map +1 -1
- package/dist/store/sync/replica.d.ts +71 -9
- package/dist/store/sync/replica.d.ts.map +1 -1
- package/dist/store/sync/replica.js +95 -11
- package/dist/store/sync/replica.js.map +1 -1
- package/dist/store/sync/row-meta.d.ts +148 -0
- package/dist/store/sync/row-meta.d.ts.map +1 -0
- package/dist/store/sync/row-meta.js +200 -0
- package/dist/store/sync/row-meta.js.map +1 -0
- package/dist/store/sync/schema.d.ts +13 -5
- package/dist/store/sync/schema.d.ts.map +1 -1
- package/dist/store/sync/schema.js +34 -7
- package/dist/store/sync/schema.js.map +1 -1
- package/dist/store/sync/sealer-values.d.ts.map +1 -1
- package/dist/store/sync/sealer-values.js +1 -0
- package/dist/store/sync/sealer-values.js.map +1 -1
- package/dist/store/sync/sealer.d.ts +96 -0
- package/dist/store/sync/sealer.d.ts.map +1 -1
- package/dist/store/sync/sealer.js +532 -58
- package/dist/store/sync/sealer.js.map +1 -1
- package/dist/store/sync/sequencing.d.ts +175 -0
- package/dist/store/sync/sequencing.d.ts.map +1 -0
- package/dist/store/sync/sequencing.js +295 -0
- package/dist/store/sync/sequencing.js.map +1 -0
- package/dist/store/sync/structural.d.ts +30 -2
- package/dist/store/sync/structural.d.ts.map +1 -1
- package/dist/store/sync/structural.js +64 -2
- package/dist/store/sync/structural.js.map +1 -1
- package/dist/store/sync/timestamp-canon.d.ts +44 -0
- package/dist/store/sync/timestamp-canon.d.ts.map +1 -0
- package/dist/store/sync/timestamp-canon.js +102 -0
- package/dist/store/sync/timestamp-canon.js.map +1 -0
- package/dist/store/sync/timestamps.d.ts +1 -30
- package/dist/store/sync/timestamps.d.ts.map +1 -1
- package/dist/store/sync/timestamps.js +2 -89
- package/dist/store/sync/timestamps.js.map +1 -1
- package/dist/store/sync/trigger-classes.d.ts +8 -0
- package/dist/store/sync/trigger-classes.d.ts.map +1 -1
- package/dist/store/sync/trigger-classes.js +13 -0
- package/dist/store/sync/trigger-classes.js.map +1 -1
- package/dist/store/sync/write-actor.d.ts +58 -0
- package/dist/store/sync/write-actor.d.ts.map +1 -0
- package/dist/store/sync/write-actor.js +67 -0
- package/dist/store/sync/write-actor.js.map +1 -0
- package/dist/store/table-classification.d.ts +27 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +116 -0
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/task-claim.d.ts +1 -1
- package/dist/store/task-claim.d.ts.map +1 -1
- package/dist/store/task-claim.js +1 -1
- package/dist/store/task-claim.js.map +1 -1
- package/dist/store/task-reference-columns.d.ts +27 -0
- package/dist/store/task-reference-columns.d.ts.map +1 -0
- package/dist/store/task-reference-columns.js +65 -0
- package/dist/store/task-reference-columns.js.map +1 -0
- package/dist/store/task-version.d.ts +1 -1
- package/dist/store/task-version.d.ts.map +1 -1
- package/dist/store/task-version.js +1 -1
- package/dist/store/task-version.js.map +1 -1
- package/dist/store/tasks-schema.d.ts +2 -1
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +5 -4
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts +1 -1
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +3 -1
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/twin-collapse.d.ts +43 -14
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +373 -32
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +44 -674
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/store/validation-schemas.js +2 -22
- package/dist/store/validation-schemas.js.map +1 -1
- package/dist/store/vault-manifest.d.ts +6 -2
- package/dist/store/vault-manifest.d.ts.map +1 -1
- package/dist/store/vault-manifest.js +10 -3
- package/dist/store/vault-manifest.js.map +1 -1
- package/dist/store/worktree-build-guard.js +1 -1
- package/dist/store/worktree-build-guard.js.map +1 -1
- package/dist/store/worktree-isolation-guard.js +1 -1
- package/dist/store/worktree-isolation-guard.js.map +1 -1
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +1 -11
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/store/zod-schema-factory.d.ts +16 -0
- package/dist/store/zod-schema-factory.d.ts.map +1 -0
- package/dist/store/zod-schema-factory.js +23 -0
- package/dist/store/zod-schema-factory.js.map +1 -0
- package/dist/system/backup.d.ts +106 -0
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +295 -19
- package/dist/system/backup.js.map +1 -1
- package/dist/system/cleanup.js +1 -1
- package/dist/system/cleanup.js.map +1 -1
- package/dist/system/health.d.ts +13 -0
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +96 -1
- package/dist/system/health.js.map +1 -1
- package/dist/system/labels.js +1 -1
- package/dist/system/labels.js.map +1 -1
- package/dist/system/migrate.js +1 -1
- package/dist/system/migrate.js.map +1 -1
- package/dist/system/safestop.d.ts.map +1 -1
- package/dist/system/safestop.js +1 -1
- package/dist/system/safestop.js.map +1 -1
- package/dist/task-work/current.d.ts +34 -0
- package/dist/task-work/current.d.ts.map +1 -0
- package/dist/task-work/current.js +34 -0
- package/dist/task-work/current.js.map +1 -0
- package/dist/task-work/index.d.ts +2 -19
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +6 -20
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/ac-identity.d.ts +28 -0
- package/dist/tasks/ac-identity.d.ts.map +1 -0
- package/dist/tasks/ac-identity.js +43 -0
- package/dist/tasks/ac-identity.js.map +1 -0
- package/dist/tasks/ac-immutability.d.ts +1 -1
- package/dist/tasks/ac-immutability.d.ts.map +1 -1
- package/dist/tasks/ac-immutability.js +1 -1
- package/dist/tasks/ac-immutability.js.map +1 -1
- package/dist/tasks/ac-table.d.ts +2 -14
- package/dist/tasks/ac-table.d.ts.map +1 -1
- package/dist/tasks/ac-table.js +6 -29
- package/dist/tasks/ac-table.js.map +1 -1
- package/dist/tasks/acceptance-input.js +1 -1
- package/dist/tasks/acceptance-input.js.map +1 -1
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +3 -1
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +100 -19
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +169 -32
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/affected-template.d.ts +93 -0
- package/dist/tasks/affected-template.d.ts.map +1 -0
- package/dist/tasks/affected-template.js +198 -0
- package/dist/tasks/affected-template.js.map +1 -0
- package/dist/tasks/archive.d.ts.map +1 -1
- package/dist/tasks/archive.js +1 -1
- package/dist/tasks/archive.js.map +1 -1
- package/dist/tasks/axis-filters.d.ts.map +1 -1
- package/dist/tasks/axis-filters.js +2 -1
- package/dist/tasks/axis-filters.js.map +1 -1
- package/dist/tasks/child-disposition.js +1 -1
- package/dist/tasks/child-disposition.js.map +1 -1
- package/dist/tasks/collection.js +1 -1
- package/dist/tasks/collection.js.map +1 -1
- package/dist/tasks/command-line.d.ts +4 -1
- package/dist/tasks/command-line.d.ts.map +1 -1
- package/dist/tasks/command-line.js +7 -2
- package/dist/tasks/command-line.js.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +2 -1
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/decompose.js +1 -1
- package/dist/tasks/decompose.js.map +1 -1
- package/dist/tasks/delete.js +1 -1
- package/dist/tasks/delete.js.map +1 -1
- package/dist/tasks/done-plan.d.ts +2 -1
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +21 -21
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/done-record.d.ts +1 -1
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +1 -1
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +11 -5
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/tasks/enforcement.d.ts +2 -1
- package/dist/tasks/enforcement.d.ts.map +1 -1
- package/dist/tasks/enforcement.js +1 -1
- package/dist/tasks/enforcement.js.map +1 -1
- package/dist/tasks/engine-wrap-ops.js +1 -1
- package/dist/tasks/engine-wrap-ops.js.map +1 -1
- package/dist/tasks/engine-wrap.d.ts.map +1 -1
- package/dist/tasks/engine-wrap.js +7 -3
- package/dist/tasks/engine-wrap.js.map +1 -1
- package/dist/tasks/epic-enforcement.js +1 -1
- package/dist/tasks/epic-enforcement.js.map +1 -1
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +216 -20
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/find.js +1 -1
- package/dist/tasks/find.js.map +1 -1
- package/dist/tasks/gate-result-cache.js +1 -1
- package/dist/tasks/gate-result-cache.js.map +1 -1
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +1 -1
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/heavy-tool-env.d.ts +454 -19
- package/dist/tasks/heavy-tool-env.d.ts.map +1 -1
- package/dist/tasks/heavy-tool-env.js +818 -42
- package/dist/tasks/heavy-tool-env.js.map +1 -1
- package/dist/tasks/index.d.ts +3 -3
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +3 -3
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/labels.js +1 -1
- package/dist/tasks/labels.js.map +1 -1
- package/dist/tasks/nexus-impact-gate.js +1 -1
- package/dist/tasks/nexus-impact-gate.js.map +1 -1
- package/dist/tasks/pipeline-stage.js +1 -1
- package/dist/tasks/pipeline-stage.js.map +1 -1
- package/dist/tasks/population.js +1 -1
- package/dist/tasks/population.js.map +1 -1
- package/dist/tasks/ranking-audit.js +1 -1
- package/dist/tasks/ranking-audit.js.map +1 -1
- package/dist/tasks/reconcile-scope.js +1 -1
- package/dist/tasks/reconcile-scope.js.map +1 -1
- package/dist/tasks/relates.js +1 -1
- package/dist/tasks/relates.js.map +1 -1
- package/dist/tasks/req.d.ts.map +1 -1
- package/dist/tasks/req.js +2 -1
- package/dist/tasks/req.js.map +1 -1
- package/dist/tasks/severity-attestation.d.ts +1 -1
- package/dist/tasks/severity-attestation.d.ts.map +1 -1
- package/dist/tasks/severity-attestation.js +1 -1
- package/dist/tasks/severity-attestation.js.map +1 -1
- package/dist/tasks/show.d.ts.map +1 -1
- package/dist/tasks/show.js +47 -3
- package/dist/tasks/show.js.map +1 -1
- package/dist/tasks/task-import.js +1 -1
- package/dist/tasks/task-import.js.map +1 -1
- package/dist/tasks/task-reparent.d.ts.map +1 -1
- package/dist/tasks/task-reparent.js +2 -1
- package/dist/tasks/task-reparent.js.map +1 -1
- package/dist/tasks/test-run-binding.d.ts.map +1 -1
- package/dist/tasks/test-run-binding.js +9 -2
- package/dist/tasks/test-run-binding.js.map +1 -1
- package/dist/tasks/tool-cache-env.d.ts +20 -13
- package/dist/tasks/tool-cache-env.d.ts.map +1 -1
- package/dist/tasks/tool-cache-env.js +27 -48
- package/dist/tasks/tool-cache-env.js.map +1 -1
- package/dist/tasks/tool-cache.d.ts +30 -7
- package/dist/tasks/tool-cache.d.ts.map +1 -1
- package/dist/tasks/tool-cache.js +74 -20
- package/dist/tasks/tool-cache.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +8 -0
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +15 -1
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/tool-runner-guard.d.ts +131 -0
- package/dist/tasks/tool-runner-guard.d.ts.map +1 -0
- package/dist/tasks/tool-runner-guard.js +141 -0
- package/dist/tasks/tool-runner-guard.js.map +1 -0
- package/dist/tasks/tool-semaphore.d.ts +106 -302
- package/dist/tasks/tool-semaphore.d.ts.map +1 -1
- package/dist/tasks/tool-semaphore.js +132 -558
- package/dist/tasks/tool-semaphore.js.map +1 -1
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +2 -1
- package/dist/tasks/update.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +35 -31
- package/dist/upgrade.js.map +1 -1
- package/dist/validation/doctor/checks.d.ts +41 -0
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/dist/validation/doctor/checks.js +251 -0
- package/dist/validation/doctor/checks.js.map +1 -1
- package/dist/validation/doctor/index.d.ts +1 -1
- package/dist/validation/doctor/index.d.ts.map +1 -1
- package/dist/validation/doctor/index.js +1 -1
- package/dist/validation/doctor/index.js.map +1 -1
- package/dist/validation/engine-ops.js +1 -1
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/validation/engine.d.ts +1 -1
- package/dist/validation/engine.d.ts.map +1 -1
- package/dist/validation/engine.js +2 -1
- package/dist/validation/engine.js.map +1 -1
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/operation-gate-validators.js +1 -1
- package/dist/validation/operation-gate-validators.js.map +1 -1
- package/dist/validation/protocol-common.js +1 -1
- package/dist/validation/protocol-common.js.map +1 -1
- package/dist/validation/protocols/_shared.js +1 -1
- package/dist/validation/protocols/_shared.js.map +1 -1
- package/dist/validation/validate-ops.js +1 -1
- package/dist/validation/validate-ops.js.map +1 -1
- package/dist/validation/verification.js +1 -1
- package/dist/validation/verification.js.map +1 -1
- package/dist/workgraph/index.d.ts +1 -1
- package/dist/workgraph/index.d.ts.map +1 -1
- package/dist/workgraph/index.js +1 -1
- package/dist/workgraph/index.js.map +1 -1
- package/dist/workgraph/reparent-preflight.d.ts +1 -2
- package/dist/workgraph/reparent-preflight.d.ts.map +1 -1
- package/dist/workgraph/reparent-preflight.js +1 -1
- package/dist/workgraph/reparent-preflight.js.map +1 -1
- package/dist/workgraph/scaffold-validate.js +1 -1
- package/dist/workgraph/scaffold-validate.js.map +1 -1
- package/dist/worktree/force-unlock.d.ts +1 -1
- package/dist/worktree/force-unlock.d.ts.map +1 -1
- package/dist/worktree/force-unlock.js +1 -1
- package/dist/worktree/force-unlock.js.map +1 -1
- package/dist/worktree/isolation.d.ts +1 -1
- package/dist/worktree/isolation.d.ts.map +1 -1
- package/dist/worktree/isolation.js +1 -1
- package/dist/worktree/isolation.js.map +1 -1
- package/dist/worktree/list.d.ts +1 -1
- package/dist/worktree/list.d.ts.map +1 -1
- package/dist/worktree/list.js +1 -1
- package/dist/worktree/list.js.map +1 -1
- package/dist/worktree/prune.d.ts +1 -1
- package/dist/worktree/prune.d.ts.map +1 -1
- package/dist/worktree/prune.js +1 -1
- package/dist/worktree/prune.js.map +1 -1
- package/dist/worktree/worktree-adopt.d.ts +1 -2
- package/dist/worktree/worktree-adopt.d.ts.map +1 -1
- package/dist/worktree/worktree-adopt.js +1 -1
- package/dist/worktree/worktree-adopt.js.map +1 -1
- package/migrations/sync-journal/20261004120000_t12757-apply-intent/migration.sql +21 -0
- package/migrations/sync-journal/20261005120000_t12344-inbox/migration.sql +67 -0
- package/migrations/sync-journal/20261006120000_t13193-rebase-undo/migration.sql +51 -0
- package/migrations/sync-journal/20261006130000_t13193-rebase-state/migration.sql +17 -0
- package/migrations/sync-journal/20261006140000_t13193-held-rows/migration.sql +24 -0
- package/package.json +13 -13
- package/schemas/project-context.schema.json +19 -1
- package/templates/CLEO-INJECTION.md +11 -11
- package/templates/CLEO-REFERENCE.md +2 -2
- package/templates/workflows/release-prepare.yml.tmpl +10 -10
|
@@ -0,0 +1,1239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The applier loop (T12344; journal spec §3.1, §3.2, §2.9).
|
|
3
|
+
*
|
|
4
|
+
* {@link applyStagedTxns} drains a stream's inbox in `(seq, txn_idx)` order.
|
|
5
|
+
* Each transaction is decided and applied in ONE apply frame, together with
|
|
6
|
+
* its status, its conflict records, its row meta and its leaves:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Schema.** A segment or transaction format newer than this build is
|
|
9
|
+
* `refused-schema` (E_SCHEMA_AHEAD), kept for replay after an upgrade.
|
|
10
|
+
* 2. **Skew (§1.3).** A transaction whose HLC is beyond the skew bound is
|
|
11
|
+
* `held-skew`, and so is every later transaction of the same origin
|
|
12
|
+
* replica in this pass (FIFO); other replicas keep flowing.
|
|
13
|
+
* 3. **Dependency holds.** A transaction touching a row a pending
|
|
14
|
+
* transaction writes waits (`pending`) behind it. Holds are scoped to
|
|
15
|
+
* those rows, never head-of-line.
|
|
16
|
+
* 4. **Plan** (nothing written). Each op is decided against the store's
|
|
17
|
+
* state carried forward inside the transaction. The transaction is
|
|
18
|
+
* `pending` when an op updates a row never seen, re-keys a row never
|
|
19
|
+
* seen, references a target never seen (§3.2 NEW-2: no age limit), or
|
|
20
|
+
* carries a secret (not unsealed yet); `refused-schema` when an op names
|
|
21
|
+
* an unknown table or column, or is malformed.
|
|
22
|
+
* 5. **Apply**, op by op, each against the store as it is now and inside its
|
|
23
|
+
* own savepoint:
|
|
24
|
+
* - references travel as target uids and are written as the targets'
|
|
25
|
+
* local keys ({@link resolveRef}, following `tasks_uid_aliases`); a
|
|
26
|
+
* reference to a deleted target is a `dangling-ref` conflict and a
|
|
27
|
+
* revivable void, never pending;
|
|
28
|
+
* - a guard trigger or constraint that aborts the write rolls back only
|
|
29
|
+
* that op: a `guard` conflict and a void (§3.2 D, T12777);
|
|
30
|
+
* - a parent delete whose CASCADE sync-set children remain follows the
|
|
31
|
+
* table's `onRemoteParentDelete` policy: `conflict` voids it with a
|
|
32
|
+
* `delete-with-live-children` conflict, `cascade-with-ops` deletes the
|
|
33
|
+
* children first with tombstones;
|
|
34
|
+
* - a K op re-keys the row through the write API (its meta and typed-rule
|
|
35
|
+
* state move with it), after `remapPending` moves local captures and
|
|
36
|
+
* unsent ops onto the new uid; a re-key onto a live uid is a
|
|
37
|
+
* `uid-collision` void.
|
|
38
|
+
* The effects go through the write API, which records the apply intents,
|
|
39
|
+
* so the sealer echoes nothing; row meta is set to the engine's state,
|
|
40
|
+
* conflicts are recorded, and the transaction is marked `applied`,
|
|
41
|
+
* `conflict` (something recorded) or `void` (every op refused).
|
|
42
|
+
*
|
|
43
|
+
* Passes repeat while a pass applies something, so a transaction pending on
|
|
44
|
+
* a row a later transaction inserts applies in the same call.
|
|
45
|
+
*
|
|
46
|
+
* Deletes run with foreign keys ON: the origin journals cascaded child Ds
|
|
47
|
+
* before the parent's D, so a child D whose row is already gone applies as a
|
|
48
|
+
* tombstone, never a missing-row failure; and SET NULL actions are not
|
|
49
|
+
* journaled yet (T13226), so this replica's own FK actions fill that gap
|
|
50
|
+
* (the delete records their intents, so nothing is re-emitted).
|
|
51
|
+
*
|
|
52
|
+
* Out of this slice: Gate C validators (PR-5), soft references across
|
|
53
|
+
* streams (`_sync_soft_ref`), holds that follow a re-keyed uid, and the
|
|
54
|
+
* scoped rebase (§3.5).
|
|
55
|
+
*
|
|
56
|
+
* @module store/sync/apply/applier
|
|
57
|
+
* @task T12344
|
|
58
|
+
*/
|
|
59
|
+
import { BIRTH_FP_COLUMN, UID_COLUMN } from '../../row-identity-registry.js';
|
|
60
|
+
import { captureTableDef } from '../capture.js';
|
|
61
|
+
import { recordConflicts } from '../conflicts.js';
|
|
62
|
+
import { clearFieldLeaves, readFieldFrontiers, readFieldLeaves, recordFieldLeaves, restoreFieldState, setFieldFrontiers, } from '../field-leave.js';
|
|
63
|
+
import { accountRebaseRows, heldOp, holdOp, txnHasHold, unholdOp } from '../held.js';
|
|
64
|
+
import { encodeHlc, genesisHlc, isWithinSkew, parseHlc } from '../hlc.js';
|
|
65
|
+
import { markTxns, stagedTxns } from '../inbox.js';
|
|
66
|
+
import { applyOp, checkSchemaVersion } from '../merge/engine.js';
|
|
67
|
+
import { mergeSpecFor } from '../merge/rules.js';
|
|
68
|
+
import { UNSEEN_ROW, } from '../merge/types.js';
|
|
69
|
+
import { remapPending } from '../remap.js';
|
|
70
|
+
import { fieldHlcsOf, readRowMetaFull, restoreRowMeta } from '../row-meta.js';
|
|
71
|
+
import { hasTable } from '../schema.js';
|
|
72
|
+
import { canonicalJson } from '../sealer-values.js';
|
|
73
|
+
import { capturePosition, markSequenced, ownEchoFastPath, readRowUndo, recordForeignTouches, resnapshotRowUndo, unsequencedLocalTxn, unsequencedLocalTxns, } from '../sequencing.js';
|
|
74
|
+
import { withTriggersSuspended } from '../trigger-classes.js';
|
|
75
|
+
import { widenFootprint } from './footprints.js';
|
|
76
|
+
import { withApplyFrame } from './frame.js';
|
|
77
|
+
import { parentDeletePolicy } from './parent-delete.js';
|
|
78
|
+
import { checkApplyPreconditions, checkTaskTreeShape } from './post-apply.js';
|
|
79
|
+
import { resolveRef, uidOfKey } from './refs.js';
|
|
80
|
+
const rowKey = (t, u) => `${t}\u0000${u}`;
|
|
81
|
+
const keyText = (k) => `${k.stream}:${k.seq}:${k.txnIdx}`;
|
|
82
|
+
/**
|
|
83
|
+
* The row's state as the merge sees it: the live row with its field HLCs
|
|
84
|
+
* and leaves, a tombstone, or never seen. A live row with no row meta (not
|
|
85
|
+
* yet sealed) carries the genesis HLC, so any stream write wins over it.
|
|
86
|
+
*/
|
|
87
|
+
function loadRowState(db, api, def, uid, localReplica) {
|
|
88
|
+
const meta = api.rowMeta(def.table, uid);
|
|
89
|
+
const row = api.readRow(def.table, uid);
|
|
90
|
+
if (row === null) {
|
|
91
|
+
return meta?.deleted ? { live: false, tombstone: meta.hlc, fields: {} } : UNSEEN_ROW;
|
|
92
|
+
}
|
|
93
|
+
const floor = encodeHlc(genesisHlc(localReplica));
|
|
94
|
+
const fh = meta && !meta.deleted ? fieldHlcsOf(def, meta) : {};
|
|
95
|
+
const leaves = readFieldLeaves(db, def.table, uid);
|
|
96
|
+
const frontiers = readFieldFrontiers(db, def.table, uid);
|
|
97
|
+
const fields = {};
|
|
98
|
+
for (const [col, stored] of Object.entries(row)) {
|
|
99
|
+
// The merge compares stream values: a reference reads as its target's uid.
|
|
100
|
+
const target = def.refs.get(col);
|
|
101
|
+
const value = target && stored !== null ? (uidOfKey(db, target, stored) ?? stored) : stored;
|
|
102
|
+
const hlc = fh[col] ?? (meta && !meta.deleted ? meta.hlc : floor);
|
|
103
|
+
const leave = leaves[col];
|
|
104
|
+
const frontier = frontiers[col];
|
|
105
|
+
fields[col] = {
|
|
106
|
+
value,
|
|
107
|
+
hlc,
|
|
108
|
+
...(leave !== undefined ? { leave } : {}),
|
|
109
|
+
...(frontier !== undefined ? { frontier } : {}),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return { live: true, tombstone: null, fields };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* This replica's own echo (§3.1: own segments are staged and applied like
|
|
116
|
+
* any other) without its counter deltas: a `{ $inc }` the replica authored is
|
|
117
|
+
* already in its row, and applying it again would double it. Everything else
|
|
118
|
+
* is idempotent for an echo (the fields already carry the op's HLCs).
|
|
119
|
+
*/
|
|
120
|
+
function ownEcho(op, st, localReplica) {
|
|
121
|
+
if (st.replicaId !== localReplica || !op.a)
|
|
122
|
+
return op;
|
|
123
|
+
const a = Object.fromEntries(Object.entries(op.a).filter(([, v]) => !(typeof v === 'object' && v !== null && '$inc' in v)));
|
|
124
|
+
return { ...op, a };
|
|
125
|
+
}
|
|
126
|
+
/** Why this slice cannot apply `op` yet, or null. */
|
|
127
|
+
function notYet(op, def) {
|
|
128
|
+
for (const [col, v] of Object.entries(op.a ?? {})) {
|
|
129
|
+
if (v !== null && def.secret.has(col))
|
|
130
|
+
return `${op.t}/${op.u}: secret ${col} (needs unsealing)`;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
/** Whether a row with `uid` exists in `table`. */
|
|
135
|
+
function rowExists(api, table, uid) {
|
|
136
|
+
return api.readRow(table, uid) !== null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* A missing reference of `op` (a target never seen), or null. A target the
|
|
140
|
+
* transaction itself inserts or re-keys to counts as present wherever its op
|
|
141
|
+
* sits: netting keeps an op at its FIRST capture, so a row may reference a
|
|
142
|
+
* row inserted after it in the same transaction (T13238).
|
|
143
|
+
*/
|
|
144
|
+
function missingRef(db, op, def, inTxn) {
|
|
145
|
+
for (const [col, v] of Object.entries(op.a ?? {})) {
|
|
146
|
+
const target = def.refs.get(col);
|
|
147
|
+
if (!target || v === null)
|
|
148
|
+
continue;
|
|
149
|
+
if (typeof v !== 'string')
|
|
150
|
+
return 'malformed';
|
|
151
|
+
if (inTxn.has(rowKey(target.table, v)))
|
|
152
|
+
continue;
|
|
153
|
+
if (resolveRef(db, target, v).kind === 'missing')
|
|
154
|
+
return { col, uid: v };
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
/** Decide every op of `txn` against the store, carrying row state forward. */
|
|
159
|
+
function planTxn(db, api, st, defs, localReplica) {
|
|
160
|
+
const states = new Map();
|
|
161
|
+
const specs = new Map();
|
|
162
|
+
// Rows the transaction itself creates: its inserts and re-key targets.
|
|
163
|
+
const txnRows = new Set(st.txn.ops.flatMap((o) => o.o === 'I' ? [rowKey(o.t, o.u)] : o.o === 'K' && o.nu ? [rowKey(o.t, o.nu)] : []));
|
|
164
|
+
// Rows a pending transaction holds: every row it writes but the one it waits for.
|
|
165
|
+
const holds = (except) => [
|
|
166
|
+
...new Set(st.txn.ops.map((o) => rowKey(o.t, o.u)).filter((k) => k !== except)),
|
|
167
|
+
];
|
|
168
|
+
for (const op of st.txn.ops) {
|
|
169
|
+
const def = defs(op.t);
|
|
170
|
+
if (!def)
|
|
171
|
+
return { kind: 'refused-schema', reason: `unknown table ${op.t}` };
|
|
172
|
+
const blocked = notYet(op, def);
|
|
173
|
+
if (blocked !== null)
|
|
174
|
+
return { kind: 'pending', reason: blocked, holds: holds() };
|
|
175
|
+
const k = rowKey(op.t, op.u);
|
|
176
|
+
if (op.o === 'K') {
|
|
177
|
+
const nu = op.nu ?? op.u;
|
|
178
|
+
const known = (u) => states.get(rowKey(op.t, u))?.live === true ||
|
|
179
|
+
rowExists(api, op.t, u) ||
|
|
180
|
+
api.rowMeta(op.t, u)?.deleted === 1;
|
|
181
|
+
if (!known(op.u) && !known(nu)) {
|
|
182
|
+
return {
|
|
183
|
+
kind: 'pending',
|
|
184
|
+
reason: `${op.t}/${op.u}: re-key of a row not seen yet`,
|
|
185
|
+
holds: holds(k),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const missing = missingRef(db, op, def, txnRows);
|
|
191
|
+
if (missing === 'malformed') {
|
|
192
|
+
return { kind: 'refused-schema', reason: `${op.t}/${op.u}: a reference that is not a uid` };
|
|
193
|
+
}
|
|
194
|
+
if (missing !== null) {
|
|
195
|
+
return {
|
|
196
|
+
kind: 'pending',
|
|
197
|
+
reason: `${op.t}/${op.u}: reference ${missing.col} to ${missing.uid} not seen yet`,
|
|
198
|
+
holds: holds(),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const before = states.get(k) ?? loadRowState(db, api, def, op.u, localReplica);
|
|
202
|
+
let spec = specs.get(op.t);
|
|
203
|
+
if (!spec) {
|
|
204
|
+
spec = mergeSpecFor(op.t, def.columns);
|
|
205
|
+
specs.set(op.t, spec);
|
|
206
|
+
}
|
|
207
|
+
const out = applyOp(before, ownEcho(op, st, localReplica), {
|
|
208
|
+
table: spec,
|
|
209
|
+
actorOp: st.txn.actor?.op ?? null,
|
|
210
|
+
});
|
|
211
|
+
if (out.status === 'refused-schema') {
|
|
212
|
+
const reason = out.malformed?.length
|
|
213
|
+
? `${op.t}/${op.u}: malformed column(s) ${out.malformed.join(', ')}`
|
|
214
|
+
: `${op.t}: unknown column(s) ${(out.unknownColumns ?? []).join(', ')}`;
|
|
215
|
+
return { kind: 'refused-schema', reason };
|
|
216
|
+
}
|
|
217
|
+
if (out.status === 'pending') {
|
|
218
|
+
return { kind: 'pending', reason: `${op.t}/${op.u}: row not seen yet`, holds: holds(k) };
|
|
219
|
+
}
|
|
220
|
+
states.set(k, out.next);
|
|
221
|
+
}
|
|
222
|
+
return { kind: 'apply' };
|
|
223
|
+
}
|
|
224
|
+
/** Values of `cols` in the merged row. */
|
|
225
|
+
function valuesOf(next, cols) {
|
|
226
|
+
const out = {};
|
|
227
|
+
for (const c of cols) {
|
|
228
|
+
const f = next.fields[c];
|
|
229
|
+
if (f)
|
|
230
|
+
out[c] = f.value;
|
|
231
|
+
}
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
/** {@link valuesOf} with reference uids translated to the targets' local keys. */
|
|
235
|
+
function localValues(next, cols, refKeys) {
|
|
236
|
+
const out = valuesOf(next, cols);
|
|
237
|
+
for (const c of Object.keys(out)) {
|
|
238
|
+
const key = refKeys.get(c);
|
|
239
|
+
if (key !== undefined && out[c] !== null)
|
|
240
|
+
out[c] = key;
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
/** Perform one decided op through the write API; returns the conflicts recorded. */
|
|
245
|
+
function effect(db, api, st, opIdx, d, nowIso, quiet = false) {
|
|
246
|
+
const { op, def, before, out } = d;
|
|
247
|
+
const actor = st.txn.actor ? JSON.stringify(st.txn.actor) : null;
|
|
248
|
+
const meta = { origin: st.replicaId, actor, keyJson: op.k ? canonicalJson(op.k) : null };
|
|
249
|
+
// Merged field HLCs; on insert a column the op omits (a NULL) is at op.h.
|
|
250
|
+
const liveHlcs = () => {
|
|
251
|
+
const m = {};
|
|
252
|
+
if (out.effect === 'insert')
|
|
253
|
+
for (const c of def.columns)
|
|
254
|
+
m[c] = op.h;
|
|
255
|
+
for (const [c, f] of Object.entries(out.next.fields))
|
|
256
|
+
m[c] = f.hlc;
|
|
257
|
+
return m;
|
|
258
|
+
};
|
|
259
|
+
switch (out.effect) {
|
|
260
|
+
case 'insert': {
|
|
261
|
+
// The sealer sends the birth fingerprint as `bfp`, not in `a` (identity
|
|
262
|
+
// columns are read from the live row at capture); the insert needs it.
|
|
263
|
+
const values = localValues(out.next, out.written, d.refKeys);
|
|
264
|
+
if (def.identity.includes(BIRTH_FP_COLUMN) && values[BIRTH_FP_COLUMN] == null && op.bfp) {
|
|
265
|
+
values[BIRTH_FP_COLUMN] = op.bfp;
|
|
266
|
+
}
|
|
267
|
+
api.insertRow(op.t, op.u, values);
|
|
268
|
+
api.setMergedRowMeta(op.t, op.u, {
|
|
269
|
+
...meta,
|
|
270
|
+
fieldHlc: liveHlcs(),
|
|
271
|
+
tombstone: null,
|
|
272
|
+
bfp: op.bfp ?? null,
|
|
273
|
+
});
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case 'update':
|
|
277
|
+
api.writeFields(op.t, op.u, localValues(out.next, out.written, d.refKeys));
|
|
278
|
+
api.setMergedRowMeta(op.t, op.u, { ...meta, fieldHlc: liveHlcs(), tombstone: null });
|
|
279
|
+
break;
|
|
280
|
+
case 'delete':
|
|
281
|
+
case 'tombstone': {
|
|
282
|
+
if (out.effect === 'delete')
|
|
283
|
+
api.deleteRow(op.t, op.u);
|
|
284
|
+
clearFieldLeaves(db, op.t, op.u);
|
|
285
|
+
api.setMergedRowMeta(op.t, op.u, {
|
|
286
|
+
...meta,
|
|
287
|
+
fieldHlc: {},
|
|
288
|
+
tombstone: out.next.tombstone,
|
|
289
|
+
chash: api.rowMeta(op.t, op.u)?.chash ?? null,
|
|
290
|
+
bfp: op.bfp ?? null,
|
|
291
|
+
});
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'none':
|
|
295
|
+
// A later delete of a deleted row moves its tombstone forward.
|
|
296
|
+
if (!out.next.live && out.next.tombstone !== before.tombstone) {
|
|
297
|
+
api.setMergedRowMeta(op.t, op.u, {
|
|
298
|
+
...meta,
|
|
299
|
+
fieldHlc: {},
|
|
300
|
+
tombstone: out.next.tombstone,
|
|
301
|
+
chash: api.rowMeta(op.t, op.u)?.chash ?? null,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
if (out.next.live) {
|
|
307
|
+
const leaves = {};
|
|
308
|
+
const frontiers = {};
|
|
309
|
+
for (const [c, f] of Object.entries(out.next.fields)) {
|
|
310
|
+
const was = before.fields[c];
|
|
311
|
+
if (f.leave !== undefined && f.leave !== was?.leave)
|
|
312
|
+
leaves[c] = f.leave;
|
|
313
|
+
if (canonicalJson(f.frontier ?? null) !== canonicalJson(was?.frontier ?? null)) {
|
|
314
|
+
frontiers[c] = f.frontier ?? null;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
recordFieldLeaves(db, op.t, op.u, leaves);
|
|
318
|
+
setFieldFrontiers(db, op.t, op.u, frontiers);
|
|
319
|
+
}
|
|
320
|
+
if (!quiet)
|
|
321
|
+
recordConflicts(db, { ...st.key, opIdx }, out.conflicts, st.replicaId, nowIso);
|
|
322
|
+
return out.conflicts.length;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* The page PAC-01 judges: only rows whose shape this transaction could have
|
|
326
|
+
* changed (an insert, a re-key, or an op carrying `parent_id` or `type`).
|
|
327
|
+
* A row that already broke the matrix before (legacy data) never voids an
|
|
328
|
+
* unrelated edit of it; two valid ops that merge into a bad tree each carry
|
|
329
|
+
* one of those columns, so nothing introduced is missed (T13244).
|
|
330
|
+
*/
|
|
331
|
+
function treeShapePage(ops) {
|
|
332
|
+
return ops
|
|
333
|
+
.filter((o) => o.o === 'I' || o.o === 'K' || (o.a !== undefined && ('parent_id' in o.a || 'type' in o.a)))
|
|
334
|
+
.map((o) => ({
|
|
335
|
+
table: o.t,
|
|
336
|
+
uid: o.o === 'K' && o.nu ? o.nu : o.u,
|
|
337
|
+
typeChanged: o.o === 'I' || (o.a !== undefined && 'type' in o.a),
|
|
338
|
+
}));
|
|
339
|
+
}
|
|
340
|
+
/** The status of an applied transaction from its ops' results. */
|
|
341
|
+
function txnStatus(results, conflicts) {
|
|
342
|
+
const voided = results.filter((r) => r === 'void').length;
|
|
343
|
+
const effective = results.filter((r) => r === 'applied').length;
|
|
344
|
+
if (voided > 0 && effective === 0)
|
|
345
|
+
return 'void';
|
|
346
|
+
return conflicts > 0 ? 'conflict' : 'applied';
|
|
347
|
+
}
|
|
348
|
+
/** SQLite's primary result code for a constraint violation (trigger RAISE, FK, UNIQUE, CHECK, NOT NULL). */
|
|
349
|
+
const SQLITE_CONSTRAINT = 19;
|
|
350
|
+
/**
|
|
351
|
+
* A write the store refused by rule: a guard trigger's `RAISE(ABORT)` or a
|
|
352
|
+
* constraint (primary code SQLITE_CONSTRAINT). Anything else (disk full, I/O,
|
|
353
|
+
* corruption, read-only, a schema error) is not the op's fault: it fails the
|
|
354
|
+
* pass, to be retried, and never voids a remote op (T13239).
|
|
355
|
+
*/
|
|
356
|
+
function isGuardRefusal(err) {
|
|
357
|
+
return (err instanceof Error &&
|
|
358
|
+
'errcode' in err &&
|
|
359
|
+
typeof err.errcode === 'number' &&
|
|
360
|
+
(err.errcode & 0xff) === SQLITE_CONSTRAINT);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* The order to apply a transaction's ops in: its own order, except that an
|
|
364
|
+
* insert another op references comes before that op (T13238). Netting keeps
|
|
365
|
+
* each row's single op at its first capture, so `I A(parent = B)` can precede
|
|
366
|
+
* `I B`; with immediate foreign keys A's insert would fail. Each row has one
|
|
367
|
+
* op per transaction, so moving an insert never reorders a row's own ops. A
|
|
368
|
+
* reference cycle keeps the original order (its first insert then fails as a
|
|
369
|
+
* guard conflict). An insert is never hoisted ahead of an earlier delete on
|
|
370
|
+
* its table, so a natural-key re-add keeps its order.
|
|
371
|
+
*/
|
|
372
|
+
function applyOrder(ops, defs) {
|
|
373
|
+
const insertAt = new Map();
|
|
374
|
+
ops.forEach((o, i) => {
|
|
375
|
+
if (o.o === 'I')
|
|
376
|
+
insertAt.set(rowKey(o.t, o.u), i);
|
|
377
|
+
});
|
|
378
|
+
const order = [];
|
|
379
|
+
const state = new Map();
|
|
380
|
+
const visit = (i) => {
|
|
381
|
+
if (state.has(i))
|
|
382
|
+
return;
|
|
383
|
+
state.set(i, 'visiting');
|
|
384
|
+
const op = ops[i];
|
|
385
|
+
// An insert never moves ahead of a delete on its table that preceded it:
|
|
386
|
+
// a natural-key re-add (D X, I Y with X's key) must keep its order.
|
|
387
|
+
if (op.o === 'I') {
|
|
388
|
+
for (let k = 0; k < i; k++) {
|
|
389
|
+
const prior = ops[k];
|
|
390
|
+
if (prior.o === 'D' && prior.t === op.t && state.get(k) !== 'visiting')
|
|
391
|
+
visit(k);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const def = defs(op.t);
|
|
395
|
+
for (const [col, v] of Object.entries(op.a ?? {})) {
|
|
396
|
+
const target = def?.refs.get(col);
|
|
397
|
+
if (!target || typeof v !== 'string')
|
|
398
|
+
continue;
|
|
399
|
+
const j = insertAt.get(rowKey(target.table, v));
|
|
400
|
+
if (j !== undefined && j !== i && state.get(j) !== 'visiting')
|
|
401
|
+
visit(j);
|
|
402
|
+
}
|
|
403
|
+
state.set(i, 'done');
|
|
404
|
+
order.push(i);
|
|
405
|
+
};
|
|
406
|
+
ops.forEach((_, i) => {
|
|
407
|
+
visit(i);
|
|
408
|
+
});
|
|
409
|
+
return order;
|
|
410
|
+
}
|
|
411
|
+
const voidWith = (c, opIdx, conflict) => {
|
|
412
|
+
if (!c.replay) {
|
|
413
|
+
recordConflicts(c.db, { ...c.st.key, opIdx }, [conflict], c.st.replicaId, c.nowIso);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
c.replay.onVoid?.([conflict]);
|
|
417
|
+
}
|
|
418
|
+
return { result: 'void', conflicts: 1 };
|
|
419
|
+
};
|
|
420
|
+
/** Apply a K op: move the row to its new uid (and birth fingerprint). */
|
|
421
|
+
function applyRekey(c, opIdx, op) {
|
|
422
|
+
const nu = op.nu ?? op.u;
|
|
423
|
+
const oldLive = rowExists(c.api, op.t, op.u);
|
|
424
|
+
const newLive = nu !== op.u && rowExists(c.api, op.t, nu);
|
|
425
|
+
if (!oldLive)
|
|
426
|
+
return { result: 'skipped', conflicts: 0 }; // already re-keyed, or deleted
|
|
427
|
+
if (newLive || (nu !== op.u && c.api.rowMeta(op.t, nu) !== undefined)) {
|
|
428
|
+
return voidWith(c, opIdx, {
|
|
429
|
+
kind: 'uid-collision',
|
|
430
|
+
table: op.t,
|
|
431
|
+
uid: op.u,
|
|
432
|
+
columns: [UID_COLUMN],
|
|
433
|
+
resolution: 'op-voided',
|
|
434
|
+
opHlc: op.h,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
// Local captures and unsent ops still naming the old uid follow it (§3.3 G).
|
|
438
|
+
// First: remapping after the re-key would rewrite the re-key's own capture,
|
|
439
|
+
// and it would no longer match its `*K` intent.
|
|
440
|
+
remapPending(c.db, { table: op.t, oldUid: op.u, newUid: nu, newBfp: op.bfp ?? null });
|
|
441
|
+
c.api.rekeyRow(op.t, op.u, nu, op.bfp ?? null);
|
|
442
|
+
return { result: 'applied', conflicts: 0 };
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Delete a row and, depth-first, its CASCADE sync-set children, each with a
|
|
446
|
+
* tombstone. `seen` stops a reference cycle in the data. Children without a
|
|
447
|
+
* uid are not listed (`childRows`), so SQLite's own cascade removes them
|
|
448
|
+
* with no intent; every sync-set row has a uid while row uids are on.
|
|
449
|
+
*/
|
|
450
|
+
function cascadeDelete(c, table, uid, h, actor, seen = new Set()) {
|
|
451
|
+
if (seen.has(rowKey(table, uid)))
|
|
452
|
+
return;
|
|
453
|
+
seen.add(rowKey(table, uid));
|
|
454
|
+
for (const child of c.api.childRows(table, uid)) {
|
|
455
|
+
if (child.key.onDelete === 'CASCADE') {
|
|
456
|
+
cascadeDelete(c, child.key.child, child.uid, h, actor, seen);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
c.api.deleteRow(table, uid);
|
|
460
|
+
clearFieldLeaves(c.db, table, uid);
|
|
461
|
+
c.api.setMergedRowMeta(table, uid, {
|
|
462
|
+
fieldHlc: {},
|
|
463
|
+
tombstone: h,
|
|
464
|
+
origin: c.st.replicaId,
|
|
465
|
+
actor,
|
|
466
|
+
chash: c.api.rowMeta(table, uid)?.chash ?? null,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Decide and apply one op against the store as it is now, inside its own
|
|
471
|
+
* savepoint: a guard refusal rolls back only this op and records it.
|
|
472
|
+
*/
|
|
473
|
+
function applyOne(c, opIdx, op) {
|
|
474
|
+
if (op.o === 'K') {
|
|
475
|
+
// A re-key gets the same savepoint and guard path as any op (T13239).
|
|
476
|
+
const sp = `apply_op_${opIdx}`;
|
|
477
|
+
c.db.exec(`SAVEPOINT ${sp}`);
|
|
478
|
+
try {
|
|
479
|
+
const r = applyRekey(c, opIdx, op);
|
|
480
|
+
c.db.exec(`RELEASE ${sp}`);
|
|
481
|
+
return r;
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
c.db.exec(`ROLLBACK TO ${sp}`);
|
|
485
|
+
c.db.exec(`RELEASE ${sp}`);
|
|
486
|
+
if (!isGuardRefusal(err))
|
|
487
|
+
throw err;
|
|
488
|
+
return voidWith(c, opIdx, {
|
|
489
|
+
kind: 'guard',
|
|
490
|
+
table: op.t,
|
|
491
|
+
uid: op.u,
|
|
492
|
+
columns: [UID_COLUMN],
|
|
493
|
+
rule: err.message.slice(0, 200),
|
|
494
|
+
resolution: 'op-voided',
|
|
495
|
+
opHlc: op.h,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
const def = c.defs(op.t);
|
|
500
|
+
// @sync-invariant none:input-shape planning refused-schema'd every op on an unknown table
|
|
501
|
+
if (!def)
|
|
502
|
+
throw new Error(`apply: ${op.t} is not a sync-set table`);
|
|
503
|
+
const refKeys = new Map();
|
|
504
|
+
for (const [col, v] of Object.entries(op.a ?? {})) {
|
|
505
|
+
const target = def.refs.get(col);
|
|
506
|
+
if (!target || typeof v !== 'string')
|
|
507
|
+
continue;
|
|
508
|
+
const ref = resolveRef(c.db, target, v);
|
|
509
|
+
if (ref.kind === 'row') {
|
|
510
|
+
refKeys.set(col, ref.key);
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
// Planning saw it; a tombstoned target is a revivable dangling reference.
|
|
514
|
+
return voidWith(c, opIdx, {
|
|
515
|
+
kind: 'dangling-ref',
|
|
516
|
+
table: op.t,
|
|
517
|
+
uid: op.u,
|
|
518
|
+
columns: [col],
|
|
519
|
+
resolution: 'op-voided',
|
|
520
|
+
opHlc: op.h,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
const before = loadRowState(c.db, c.api, def, op.u, c.replica);
|
|
524
|
+
const out = applyOp(before, c.replay ? op : ownEcho(op, c.st, c.replica), {
|
|
525
|
+
table: mergeSpecFor(op.t, def.columns),
|
|
526
|
+
actorOp: (c.replay ? c.replay.actor?.op : c.st.txn.actor?.op) ?? null,
|
|
527
|
+
});
|
|
528
|
+
const live = out.effect === 'delete'
|
|
529
|
+
? c.api.childRows(op.t, op.u).filter((x) => x.key.onDelete === 'CASCADE')
|
|
530
|
+
: [];
|
|
531
|
+
if (live.length > 0) {
|
|
532
|
+
if (parentDeletePolicy(op.t) === 'conflict') {
|
|
533
|
+
return voidWith(c, opIdx, {
|
|
534
|
+
kind: 'delete-with-live-children',
|
|
535
|
+
table: op.t,
|
|
536
|
+
uid: op.u,
|
|
537
|
+
columns: live.map((x) => `${x.key.child}:${x.uid}`).sort(),
|
|
538
|
+
resolution: 'op-voided',
|
|
539
|
+
opHlc: op.h,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
const sp = `apply_op_${opIdx}`;
|
|
544
|
+
c.db.exec(`SAVEPOINT ${sp}`);
|
|
545
|
+
try {
|
|
546
|
+
// cascade-with-ops: the remaining children go first, with ops' tombstones.
|
|
547
|
+
const actor = c.st.txn.actor ? JSON.stringify(c.st.txn.actor) : null;
|
|
548
|
+
for (const x of live)
|
|
549
|
+
cascadeDelete(c, x.key.child, x.uid, op.h, actor);
|
|
550
|
+
const st = c.replay
|
|
551
|
+
? { ...c.st, replicaId: c.replica, txn: { ...c.st.txn, actor: c.replay.actor } }
|
|
552
|
+
: c.st;
|
|
553
|
+
const n = effect(c.db, c.api, st, opIdx, { op, def, before, out, refKeys }, c.nowIso, c.replay !== undefined);
|
|
554
|
+
c.db.exec(`RELEASE ${sp}`);
|
|
555
|
+
const result = out.status === 'applied' || out.status === 'partial'
|
|
556
|
+
? 'applied'
|
|
557
|
+
: out.status === 'void'
|
|
558
|
+
? 'void'
|
|
559
|
+
: 'skipped';
|
|
560
|
+
if (c.replay && result === 'void')
|
|
561
|
+
c.replay.onVoid?.(out.conflicts);
|
|
562
|
+
return { result, conflicts: n };
|
|
563
|
+
}
|
|
564
|
+
catch (err) {
|
|
565
|
+
c.db.exec(`ROLLBACK TO ${sp}`);
|
|
566
|
+
c.db.exec(`RELEASE ${sp}`);
|
|
567
|
+
if (!isGuardRefusal(err))
|
|
568
|
+
throw err;
|
|
569
|
+
return voidWith(c, opIdx, {
|
|
570
|
+
kind: 'guard',
|
|
571
|
+
table: op.t,
|
|
572
|
+
uid: op.u,
|
|
573
|
+
columns: [...out.written],
|
|
574
|
+
rule: err.message.slice(0, 200),
|
|
575
|
+
resolution: 'op-voided',
|
|
576
|
+
opHlc: op.h,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
/** The rows a transaction's ops write (a re-key's both uids). */
|
|
581
|
+
function touchedRows(ops) {
|
|
582
|
+
return ops.flatMap((o) => o.o === 'K' && o.nu && o.nu !== o.u
|
|
583
|
+
? [
|
|
584
|
+
{ table: o.t, uid: o.u },
|
|
585
|
+
{ table: o.t, uid: o.nu },
|
|
586
|
+
]
|
|
587
|
+
: [{ table: o.t, uid: o.u }]);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Give the unfilled natural-key rows `ops` name their uid (T13273): the
|
|
591
|
+
* op's key (`k`, references as uids) resolved to local keys. A key whose
|
|
592
|
+
* reference does not resolve is left for planning to judge.
|
|
593
|
+
*/
|
|
594
|
+
function adoptNaturalRows(db, api, defs, ops) {
|
|
595
|
+
for (const op of ops) {
|
|
596
|
+
const def = defs(op.t);
|
|
597
|
+
if (!def || !op.k)
|
|
598
|
+
continue;
|
|
599
|
+
const local = {};
|
|
600
|
+
let resolved = true;
|
|
601
|
+
for (const [col, v] of Object.entries(op.k)) {
|
|
602
|
+
if (typeof v === 'object' && v !== null && '$inc' in v) {
|
|
603
|
+
resolved = false;
|
|
604
|
+
break;
|
|
605
|
+
}
|
|
606
|
+
const target = def.refs.get(col);
|
|
607
|
+
if (target && typeof v === 'string') {
|
|
608
|
+
const ref = resolveRef(db, target, v);
|
|
609
|
+
if (ref.kind !== 'row') {
|
|
610
|
+
resolved = false;
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
local[col] = ref.key;
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
local[col] = v;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (resolved)
|
|
620
|
+
api.adoptNaturalRow(op.t, op.u, local);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
/** Whether `op` writes an append-only table (insert-only rows, never rewound). */
|
|
624
|
+
function isAppendOnly(defs, op) {
|
|
625
|
+
return defs(op.t)?.appendOnly === true;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* The rows ops write or reference, widened by what their guards and checks
|
|
629
|
+
* read (their footprint, Rule 3; R7-6), by row key.
|
|
630
|
+
*/
|
|
631
|
+
function footprintOf(db, ops, defs) {
|
|
632
|
+
const out = new Map();
|
|
633
|
+
const add = (table, uid) => {
|
|
634
|
+
out.set(rowKey(table, uid), { table, uid });
|
|
635
|
+
};
|
|
636
|
+
widenFootprint(db, ops, defs, add);
|
|
637
|
+
for (const o of ops) {
|
|
638
|
+
add(o.t, o.u);
|
|
639
|
+
if (o.o === 'K' && o.nu)
|
|
640
|
+
add(o.t, o.nu);
|
|
641
|
+
const def = defs(o.t);
|
|
642
|
+
for (const [col, v] of Object.entries(o.a ?? {})) {
|
|
643
|
+
const target = def?.refs.get(col);
|
|
644
|
+
if (target && typeof v === 'string')
|
|
645
|
+
add(target.table, v);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return out;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Whether an own echo may apply in place and be sequenced (the fast path,
|
|
652
|
+
* Rule 3): no foreign touch of its footprint since its commit, and no later
|
|
653
|
+
* unsequenced local transaction on that footprint (the echo would otherwise
|
|
654
|
+
* apply over that transaction's effects). Otherwise a rebase decides.
|
|
655
|
+
*/
|
|
656
|
+
function echoInPlace(db, st, defs, local, unsequenced) {
|
|
657
|
+
// A held op sits rewound: only a rebase can apply it and restore what it kept.
|
|
658
|
+
if (txnHasHold(db, local.txn))
|
|
659
|
+
return false;
|
|
660
|
+
const fp = footprintOf(db, st.txn.ops, defs);
|
|
661
|
+
if (!ownEchoFastPath(db, local, [...fp.values()]))
|
|
662
|
+
return false;
|
|
663
|
+
const later = unsequenced.slice(unsequenced.findIndex((l) => l.txn === local.txn) + 1);
|
|
664
|
+
return later.every((l) => ![...footprintOf(db, l.ops, defs).keys()].some((k) => fp.has(k)));
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Grow `scope` over `locals` to a fixed point (Rule 3): a local transaction
|
|
668
|
+
* whose footprint meets `reach` joins, and its footprint joins `reach`. The
|
|
669
|
+
* rewind set, in local commit order, or null when it is empty or a member
|
|
670
|
+
* has an op without row undo (it cannot be rewound: apply in place, as
|
|
671
|
+
* before undo existed).
|
|
672
|
+
*/
|
|
673
|
+
function scopeRewind(db, locals, defs, reach, scope) {
|
|
674
|
+
for (let grown = true; grown;) {
|
|
675
|
+
grown = false;
|
|
676
|
+
for (const l of locals) {
|
|
677
|
+
if (scope.has(l.txn))
|
|
678
|
+
continue;
|
|
679
|
+
const fp = [...footprintOf(db, l.ops, defs).keys()];
|
|
680
|
+
if (fp.some((k) => reach.has(k))) {
|
|
681
|
+
scope.add(l.txn);
|
|
682
|
+
for (const k of fp)
|
|
683
|
+
reach.add(k);
|
|
684
|
+
grown = true;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
const rewind = locals.filter((l) => scope.has(l.txn));
|
|
689
|
+
if (rewind.length === 0)
|
|
690
|
+
return null;
|
|
691
|
+
for (const l of rewind) {
|
|
692
|
+
for (let i = 0; i < l.ops.length; i++)
|
|
693
|
+
if (!readRowUndo(db, l.txn, i))
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
return rewind;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Plan the scoped rebase around one own echo the post-apply checks refused
|
|
700
|
+
* while it sat in place (Rule 6): its transaction and the local ones its
|
|
701
|
+
* footprint reaches, leaving out those the page already rewound.
|
|
702
|
+
*/
|
|
703
|
+
function planOwnRebase(db, st, defs, exclude) {
|
|
704
|
+
const locals = unsequencedLocalTxns(db).filter((l) => !exclude.has(l.txn));
|
|
705
|
+
const own = locals.find((l) => l.txn === st.txn.txn) ?? null;
|
|
706
|
+
if (!own)
|
|
707
|
+
return null;
|
|
708
|
+
const reach = new Set(footprintOf(db, st.txn.ops, defs).keys());
|
|
709
|
+
for (const k of footprintOf(db, own.ops, defs).keys())
|
|
710
|
+
reach.add(k);
|
|
711
|
+
const rewind = scopeRewind(db, locals, defs, reach, new Set([own.txn]));
|
|
712
|
+
return rewind ? { rewind, replay: rewind.filter((l) => l !== own), own } : null;
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Plan a page's scoped rebase (Rule 3): the unsequenced local transactions
|
|
716
|
+
* whose footprint meets a foreign transaction of the page, or an own echo
|
|
717
|
+
* of the page that fails the fast path, to a fixed point. Null when none.
|
|
718
|
+
*/
|
|
719
|
+
function planPageRebase(db, page, defs, localReplica) {
|
|
720
|
+
const inPlace = new Set();
|
|
721
|
+
const locals = unsequencedLocalTxns(db);
|
|
722
|
+
if (locals.length === 0)
|
|
723
|
+
return { plan: null, inPlace };
|
|
724
|
+
const reach = new Set();
|
|
725
|
+
const scope = new Set();
|
|
726
|
+
for (const st of page) {
|
|
727
|
+
if (st.replicaId !== localReplica) {
|
|
728
|
+
for (const k of footprintOf(db, st.txn.ops, defs).keys())
|
|
729
|
+
reach.add(k);
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
const own = locals.find((l) => l.txn === st.txn.txn);
|
|
733
|
+
if (!own)
|
|
734
|
+
continue;
|
|
735
|
+
// Judged once per page: a page write meeting it puts it in scope instead.
|
|
736
|
+
if (echoInPlace(db, st, defs, own, locals)) {
|
|
737
|
+
inPlace.add(own.txn);
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
scope.add(own.txn);
|
|
741
|
+
for (const k of footprintOf(db, st.txn.ops, defs).keys())
|
|
742
|
+
reach.add(k);
|
|
743
|
+
for (const k of footprintOf(db, own.ops, defs).keys())
|
|
744
|
+
reach.add(k);
|
|
745
|
+
}
|
|
746
|
+
const rewind = scopeRewind(db, locals, defs, reach, scope);
|
|
747
|
+
for (const l of rewind ?? [])
|
|
748
|
+
inPlace.delete(l.txn);
|
|
749
|
+
return { plan: rewind ? { rewind, replay: rewind, own: null } : null, inPlace };
|
|
750
|
+
}
|
|
751
|
+
/** Wire values with references turned into local keys (unresolvable ones drop to NULL). */
|
|
752
|
+
function toLocal(db, def, values) {
|
|
753
|
+
const out = {};
|
|
754
|
+
for (const [col, v] of Object.entries(values)) {
|
|
755
|
+
if (col === UID_COLUMN)
|
|
756
|
+
continue;
|
|
757
|
+
const target = def.refs.get(col);
|
|
758
|
+
if (target && typeof v === 'string') {
|
|
759
|
+
const ref = resolveRef(db, target, v);
|
|
760
|
+
out[col] = ref.kind === 'row' ? ref.key : null;
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
out[col] = v;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return out;
|
|
767
|
+
}
|
|
768
|
+
/** Put back what a rewound insert kept, once its insert applied again. */
|
|
769
|
+
function restoreKept(c, op, result, kept) {
|
|
770
|
+
if (op.o !== 'I' || result !== 'applied')
|
|
771
|
+
return;
|
|
772
|
+
const k = kept.get(rowKey(op.t, op.u));
|
|
773
|
+
if (!k)
|
|
774
|
+
return;
|
|
775
|
+
if (k.local)
|
|
776
|
+
c.api.writeLocalOnly(op.t, op.u, k.local);
|
|
777
|
+
c.api.writeLocalDescendants(k.descendants);
|
|
778
|
+
}
|
|
779
|
+
/** Re-snapshot op `i`'s row undo with the row as it stands now (D2). */
|
|
780
|
+
function resnapshotOp(c, l, i, op) {
|
|
781
|
+
const def = c.defs(op.t);
|
|
782
|
+
if (!def)
|
|
783
|
+
return;
|
|
784
|
+
const state = loadRowState(c.db, c.api, def, op.u, c.replica);
|
|
785
|
+
const now = {};
|
|
786
|
+
const cols = op.o === 'U' ? Object.keys(op.a ?? {}) : Object.keys(state.fields);
|
|
787
|
+
for (const col of cols) {
|
|
788
|
+
const f = state.fields[col];
|
|
789
|
+
if (f)
|
|
790
|
+
now[col] = f.value;
|
|
791
|
+
}
|
|
792
|
+
resnapshotRowUndo(c.db, l.txn, i, op.t, op.u, now);
|
|
793
|
+
}
|
|
794
|
+
const opKey = (txn, idx) => `${txn}\u0000${idx}`;
|
|
795
|
+
/** A one-line conflict preview of why a replay refused an op (Rule 5). */
|
|
796
|
+
function describeConflicts(cs) {
|
|
797
|
+
return cs
|
|
798
|
+
.map((x) => `${x.kind}${x.rule ? ` (${x.rule})` : ''} on ${x.table}/${x.uid}${x.columns.length > 0 ? ` [${x.columns.join(', ')}]` : ''}`)
|
|
799
|
+
.join('; ');
|
|
800
|
+
}
|
|
801
|
+
function rewindTxns(c, plan) {
|
|
802
|
+
const kept = new Map();
|
|
803
|
+
const after = new Map();
|
|
804
|
+
withTriggersSuspended(c.db, ['capture', 'guard', 'side-effect'], 'rewind', () => {
|
|
805
|
+
for (const l of [...plan.rewind].reverse()) {
|
|
806
|
+
adoptNaturalRows(c.db, c.api, c.defs, l.ops);
|
|
807
|
+
for (let i = l.ops.length - 1; i >= 0; i--) {
|
|
808
|
+
const op = l.ops[i];
|
|
809
|
+
const def = c.defs(op.t);
|
|
810
|
+
const undo = readRowUndo(c.db, l.txn, i);
|
|
811
|
+
if (!def || !undo || def.appendOnly)
|
|
812
|
+
continue;
|
|
813
|
+
const exists = (uid) => c.api.readRow(op.t, uid) !== null;
|
|
814
|
+
// A held op is decided again: lift its hold, keep what it kept.
|
|
815
|
+
const held = heldOp(c.db, l.txn, i);
|
|
816
|
+
if (held) {
|
|
817
|
+
unholdOp(c.db, l.txn, i);
|
|
818
|
+
if (held.kept)
|
|
819
|
+
kept.set(rowKey(op.t, op.u), held.kept);
|
|
820
|
+
}
|
|
821
|
+
const had = exists(op.u);
|
|
822
|
+
const before = undo.values ?? op.b ?? {};
|
|
823
|
+
// A replay that found its row already gone snapshotted it as absent.
|
|
824
|
+
const absent = undo.values !== null && Object.keys(undo.values).length === 0;
|
|
825
|
+
if (op.o === 'I' && exists(op.u) && undo.values && Object.keys(undo.values).length > 0) {
|
|
826
|
+
// Its last replay sat on a row the stream had inserted too (a natural
|
|
827
|
+
// twin): rewinding restores that row, never deletes it (D2).
|
|
828
|
+
const local = toLocal(c.db, def, undo.values);
|
|
829
|
+
if (Object.keys(local).length > 0)
|
|
830
|
+
c.api.writeFields(op.t, op.u, local);
|
|
831
|
+
}
|
|
832
|
+
else if (op.o === 'I' && exists(op.u)) {
|
|
833
|
+
kept.set(rowKey(op.t, op.u), {
|
|
834
|
+
local: c.api.readLocalOnly(op.t, op.u),
|
|
835
|
+
descendants: c.api.readLocalDescendants(op.t, op.u),
|
|
836
|
+
});
|
|
837
|
+
c.api.deleteRow(op.t, op.u);
|
|
838
|
+
}
|
|
839
|
+
else if (op.o === 'U' && exists(op.u)) {
|
|
840
|
+
const cols = Object.keys(op.a ?? {});
|
|
841
|
+
const vals = {};
|
|
842
|
+
for (const col of cols)
|
|
843
|
+
if (col in before)
|
|
844
|
+
vals[col] = before[col];
|
|
845
|
+
const local = toLocal(c.db, def, vals);
|
|
846
|
+
if (Object.keys(local).length > 0)
|
|
847
|
+
c.api.writeFields(op.t, op.u, local);
|
|
848
|
+
}
|
|
849
|
+
else if (op.o === 'D' && !absent && !exists(op.u)) {
|
|
850
|
+
const vals = toLocal(c.db, def, before);
|
|
851
|
+
if (def.identity.includes(BIRTH_FP_COLUMN) && vals[BIRTH_FP_COLUMN] == null && op.bfp) {
|
|
852
|
+
vals[BIRTH_FP_COLUMN] = op.bfp;
|
|
853
|
+
}
|
|
854
|
+
c.api.insertRow(op.t, op.u, vals);
|
|
855
|
+
}
|
|
856
|
+
else if (op.o === 'K' && op.nu && exists(op.nu)) {
|
|
857
|
+
c.api.rekeyRow(op.t, op.nu, op.u, op.obfp ?? null);
|
|
858
|
+
}
|
|
859
|
+
if (op.o === 'I' || op.o === 'D') {
|
|
860
|
+
accountRebaseRows(c.db, op.t, Number(exists(op.u)) - Number(had));
|
|
861
|
+
}
|
|
862
|
+
after.set(opKey(l.txn, i), readRowMetaFull(c.db, op.t, op.u) ?? null);
|
|
863
|
+
restoreRowMeta(c.db, op.t, op.u, undo.meta);
|
|
864
|
+
restoreFieldState(c.db, op.t, op.u, undo.state);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
return { kept, after };
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Replay the plan's local transactions in commit order, after the incoming
|
|
872
|
+
* one applied (Rule 4): each op goes through the merge engine against the
|
|
873
|
+
* state now, so a field the stream wrote with a newer HLC is not overwritten
|
|
874
|
+
* (R6-7), and an op the stream now refuses stays rewound (Rule 6). Before each
|
|
875
|
+
* op its row undo is re-snapshotted, so the next rewind restores exactly what
|
|
876
|
+
* this replay sat on (D2). Capture and side-effect triggers are suspended;
|
|
877
|
+
* guards stay active, and each replayed transaction gets the post-apply
|
|
878
|
+
* checks: one that fails them stays rewound whole (Rule 6, T13268).
|
|
879
|
+
* Returns the transactions it left held (Rule 5).
|
|
880
|
+
*/
|
|
881
|
+
function replayTxns(c, plan, rw) {
|
|
882
|
+
const exists = (op) => c.api.readRow(op.t, op.u) !== null;
|
|
883
|
+
const heldTxns = [];
|
|
884
|
+
withTriggersSuspended(c.db, ['capture', 'side-effect'], 'forward', () => {
|
|
885
|
+
for (const l of plan.replay) {
|
|
886
|
+
let refused = null;
|
|
887
|
+
const rc = {
|
|
888
|
+
...c,
|
|
889
|
+
replay: {
|
|
890
|
+
actor: l.actor,
|
|
891
|
+
onVoid: (cs) => {
|
|
892
|
+
refused = describeConflicts(cs);
|
|
893
|
+
},
|
|
894
|
+
},
|
|
895
|
+
};
|
|
896
|
+
let holds = [];
|
|
897
|
+
c.db.exec('SAVEPOINT replay_txn');
|
|
898
|
+
l.ops.forEach((op, i) => {
|
|
899
|
+
if (isAppendOnly(c.defs, op))
|
|
900
|
+
return; // never rewound, so never replayed
|
|
901
|
+
resnapshotOp(c, l, i, op);
|
|
902
|
+
const had = exists(op);
|
|
903
|
+
refused = null;
|
|
904
|
+
const r = applyOne(rc, i, op);
|
|
905
|
+
if (op.o === 'I' || op.o === 'D') {
|
|
906
|
+
accountRebaseRows(c.db, op.t, Number(exists(op)) - Number(had));
|
|
907
|
+
}
|
|
908
|
+
restoreKept(c, op, r.result, rw.kept);
|
|
909
|
+
if (r.result === 'void')
|
|
910
|
+
holds.push({ idx: i, reason: refused ?? 'refused on replay' });
|
|
911
|
+
});
|
|
912
|
+
// Gate C over the replay too (T13268): a replayed transaction that
|
|
913
|
+
// breaks a post-apply check stays rewound whole, as its echo will be
|
|
914
|
+
// voided on every receiver. Every op of it now sits on the rewound row.
|
|
915
|
+
const broken = checkTaskTreeShape(c.db, treeShapePage(l.ops));
|
|
916
|
+
if (broken.length > 0) {
|
|
917
|
+
c.db.exec('ROLLBACK TO replay_txn');
|
|
918
|
+
l.ops.forEach((op, i) => {
|
|
919
|
+
resnapshotOp(c, l, i, op);
|
|
920
|
+
});
|
|
921
|
+
const reason = broken.map((v) => `${v.check}: ${v.message}`).join('; ');
|
|
922
|
+
holds = l.ops.map((_, i) => ({ idx: i, reason }));
|
|
923
|
+
}
|
|
924
|
+
c.db.exec('RELEASE replay_txn');
|
|
925
|
+
// What stays rewound is held until its echo is decided (Rule 5).
|
|
926
|
+
if (holds.length > 0)
|
|
927
|
+
heldTxns.push(l.txn);
|
|
928
|
+
for (const h of holds) {
|
|
929
|
+
const op = l.ops[h.idx];
|
|
930
|
+
holdOp(c.db, {
|
|
931
|
+
txn: l.txn,
|
|
932
|
+
idx: h.idx,
|
|
933
|
+
op,
|
|
934
|
+
exists: exists(op),
|
|
935
|
+
reason: h.reason,
|
|
936
|
+
afterMeta: rw.after.get(opKey(l.txn, h.idx)) ?? null,
|
|
937
|
+
kept: rw.kept.get(rowKey(op.t, op.u)) ?? null,
|
|
938
|
+
nowIso: c.nowIso,
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
});
|
|
943
|
+
return heldTxns;
|
|
944
|
+
}
|
|
945
|
+
/** A page holds at most this many ops (§3.5 Rule 3), unless one transaction is larger. */
|
|
946
|
+
export const REBASE_PAGE_OPS = 2_000;
|
|
947
|
+
/** A page stops taking transactions after this long (§3.5 Rule 3). */
|
|
948
|
+
export const REBASE_PAGE_MS = 50;
|
|
949
|
+
/**
|
|
950
|
+
* The next page from `staged[from]`: consecutive transactions with the same
|
|
951
|
+
* actor (one apply frame records one), up to `maxOps` ops. A
|
|
952
|
+
* page breaks only between transactions, and a transaction larger than a
|
|
953
|
+
* page is a page alone (the declared exemption).
|
|
954
|
+
*/
|
|
955
|
+
function takePage(staged, from, maxOps) {
|
|
956
|
+
const out = [];
|
|
957
|
+
let ops = 0;
|
|
958
|
+
for (let i = from; i < staged.length; i++) {
|
|
959
|
+
const st = staged[i];
|
|
960
|
+
const actor = st.txn.actor ? JSON.stringify(st.txn.actor) : null;
|
|
961
|
+
const first = out[0];
|
|
962
|
+
if (first && (actor !== first.actor || ops + st.txn.ops.length > maxOps))
|
|
963
|
+
break;
|
|
964
|
+
out.push({ st, actor });
|
|
965
|
+
ops += st.txn.ops.length;
|
|
966
|
+
}
|
|
967
|
+
return out;
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Apply one staged transaction inside its page's frame: the pre-checks,
|
|
971
|
+
* planning, the clock, its ops in one Gate C savepoint, the post-apply
|
|
972
|
+
* checks, sequencing and the inbox mark. The page's rewind is already done
|
|
973
|
+
* and its replay follows the page.
|
|
974
|
+
*/
|
|
975
|
+
function applyInPage(x, st) {
|
|
976
|
+
const { db, api, defs, opts, nowIso } = x;
|
|
977
|
+
const stop = (status, reason, holds = []) => {
|
|
978
|
+
markTxns(db, st.parts, status, { reason, nowIso });
|
|
979
|
+
return { status, holds, n: 0, applied: false, decided: null };
|
|
980
|
+
};
|
|
981
|
+
const refusal = checkSchemaVersion(st.schemaVersion, st.txn.v);
|
|
982
|
+
if (refusal)
|
|
983
|
+
return stop('refused-schema', `${refusal.code}: ${refusal.message}`);
|
|
984
|
+
if (x.heldReplicas.has(st.replicaId)) {
|
|
985
|
+
return stop('held-skew', `behind a held transaction of replica ${st.replicaId}`);
|
|
986
|
+
}
|
|
987
|
+
if (!isWithinSkew(parseHlc(st.txn.hlc), x.nowMs)) {
|
|
988
|
+
return stop('held-skew', `HLC ${st.txn.hlc} is beyond the skew bound`);
|
|
989
|
+
}
|
|
990
|
+
const waits = st.txn.ops.find((o) => x.held.has(rowKey(o.t, o.u)));
|
|
991
|
+
if (waits) {
|
|
992
|
+
return stop('pending', `waits on a pending transaction writing ${waits.t}/${waits.u}`, st.txn.ops.map((o) => rowKey(o.t, o.u)));
|
|
993
|
+
}
|
|
994
|
+
const plan = planTxn(db, api, st, defs, opts.replica);
|
|
995
|
+
if (plan.kind !== 'apply') {
|
|
996
|
+
return stop(plan.kind, plan.reason, plan.kind === 'pending' ? plan.holds : []);
|
|
997
|
+
}
|
|
998
|
+
if (api.clockReceive(opts.replica, st.txn.hlc, x.nowMs).held) {
|
|
999
|
+
return stop('held-skew', 'clock refused the HLC');
|
|
1000
|
+
}
|
|
1001
|
+
// §3.5 Rule 3 (T13193): where this txn sits in the capture order.
|
|
1002
|
+
const touchPos = x.sequencingOn ? capturePosition(db) : 0;
|
|
1003
|
+
const local = x.sequencingOn && st.replicaId === opts.replica ? unsequencedLocalTxn(db, st.txn.txn) : null;
|
|
1004
|
+
// An own echo whose transaction the page rewound applies it at its stream position.
|
|
1005
|
+
const rewoundEcho = local !== null && x.rewound.has(local.txn);
|
|
1006
|
+
const c = { db, api, st, defs, replica: opts.replica, nowIso };
|
|
1007
|
+
let n = 0;
|
|
1008
|
+
// Gate C (§3.6): the whole transaction is one savepoint, so a broken
|
|
1009
|
+
// multi-row invariant rolls all of it back (the page's rewind stays).
|
|
1010
|
+
db.exec('SAVEPOINT apply_txn');
|
|
1011
|
+
const results = applyOrder(st.txn.ops, defs).map((i) => {
|
|
1012
|
+
const op = st.txn.ops[i];
|
|
1013
|
+
const r = applyOne(c, i, op);
|
|
1014
|
+
n += r.conflicts;
|
|
1015
|
+
// A rewound own insert applies again here: put back what it kept.
|
|
1016
|
+
if (rewoundEcho && r.result === 'applied' && op.o === 'I') {
|
|
1017
|
+
withTriggersSuspended(db, ['capture', 'side-effect'], 'forward', () => {
|
|
1018
|
+
restoreKept(c, op, r.result, x.rw.kept);
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
return r.result;
|
|
1022
|
+
});
|
|
1023
|
+
// Every per-transaction post-apply check, by name (the registry's runtime gates).
|
|
1024
|
+
const violations = [...checkTaskTreeShape(db, treeShapePage(st.txn.ops))];
|
|
1025
|
+
if (violations.length > 0) {
|
|
1026
|
+
db.exec('ROLLBACK TO apply_txn');
|
|
1027
|
+
db.exec('RELEASE apply_txn');
|
|
1028
|
+
recordConflicts(db, { ...st.key, opIdx: -1 }, violations.map((v) => ({
|
|
1029
|
+
kind: 'post-apply',
|
|
1030
|
+
table: v.table,
|
|
1031
|
+
uid: v.uid,
|
|
1032
|
+
columns: [],
|
|
1033
|
+
rule: `${v.check}: ${v.message}`.slice(0, 200),
|
|
1034
|
+
resolution: 'op-voided',
|
|
1035
|
+
opHlc: st.txn.hlc,
|
|
1036
|
+
})), st.replicaId, nowIso);
|
|
1037
|
+
// A refused own echo stays rewound and keeps its undo (Rule 6). Rewound
|
|
1038
|
+
// by the page, the rollback left it so; in place, rewind it now.
|
|
1039
|
+
const own = local && !rewoundEcho ? planOwnRebase(db, st, defs, x.rewound) : null;
|
|
1040
|
+
const heldTxns = own ? replayTxns(c, own, rewindTxns(c, own)) : [];
|
|
1041
|
+
if (local && (rewoundEcho || own)) {
|
|
1042
|
+
markSequenced(db, local, { stream: st.key.stream, seq: st.key.seq, nowIso, outcome: 'void' });
|
|
1043
|
+
}
|
|
1044
|
+
markTxns(db, st.parts, 'void', {
|
|
1045
|
+
frame: api.frame,
|
|
1046
|
+
reason: `post-apply: ${violations.map((v) => v.check).join(', ')}`,
|
|
1047
|
+
nowIso,
|
|
1048
|
+
});
|
|
1049
|
+
return {
|
|
1050
|
+
status: 'void',
|
|
1051
|
+
holds: [],
|
|
1052
|
+
n: violations.length,
|
|
1053
|
+
applied: true,
|
|
1054
|
+
decided: rewoundEcho && local ? local.txn : null,
|
|
1055
|
+
heldTxns,
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
db.exec('RELEASE apply_txn');
|
|
1059
|
+
const status = txnStatus(results, n);
|
|
1060
|
+
if (x.sequencingOn) {
|
|
1061
|
+
if (st.replicaId !== opts.replica) {
|
|
1062
|
+
// The rows it wrote: an echo widens its own footprint by what its
|
|
1063
|
+
// guards read, so a write to any of those rows meets it (R7-6).
|
|
1064
|
+
recordForeignTouches(db, touchedRows(st.txn.ops), touchPos);
|
|
1065
|
+
}
|
|
1066
|
+
else if (local && rewoundEcho) {
|
|
1067
|
+
// Rebased at its stream position: the stream decided it. A voided
|
|
1068
|
+
// echo stays rewound and keeps its undo (Rule 6).
|
|
1069
|
+
markSequenced(db, local, {
|
|
1070
|
+
stream: st.key.stream,
|
|
1071
|
+
seq: st.key.seq,
|
|
1072
|
+
nowIso,
|
|
1073
|
+
outcome: results.includes('void') ? 'void' : 'applied',
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
else if (local && !results.includes('void') && x.inPlace.has(local.txn)) {
|
|
1077
|
+
// Own echo in place: the stream order agrees with ours.
|
|
1078
|
+
markSequenced(db, local, { stream: st.key.stream, seq: st.key.seq, nowIso });
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
markTxns(db, st.parts, status, {
|
|
1082
|
+
frame: api.frame,
|
|
1083
|
+
reason: n > 0 ? `${n} conflict(s) recorded` : null,
|
|
1084
|
+
nowIso,
|
|
1085
|
+
});
|
|
1086
|
+
return { status, holds: [], n, applied: true, decided: rewoundEcho && local ? local.txn : null };
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Apply a stream's staged transactions (see the module doc).
|
|
1090
|
+
*
|
|
1091
|
+
* @param db - The store (the journal schema applied, capture on); must not
|
|
1092
|
+
* be inside a transaction.
|
|
1093
|
+
* @param opts - Scope, stream, this replica, clock, sealing and pass bound.
|
|
1094
|
+
* @returns What the inbox holds for the transactions tried, per status.
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* ```ts
|
|
1098
|
+
* stageTxns(db, stream, segment, new Date().toISOString());
|
|
1099
|
+
* const r = applyStagedTxns(db, { scope: 'project', stream, replica });
|
|
1100
|
+
* if (r.pending > 0) reportHolds();
|
|
1101
|
+
* ```
|
|
1102
|
+
*/
|
|
1103
|
+
export function applyStagedTxns(db, opts) {
|
|
1104
|
+
const now = opts.now ?? Date.now;
|
|
1105
|
+
const maxPasses = opts.maxPasses ?? 16;
|
|
1106
|
+
// PAC-15: a store that refuses writes applies nothing; the inbox waits.
|
|
1107
|
+
const blocked = checkApplyPreconditions(db);
|
|
1108
|
+
if (blocked !== null) {
|
|
1109
|
+
return {
|
|
1110
|
+
applied: 0,
|
|
1111
|
+
conflict: 0,
|
|
1112
|
+
void: 0,
|
|
1113
|
+
pending: 0,
|
|
1114
|
+
heldSkew: 0,
|
|
1115
|
+
refusedSchema: 0,
|
|
1116
|
+
conflicts: 0,
|
|
1117
|
+
passes: 0,
|
|
1118
|
+
rebased: 0,
|
|
1119
|
+
held: [],
|
|
1120
|
+
blocked,
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
opts.seal?.();
|
|
1124
|
+
const sequencingOn = hasTable(db, '_sync_sequenced');
|
|
1125
|
+
const defCache = new Map();
|
|
1126
|
+
const defs = (table) => {
|
|
1127
|
+
if (!defCache.has(table))
|
|
1128
|
+
defCache.set(table, captureTableDef(db, opts.scope, table) ?? null);
|
|
1129
|
+
return defCache.get(table) ?? null;
|
|
1130
|
+
};
|
|
1131
|
+
const last = new Map();
|
|
1132
|
+
let conflicts = 0;
|
|
1133
|
+
let passes = 0;
|
|
1134
|
+
let rebased = 0;
|
|
1135
|
+
const heldTxns = new Set();
|
|
1136
|
+
for (let progress = true; progress && passes < maxPasses;) {
|
|
1137
|
+
progress = false;
|
|
1138
|
+
passes += 1;
|
|
1139
|
+
const heldReplicas = new Set();
|
|
1140
|
+
const held = new Set(); // rows written by a pending transaction
|
|
1141
|
+
const staged = [...stagedTxns(db, opts.stream)];
|
|
1142
|
+
// Each page is one frame and one scoped rebase (§3.5 Rule 3): rewind the
|
|
1143
|
+
// page's scope once, apply its transactions in stream order, replay once.
|
|
1144
|
+
for (let at = 0; at < staged.length;) {
|
|
1145
|
+
const page = takePage(staged, at, opts.pageOps ?? REBASE_PAGE_OPS);
|
|
1146
|
+
const pageStart = now();
|
|
1147
|
+
const done = withApplyFrame(db, opts.scope, page[0]?.actor ?? null, (api) => {
|
|
1148
|
+
const pageIso = new Date(pageStart).toISOString();
|
|
1149
|
+
for (const p of page)
|
|
1150
|
+
adoptNaturalRows(db, api, defs, p.st.txn.ops);
|
|
1151
|
+
const planned = sequencingOn
|
|
1152
|
+
? planPageRebase(db, page.map((p) => p.st), defs, opts.replica)
|
|
1153
|
+
: { plan: null, inPlace: new Set() };
|
|
1154
|
+
const rebase = planned.plan;
|
|
1155
|
+
const c0 = {
|
|
1156
|
+
db,
|
|
1157
|
+
api,
|
|
1158
|
+
st: page[0].st,
|
|
1159
|
+
defs,
|
|
1160
|
+
replica: opts.replica,
|
|
1161
|
+
nowIso: pageIso,
|
|
1162
|
+
};
|
|
1163
|
+
const rw = rebase ? rewindTxns(c0, rebase) : { kept: new Map(), after: new Map() };
|
|
1164
|
+
const rewound = new Set(rebase?.rewind.map((l) => l.txn) ?? []);
|
|
1165
|
+
const decided = new Set(); // rewound locals whose echo this page applied
|
|
1166
|
+
// The time bound covers applying, not the rewind: a large scope must
|
|
1167
|
+
// not shrink every page to one transaction that rewinds it again.
|
|
1168
|
+
const applyStart = now();
|
|
1169
|
+
let taken = 0;
|
|
1170
|
+
for (const { st } of page) {
|
|
1171
|
+
// The time bound cuts a page between transactions (never inside one).
|
|
1172
|
+
if (taken > 0 && now() - applyStart > (opts.pageMs ?? REBASE_PAGE_MS))
|
|
1173
|
+
break;
|
|
1174
|
+
taken += 1;
|
|
1175
|
+
const nowMs = now();
|
|
1176
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
1177
|
+
const id = keyText(st.key);
|
|
1178
|
+
const result = applyInPage({
|
|
1179
|
+
db,
|
|
1180
|
+
api,
|
|
1181
|
+
defs,
|
|
1182
|
+
opts,
|
|
1183
|
+
sequencingOn,
|
|
1184
|
+
rewound,
|
|
1185
|
+
inPlace: planned.inPlace,
|
|
1186
|
+
rw,
|
|
1187
|
+
nowMs,
|
|
1188
|
+
nowIso,
|
|
1189
|
+
held,
|
|
1190
|
+
heldReplicas,
|
|
1191
|
+
}, st);
|
|
1192
|
+
if (result.decided)
|
|
1193
|
+
decided.add(result.decided);
|
|
1194
|
+
for (const t of result.heldTxns ?? [])
|
|
1195
|
+
heldTxns.add(t);
|
|
1196
|
+
if (result.status !== null)
|
|
1197
|
+
last.set(id, result.status);
|
|
1198
|
+
conflicts += result.n;
|
|
1199
|
+
if (rebase && result.applied)
|
|
1200
|
+
rebased += 1;
|
|
1201
|
+
if (result.status === 'held-skew')
|
|
1202
|
+
heldReplicas.add(st.replicaId);
|
|
1203
|
+
if (result.status === 'pending')
|
|
1204
|
+
for (const k of result.holds)
|
|
1205
|
+
held.add(k);
|
|
1206
|
+
if (result.status === 'applied' ||
|
|
1207
|
+
result.status === 'conflict' ||
|
|
1208
|
+
result.status === 'void') {
|
|
1209
|
+
progress = true;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
// Replay what the page rewound and did not decide by its echo.
|
|
1213
|
+
if (rebase) {
|
|
1214
|
+
const replay = rebase.rewind.filter((l) => !decided.has(l.txn));
|
|
1215
|
+
for (const t of replayTxns(c0, { rewind: rebase.rewind, replay, own: null }, rw)) {
|
|
1216
|
+
heldTxns.add(t);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
return taken;
|
|
1220
|
+
});
|
|
1221
|
+
at += done;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
const count = (s) => [...last.values()].filter((v) => v === s).length;
|
|
1225
|
+
return {
|
|
1226
|
+
applied: count('applied'),
|
|
1227
|
+
conflict: count('conflict'),
|
|
1228
|
+
void: count('void'),
|
|
1229
|
+
pending: count('pending'),
|
|
1230
|
+
heldSkew: count('held-skew'),
|
|
1231
|
+
refusedSchema: count('refused-schema'),
|
|
1232
|
+
conflicts,
|
|
1233
|
+
passes,
|
|
1234
|
+
rebased,
|
|
1235
|
+
// Still held when the call ends (a later page of it may have applied one).
|
|
1236
|
+
held: [...heldTxns].filter((t) => txnHasHold(db, t)),
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
//# sourceMappingURL=applier.js.map
|