@cleocode/core 2026.5.134 → 2026.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binaries/README.md +49 -27
- package/dist/agents/{agent-registry.d.ts → agent-capacity-tracker.d.ts} +2 -2
- package/dist/agents/agent-capacity-tracker.d.ts.map +1 -0
- package/dist/agents/{agent-registry.js → agent-capacity-tracker.js} +2 -2
- package/dist/agents/agent-capacity-tracker.js.map +1 -0
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +4 -2
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/seed-install.d.ts +1 -1
- package/dist/agents/seed-install.d.ts.map +1 -1
- package/dist/agents/seed-install.js +42 -36
- package/dist/agents/seed-install.js.map +1 -1
- package/dist/caamp-export.d.ts +18 -0
- package/dist/caamp-export.d.ts.map +1 -0
- package/dist/caamp-export.js +18 -0
- package/dist/caamp-export.js.map +1 -0
- package/dist/conduit/local-transport.d.ts +1 -1
- package/dist/conduit/local-transport.d.ts.map +1 -1
- package/dist/conduit/local-transport.js +69 -43
- package/dist/conduit/local-transport.js.map +1 -1
- package/dist/dispatch/mutate-projection.d.ts.map +1 -1
- package/dist/dispatch/mutate-projection.js +11 -0
- package/dist/dispatch/mutate-projection.js.map +1 -1
- package/dist/docs/docs-read-model.d.ts +7 -0
- package/dist/docs/docs-read-model.d.ts.map +1 -1
- package/dist/docs/docs-read-model.js +5 -0
- package/dist/docs/docs-read-model.js.map +1 -1
- package/dist/docs/supersede.d.ts.map +1 -1
- package/dist/docs/supersede.js +12 -7
- package/dist/docs/supersede.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +10 -9
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/git-shim-export.d.ts +18 -0
- package/dist/git-shim-export.d.ts.map +1 -0
- package/dist/git-shim-export.js +18 -0
- package/dist/git-shim-export.js.map +1 -0
- package/dist/hooks/payload-schemas.d.ts +2 -2
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +39 -32
- package/dist/init.js.map +1 -1
- package/dist/internal.d.ts +11 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +14 -5
- package/dist/internal.js.map +1 -1
- package/dist/lafs-export.d.ts +18 -0
- package/dist/lafs-export.d.ts.map +1 -0
- package/dist/lafs-export.js +18 -0
- package/dist/lafs-export.js.map +1 -0
- package/dist/lifecycle/effective-stage.js +1 -1
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle/index.js.map +1 -1
- package/dist/lifecycle/rollup.js +1 -1
- package/dist/llm/credential-pool.d.ts +17 -0
- package/dist/llm/credential-pool.d.ts.map +1 -1
- package/dist/llm/credential-pool.js +40 -1
- package/dist/llm/credential-pool.js.map +1 -1
- package/dist/llm/plugin-facade.d.ts.map +1 -1
- package/dist/llm/plugin-facade.js +11 -19
- package/dist/llm/plugin-facade.js.map +1 -1
- package/dist/llm/role-executor.d.ts +8 -0
- package/dist/llm/role-executor.d.ts.map +1 -1
- package/dist/llm/role-executor.js +96 -4
- package/dist/llm/role-executor.js.map +1 -1
- package/dist/llm/role-resolver.d.ts.map +1 -1
- package/dist/llm/role-resolver.js +56 -1
- package/dist/llm/role-resolver.js.map +1 -1
- package/dist/llm/transports/codex-oauth-headers.d.ts +51 -0
- package/dist/llm/transports/codex-oauth-headers.d.ts.map +1 -0
- package/dist/llm/transports/codex-oauth-headers.js +89 -0
- package/dist/llm/transports/codex-oauth-headers.js.map +1 -0
- package/dist/memory/claude-mem-migration.d.ts.map +1 -1
- package/dist/memory/claude-mem-migration.js +1 -3
- package/dist/memory/claude-mem-migration.js.map +1 -1
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +77 -23
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +12 -6
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/learnings.d.ts +2 -2
- package/dist/memory/nexus-plasticity.d.ts +21 -9
- package/dist/memory/nexus-plasticity.d.ts.map +1 -1
- package/dist/memory/nexus-plasticity.js +44 -22
- package/dist/memory/nexus-plasticity.js.map +1 -1
- package/dist/memory/patterns.d.ts +2 -2
- package/dist/memory/redaction.d.ts +19 -3
- package/dist/memory/redaction.d.ts.map +1 -1
- package/dist/memory/redaction.js +22 -94
- package/dist/memory/redaction.js.map +1 -1
- package/dist/metrics/token-service.d.ts +8 -2
- package/dist/metrics/token-service.d.ts.map +1 -1
- package/dist/metrics/token-service.js +1 -1
- package/dist/metrics/token-service.js.map +1 -1
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +6 -8
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- 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/clusters.d.ts.map +1 -1
- package/dist/nexus/clusters.js +3 -2
- package/dist/nexus/clusters.js.map +1 -1
- package/dist/nexus/context.d.ts.map +1 -1
- package/dist/nexus/context.js +10 -16
- package/dist/nexus/context.js.map +1 -1
- package/dist/nexus/diff.d.ts.map +1 -1
- package/dist/nexus/diff.js +6 -4
- package/dist/nexus/diff.js.map +1 -1
- package/dist/nexus/export.d.ts.map +1 -1
- package/dist/nexus/export.js +7 -4
- package/dist/nexus/export.js.map +1 -1
- package/dist/nexus/flows.d.ts.map +1 -1
- package/dist/nexus/flows.js +3 -1
- package/dist/nexus/flows.js.map +1 -1
- package/dist/nexus/impact.d.ts +1 -1
- package/dist/nexus/impact.d.ts.map +1 -1
- package/dist/nexus/impact.js +31 -17
- package/dist/nexus/impact.js.map +1 -1
- package/dist/nexus/living-brain.d.ts.map +1 -1
- package/dist/nexus/living-brain.js +27 -15
- package/dist/nexus/living-brain.js.map +1 -1
- package/dist/nexus/nexus-bridge.d.ts.map +1 -1
- package/dist/nexus/nexus-bridge.js +28 -29
- package/dist/nexus/nexus-bridge.js.map +1 -1
- package/dist/nexus/plasticity-queries.d.ts +4 -2
- package/dist/nexus/plasticity-queries.d.ts.map +1 -1
- package/dist/nexus/plasticity-queries.js +27 -15
- package/dist/nexus/plasticity-queries.js.map +1 -1
- package/dist/nexus/query.d.ts.map +1 -1
- package/dist/nexus/query.js +6 -2
- package/dist/nexus/query.js.map +1 -1
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +65 -30
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/route-analysis.d.ts +3 -2
- package/dist/nexus/route-analysis.d.ts.map +1 -1
- package/dist/nexus/route-analysis.js +11 -10
- package/dist/nexus/route-analysis.js.map +1 -1
- package/dist/nexus/sigil.d.ts.map +1 -1
- package/dist/nexus/sigil.js +60 -13
- package/dist/nexus/sigil.js.map +1 -1
- package/dist/nexus/user-profile.d.ts +2 -1
- package/dist/nexus/user-profile.d.ts.map +1 -1
- package/dist/nexus/user-profile.js +8 -4
- package/dist/nexus/user-profile.js.map +1 -1
- package/dist/orchestrate/index.d.ts +1 -1
- package/dist/orchestrate/index.d.ts.map +1 -1
- package/dist/orchestrate/index.js +1 -1
- package/dist/orchestrate/index.js.map +1 -1
- package/dist/orchestrate/plan.d.ts +3 -3
- package/dist/orchestrate/plan.d.ts.map +1 -1
- package/dist/orchestrate/plan.js +7 -7
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestrate/spawn-ops.js +2 -2
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/classify.d.ts +2 -2
- package/dist/orchestration/classify.js +3 -3
- package/dist/orchestration/classify.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +5 -5
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/paths-export.d.ts +18 -0
- package/dist/paths-export.d.ts.map +1 -0
- package/dist/paths-export.js +18 -0
- package/dist/paths-export.js.map +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +24 -11
- package/dist/paths.js.map +1 -1
- package/dist/playbooks/index.d.ts +1 -0
- package/dist/playbooks/index.d.ts.map +1 -1
- package/dist/playbooks/index.js +4 -0
- package/dist/playbooks/index.js.map +1 -1
- package/dist/playbooks/skill-node-executor.d.ts +155 -0
- package/dist/playbooks/skill-node-executor.d.ts.map +1 -0
- package/dist/playbooks/skill-node-executor.js +156 -0
- package/dist/playbooks/skill-node-executor.js.map +1 -0
- package/dist/repair.d.ts +3 -7
- package/dist/repair.d.ts.map +1 -1
- package/dist/repair.js +5 -43
- package/dist/repair.js.map +1 -1
- package/dist/sagas/migrate-containment.js +7 -7
- package/dist/sagas/migrate-containment.js.map +1 -1
- package/dist/scaffold/ensure-dirs.d.ts +8 -2
- package/dist/scaffold/ensure-dirs.d.ts.map +1 -1
- package/dist/scaffold/ensure-dirs.js +24 -11
- package/dist/scaffold/ensure-dirs.js.map +1 -1
- package/dist/scaffold/project-detection.d.ts +5 -1
- package/dist/scaffold/project-detection.d.ts.map +1 -1
- package/dist/scaffold/project-detection.js +9 -5
- package/dist/scaffold/project-detection.js.map +1 -1
- package/dist/sentient/hygiene-scan.js +6 -6
- package/dist/sentient/hygiene-scan.js.map +1 -1
- package/dist/sentient/proposal-dedup.js +2 -2
- package/dist/sentient/proposal-rate-limiter.js +1 -1
- package/dist/sentient/propose-tick.js +5 -5
- package/dist/sentient/propose-tick.js.map +1 -1
- package/dist/sentient/stage-drift-tick.js +3 -3
- package/dist/sentient/stage-drift-tick.js.map +1 -1
- package/dist/sequence/index.d.ts.map +1 -1
- package/dist/sequence/index.js +6 -2
- package/dist/sequence/index.js.map +1 -1
- package/dist/setup/sections/verification.js +2 -2
- package/dist/setup/sections/verification.js.map +1 -1
- package/dist/shutdown.d.ts +81 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +105 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/skills/index.d.ts +2 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-executor-adapter.d.ts +136 -0
- package/dist/skills/skill-executor-adapter.d.ts.map +1 -0
- package/dist/skills/skill-executor-adapter.js +137 -0
- package/dist/skills/skill-executor-adapter.js.map +1 -0
- package/dist/skills/usage-recorder.d.ts.map +1 -1
- package/dist/skills/usage-recorder.js +30 -0
- package/dist/skills/usage-recorder.js.map +1 -1
- package/dist/skills-export.d.ts +23 -0
- package/dist/skills-export.d.ts.map +1 -0
- package/dist/skills-export.js +23 -0
- package/dist/skills-export.js.map +1 -0
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +8 -3
- package/dist/stats/index.js.map +1 -1
- package/dist/store/agent-doctor.d.ts +3 -3
- package/dist/store/agent-doctor.d.ts.map +1 -1
- package/dist/store/agent-doctor.js +18 -13
- package/dist/store/agent-doctor.js.map +1 -1
- package/dist/store/agent-install.d.ts +6 -5
- package/dist/store/agent-install.d.ts.map +1 -1
- package/dist/store/agent-install.js +20 -16
- package/dist/store/agent-install.js.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts +66 -28
- package/dist/store/agent-registry-accessor.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.js +248 -167
- package/dist/store/agent-registry-accessor.js.map +1 -1
- package/dist/store/agent-registry-store.d.ts +242 -0
- package/dist/store/agent-registry-store.d.ts.map +1 -0
- package/dist/store/agent-registry-store.js +501 -0
- package/dist/store/agent-registry-store.js.map +1 -0
- package/dist/store/agent-resolver.d.ts +8 -8
- package/dist/store/agent-resolver.d.ts.map +1 -1
- package/dist/store/agent-resolver.js +19 -17
- package/dist/store/agent-resolver.js.map +1 -1
- package/dist/store/backup-pack.d.ts.map +1 -1
- package/dist/store/backup-pack.js +24 -8
- package/dist/store/backup-pack.js.map +1 -1
- package/dist/store/conduit-sqlite.d.ts +181 -74
- package/dist/store/conduit-sqlite.d.ts.map +1 -1
- package/dist/store/conduit-sqlite.js +307 -528
- package/dist/store/conduit-sqlite.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +5 -5
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +12 -10
- package/dist/store/cross-db-cleanup.js.map +1 -1
- package/dist/store/data-accessor.d.ts +4 -4
- package/dist/store/data-accessor.js +5 -5
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/data-safety-central.d.ts +83 -1
- package/dist/store/data-safety-central.d.ts.map +1 -1
- package/dist/store/data-safety-central.js +257 -0
- package/dist/store/data-safety-central.js.map +1 -1
- package/dist/store/db-helpers.d.ts +8 -2
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +6 -2
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +46 -4
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +103 -9
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/__fixtures__/representative-fixture.d.ts +116 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.d.ts.map +1 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.js +274 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.js.map +1 -0
- package/dist/store/exodus/index.d.ts +3 -1
- package/dist/store/exodus/index.d.ts.map +1 -1
- package/dist/store/exodus/index.js +3 -1
- package/dist/store/exodus/index.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts +120 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +923 -119
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +189 -0
- package/dist/store/exodus/on-open.d.ts.map +1 -0
- package/dist/store/exodus/on-open.js +464 -0
- package/dist/store/exodus/on-open.js.map +1 -0
- package/dist/store/exodus/table-name-map.d.ts +173 -0
- package/dist/store/exodus/table-name-map.d.ts.map +1 -0
- package/dist/store/exodus/table-name-map.js +660 -0
- package/dist/store/exodus/table-name-map.js.map +1 -0
- package/dist/store/exodus/verify-migration.d.ts +72 -0
- package/dist/store/exodus/verify-migration.d.ts.map +1 -0
- package/dist/store/exodus/verify-migration.js +678 -0
- package/dist/store/exodus/verify-migration.js.map +1 -0
- package/dist/store/exodus/verify.d.ts +32 -8
- package/dist/store/exodus/verify.d.ts.map +1 -1
- package/dist/store/exodus/verify.js +48 -142
- package/dist/store/exodus/verify.js.map +1 -1
- package/dist/store/index.d.ts +2 -3
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +2 -3
- package/dist/store/index.js.map +1 -1
- package/dist/store/memory-accessor.d.ts +31 -0
- package/dist/store/memory-accessor.d.ts.map +1 -1
- package/dist/store/memory-accessor.js +38 -0
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/memory-sqlite.d.ts +86 -13
- package/dist/store/memory-sqlite.d.ts.map +1 -1
- package/dist/store/memory-sqlite.js +326 -528
- package/dist/store/memory-sqlite.js.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.js +126 -35
- package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
- package/dist/store/migration-manager.d.ts +49 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +167 -67
- package/dist/store/migration-manager.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 +32 -3
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts +152 -29
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +496 -177
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/nexus-validation-schemas.d.ts +32 -32
- package/dist/store/open-cleo-db.d.ts +37 -40
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +76 -153
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/role-accessors-impl.d.ts +4 -4
- package/dist/store/role-accessors-impl.d.ts.map +1 -1
- package/dist/store/role-accessors-impl.js +18 -15
- package/dist/store/role-accessors-impl.js.map +1 -1
- package/dist/store/schema/{signaldock-schema.d.ts → agent-registry-schema.d.ts} +15 -5
- package/dist/store/schema/agent-registry-schema.d.ts.map +1 -0
- package/dist/store/schema/{signaldock-schema.js → agent-registry-schema.js} +15 -5
- package/dist/store/schema/agent-registry-schema.js.map +1 -0
- package/dist/store/schema/agent-schema.d.ts +1 -1
- package/dist/store/schema/agent-schema.js +4 -4
- package/dist/store/schema/agent-schema.js.map +1 -1
- package/dist/store/schema/attachments.d.ts +1 -1
- package/dist/store/schema/audit.d.ts +15 -5
- package/dist/store/schema/audit.d.ts.map +1 -1
- package/dist/store/schema/audit.js +12 -2
- package/dist/store/schema/audit.js.map +1 -1
- package/dist/store/schema/background-jobs.d.ts +1 -1
- package/dist/store/schema/cleo-global/{signaldock.d.ts → agent-registry.d.ts} +277 -271
- package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -0
- package/dist/store/schema/cleo-global/{signaldock.js → agent-registry.js} +136 -125
- package/dist/store/schema/cleo-global/agent-registry.js.map +1 -0
- package/dist/store/schema/cleo-global/index.d.ts +29 -22
- package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/index.js +29 -22
- package/dist/store/schema/cleo-global/index.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +36 -1034
- package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/nexus.js +32 -337
- package/dist/store/schema/cleo-global/nexus.js.map +1 -1
- package/dist/store/schema/cleo-global/skills.d.ts +16 -0
- package/dist/store/schema/cleo-global/skills.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/skills.js +11 -0
- package/dist/store/schema/cleo-global/skills.js.map +1 -1
- package/dist/store/schema/{cleo-project → cleo-global}/telemetry.d.ts +33 -17
- package/dist/store/schema/cleo-global/telemetry.d.ts.map +1 -0
- package/dist/store/schema/{cleo-project → cleo-global}/telemetry.js +30 -18
- package/dist/store/schema/cleo-global/telemetry.js.map +1 -0
- package/dist/store/schema/cleo-project/audit.d.ts +8 -8
- package/dist/store/schema/cleo-project/audit.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/audit.js +2 -6
- package/dist/store/schema/cleo-project/audit.js.map +1 -1
- package/dist/store/schema/cleo-project/docs.d.ts +1 -1
- package/dist/store/schema/cleo-project/index.d.ts +29 -12
- package/dist/store/schema/cleo-project/index.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/index.js +29 -12
- package/dist/store/schema/cleo-project/index.js.map +1 -1
- package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
- package/dist/store/schema/cleo-project/nexus-graph.d.ts +1067 -0
- package/dist/store/schema/cleo-project/nexus-graph.d.ts.map +1 -0
- package/dist/store/schema/cleo-project/nexus-graph.js +407 -0
- package/dist/store/schema/cleo-project/nexus-graph.js.map +1 -0
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts +385 -0
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -0
- package/dist/store/schema/cleo-project/provenance-orphans.js +142 -0
- package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -0
- package/dist/store/schema/cleo-project/provenance-rest.d.ts +1 -1
- package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +3 -3
- package/dist/store/schema/cleo-shared/brain.d.ts +711 -494
- package/dist/store/schema/cleo-shared/brain.d.ts.map +1 -1
- package/dist/store/schema/cleo-shared/brain.js +215 -134
- package/dist/store/schema/cleo-shared/brain.js.map +1 -1
- package/dist/store/schema/conduit-schema.d.ts +63 -51
- package/dist/store/schema/conduit-schema.d.ts.map +1 -1
- package/dist/store/schema/conduit-schema.js +23 -11
- package/dist/store/schema/conduit-schema.js.map +1 -1
- package/dist/store/schema/goal.d.ts +3 -2
- package/dist/store/schema/goal.d.ts.map +1 -1
- package/dist/store/schema/goal.js +3 -2
- package/dist/store/schema/goal.js.map +1 -1
- package/dist/store/schema/index.d.ts +1 -0
- package/dist/store/schema/index.d.ts.map +1 -1
- package/dist/store/schema/index.js +1 -0
- package/dist/store/schema/index.js.map +1 -1
- package/dist/store/schema/lifecycle.d.ts +2 -2
- package/dist/store/schema/memory-schema.d.ts +2 -2
- package/dist/store/schema/nexus-schema.d.ts +174 -115
- package/dist/store/schema/nexus-schema.d.ts.map +1 -1
- package/dist/store/schema/nexus-schema.js +175 -55
- package/dist/store/schema/nexus-schema.js.map +1 -1
- package/dist/store/schema/provenance/releases.d.ts +1 -1
- package/dist/store/schema/schema-utils.d.ts +78 -0
- package/dist/store/schema/schema-utils.d.ts.map +1 -0
- package/dist/store/schema/schema-utils.js +49 -0
- package/dist/store/schema/schema-utils.js.map +1 -0
- package/dist/store/schema/skills-schema.d.ts +81 -44
- package/dist/store/schema/skills-schema.d.ts.map +1 -1
- package/dist/store/schema/skills-schema.js +49 -16
- package/dist/store/schema/skills-schema.js.map +1 -1
- package/dist/store/schema/tasks.d.ts +3 -3
- package/dist/store/skills-db.d.ts +90 -50
- package/dist/store/skills-db.d.ts.map +1 -1
- package/dist/store/skills-db.js +132 -146
- package/dist/store/skills-db.js.map +1 -1
- package/dist/store/sqlite-backup.d.ts +2 -2
- package/dist/store/sqlite-backup.d.ts.map +1 -1
- package/dist/store/sqlite-backup.js +11 -10
- package/dist/store/sqlite-backup.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +25 -18
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts +72 -12
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +153 -89
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/tasks-schema.d.ts +4 -0
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +60 -0
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts +2 -2
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +10 -5
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +17 -6
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +8 -8
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +241 -208
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +11 -6
- package/dist/system/health.js.map +1 -1
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +58 -12
- package/dist/system/project-health.js.map +1 -1
- package/dist/tasks/add.d.ts +8 -0
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +101 -0
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/cancelled-child-waiver-audit.d.ts +47 -0
- package/dist/tasks/cancelled-child-waiver-audit.d.ts.map +1 -0
- package/dist/tasks/cancelled-child-waiver-audit.js +34 -0
- package/dist/tasks/cancelled-child-waiver-audit.js.map +1 -0
- package/dist/tasks/complete.d.ts +22 -2
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +71 -6
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/compute-task-view.js +1 -1
- package/dist/tasks/session-scope.d.ts +5 -0
- package/dist/tasks/session-scope.d.ts.map +1 -1
- package/dist/tasks/session-scope.js +4 -0
- package/dist/tasks/session-scope.js.map +1 -1
- package/dist/tools/guard.d.ts +71 -1
- package/dist/tools/guard.d.ts.map +1 -1
- package/dist/tools/guard.js +73 -1
- package/dist/tools/guard.js.map +1 -1
- package/dist/tools/index.d.ts +21 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +25 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +22 -13
- package/dist/upgrade.js.map +1 -1
- package/dist/workgraph/containment.js +18 -18
- package/dist/workgraph/relations.js +2 -2
- package/dist/worktree/list.d.ts +1 -1
- package/dist/worktree/list.d.ts.map +1 -1
- package/dist/worktree/list.js +19 -21
- package/dist/worktree/list.js.map +1 -1
- package/dist/worktree-export.d.ts +18 -0
- package/dist/worktree-export.d.ts.map +1 -0
- package/dist/worktree-export.js +18 -0
- package/dist/worktree-export.js.map +1 -0
- package/migrations/drizzle-agent-registry/20260412000000_initial-global-agent-registry/migration.sql +29 -0
- package/migrations/drizzle-brain/20260601000001_t11522-brain-task-observations/migration.sql +28 -0
- package/migrations/drizzle-brain/20260601000002_t11522-inline-only-brain-tables/migration.sql +75 -0
- package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/migration.sql +49 -144
- package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/snapshot.json +8 -8
- package/migrations/drizzle-cleo-global/20260531000002_t11546-brain-usage-log/migration.sql +16 -0
- package/migrations/drizzle-cleo-global/20260601000001_t11544-skills-usage-project-id/migration.sql +12 -0
- package/migrations/drizzle-cleo-global/20260602000001_t11622-agent-registry-rename/migration.sql +80 -0
- package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/migration.sql +26 -167
- package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/snapshot.json +8 -8
- package/migrations/drizzle-cleo-project/20260531000002_t11546-brain-usage-log/migration.sql +21 -0
- package/migrations/drizzle-cleo-project/20260601000001_t11549-agent-credentials-brain-release-links/migration.sql +49 -0
- package/migrations/drizzle-cleo-project/20260601000002_t11538-project-nexus-graph/migration.sql +140 -0
- package/migrations/drizzle-cleo-project/20260602000002_t11649-token-usage-transport-mcp/migration.sql +146 -0
- package/migrations/drizzle-conduit/20260601000003_t11523-conduit-inline-schema/migration.sql +82 -0
- package/migrations/drizzle-nexus/20260421200001_t1165-baseline-reset/migration.sql +26 -8
- package/migrations/drizzle-nexus/20260601000001_t11545-nexus-relation-weights-partition/migration.sql +97 -0
- package/package.json +44 -12
- package/scripts/install-supervisor-binary.mjs +50 -201
- package/scripts/napi-binary-picker.mjs +267 -0
- package/dist/agents/agent-registry.d.ts.map +0 -1
- package/dist/agents/agent-registry.js.map +0 -1
- package/dist/store/data-safety.d.ts +0 -92
- package/dist/store/data-safety.d.ts.map +0 -1
- package/dist/store/data-safety.js +0 -274
- package/dist/store/data-safety.js.map +0 -1
- package/dist/store/schema/cleo-global/signaldock.d.ts.map +0 -1
- package/dist/store/schema/cleo-global/signaldock.js.map +0 -1
- package/dist/store/schema/cleo-project/telemetry.d.ts.map +0 -1
- package/dist/store/schema/cleo-project/telemetry.js.map +0 -1
- package/dist/store/schema/signaldock-schema.d.ts.map +0 -1
- package/dist/store/schema/signaldock-schema.js.map +0 -1
- package/dist/store/signaldock-sqlite.d.ts +0 -173
- package/dist/store/signaldock-sqlite.d.ts.map +0 -1
- package/dist/store/signaldock-sqlite.js +0 -445
- package/dist/store/signaldock-sqlite.js.map +0 -1
- package/migrations/drizzle-nexus/20260318205558_initial/migration.sql +0 -46
- package/migrations/drizzle-nexus/20260412000001_t529-nexus-graph-tables/migration.sql +0 -49
- package/migrations/drizzle-nexus/20260415000001_t622-project-registry-paths/migration.sql +0 -12
- package/migrations/drizzle-nexus/20260419000001_t998-nexus-plasticity/migration.sql +0 -13
- package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/migration.sql +0 -16
- package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/snapshot.json +0 -1531
- package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/migration.sql +0 -13
- package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/snapshot.json +0 -1652
- package/migrations/drizzle-nexus/20260504000001_t1839-fts5-nexus-symbols/migration.sql +0 -68
- package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/migration.sql +0 -20
- package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/snapshot.json +0 -1652
- package/migrations/drizzle-nexus/20260526222449_t11025-project-id-aliases/migration.sql +0 -16
- package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/migration.sql +0 -209
- package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/snapshot.json +0 -2060
|
@@ -1,66 +1,229 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SQLite store for
|
|
2
|
+
* SQLite store for the NEXUS domain via drizzle-orm/node-sqlite + node:sqlite
|
|
3
|
+
* (DatabaseSync).
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
* and audit infrastructure. Follows the same singleton + WAL + migration
|
|
6
|
-
* pattern as memory-sqlite.ts.
|
|
5
|
+
* ## Dual-scope residency split (ADR-090 · T11648 — runtime read half)
|
|
7
6
|
*
|
|
8
|
-
* nexus
|
|
9
|
-
* since it stores cross-project data.
|
|
7
|
+
* The nexus domain is now SPLIT across the two consolidated `cleo.db` files:
|
|
10
8
|
*
|
|
9
|
+
* - **GRAPH (project scope):** the four code-graph tables (`nexus_nodes`,
|
|
10
|
+
* `nexus_relations`, `nexus_contracts`, `nexus_code_index`) + the
|
|
11
|
+
* `nexus_relation_weights` plasticity sibling live in
|
|
12
|
+
* `<projectRoot>/.cleo/cleo.db` — the portable per-project living brain.
|
|
13
|
+
* This is where exodus WRITES them (`resolveTableTargetScope` in
|
|
14
|
+
* `store/exodus/table-name-map.ts`), so the runtime READS them from there too.
|
|
15
|
+
* - **REGISTRY/identity (global scope):** the six cross-project tables
|
|
16
|
+
* (`nexus_project_registry`, `nexus_project_id_aliases`, `nexus_user_profile`,
|
|
17
|
+
* `nexus_sigils`, `nexus_audit_log`, `nexus_schema_meta`) stay in the GLOBAL
|
|
18
|
+
* `cleo.db` under {@link getCleoHome} (ADR-090 §2.2).
|
|
19
|
+
*
|
|
20
|
+
* `getNexusDb()` opens the PROJECT scope as `main` (via {@link openDualScopeDb}
|
|
21
|
+
* ('project')) and ATTACHes the GLOBAL `cleo.db` under
|
|
22
|
+
* {@link NEXUS_GLOBAL_ATTACH_ALIAS}. SQLite's bare-name resolution then routes
|
|
23
|
+
* each query to the correct file with ZERO accessor changes: graph tables exist
|
|
24
|
+
* in `main` (project) and resolve there; registry/identity tables are absent
|
|
25
|
+
* from `main` and fall through to the attached GLOBAL db. The GLOBAL db also
|
|
26
|
+
* carries empty graph tables (frozen T11363 migration leftovers), correctly
|
|
27
|
+
* SHADOWED by `main`.
|
|
28
|
+
*
|
|
29
|
+
* ### Why this fix (T11648)
|
|
30
|
+
*
|
|
31
|
+
* T11538/T11539 moved the graph schema to PROJECT scope and routed exodus there,
|
|
32
|
+
* but the runtime READ accessors still opened the GLOBAL handle — so after a
|
|
33
|
+
* `cleo exodus migrate` the project held 24k+ `nexus_nodes` while the runtime
|
|
34
|
+
* read 0 from global (`cleo nexus search-code` / `context` returned empty). This
|
|
35
|
+
* module is the deferred runtime half: it reads the graph from the SAME scope
|
|
36
|
+
* exodus writes it.
|
|
37
|
+
*
|
|
38
|
+
* This preserves the prior guarantees:
|
|
39
|
+
* - Every nexus-domain open flows through the single pragma SSoT (ADR-068/069).
|
|
40
|
+
* - DB Open Guard Gate 3 (`scripts/lint-no-direct-db-open.mjs`) stays green: the
|
|
41
|
+
* only native open is inside `dual-scope-db.ts` (the ATTACH below is a SQL
|
|
42
|
+
* statement on an already-chokepointed handle, not a `new DatabaseSync(`).
|
|
43
|
+
*
|
|
44
|
+
* ## COMPLETE-CUTOVER to prefixed `nexus_*` tables (T11578 · AC3)
|
|
45
|
+
*
|
|
46
|
+
* The nexus runtime READ + WRITE path targets PREFIXED consolidated tables. The
|
|
47
|
+
* five PROJECT graph tables are owned by the consolidated cleo-project migration;
|
|
48
|
+
* the six GLOBAL registry/identity tables by the consolidated cleo-global
|
|
49
|
+
* migration. The former legacy drop/rebuild (`establishLegacyNexusSchema`) and
|
|
50
|
+
* BARE registry tables (`project_registry`, …) are GONE. The runtime schema
|
|
51
|
+
* barrel `schema/nexus-schema.ts` maps every export symbol to its prefixed
|
|
52
|
+
* physical name — accessors need ZERO change.
|
|
53
|
+
*
|
|
54
|
+
* The `drizzle-nexus` migration set carries ONLY the delta the consolidated
|
|
55
|
+
* migration cannot model: the `nexus_symbols_fts` FTS5 virtual table + its three
|
|
56
|
+
* `nexus_nodes` triggers, the `nexus_relation_weights` plasticity-partition
|
|
57
|
+
* sibling (T11545), and the `_nexus_meta` health-probe table (the reconcile
|
|
58
|
+
* sentinel). The destructive half of the plasticity partition is applied
|
|
59
|
+
* idempotently at open by `ensureNexusRelationWeights` (a no-op for the
|
|
60
|
+
* already-narrow project-scope `nexus_relations`).
|
|
61
|
+
*
|
|
62
|
+
* @adr ADR-036 — registry/identity is global-only (relaxed for the 4 graph
|
|
63
|
+
* tables by ADR-090 §2.4).
|
|
64
|
+
* @adr ADR-090 — nexus code-graph residency global→project scope split.
|
|
11
65
|
* @task T5365
|
|
66
|
+
* @task T11524 - E6-L4: route getNexusDb through the dual-scope chokepoint
|
|
67
|
+
* @task T11578 - AC3: COMPLETE-CUTOVER nexus runtime → prefixed nexus_* tables
|
|
68
|
+
* @task T11648 - ADR-090 runtime read half: route graph reads to project scope
|
|
12
69
|
*/
|
|
13
|
-
import { copyFileSync, existsSync
|
|
14
|
-
import {
|
|
15
|
-
import { readMigrationFiles } from 'drizzle-orm/migrator';
|
|
70
|
+
import { copyFileSync, existsSync } from 'node:fs';
|
|
71
|
+
import { join } from 'node:path';
|
|
16
72
|
import { drizzle } from 'drizzle-orm/node-sqlite';
|
|
17
73
|
import { getLogger } from '../logger.js';
|
|
18
74
|
import { getCleoHome } from '../paths.js';
|
|
75
|
+
// E6-L4 (T11524): dual-scope chokepoint — the nexus domain now opens the
|
|
76
|
+
// consolidated GLOBAL `cleo.db` through here. openDualScopeDb manages the
|
|
77
|
+
// DatabaseSync lifecycle, pragmas, and consolidated migrations. We extract the
|
|
78
|
+
// native handle and re-wrap it with the legacy nexus-schema drizzle instance so
|
|
79
|
+
// existing callers (nexusSchema.* queries) compile and run without change.
|
|
80
|
+
import { openDualScopeDb, resolveDualScopeDbPath } from './dual-scope-db.js';
|
|
19
81
|
import { ensureColumns, migrateWithRetry, reconcileJournal } from './migration-manager.js';
|
|
20
82
|
import { resolveCorePackageMigrationsFolder } from './resolve-migrations-folder.js';
|
|
21
83
|
import * as nexusSchema from './schema/nexus-schema.js';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
84
|
+
// isSqliteBusy is a pure predicate with no node:sqlite dependency — import it
|
|
85
|
+
// from its canonical leaf home (with-retry.ts) rather than sqlite.ts so this
|
|
86
|
+
// module no longer pulls the native open path.
|
|
87
|
+
import { isSqliteBusy } from './with-retry.js';
|
|
25
88
|
/** Schema version for newly created nexus databases. Single source of truth. */
|
|
26
89
|
export const NEXUS_SCHEMA_VERSION = '1.0.0';
|
|
27
90
|
/** Singleton state for lazy initialization. */
|
|
28
91
|
let _nexusDb = null;
|
|
29
92
|
let _nexusNativeDb = null;
|
|
30
93
|
let _nexusDbPath = null;
|
|
94
|
+
/**
|
|
95
|
+
* The GLOBAL registry path the current singleton's ATTACH targets (ADR-090 ·
|
|
96
|
+
* T11648). When `getCleoHome()` changes (e.g. tests mutating `CLEO_HOME`), the
|
|
97
|
+
* attached global differs AND must be migrated via `openDualScopeDb('global')` —
|
|
98
|
+
* which only runs on the init path. So a registry-path change forces a full
|
|
99
|
+
* singleton reset rather than a cheap re-attach to an unmigrated file.
|
|
100
|
+
*/
|
|
101
|
+
let _nexusRegistryPath = null;
|
|
31
102
|
/** Guard against concurrent initialization (async migration). */
|
|
32
103
|
let _nexusInitPromise = null;
|
|
33
104
|
/**
|
|
34
|
-
*
|
|
105
|
+
* SQLite ATTACH alias under which the GLOBAL consolidated `cleo.db` is mounted
|
|
106
|
+
* into the PROJECT-scope nexus handle so the cross-project registry/identity
|
|
107
|
+
* tables (`nexus_project_registry`, `nexus_user_profile`, `nexus_sigils`,
|
|
108
|
+
* `nexus_project_id_aliases`, `nexus_audit_log`, `nexus_schema_meta`) stay
|
|
109
|
+
* reachable by their BARE names (ADR-090 · T11648).
|
|
110
|
+
*
|
|
111
|
+
* SQLite resolves a bare table name against `main` first, then attached
|
|
112
|
+
* databases in attach order. The PROJECT `cleo.db` (`main`) physically carries
|
|
113
|
+
* ONLY the five graph tables (`nexus_nodes`, `nexus_relations`,
|
|
114
|
+
* `nexus_contracts`, `nexus_code_index`, `nexus_relation_weights`), so those
|
|
115
|
+
* bare names resolve to the populated project graph; the registry/identity
|
|
116
|
+
* tables — absent from `main` — fall through to this attached GLOBAL db. The
|
|
117
|
+
* GLOBAL db ALSO carries empty graph tables (frozen T11363 migration leftovers),
|
|
118
|
+
* but those are correctly SHADOWED by `main` and never read or written.
|
|
119
|
+
*/
|
|
120
|
+
const NEXUS_GLOBAL_ATTACH_ALIAS = 'nexus_global';
|
|
121
|
+
/**
|
|
122
|
+
* Returns the nexus GRAPH DB path — the consolidated PROJECT `cleo.db`
|
|
123
|
+
* (`<projectRoot>/.cleo/cleo.db`), where the four code-graph tables
|
|
124
|
+
* (`nexus_nodes`, `nexus_relations`, `nexus_contracts`, `nexus_code_index`) and
|
|
125
|
+
* the `nexus_relation_weights` plasticity sibling physically reside post the
|
|
126
|
+
* ADR-090 residency split (T11538/T11539).
|
|
127
|
+
*
|
|
128
|
+
* ## ADR-090 residency move — runtime read half (T11648)
|
|
35
129
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
130
|
+
* Exodus WRITES the graph tables to PROJECT scope (per `resolveTableTargetScope`
|
|
131
|
+
* in `store/exodus/table-name-map.ts`); this resolver routes the runtime READ
|
|
132
|
+
* path to the SAME scope so the migrated graph is visible. Previously this
|
|
133
|
+
* returned the GLOBAL `cleo.db` (`resolveDualScopeDbPath('global')`), which left
|
|
134
|
+
* `cleo nexus search-code` / `context` reading the empty global graph tables —
|
|
135
|
+
* the T11538/T11539 runtime-half gap this fix closes. The cross-project
|
|
136
|
+
* registry/identity tables stay GLOBAL and are reached via the
|
|
137
|
+
* {@link NEXUS_GLOBAL_ATTACH_ALIAS} attach (see {@link getNexusRegistryDbPath}).
|
|
39
138
|
*
|
|
139
|
+
* @param cwd - Optional working directory used to resolve the owning project
|
|
140
|
+
* root (forwarded to {@link resolveDualScopeDbPath}('project', cwd)).
|
|
40
141
|
* @task T307
|
|
41
142
|
* @epic T299
|
|
42
|
-
* @
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* bug that must be fixed rather than silently tolerated.
|
|
143
|
+
* @task T11648 (ADR-090 runtime read half — route graph reads to project scope)
|
|
144
|
+
* @why ADR-090 §2.1/§2.4 supersedes ADR-036's global-only assertion FOR THE
|
|
145
|
+
* GRAPH TABLES ONLY. The graph is per-project and must live in the portable
|
|
146
|
+
* `.cleo/cleo.db`; the registry/identity tables remain global-asserted in
|
|
147
|
+
* {@link getNexusRegistryDbPath}.
|
|
48
148
|
*/
|
|
49
|
-
export function getNexusDbPath() {
|
|
149
|
+
export function getNexusDbPath(cwd) {
|
|
150
|
+
return resolveDualScopeDbPath('project', cwd);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Returns the cross-project nexus REGISTRY/identity DB path — the consolidated
|
|
154
|
+
* GLOBAL `cleo.db` under `getCleoHome()`.
|
|
155
|
+
*
|
|
156
|
+
* The registry/identity tables (`nexus_project_registry`,
|
|
157
|
+
* `nexus_project_id_aliases`, `nexus_user_profile`, `nexus_sigils`,
|
|
158
|
+
* `nexus_audit_log`, `nexus_schema_meta`) are genuinely global (ADR-090 §2.2)
|
|
159
|
+
* and MUST stay under `getCleoHome()`. The ADR-036 global-only assertion is
|
|
160
|
+
* retained here as defence-in-depth (it was relaxed only for the four graph
|
|
161
|
+
* tables, now homed in PROJECT scope via {@link getNexusDbPath}).
|
|
162
|
+
*
|
|
163
|
+
* @task T11648 (ADR-090 — registry stays global-asserted)
|
|
164
|
+
* @adr ADR-036 — registry/identity is global-only.
|
|
165
|
+
* @throws {Error} If the resolved path is not under `getCleoHome()`.
|
|
166
|
+
*/
|
|
167
|
+
export function getNexusRegistryDbPath() {
|
|
50
168
|
const cleoHome = getCleoHome();
|
|
51
|
-
const
|
|
52
|
-
// Guard: the
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
169
|
+
const registryPath = resolveDualScopeDbPath('global');
|
|
170
|
+
// Guard: the registry/identity home MUST be under the global tier (ADR-036).
|
|
171
|
+
if (!registryPath.startsWith(cleoHome)) {
|
|
172
|
+
throw new Error(`BUG: getNexusRegistryDbPath() resolved to "${registryPath}" which is NOT ` +
|
|
173
|
+
`under getCleoHome() ("${cleoHome}"). The nexus registry/identity tables ` +
|
|
174
|
+
`are global-only per ADR-036/ADR-090 §2.2. This indicates a code path that ` +
|
|
175
|
+
`bypasses canonical path resolution — fix the caller, do not suppress this error.`);
|
|
176
|
+
}
|
|
177
|
+
return registryPath;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Idempotently ATTACH the GLOBAL consolidated `cleo.db` into a PROJECT-scope
|
|
181
|
+
* nexus handle under {@link NEXUS_GLOBAL_ATTACH_ALIAS}, so the cross-project
|
|
182
|
+
* registry/identity tables resolve by their bare names (ADR-090 · T11648).
|
|
183
|
+
*
|
|
184
|
+
* Safe to call repeatedly: if the alias is already attached (a sibling domain
|
|
185
|
+
* opened the same shared project handle first, or a prior nexus open ran this),
|
|
186
|
+
* the duplicate `ATTACH` throws and is swallowed. The global `cleo.db` is the
|
|
187
|
+
* canonical registry home; we ensure its directory exists via the global open
|
|
188
|
+
* resolver before attaching.
|
|
189
|
+
*
|
|
190
|
+
* @param nativeDb - The open PROJECT-scope `DatabaseSync` handle.
|
|
191
|
+
* @task T11648
|
|
192
|
+
*/
|
|
193
|
+
function ensureGlobalRegistryAttached(nativeDb) {
|
|
194
|
+
const globalPath = getNexusRegistryDbPath();
|
|
195
|
+
const escaped = globalPath.replace(/'/g, "''");
|
|
196
|
+
// Inspect the current attach (if any). `PRAGMA database_list` reports the alias
|
|
197
|
+
// + the file each schema is bound to. The registry home is resolved fresh from
|
|
198
|
+
// `getNexusRegistryDbPath()` (which reads `getCleoHome()`), so it can change
|
|
199
|
+
// between opens — e.g. tests that mutate `CLEO_HOME` while sharing the cwd-keyed
|
|
200
|
+
// project handle, or a sibling domain that re-opened the shared project DB. A
|
|
201
|
+
// stale ATTACH would silently read a prior registry. To stay deterministic we
|
|
202
|
+
// DETACH any existing `nexus_global` (unless it is provably the same file) and
|
|
203
|
+
// re-ATTACH the current registry path.
|
|
204
|
+
const existing = nativeDb.prepare('PRAGMA database_list').all().find((row) => row.name === NEXUS_GLOBAL_ATTACH_ALIAS);
|
|
205
|
+
if (existing) {
|
|
206
|
+
// Fast path: the alias is already bound to exactly the current registry file.
|
|
207
|
+
if (existing.file === globalPath)
|
|
208
|
+
return;
|
|
209
|
+
// Otherwise re-bind. DETACH is best-effort; the subsequent ATTACH surfaces a
|
|
210
|
+
// clear error rather than silently leaving a stale binding.
|
|
211
|
+
try {
|
|
212
|
+
nativeDb.exec(`DETACH DATABASE ${NEXUS_GLOBAL_ATTACH_ALIAS}`);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Alias still bound (e.g. an open statement) — the ATTACH below would throw
|
|
216
|
+
// "database nexus_global is already in use"; treat the existing binding as
|
|
217
|
+
// authoritative only when its file matches, which we already returned for.
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
62
220
|
}
|
|
63
|
-
|
|
221
|
+
// The global cleo.db is created/migrated by the global dual-scope open path
|
|
222
|
+
// (sibling domains: skills/agent-registry/global-brain). ATTACH only needs the
|
|
223
|
+
// file to exist; SQLite creates it if absent, but it will then lack the
|
|
224
|
+
// consolidated registry schema. Registry readers tolerate a missing table
|
|
225
|
+
// (try/catch), so a bare ATTACH is sufficient and non-fatal here.
|
|
226
|
+
nativeDb.exec(`ATTACH DATABASE '${escaped}' AS ${NEXUS_GLOBAL_ATTACH_ALIAS}`);
|
|
64
227
|
}
|
|
65
228
|
/**
|
|
66
229
|
* Resolve the absolute path to the drizzle-nexus migrations folder inside
|
|
@@ -109,9 +272,8 @@ export function getNestedNexusSentinelPath() {
|
|
|
109
272
|
* warning via the canonical pino logger if found.
|
|
110
273
|
*
|
|
111
274
|
* The function is non-blocking and non-throwing — it never alters the
|
|
112
|
-
* outcome of the surrounding `getNexusDb()` open. The canonical
|
|
113
|
-
*
|
|
114
|
-
* is present.
|
|
275
|
+
* outcome of the surrounding `getNexusDb()` open. The canonical consolidated
|
|
276
|
+
* open proceeds normally regardless of whether the nested debris is present.
|
|
115
277
|
*
|
|
116
278
|
* Idempotency: the first call for a given nested path emits the warning;
|
|
117
279
|
* subsequent calls within the same process are no-ops. Tests can reset the
|
|
@@ -145,7 +307,7 @@ export function detectAndWarnOnNestedNexus() {
|
|
|
145
307
|
migrationCommand: 'node scripts/migrate-nested-nexus.mjs',
|
|
146
308
|
adr: 'ADR-086',
|
|
147
309
|
task: 'T10321',
|
|
148
|
-
}, 'Detected nested-nexus structural bug — canonical
|
|
310
|
+
}, 'Detected nested-nexus structural bug — canonical consolidated cleo.db is in use; ' +
|
|
149
311
|
'nested duplicates at <cleoHome>/nexus/ are migration debris. Run the ' +
|
|
150
312
|
'migration script to remove them.');
|
|
151
313
|
return true;
|
|
@@ -254,17 +416,151 @@ function ensureNexusFts5(nativeDb) {
|
|
|
254
416
|
`);
|
|
255
417
|
}
|
|
256
418
|
/**
|
|
257
|
-
*
|
|
419
|
+
* Idempotent safety net + partition completer for `nexus_relation_weights`
|
|
420
|
+
* (T11545 · ADR-090 §5.3 · T11578 · AC3).
|
|
421
|
+
*
|
|
422
|
+
* The Hebbian plasticity columns were partitioned out of `nexus_relations` into
|
|
423
|
+
* this sibling 1:1 table. After the AC3 cutover the consolidated cleo-global
|
|
424
|
+
* migration (T11363) owns `nexus_relations` but still creates it with the THREE
|
|
425
|
+
* inline plasticity columns (`weight`, `last_accessed_at`, `co_accessed_count`)
|
|
426
|
+
* — the T11363 shape predates the partition. This safety net completes the
|
|
427
|
+
* partition idempotently at runtime (the destructive column-DROP is kept OUT of
|
|
428
|
+
* the journaled migration SQL, where re-runs would throw):
|
|
429
|
+
*
|
|
430
|
+
* 1. CREATE the sibling table (+ indexes) — covers fresh + pre-partition DBs.
|
|
431
|
+
* 2. When the inline columns are still present on `nexus_relations`, BACKFILL
|
|
432
|
+
* any non-default plasticity state into the sibling table so no weights are
|
|
433
|
+
* lost, then DROP the three inline columns so the structural graph row is
|
|
434
|
+
* narrow (matching `nexus-schema.ts` + the must-pass fresh-init test).
|
|
435
|
+
*
|
|
436
|
+
* Every statement is guarded by IF-NOT-EXISTS / column-presence probes; safe to
|
|
437
|
+
* re-run on every open (the DROP only fires while the inline columns exist).
|
|
438
|
+
*
|
|
439
|
+
* @task T11545
|
|
440
|
+
* @task T11578
|
|
441
|
+
*/
|
|
442
|
+
function ensureNexusRelationWeights(nativeDb) {
|
|
443
|
+
// Only meaningful once the parent graph table exists.
|
|
444
|
+
if (!tableExists(nativeDb, 'nexus_relations'))
|
|
445
|
+
return;
|
|
446
|
+
nativeDb.exec(`
|
|
447
|
+
CREATE TABLE IF NOT EXISTS nexus_relation_weights (
|
|
448
|
+
relation_id TEXT PRIMARY KEY NOT NULL,
|
|
449
|
+
weight REAL DEFAULT 0.0 NOT NULL,
|
|
450
|
+
last_accessed_at TEXT,
|
|
451
|
+
co_accessed_count INTEGER DEFAULT 0 NOT NULL
|
|
452
|
+
)
|
|
453
|
+
`);
|
|
454
|
+
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_nexus_relation_weights_last_accessed ON nexus_relation_weights (last_accessed_at)`);
|
|
455
|
+
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_nexus_relation_weights_weight ON nexus_relation_weights (weight)`);
|
|
456
|
+
// Detect the inline plasticity columns the consolidated T11363 `nexus_relations`
|
|
457
|
+
// still carries. When absent, the partition is already complete — nothing to do.
|
|
458
|
+
const relCols = nativeDb.prepare('PRAGMA table_info(nexus_relations)').all();
|
|
459
|
+
const hasInlinePlasticity = relCols.some((c) => c.name === 'weight');
|
|
460
|
+
if (!hasInlinePlasticity)
|
|
461
|
+
return;
|
|
462
|
+
// Backfill any non-default plasticity state before dropping the columns
|
|
463
|
+
// (pristine rows are intentionally NOT copied — absence == weight 0.0).
|
|
464
|
+
nativeDb.exec(`
|
|
465
|
+
INSERT OR IGNORE INTO nexus_relation_weights (relation_id, weight, last_accessed_at, co_accessed_count)
|
|
466
|
+
SELECT id, COALESCE(weight, 0.0), last_accessed_at, COALESCE(co_accessed_count, 0)
|
|
467
|
+
FROM nexus_relations
|
|
468
|
+
WHERE COALESCE(weight, 0.0) > 0.0
|
|
469
|
+
OR last_accessed_at IS NOT NULL
|
|
470
|
+
OR COALESCE(co_accessed_count, 0) > 0
|
|
471
|
+
`);
|
|
472
|
+
// Complete the partition: rebuild `nexus_relations` to the narrow structural
|
|
473
|
+
// shape (T11578 · AC3). A plain `ALTER TABLE ... DROP COLUMN last_accessed_at`
|
|
474
|
+
// is REJECTED by SQLite because the consolidated T11363 table carries
|
|
475
|
+
// `CHECK ("last_accessed_at" GLOB …)` — a column referenced by a CHECK cannot
|
|
476
|
+
// be dropped without a full table rebuild (the T11545 migration note). So we
|
|
477
|
+
// CREATE the narrow table, copy the structural columns, drop the old table, and
|
|
478
|
+
// rename. The `type`/`indexed_at` CHECKs + indexes are preserved; only the three
|
|
479
|
+
// plasticity columns + their CHECK + the plasticity index are removed.
|
|
480
|
+
//
|
|
481
|
+
// The FTS triggers fire on `nexus_nodes` (not `nexus_relations`), so they are
|
|
482
|
+
// unaffected. FKs are disabled for the rebuild then restored to the dual-scope
|
|
483
|
+
// SSoT state (T10314 idempotent-pragma contract).
|
|
484
|
+
const fkRow = nativeDb.prepare('PRAGMA foreign_keys').get();
|
|
485
|
+
const fkWasOn = fkRow?.foreign_keys === 1;
|
|
486
|
+
nativeDb.exec('PRAGMA foreign_keys=OFF');
|
|
487
|
+
try {
|
|
488
|
+
nativeDb.exec('DROP INDEX IF EXISTS idx_nexus_relations_last_accessed');
|
|
489
|
+
nativeDb.exec(`
|
|
490
|
+
CREATE TABLE nexus_relations__narrow (
|
|
491
|
+
id text PRIMARY KEY,
|
|
492
|
+
project_id text NOT NULL,
|
|
493
|
+
source_id text NOT NULL,
|
|
494
|
+
target_id text NOT NULL,
|
|
495
|
+
type text NOT NULL,
|
|
496
|
+
confidence real NOT NULL,
|
|
497
|
+
reason text,
|
|
498
|
+
step integer,
|
|
499
|
+
indexed_at text DEFAULT (datetime('now')) NOT NULL,
|
|
500
|
+
CHECK ("type" IN ('contains', 'defines', 'imports', 'accesses', 'calls', 'extends', 'implements', 'method_overrides', 'method_implements', 'has_method', 'has_property', 'member_of', 'step_in_process', 'handles_route', 'fetches', 'handles_tool', 'entry_point_of', 'wraps', 'queries', 'documents', 'applies_to', 'co_changed', 'co_cited_in_task')),
|
|
501
|
+
CHECK ("indexed_at" IS NULL OR "indexed_at" GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*')
|
|
502
|
+
)
|
|
503
|
+
`);
|
|
504
|
+
nativeDb.exec(`
|
|
505
|
+
INSERT INTO nexus_relations__narrow
|
|
506
|
+
(id, project_id, source_id, target_id, type, confidence, reason, step, indexed_at)
|
|
507
|
+
SELECT id, project_id, source_id, target_id, type, confidence, reason, step, indexed_at
|
|
508
|
+
FROM nexus_relations
|
|
509
|
+
`);
|
|
510
|
+
nativeDb.exec('DROP TABLE nexus_relations');
|
|
511
|
+
nativeDb.exec('ALTER TABLE nexus_relations__narrow RENAME TO nexus_relations');
|
|
512
|
+
// Recreate the structural indexes the rebuild dropped (match T11363 names).
|
|
513
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_project ON nexus_relations (project_id)');
|
|
514
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_source ON nexus_relations (source_id)');
|
|
515
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_target ON nexus_relations (target_id)');
|
|
516
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_type ON nexus_relations (type)');
|
|
517
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_project_type ON nexus_relations (project_id, type)');
|
|
518
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_source_type ON nexus_relations (source_id, type)');
|
|
519
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_target_type ON nexus_relations (target_id, type)');
|
|
520
|
+
nativeDb.exec('CREATE INDEX IF NOT EXISTS idx_nexus_relations_confidence ON nexus_relations (confidence)');
|
|
521
|
+
}
|
|
522
|
+
finally {
|
|
523
|
+
nativeDb.exec(`PRAGMA foreign_keys=${fkWasOn ? 'ON' : 'OFF'}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Apply the nexus-domain DELTA migration + idempotent safety nets on top of the
|
|
528
|
+
* PREFIXED consolidated graph tables the PROJECT dual-scope chokepoint already
|
|
529
|
+
* created (T11578 · AC3 · ADR-090 T11648).
|
|
258
530
|
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
531
|
+
* ## COMPLETE-CUTOVER (T11578 · AC3) + residency move (ADR-090 · T11648)
|
|
532
|
+
*
|
|
533
|
+
* The consolidated cleo-project migration OWNS the five PREFIXED graph tables
|
|
534
|
+
* in the PROJECT `cleo.db` `main` (`nexus_nodes`, `nexus_relations`,
|
|
535
|
+
* `nexus_contracts`, `nexus_code_index`, `nexus_relation_weights`); the
|
|
536
|
+
* cross-project registry/identity tables are owned by the cleo-global migration
|
|
537
|
+
* and reached through the {@link NEXUS_GLOBAL_ATTACH_ALIAS} attach. The runtime
|
|
538
|
+
* no longer drops/rebuilds a legacy shape (former `establishLegacyNexusSchema`).
|
|
539
|
+
* The `drizzle-nexus` set carries ONLY the delta the consolidated migration
|
|
540
|
+
* cannot model:
|
|
541
|
+
* - the `nexus_relation_weights` sibling (plasticity partition, T11545),
|
|
542
|
+
* - the `nexus_symbols_fts` FTS5 virtual table + its three triggers (over the
|
|
543
|
+
* project-scope `nexus_nodes`), and
|
|
544
|
+
* - the `_nexus_meta` health-probe table (also the reconcile sentinel).
|
|
545
|
+
*
|
|
546
|
+
* The reconcile sentinel is `_nexus_meta` (a table the nexus migration ITSELF
|
|
547
|
+
* creates, NOT a consolidated-owned table). This keeps `reconcileJournal`
|
|
548
|
+
* Scenario 2 (orphan deletion) dormant until the nexus migration set is journaled
|
|
549
|
+
* — otherwise the consolidated PROJECT migration's journal entries (written FIRST
|
|
550
|
+
* by `openDualScopeDb`) would look like orphans and be deleted, corrupting the
|
|
551
|
+
* shared journal (mirrors the conduit `_conduit_meta` sentinel, AC4).
|
|
261
552
|
*
|
|
262
553
|
* @task T5365
|
|
554
|
+
* @task T11578
|
|
555
|
+
* @task T11648
|
|
263
556
|
*/
|
|
264
557
|
function runNexusMigrations(nativeDb, db) {
|
|
265
558
|
const migrationsFolder = resolveNexusMigrationsFolder();
|
|
266
|
-
// If existing DB with
|
|
267
|
-
|
|
559
|
+
// If existing DB with populated graph, create a safety backup (cleo compat).
|
|
560
|
+
// Sentinel is `nexus_nodes` — the canonical project-scope graph table in
|
|
561
|
+
// `main` (ADR-090 · T11648); the former `nexus_project_registry` sentinel now
|
|
562
|
+
// lives in the attached GLOBAL db, not this project handle.
|
|
563
|
+
if (tableExists(nativeDb, 'nexus_nodes') && _nexusDbPath) {
|
|
268
564
|
const backupPath = _nexusDbPath.replace(/\.db$/, '-pre-cleo.db.bak');
|
|
269
565
|
if (!existsSync(backupPath)) {
|
|
270
566
|
try {
|
|
@@ -275,103 +571,24 @@ function runNexusMigrations(nativeDb, db) {
|
|
|
275
571
|
}
|
|
276
572
|
}
|
|
277
573
|
}
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
.run();
|
|
288
|
-
nativeDb
|
|
289
|
-
.prepare(`INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES ('${baseline.hash}', ${baseline.folderMillis})`)
|
|
290
|
-
.run();
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
// T998: idempotent safety net for plasticity columns — covers pre-migration
|
|
294
|
-
// nexus.db instances that were created before the drizzle migration runs.
|
|
295
|
-
// ensureColumns is a no-op when the columns already exist.
|
|
296
|
-
ensureColumns(nativeDb, 'nexus_relations', [
|
|
297
|
-
{ name: 'weight', ddl: 'real DEFAULT 0.0' },
|
|
298
|
-
{ name: 'last_accessed_at', ddl: 'text' },
|
|
299
|
-
{ name: 'co_accessed_count', ddl: 'integer DEFAULT 0' },
|
|
300
|
-
], 'nexus');
|
|
301
|
-
// T1062: idempotent safety net for external module nodes — covers pre-migration
|
|
302
|
-
// nexus.db instances that were created before the drizzle migration runs.
|
|
303
|
-
// Unresolved imports are persisted as ExternalModule nodes with is_external=true.
|
|
304
|
-
ensureColumns(nativeDb, 'nexus_nodes', [{ name: 'is_external', ddl: 'integer DEFAULT 0' }], 'nexus');
|
|
305
|
-
// T1065: idempotent safety net for contracts table — covers pre-migration
|
|
306
|
-
// nexus.db instances that were created before contracts extraction.
|
|
307
|
-
// If the table doesn't exist after migrations, it will be created here.
|
|
308
|
-
if (!tableExists(nativeDb, 'nexus_contracts')) {
|
|
309
|
-
nativeDb
|
|
310
|
-
.prepare(`CREATE TABLE IF NOT EXISTS nexus_contracts (
|
|
311
|
-
contract_id TEXT PRIMARY KEY,
|
|
312
|
-
project_id TEXT NOT NULL,
|
|
313
|
-
type TEXT NOT NULL CHECK (type IN ('http', 'grpc', 'topic')),
|
|
314
|
-
path TEXT NOT NULL,
|
|
315
|
-
method TEXT,
|
|
316
|
-
request_schema_json TEXT NOT NULL DEFAULT '{}',
|
|
317
|
-
response_schema_json TEXT NOT NULL DEFAULT '{}',
|
|
318
|
-
source_symbol_id TEXT,
|
|
319
|
-
route_node_id TEXT,
|
|
320
|
-
confidence REAL NOT NULL DEFAULT 1.0,
|
|
321
|
-
description TEXT,
|
|
322
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
323
|
-
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
324
|
-
)`)
|
|
325
|
-
.run();
|
|
326
|
-
// Create indexes
|
|
327
|
-
nativeDb
|
|
328
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_project ON nexus_contracts(project_id)')
|
|
329
|
-
.run();
|
|
330
|
-
nativeDb
|
|
331
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_type ON nexus_contracts(type)')
|
|
332
|
-
.run();
|
|
333
|
-
nativeDb
|
|
334
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_path ON nexus_contracts(path)')
|
|
335
|
-
.run();
|
|
336
|
-
nativeDb
|
|
337
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_method ON nexus_contracts(method)')
|
|
338
|
-
.run();
|
|
339
|
-
nativeDb
|
|
340
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_project_type ON nexus_contracts(project_id, type)')
|
|
341
|
-
.run();
|
|
342
|
-
nativeDb
|
|
343
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_source_symbol ON nexus_contracts(source_symbol_id)')
|
|
344
|
-
.run();
|
|
345
|
-
nativeDb
|
|
346
|
-
.prepare('CREATE INDEX IF NOT EXISTS idx_nexus_contracts_created ON nexus_contracts(created_at)')
|
|
347
|
-
.run();
|
|
348
|
-
}
|
|
349
|
-
// T1839: idempotent safety net for FTS5 virtual table + triggers.
|
|
350
|
-
// Covers existing nexus.db instances that were created before this migration.
|
|
351
|
-
// Each statement uses nativeDb.exec() (not prepare().run()) so that the entire
|
|
352
|
-
// DDL block executes atomically without the node:sqlite first-statement-only limit.
|
|
353
|
-
ensureNexusFts5(nativeDb);
|
|
354
|
-
// T9183: Reconcile partial migrations before running migrate (matches brain.db
|
|
355
|
-
// pattern in memory-sqlite.ts). When a legacy nexus.db has columns from prior
|
|
356
|
-
// ensureColumns() repair but no journal entries, reconcileJournal Scenario 3
|
|
357
|
-
// marks those migrations applied via DDL probe so migrateWithRetry doesn't
|
|
358
|
-
// hit duplicate-column errors on the legacy-upgrade path.
|
|
359
|
-
reconcileJournal(nativeDb, migrationsFolder, 'project_registry', 'nexus');
|
|
360
|
-
// Run pending migrations via migrateWithRetry which catches duplicate-column
|
|
361
|
-
// errors and triggers Scenario 3 reconciliation as a belt-and-suspenders
|
|
362
|
-
// safety net (T9183, matches memory-sqlite.ts:99 brain pattern).
|
|
574
|
+
// Reconcile the Drizzle journal first so existing DBs don't try to re-run the
|
|
575
|
+
// comment-only baseline marker, and so removed legacy per-table migrations are
|
|
576
|
+
// treated as true orphans (Sub-case B) rather than re-run. Sentinel =
|
|
577
|
+
// `_nexus_meta` (created by the nexus delta migration itself — NOT a
|
|
578
|
+
// consolidated-owned table; see the doc note above).
|
|
579
|
+
reconcileJournal(nativeDb, migrationsFolder, '_nexus_meta', 'nexus');
|
|
580
|
+
// Run the nexus DELTA migration (FTS5 quartet + nexus_relation_weights +
|
|
581
|
+
// `_nexus_meta`). Wrapped in a busy retry — the GLOBAL `cleo.db` handle is
|
|
582
|
+
// shared with sibling domains, so a concurrent open may briefly hold a lock.
|
|
363
583
|
const MAX_RETRIES = 5;
|
|
364
584
|
const BASE_DELAY_MS = 100;
|
|
365
585
|
const MAX_DELAY_MS = 2000;
|
|
366
586
|
let lastError;
|
|
367
587
|
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
368
588
|
try {
|
|
369
|
-
migrateWithRetry(db, migrationsFolder, nativeDb, '
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
// old DBs where this column was added after initial schema creation.
|
|
373
|
-
ensureColumns(nativeDb, 'nexus_nodes', [{ name: 'is_external', ddl: 'integer DEFAULT 0' }], 'nexus');
|
|
374
|
-
return;
|
|
589
|
+
migrateWithRetry(db, migrationsFolder, nativeDb, '_nexus_meta', 'nexus');
|
|
590
|
+
lastError = undefined;
|
|
591
|
+
break;
|
|
375
592
|
}
|
|
376
593
|
catch (err) {
|
|
377
594
|
if (!isSqliteBusy(err) || attempt === MAX_RETRIES)
|
|
@@ -381,42 +598,141 @@ function runNexusMigrations(nativeDb, db) {
|
|
|
381
598
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, Math.round(delay));
|
|
382
599
|
}
|
|
383
600
|
}
|
|
384
|
-
/* c8 ignore next */
|
|
385
|
-
|
|
601
|
+
/* c8 ignore next 1 */
|
|
602
|
+
if (lastError)
|
|
603
|
+
throw lastError;
|
|
604
|
+
// Complete the plasticity partition: create the sibling table (the migration
|
|
605
|
+
// also creates it idempotently), backfill, then DROP the inline plasticity
|
|
606
|
+
// columns the consolidated T11363 `nexus_relations` still carries (T11578 · AC3).
|
|
607
|
+
ensureNexusRelationWeights(nativeDb);
|
|
608
|
+
// T1062 safety net: ensure `nexus_nodes.is_external` exists (the consolidated
|
|
609
|
+
// T11363 shape already includes it; this is a belt-and-suspenders no-op).
|
|
610
|
+
ensureColumns(nativeDb, 'nexus_nodes', [{ name: 'is_external', ddl: 'integer DEFAULT 0' }], 'nexus');
|
|
611
|
+
// T1839 safety net: (re)build the FTS5 virtual table + triggers and backfill
|
|
612
|
+
// existing `nexus_nodes` rows. Idempotent — a no-op once the index exists.
|
|
613
|
+
ensureNexusFts5(nativeDb);
|
|
386
614
|
}
|
|
387
615
|
/**
|
|
388
|
-
* Initialize the
|
|
389
|
-
*
|
|
390
|
-
*
|
|
616
|
+
* Initialize the consolidated PROJECT `cleo.db` (the nexus GRAPH home) with the
|
|
617
|
+
* GLOBAL `cleo.db` ATTACHed for registry/identity reads, plus the nexus DELTA
|
|
618
|
+
* schema within it (lazy, singleton).
|
|
619
|
+
*
|
|
620
|
+
* ## ADR-090 residency move — runtime read half (T11648)
|
|
621
|
+
*
|
|
622
|
+
* The four code-graph tables (`nexus_nodes`, `nexus_relations`, `nexus_contracts`,
|
|
623
|
+
* `nexus_code_index`) + the `nexus_relation_weights` plasticity sibling now live
|
|
624
|
+
* in PROJECT scope (`<projectRoot>/.cleo/cleo.db`) — that is where exodus WRITES
|
|
625
|
+
* them. The runtime READ path therefore opens the PROJECT scope as `main` so the
|
|
626
|
+
* graph is visible (previously it opened GLOBAL and read empty graph tables —
|
|
627
|
+
* the T11538/T11539 gap). The cross-project registry/identity tables stay GLOBAL;
|
|
628
|
+
* we open GLOBAL first (so its consolidated migration creates them) then ATTACH
|
|
629
|
+
* it under {@link NEXUS_GLOBAL_ATTACH_ALIAS} so the registry/identity accessors —
|
|
630
|
+
* which reference bare names (`nexus_project_registry`, `nexus_user_profile`,
|
|
631
|
+
* `nexus_sigils`, `nexus_project_id_aliases`, `nexus_audit_log`,
|
|
632
|
+
* `nexus_schema_meta`) — resolve via SQLite's bare-name fall-through to the
|
|
633
|
+
* attached GLOBAL db. ADR-036's global-only assertion is relaxed for the four
|
|
634
|
+
* graph tables ONLY (registry stays global-asserted in {@link getNexusRegistryDbPath}).
|
|
391
635
|
*
|
|
392
|
-
* Uses a promise guard so concurrent callers wait for the same
|
|
393
|
-
*
|
|
636
|
+
* Uses a promise guard so concurrent callers wait for the same initialization to
|
|
637
|
+
* complete (migrations are async).
|
|
638
|
+
*
|
|
639
|
+
* @task T307
|
|
640
|
+
* @task T11524 (E6-L4 — dual-scope chokepoint delegation)
|
|
641
|
+
* @task T11578 (AC3 — prefixed `nexus_*` tables)
|
|
642
|
+
* @task T11648 (ADR-090 runtime read half — project-scope graph + global attach)
|
|
394
643
|
*/
|
|
395
644
|
export async function getNexusDb() {
|
|
396
645
|
const requestedPath = getNexusDbPath();
|
|
397
|
-
|
|
646
|
+
const requestedRegistryPath = getNexusRegistryDbPath();
|
|
647
|
+
// If singleton exists but points to a different PROJECT graph path (e.g.
|
|
648
|
+
// CLEO_DIR changed between tests), reset it.
|
|
398
649
|
if (_nexusDb && _nexusDbPath !== requestedPath) {
|
|
399
650
|
resetNexusDbState();
|
|
400
651
|
}
|
|
401
|
-
|
|
402
|
-
|
|
652
|
+
// If the GLOBAL registry path changed (e.g. CLEO_HOME changed), reset fully so
|
|
653
|
+
// the init path runs `openDualScopeDb('global')` to MIGRATE the new registry
|
|
654
|
+
// file before the ATTACH — a cheap re-attach alone would bind an unmigrated
|
|
655
|
+
// global (→ "no such table: nexus_project_registry"). (ADR-090 · T11648)
|
|
656
|
+
if (_nexusDb && _nexusRegistryPath !== requestedRegistryPath) {
|
|
657
|
+
resetNexusDbState();
|
|
658
|
+
}
|
|
659
|
+
// Liveness guard (T11524): nexus shares the consolidated PROJECT `cleo.db`
|
|
660
|
+
// handle with the other project-tier domains (tasks/brain/conduit). Another
|
|
661
|
+
// domain may have closed + re-opened the shared `DatabaseSync` while our nexus
|
|
662
|
+
// singleton still references the now-closed handle. Detect a stale (closed)
|
|
663
|
+
// handle and drop the singleton so we re-derive from the live openDualScopeDb
|
|
664
|
+
// cache below.
|
|
665
|
+
if (_nexusDb && (_nexusNativeDb === null || !_nexusNativeDb.isOpen)) {
|
|
666
|
+
resetNexusDbState();
|
|
667
|
+
}
|
|
668
|
+
if (_nexusDb) {
|
|
669
|
+
// Re-validate the GLOBAL registry ATTACH on every singleton hit (ADR-090 ·
|
|
670
|
+
// T11648). The registry home (`getCleoHome()`) can change between calls —
|
|
671
|
+
// tests that mutate `CLEO_HOME` while the cwd-keyed project handle stays
|
|
672
|
+
// cached, or a sibling domain that re-opened the shared project handle and
|
|
673
|
+
// dropped the attach. `ensureGlobalRegistryAttached` early-returns when the
|
|
674
|
+
// current attach already points at the right file, so this is cheap.
|
|
675
|
+
if (_nexusNativeDb) {
|
|
676
|
+
try {
|
|
677
|
+
ensureGlobalRegistryAttached(_nexusNativeDb);
|
|
678
|
+
}
|
|
679
|
+
catch {
|
|
680
|
+
// A failed re-attach means the shared handle is unusable — drop the
|
|
681
|
+
// singleton so the next call re-derives a fresh handle + attach.
|
|
682
|
+
resetNexusDbState();
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (_nexusDb)
|
|
686
|
+
return _nexusDb;
|
|
687
|
+
}
|
|
403
688
|
// If already initializing, wait for the in-flight init
|
|
404
689
|
if (_nexusInitPromise)
|
|
405
690
|
return _nexusInitPromise;
|
|
406
691
|
_nexusInitPromise = (async () => {
|
|
407
692
|
const dbPath = requestedPath;
|
|
408
693
|
_nexusDbPath = dbPath;
|
|
694
|
+
_nexusRegistryPath = requestedRegistryPath;
|
|
409
695
|
// ADR-086 / T10321 — warn (one-shot, non-blocking) if the install still
|
|
410
696
|
// carries the nested-nexus migration debris. Does not alter the open.
|
|
411
697
|
detectAndWarnOnNestedNexus();
|
|
412
|
-
//
|
|
413
|
-
|
|
414
|
-
//
|
|
415
|
-
|
|
698
|
+
// ── Registry home: open GLOBAL first (T11648) ──────────────────────────
|
|
699
|
+
// The registry/identity tables are global (ADR-090 §2.2). Opening the GLOBAL
|
|
700
|
+
// scope through the dual-scope chokepoint runs its consolidated migration,
|
|
701
|
+
// guaranteeing those tables (and their schema) physically exist before we
|
|
702
|
+
// ATTACH the global file into the project handle below. This is the same
|
|
703
|
+
// shared handle the global-tier siblings (skills/agent-registry) hold; we do
|
|
704
|
+
// NOT keep a reference to it — we only need its schema materialised on disk.
|
|
705
|
+
await openDualScopeDb('global');
|
|
706
|
+
// ── Graph home: open PROJECT scope as `main` (T11648 · ADR-090 §2.1/§2.4) ─
|
|
707
|
+
// openDualScopeDb('project') applies the pragma SSoT, creates the directory,
|
|
708
|
+
// runs the consolidated cleo-project migrations (which OWN the five PREFIXED
|
|
709
|
+
// graph tables), and manages the singleton cache. We pass NO cwd: the
|
|
710
|
+
// dual-scope resolver resolves the canonical project root via the
|
|
711
|
+
// `resolveCleoDir()` SSoT (CWD-walk / CLEO_DIR / worktree scope) — never a
|
|
712
|
+
// bare `process.cwd()` (T9584). Omitting the cwd also keeps the exodus-on-open
|
|
713
|
+
// hook un-armed, which is correct for the runtime READ path (exodus is a
|
|
714
|
+
// separate explicit step).
|
|
715
|
+
const dualHandle = await openDualScopeDb('project');
|
|
716
|
+
// Extract the underlying DatabaseSync. Drizzle exposes it via `$client`.
|
|
717
|
+
const nativeDb = dualHandle.db.$client ?? null;
|
|
718
|
+
if (!nativeDb) {
|
|
719
|
+
throw new Error('T11648: openDualScopeDb returned a handle without $client — ' +
|
|
720
|
+
'cannot extract DatabaseSync for the nexus-schema drizzle wrapping.');
|
|
721
|
+
}
|
|
416
722
|
_nexusNativeDb = nativeDb;
|
|
417
|
-
//
|
|
723
|
+
// ATTACH the GLOBAL `cleo.db` so the registry/identity tables resolve by
|
|
724
|
+
// their bare names via SQLite's fall-through (ADR-090 · T11648). Idempotent.
|
|
725
|
+
ensureGlobalRegistryAttached(nativeDb);
|
|
726
|
+
// Wrap the native handle with the `nexusSchema` drizzle instance so existing
|
|
727
|
+
// accessors (nexusSchema.* queries) run unchanged: graph tables resolve to
|
|
728
|
+
// the project `main`; registry/identity tables fall through to the attach.
|
|
418
729
|
const db = drizzle({ client: nativeDb, schema: nexusSchema });
|
|
419
|
-
//
|
|
730
|
+
// Apply the nexus DELTA migration + idempotent safety nets on top of the
|
|
731
|
+
// consolidated prefixed tables openDualScopeDb already created: the FTS5
|
|
732
|
+
// quartet, the `nexus_relation_weights` plasticity partition (incl. the
|
|
733
|
+
// inline-column DROP), and the `_nexus_meta` health-probe sentinel. The
|
|
734
|
+
// legacy drop/rebuild (`establishLegacyNexusSchema`) is GONE — the
|
|
735
|
+
// consolidated migration is the single SSoT for the base tables (T11578 · AC3).
|
|
420
736
|
runNexusMigrations(nativeDb, db);
|
|
421
737
|
// Seed schema version for new databases (no-op if already set)
|
|
422
738
|
nativeDb
|
|
@@ -434,46 +750,49 @@ export async function getNexusDb() {
|
|
|
434
750
|
}
|
|
435
751
|
}
|
|
436
752
|
/**
|
|
437
|
-
* Close the nexus
|
|
753
|
+
* Close the nexus-domain database connection and release resources.
|
|
754
|
+
*
|
|
755
|
+
* ## E6-L4 (T11524) · ADR-090 runtime read half (T11648)
|
|
756
|
+
*
|
|
757
|
+
* The nexus GRAPH domain now SHARES the consolidated PROJECT `cleo.db` handle
|
|
758
|
+
* with the other project-tier domains (tasks/brain/conduit — all open it via
|
|
759
|
+
* {@link openDualScopeDb}('project'), same cache key), with the GLOBAL `cleo.db`
|
|
760
|
+
* ATTACHed for registry/identity reads. This function therefore must NOT close
|
|
761
|
+
* the underlying `DatabaseSync` nor evict the dual-scope cache — doing so would
|
|
762
|
+
* break in-flight queries from those siblings with "database is not open". It
|
|
763
|
+
* only drops the nexus-domain singleton references; the shared handle's lifecycle
|
|
764
|
+
* (and the global ATTACH) is owned by `openDualScopeDb` and torn down by a
|
|
765
|
+
* coordinated reset (`closeAllDatabases` → `_resetDualScopeDbCache`).
|
|
438
766
|
*/
|
|
439
767
|
export function closeNexusDb() {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
_nexusNativeDb.close();
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
catch {
|
|
447
|
-
// Ignore close errors
|
|
448
|
-
}
|
|
449
|
-
_nexusNativeDb = null;
|
|
450
|
-
}
|
|
768
|
+
// Drop only the nexus singleton references. Do NOT close `_nexusNativeDb` — it
|
|
769
|
+
// is the shared dual-scope project handle, possibly still in use by siblings.
|
|
770
|
+
_nexusNativeDb = null;
|
|
451
771
|
_nexusDb = null;
|
|
452
772
|
_nexusDbPath = null;
|
|
773
|
+
_nexusRegistryPath = null;
|
|
774
|
+
_nexusInitPromise = null;
|
|
453
775
|
}
|
|
454
776
|
/**
|
|
455
|
-
* Reset nexus
|
|
456
|
-
* Used during tests or when database file is recreated.
|
|
777
|
+
* Reset nexus singleton state without saving.
|
|
778
|
+
* Used during tests or when the database file is recreated.
|
|
457
779
|
* Safe to call multiple times.
|
|
780
|
+
*
|
|
781
|
+
* ## E6-L4 (T11524) · ADR-090 runtime read half (T11648)
|
|
782
|
+
*
|
|
783
|
+
* Drops only the nexus-domain singleton references — does NOT close the shared
|
|
784
|
+
* dual-scope PROJECT `cleo.db` handle nor evict the dual-scope cache (that handle
|
|
785
|
+
* is shared with the other project-tier domains). Mirrors {@link closeNexusDb}.
|
|
458
786
|
*/
|
|
459
787
|
export function resetNexusDbState() {
|
|
460
|
-
|
|
461
|
-
try {
|
|
462
|
-
if (_nexusNativeDb.isOpen) {
|
|
463
|
-
_nexusNativeDb.close();
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
catch {
|
|
467
|
-
// Ignore close errors
|
|
468
|
-
}
|
|
469
|
-
_nexusNativeDb = null;
|
|
470
|
-
}
|
|
788
|
+
_nexusNativeDb = null;
|
|
471
789
|
_nexusDb = null;
|
|
472
790
|
_nexusDbPath = null;
|
|
791
|
+
_nexusRegistryPath = null;
|
|
473
792
|
_nexusInitPromise = null;
|
|
474
793
|
}
|
|
475
794
|
/**
|
|
476
|
-
* Get the underlying node:sqlite DatabaseSync instance for nexus.
|
|
795
|
+
* Get the underlying node:sqlite DatabaseSync instance for the nexus domain.
|
|
477
796
|
* Useful for direct PRAGMA calls or raw SQL operations.
|
|
478
797
|
* Returns null if the database hasn't been initialized.
|
|
479
798
|
*/
|