@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,30 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SQLite store for
|
|
2
|
+
* SQLite store for the project-scope BRAIN domain via drizzle-orm/node-sqlite +
|
|
3
|
+
* node:sqlite (DatabaseSync).
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* ## E6-L2 — thin-facade migration (T11522)
|
|
6
|
+
*
|
|
7
|
+
* `getBrainDb()` is now a thin facade that delegates the database open to
|
|
8
|
+
* {@link openDualScopeDb}('project', cwd) — the canonical dual-scope chokepoint
|
|
9
|
+
* introduced by E3/E4 (T11512/T11517) and already adopted by the tasks domain
|
|
10
|
+
* (E6-L1, T11521). This ensures:
|
|
11
|
+
*
|
|
12
|
+
* - Every brain-domain open flows through the single pragma SSoT (ADR-068/069).
|
|
13
|
+
* - The brain tables now live inside the consolidated project `cleo.db` — NOT a
|
|
14
|
+
* separate `brain.db` file — co-existing with `tasks_*` / `conduit_*` / etc.
|
|
15
|
+
* - DB Open Guard Gate 3 (`scripts/lint-no-direct-db-open.mjs`) stays green: the
|
|
16
|
+
* only native open is inside `dual-scope-db.ts`.
|
|
17
|
+
*
|
|
18
|
+
* The legacy `drizzle-brain` migrations are still applied to this handle during
|
|
19
|
+
* the E3→E6 transition (every brain migration is `CREATE TABLE IF NOT EXISTS` /
|
|
20
|
+
* additive `ALTER TABLE`, so re-applying onto the consolidated `cleo.db` is
|
|
21
|
+
* idempotent). This creates the legacy runtime-queried physical tables — most
|
|
22
|
+
* notably `deriver_queue` (unprefixed; the consolidated schema carries the
|
|
23
|
+
* prefixed `brain_deriver_queue`) — alongside the consolidated `brain_*` tables.
|
|
24
|
+
* The exodus migration (T11248) renames them; E6-L7/L8 remove the legacy ones.
|
|
25
|
+
*
|
|
26
|
+
* ## Post-hoc DDL removal (T11522 acceptance criteria)
|
|
27
|
+
*
|
|
28
|
+
* Every `ensureColumns` band-aid (~15) and raw `CREATE TABLE IF NOT EXISTS`
|
|
29
|
+
* (~8) that previously lived in {@link runBrainMigrations} has been removed. All
|
|
30
|
+
* of them were redundant safety-nets fully covered by the `drizzle-brain`
|
|
31
|
+
* migration files (the journal reconciler `probeAndMarkApplied` is robust enough
|
|
32
|
+
* to detect already-applied DDL — see migration-manager.ts, T632). The ONE table
|
|
33
|
+
* with no migration anywhere — `brain_task_observations` (T1615, a runtime-only
|
|
34
|
+
* join cache mapped to `null` by exodus) — was converted to a forward Drizzle
|
|
35
|
+
* migration under `migrations/drizzle-cleo-project/20260601000002_t11522-brain-task-observations`,
|
|
36
|
+
* matching the T9179 precedent (ensureColumns → forward migration).
|
|
7
37
|
*
|
|
8
38
|
* @epic T5149
|
|
9
39
|
* @task T5128
|
|
40
|
+
* @task T11522 - E6-L2: route getBrainDb through openDualScopeDb (SG-DB-SUBSTRATE-V2)
|
|
10
41
|
*/
|
|
11
|
-
import { mkdirSync } from 'node:fs';
|
|
12
42
|
import { createRequire } from 'node:module';
|
|
13
|
-
|
|
14
|
-
|
|
43
|
+
// E6-L2 (T11522): dual-scope chokepoint — the brain domain now opens the
|
|
44
|
+
// consolidated project `cleo.db` through here. openDualScopeDb manages the
|
|
45
|
+
// DatabaseSync lifecycle, pragmas, and consolidated migrations. We extract the
|
|
46
|
+
// native handle and re-wrap it with the legacy brain-schema drizzle instance so
|
|
47
|
+
// existing callers (brainSchema.* queries) compile and run without change.
|
|
15
48
|
import { getLogger } from '../logger.js';
|
|
16
|
-
import {
|
|
17
|
-
import { createSafetyBackup,
|
|
18
|
-
import { recoverMalformedBrainDb } from './recover-brain-db.js';
|
|
49
|
+
import { openDualScopeDb, resolveDualScopeDbPath } from './dual-scope-db.js';
|
|
50
|
+
import { createSafetyBackup, migrateWithRetry, reconcileBrainMigrationsForConsolidatedDb, reconcileJournal, tableExists, } from './migration-manager.js';
|
|
19
51
|
import { resolveCorePackageMigrationsFolder } from './resolve-migrations-folder.js';
|
|
20
52
|
import * as brainSchema from './schema/memory-schema.js';
|
|
21
|
-
// Import openNativeDatabase directly from the leaf module (sqlite-native.ts) to
|
|
22
|
-
// avoid any static import from sqlite.ts that could re-enter the circular chain
|
|
23
|
-
// agent-resolver → ... → memory-sqlite → sqlite.ts (T1325/T1331 v3).
|
|
24
|
-
import { openNativeDatabase } from './sqlite-native.js';
|
|
25
53
|
const _require = createRequire(import.meta.url);
|
|
26
|
-
/**
|
|
27
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Cached `drizzle` factory from `drizzle-orm/node-sqlite`, loaded on first use.
|
|
56
|
+
*
|
|
57
|
+
* Loaded via `createRequire` rather than a top-level import so that importing
|
|
58
|
+
* `memory-sqlite.ts` does not eagerly pull in `node:sqlite` (which the drizzle
|
|
59
|
+
* driver statically imports). Memoized after the first call. Mirrors the
|
|
60
|
+
* `_getDrizzle` lazy pattern in sqlite.ts (T11280/T11521).
|
|
61
|
+
*
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
let _drizzle = null;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the `drizzle` factory, loading `drizzle-orm/node-sqlite` on first call.
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
* @task T11522
|
|
70
|
+
*/
|
|
71
|
+
function _getDrizzle() {
|
|
72
|
+
if (_drizzle === null) {
|
|
73
|
+
const mod = _require('drizzle-orm/node-sqlite');
|
|
74
|
+
_drizzle = mod.drizzle;
|
|
75
|
+
}
|
|
76
|
+
return _drizzle;
|
|
77
|
+
}
|
|
28
78
|
/** Schema version for newly created brain databases. Single source of truth. */
|
|
29
79
|
export const BRAIN_SCHEMA_VERSION = '1.0.0';
|
|
30
80
|
/** Singleton state for lazy initialization. */
|
|
@@ -36,10 +86,18 @@ let _initPromise = null;
|
|
|
36
86
|
/** Whether sqlite-vec extension loaded successfully. */
|
|
37
87
|
let _vecLoaded = false;
|
|
38
88
|
/**
|
|
39
|
-
* Get the path to the brain
|
|
89
|
+
* Get the path to the brain-domain SQLite database file.
|
|
90
|
+
*
|
|
91
|
+
* ## E6-L2 (T11522)
|
|
92
|
+
*
|
|
93
|
+
* After the dual-scope migration, `getBrainDb()` opens the consolidated project
|
|
94
|
+
* `cleo.db` via {@link openDualScopeDb} — not the legacy standalone `brain.db`.
|
|
95
|
+
* This function therefore returns the dual-scope `cleo.db` path so that callers
|
|
96
|
+
* checking for the file `getBrainDb()` created (existence / backup / health
|
|
97
|
+
* probes) point at the correct file.
|
|
40
98
|
*/
|
|
41
99
|
export function getBrainDbPath(cwd) {
|
|
42
|
-
return
|
|
100
|
+
return resolveDualScopeDbPath('project', cwd);
|
|
43
101
|
}
|
|
44
102
|
/**
|
|
45
103
|
* Resolve the absolute path to the drizzle-brain migrations folder inside
|
|
@@ -53,373 +111,172 @@ export function resolveBrainMigrationsFolder() {
|
|
|
53
111
|
return resolveCorePackageMigrationsFolder('drizzle-brain');
|
|
54
112
|
}
|
|
55
113
|
// tableExists — delegated to migration-manager.ts (T132)
|
|
114
|
+
//
|
|
115
|
+
// E6-L2 (T11522): the legacy `runBrainMigrations` helper that ran the
|
|
116
|
+
// `drizzle-brain` migration folder (with ~15 ensureColumns + ~8 raw CREATE TABLE
|
|
117
|
+
// band-aids). After getBrainDb() routes through openDualScopeDb('project'), the
|
|
118
|
+
// brain domain is served from the consolidated `cleo.db`. See
|
|
119
|
+
// `establishLegacyBrainSchema` below for why the runtime keeps the LEGACY brain
|
|
120
|
+
// table shape during the E3→E6 transition.
|
|
56
121
|
/**
|
|
57
|
-
*
|
|
122
|
+
* The set of brain-domain physical tables the T11363 consolidation migration
|
|
123
|
+
* creates in the project `cleo.db`. Each is dropped + recreated in its LEGACY
|
|
124
|
+
* runtime shape by {@link establishLegacyBrainSchema} (see that function for the
|
|
125
|
+
* rationale). `deriver_queue` is included because the legacy `t1145` migration
|
|
126
|
+
* creates it (unprefixed) and we must clear any prior shape first.
|
|
58
127
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
128
|
+
* @internal
|
|
129
|
+
* @task T11522
|
|
130
|
+
*/
|
|
131
|
+
const CONSOLIDATED_BRAIN_TABLES = [
|
|
132
|
+
'brain_attention',
|
|
133
|
+
'brain_backfill_runs',
|
|
134
|
+
'brain_consolidation_events',
|
|
135
|
+
'brain_decisions',
|
|
136
|
+
'brain_deriver_queue',
|
|
137
|
+
'brain_embeddings',
|
|
138
|
+
'brain_learnings',
|
|
139
|
+
'brain_memory_links',
|
|
140
|
+
'brain_memory_trees',
|
|
141
|
+
'brain_modulators',
|
|
142
|
+
'brain_observations',
|
|
143
|
+
'brain_observations_staging',
|
|
144
|
+
'brain_page_edges',
|
|
145
|
+
'brain_page_nodes',
|
|
146
|
+
'brain_patterns',
|
|
147
|
+
'brain_plasticity_events',
|
|
148
|
+
'brain_promotion_log',
|
|
149
|
+
'brain_retrieval_log',
|
|
150
|
+
'brain_schema_meta',
|
|
151
|
+
'brain_session_narrative',
|
|
152
|
+
'brain_sticky_notes',
|
|
153
|
+
'brain_sticky_tags',
|
|
154
|
+
'brain_transcript_events',
|
|
155
|
+
'brain_usage_log',
|
|
156
|
+
'brain_weight_history',
|
|
157
|
+
];
|
|
158
|
+
/**
|
|
159
|
+
* Detect whether the brain tables in the open handle carry the CONSOLIDATED
|
|
160
|
+
* (exodus-target) shape rather than the LEGACY runtime shape.
|
|
61
161
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
162
|
+
* The consolidation migration (T11363) types `brain_attention.created_at` as
|
|
163
|
+
* `text` (ISO-8601, with a GLOB CHECK constraint); the legacy runtime schema
|
|
164
|
+
* (`memory-schema.ts`) types it as `integer` (epoch-ms, `unixepoch() * 1000`).
|
|
165
|
+
* The column affinity is therefore a reliable, cheap discriminator.
|
|
166
|
+
*
|
|
167
|
+
* @internal
|
|
168
|
+
* @task T11522
|
|
169
|
+
*/
|
|
170
|
+
function brainTablesAreConsolidatedShape(nativeDb) {
|
|
171
|
+
if (!tableExists(nativeDb, 'brain_attention'))
|
|
172
|
+
return false;
|
|
173
|
+
const cols = nativeDb.prepare('PRAGMA table_info(brain_attention)').all();
|
|
174
|
+
const createdAt = cols.find((c) => c.name === 'created_at');
|
|
175
|
+
// Legacy = INTEGER; consolidated target = TEXT. Anything non-INTEGER means we
|
|
176
|
+
// are looking at the consolidated target shape and must rebuild to legacy.
|
|
177
|
+
return createdAt !== undefined && createdAt.type.toUpperCase() !== 'INTEGER';
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Establish the LEGACY brain-domain schema inside the consolidated project
|
|
181
|
+
* `cleo.db`, replacing the consolidated (exodus-target) brain tables.
|
|
182
|
+
*
|
|
183
|
+
* ## Why (T11522 · E6-L2)
|
|
184
|
+
*
|
|
185
|
+
* Routing `getBrainDb()` through {@link openDualScopeDb} runs the T11363
|
|
186
|
+
* consolidation migration, which creates every `brain_*` table in its
|
|
187
|
+
* **exodus-target** shape: ISO-8601 `text` timestamps and enum/format `CHECK`
|
|
188
|
+
* constraints (e.g. `brain_attention.created_at GLOB '[0-9][0-9][0-9][0-9]-…'`,
|
|
189
|
+
* `brain_page_nodes.node_type IN (…)`). The runtime brain writers and the
|
|
190
|
+
* `brainSchema` (`memory-schema.ts`) still use the **legacy** shape — epoch-ms
|
|
191
|
+
* `integer` timestamps and no enum CHECKs — exactly as the tasks domain keeps
|
|
192
|
+
* using the legacy `tasks` table after E6-L1.
|
|
193
|
+
*
|
|
194
|
+
* Unlike tasks (legacy `tasks` ≠ consolidated `tasks_tasks`, so both co-exist),
|
|
195
|
+
* the brain tables were already domain-prefixed, so legacy and consolidated
|
|
196
|
+
* share the SAME physical names — they cannot co-exist. The runtime must win, so
|
|
197
|
+
* on first open we drop the consolidated brain tables and run the legacy
|
|
198
|
+
* `drizzle-brain` migrations to recreate them in the runtime shape. The
|
|
199
|
+
* consolidated-target cutover (epoch→ISO conversion, CHECK constraints) is the
|
|
200
|
+
* exodus's job — see T11248 / exodus-on-open T11553, which migrate the standalone
|
|
201
|
+
* legacy `brain.db` into `cleo.db`.
|
|
202
|
+
*
|
|
203
|
+
* Idempotent: after the first rebuild the tables are already legacy-shaped, so
|
|
204
|
+
* {@link brainTablesAreConsolidatedShape} returns `false` and this is a no-op
|
|
205
|
+
* (the `drizzle-brain` journal is reconciled, nothing is dropped).
|
|
206
|
+
*
|
|
207
|
+
* @internal
|
|
208
|
+
* @task T11522
|
|
64
209
|
*/
|
|
65
|
-
function
|
|
210
|
+
function establishLegacyBrainSchema(nativeDb, db) {
|
|
211
|
+
const log = getLogger('brain-schema');
|
|
212
|
+
if (brainTablesAreConsolidatedShape(nativeDb)) {
|
|
213
|
+
// Drop the consolidated (exodus-target) brain tables so the legacy
|
|
214
|
+
// `drizzle-brain` migrations can recreate them in the runtime shape.
|
|
215
|
+
// `brain_embeddings` is a vec0 virtual table once the extension is loaded;
|
|
216
|
+
// DROP TABLE handles both regular and virtual tables when sqlite-vec is
|
|
217
|
+
// present. Disable FKs during the drop so cross-table references do not
|
|
218
|
+
// block the teardown — then RESTORE the prior pragma state (the dual-scope
|
|
219
|
+
// pragma SSoT enables foreign_keys; leaving it OFF would break the
|
|
220
|
+
// idempotent-pragma contract, T10314).
|
|
221
|
+
const fkRow = nativeDb.prepare('PRAGMA foreign_keys').get();
|
|
222
|
+
const fkWasOn = fkRow?.foreign_keys === 1;
|
|
223
|
+
nativeDb.exec('PRAGMA foreign_keys=OFF');
|
|
224
|
+
try {
|
|
225
|
+
for (const table of CONSOLIDATED_BRAIN_TABLES) {
|
|
226
|
+
try {
|
|
227
|
+
nativeDb.exec(`DROP TABLE IF EXISTS \`${table}\``);
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
log.warn({ table, err }, 'Failed to drop consolidated brain table during legacy rebuild.');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
// Restore the pragma to its pre-drop state (ON under the dual-scope SSoT).
|
|
236
|
+
nativeDb.exec(`PRAGMA foreign_keys=${fkWasOn ? 'ON' : 'OFF'}`);
|
|
237
|
+
}
|
|
238
|
+
log.debug({ count: CONSOLIDATED_BRAIN_TABLES.length }, 'Dropped consolidated (exodus-target) brain tables — rebuilding in legacy runtime shape.');
|
|
239
|
+
}
|
|
66
240
|
const migrationsFolder = resolveBrainMigrationsFolder();
|
|
67
|
-
//
|
|
241
|
+
// T11647 — CONSOLIDATED `cleo.db` path. The consolidated `drizzle-cleo-project`
|
|
242
|
+
// / `drizzle-cleo-global` migration already created every DOMAIN-PREFIXED
|
|
243
|
+
// `brain_*` table in the LEGACY RUNTIME shape (the exodus target was aligned to
|
|
244
|
+
// the runtime shape — see `cleo-shared/brain.ts`), so `brain_decisions` exists
|
|
245
|
+
// and `brainTablesAreConsolidatedShape` is false (no DROP fired above). The
|
|
246
|
+
// standalone `drizzle-brain` migrations must NOT be re-run wholesale: their
|
|
247
|
+
// non-`IF NOT EXISTS` `CREATE TABLE`s / table-rebuilds for already-present
|
|
248
|
+
// prefixed tables (e.g. `brain_observations_staging`) and their ALTER-ADD-COLUMN
|
|
249
|
+
// for already-present columns would collide.
|
|
250
|
+
if (tableExists(nativeDb, 'brain_decisions') && !brainTablesAreConsolidatedShape(nativeDb)) {
|
|
251
|
+
// Additive reconcile-and-apply: for each not-yet-journaled `drizzle-brain`
|
|
252
|
+
// migration, mark-applied-without-running when its net effect is already
|
|
253
|
+
// present (the prefixed `brain_*` tables + their final columns the
|
|
254
|
+
// consolidated migration created), else exec it directly (the UNPREFIXED
|
|
255
|
+
// runtime tables `deriver_queue`/`sticky_tags`/`session_narrative`/
|
|
256
|
+
// `brain_task_observations` the consolidated migration omits but the runtime
|
|
257
|
+
// queries). This NEVER deletes a journal row and never engages drizzle's
|
|
258
|
+
// shared-handle transaction, so it cannot corrupt the tasks-domain journal
|
|
259
|
+
// entries that share this consolidated `cleo.db`'s `__drizzle_migrations` —
|
|
260
|
+
// see reconcileBrainMigrationsForConsolidatedDb for the full rationale. The
|
|
261
|
+
// exodus-migrated rows in the prefixed tables survive untouched (the
|
|
262
|
+
// data-loss fix).
|
|
263
|
+
const { marked, applied } = reconcileBrainMigrationsForConsolidatedDb(nativeDb, migrationsFolder);
|
|
264
|
+
log.debug({ marked, applied }, 'brain consolidated cleo.db reconcile (T11647) — marked already-present migrations applied + executed the missing unprefixed-table migrations directly.');
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// LEGACY standalone `brain.db` (or brand-new DB) path: no prefixed brain tables
|
|
268
|
+
// pre-created, so run the full `drizzle-brain` migrate via the generic
|
|
269
|
+
// reconcile (its Scenario-2 orphan-delete is safe here — a standalone brain.db
|
|
270
|
+
// journal contains only brain hashes).
|
|
68
271
|
if (tableExists(nativeDb, 'brain_decisions') && _dbPath) {
|
|
69
272
|
createSafetyBackup(_dbPath);
|
|
70
273
|
}
|
|
71
|
-
// Bootstrap baseline + reconcile stale journal entries
|
|
72
274
|
reconcileJournal(nativeDb, migrationsFolder, 'brain_decisions', 'brain');
|
|
73
|
-
// Run pending migrations with SQLITE_BUSY retry.
|
|
74
|
-
// Pass nativeDb + existenceTable so migrateWithRetry can auto-reconcile any
|
|
75
|
-
// partial migration (Scenario 3) that slips through the proactive check above.
|
|
76
275
|
migrateWithRetry(db, migrationsFolder, nativeDb, 'brain_decisions', 'brain');
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
// now run correctly when their columns are missing — the reconciler leaves them
|
|
82
|
-
// unjournaled so Drizzle's migrate() runs the DDL.
|
|
83
|
-
//
|
|
84
|
-
// The ensureColumns band-aids for T528/T531/T549 were removed here as part of
|
|
85
|
-
// T632 because all their columns are covered by Drizzle migration files. If a
|
|
86
|
-
// schema regression recurs, debug probeAndMarkApplied in migration-manager.ts —
|
|
87
|
-
// do NOT add new band-aids here.
|
|
88
|
-
//
|
|
89
|
-
// ensureColumns below are retained ONLY for columns that have NO corresponding
|
|
90
|
-
// Drizzle migration file (self-healing DDL only — see each comment).
|
|
91
|
-
// T626-M1: Normalize co_retrieved edge type — idempotent safety-net UPDATE.
|
|
92
|
-
// The shipped Hebbian strengthener emitted edge_type = 'relates_to' instead of
|
|
93
|
-
// 'co_retrieved'. Relabel only rows from the consolidation provenance so no
|
|
94
|
-
// semantic edges are affected. The Drizzle migration file does the same UPDATE;
|
|
95
|
-
// this guard handles installs where the journal reconciler already marked
|
|
96
|
-
// the migration applied before the SQL ran.
|
|
97
|
-
//
|
|
98
|
-
// T759: Guard provenance column existence before UPDATE. If T528 migration has
|
|
99
|
-
// not yet run (e.g. on a fresh install where only the initial migration is
|
|
100
|
-
// present), brain_page_edges will not have a provenance column and the UPDATE
|
|
101
|
-
// will throw "no such column: provenance". ensureColumns adds the column if
|
|
102
|
-
// missing so the UPDATE is always safe to execute.
|
|
103
|
-
if (tableExists(nativeDb, 'brain_page_edges')) {
|
|
104
|
-
ensureColumns(nativeDb, 'brain_page_edges', [{ name: 'provenance', ddl: 'text' }], 'brain');
|
|
105
|
-
nativeDb
|
|
106
|
-
.prepare(`UPDATE brain_page_edges
|
|
107
|
-
SET edge_type = 'co_retrieved'
|
|
108
|
-
WHERE edge_type = 'relates_to'
|
|
109
|
-
AND provenance LIKE 'consolidation:%'`)
|
|
110
|
-
.run();
|
|
111
|
-
}
|
|
112
|
-
// T673-M1: STDP plasticity columns on brain_retrieval_log.
|
|
113
|
-
// session_id was declared in the Drizzle schema but never applied to the live table.
|
|
114
|
-
// reward_signal, retrieval_order, delta_ms are new additions per spec §2.1.1.
|
|
115
|
-
if (tableExists(nativeDb, 'brain_retrieval_log')) {
|
|
116
|
-
ensureColumns(nativeDb, 'brain_retrieval_log', [
|
|
117
|
-
{ name: 'session_id', ddl: 'text' },
|
|
118
|
-
{ name: 'reward_signal', ddl: 'real' },
|
|
119
|
-
{ name: 'retrieval_order', ddl: 'integer' },
|
|
120
|
-
{ name: 'delta_ms', ddl: 'integer' },
|
|
121
|
-
], 'brain');
|
|
122
|
-
}
|
|
123
|
-
// T673-M2: observability columns on brain_plasticity_events
|
|
124
|
-
// session_id is declared in Drizzle schema and included in M2 CREATE TABLE IF NOT EXISTS,
|
|
125
|
-
// but may be missing from installs where the table was created before M2.
|
|
126
|
-
if (tableExists(nativeDb, 'brain_plasticity_events')) {
|
|
127
|
-
ensureColumns(nativeDb, 'brain_plasticity_events', [
|
|
128
|
-
{ name: 'session_id', ddl: 'text' },
|
|
129
|
-
{ name: 'weight_before', ddl: 'real' },
|
|
130
|
-
{ name: 'weight_after', ddl: 'real' },
|
|
131
|
-
{ name: 'retrieval_log_id', ddl: 'integer' },
|
|
132
|
-
{ name: 'reward_signal', ddl: 'real' },
|
|
133
|
-
{ name: 'delta_t_ms', ddl: 'integer' },
|
|
134
|
-
], 'brain');
|
|
135
|
-
}
|
|
136
|
-
// T673-M3: plasticity tracking columns on brain_page_edges
|
|
137
|
-
ensureColumns(nativeDb, 'brain_page_edges', [
|
|
138
|
-
{ name: 'last_reinforced_at', ddl: 'text' },
|
|
139
|
-
{ name: 'reinforcement_count', ddl: 'integer NOT NULL DEFAULT 0' },
|
|
140
|
-
{ name: 'plasticity_class', ddl: "text NOT NULL DEFAULT 'static'" },
|
|
141
|
-
{ name: 'last_depressed_at', ddl: 'text' },
|
|
142
|
-
{ name: 'depression_count', ddl: 'integer NOT NULL DEFAULT 0' },
|
|
143
|
-
{ name: 'stability_score', ddl: 'real' },
|
|
144
|
-
], 'brain');
|
|
145
|
-
// T673-M3: seed co_retrieved edges as hebbian (idempotent)
|
|
146
|
-
if (tableExists(nativeDb, 'brain_page_edges')) {
|
|
147
|
-
nativeDb
|
|
148
|
-
.prepare(`UPDATE brain_page_edges SET plasticity_class = 'hebbian'
|
|
149
|
-
WHERE edge_type = 'co_retrieved' AND plasticity_class = 'static'`)
|
|
150
|
-
.run();
|
|
151
|
-
}
|
|
152
|
-
// T673-M4: new plasticity infrastructure tables — self-healing CREATE IF NOT EXISTS.
|
|
153
|
-
// These guards ensure the tables exist even on installs where the Drizzle migration
|
|
154
|
-
// journal was already partially applied. All three tables are CREATE IF NOT EXISTS
|
|
155
|
-
// so re-running is safe.
|
|
156
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_weight_history (
|
|
157
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
158
|
-
edge_from_id TEXT NOT NULL,
|
|
159
|
-
edge_to_id TEXT NOT NULL,
|
|
160
|
-
edge_type TEXT NOT NULL,
|
|
161
|
-
weight_before REAL,
|
|
162
|
-
weight_after REAL NOT NULL,
|
|
163
|
-
delta_weight REAL NOT NULL,
|
|
164
|
-
event_kind TEXT NOT NULL,
|
|
165
|
-
source_plasticity_event_id INTEGER,
|
|
166
|
-
retrieval_log_id INTEGER,
|
|
167
|
-
reward_signal REAL,
|
|
168
|
-
changed_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
169
|
-
)`);
|
|
170
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_weight_history_edge
|
|
171
|
-
ON brain_weight_history (edge_from_id, edge_to_id, edge_type)`);
|
|
172
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_weight_history_changed_at
|
|
173
|
-
ON brain_weight_history (changed_at)`);
|
|
174
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_modulators (
|
|
175
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
176
|
-
modulator_type TEXT NOT NULL,
|
|
177
|
-
valence REAL NOT NULL,
|
|
178
|
-
magnitude REAL NOT NULL DEFAULT 1.0,
|
|
179
|
-
source_event_id TEXT,
|
|
180
|
-
session_id TEXT,
|
|
181
|
-
description TEXT,
|
|
182
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
183
|
-
)`);
|
|
184
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_modulators_session
|
|
185
|
-
ON brain_modulators (session_id)`);
|
|
186
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_consolidation_events (
|
|
187
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
188
|
-
trigger TEXT NOT NULL,
|
|
189
|
-
session_id TEXT,
|
|
190
|
-
step_results_json TEXT NOT NULL,
|
|
191
|
-
duration_ms INTEGER,
|
|
192
|
-
succeeded INTEGER NOT NULL DEFAULT 1,
|
|
193
|
-
started_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
194
|
-
)`);
|
|
195
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_consolidation_events_started_at
|
|
196
|
-
ON brain_consolidation_events (started_at)`);
|
|
197
|
-
// T1002: brain_transcript_events — full-fidelity Claude session block store.
|
|
198
|
-
// CREATE IF NOT EXISTS so re-runs on existing databases are safe.
|
|
199
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_transcript_events (
|
|
200
|
-
id TEXT PRIMARY KEY,
|
|
201
|
-
session_id TEXT NOT NULL,
|
|
202
|
-
seq INTEGER NOT NULL,
|
|
203
|
-
role TEXT NOT NULL,
|
|
204
|
-
block_type TEXT NOT NULL,
|
|
205
|
-
content TEXT NOT NULL,
|
|
206
|
-
tokens INTEGER,
|
|
207
|
-
redacted_at TEXT,
|
|
208
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
209
|
-
)`);
|
|
210
|
-
nativeDb.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_transcript_events_session_seq
|
|
211
|
-
ON brain_transcript_events (session_id, seq)`);
|
|
212
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_transcript_events_session
|
|
213
|
-
ON brain_transcript_events (session_id)`);
|
|
214
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_transcript_events_role
|
|
215
|
-
ON brain_transcript_events (role)`);
|
|
216
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_transcript_events_block_type
|
|
217
|
-
ON brain_transcript_events (block_type)`);
|
|
218
|
-
// T1001: stability_score column on brain_observations (distinct from brain_page_edges.stability_score).
|
|
219
|
-
// Added via ensureColumns — idempotent, safe on existing databases.
|
|
220
|
-
ensureColumns(nativeDb, 'brain_observations', [{ name: 'stability_score', ddl: 'real DEFAULT 0.5' }], 'brain');
|
|
221
|
-
// T1084: PSYCHE Wave 2 — peer_id + peer_scope on all four brain memory tables.
|
|
222
|
-
// Drizzle migration 20260423000001_t1084-peer-id-memory-isolation handles fresh installs.
|
|
223
|
-
// ensureColumns here is the safety-net for installs where the migration journal was
|
|
224
|
-
// already partially applied or the journal reconciler skips DDL-only migrations.
|
|
225
|
-
// Both columns are NOT NULL with a DEFAULT so the ALTER is safe on non-empty tables.
|
|
226
|
-
const peerColumns = [
|
|
227
|
-
{ name: 'peer_id', ddl: "text NOT NULL DEFAULT 'global'" },
|
|
228
|
-
{ name: 'peer_scope', ddl: "text NOT NULL DEFAULT 'project'" },
|
|
229
|
-
];
|
|
230
|
-
ensureColumns(nativeDb, 'brain_decisions', peerColumns, 'brain');
|
|
231
|
-
ensureColumns(nativeDb, 'brain_patterns', peerColumns, 'brain');
|
|
232
|
-
ensureColumns(nativeDb, 'brain_learnings', peerColumns, 'brain');
|
|
233
|
-
ensureColumns(nativeDb, 'brain_observations', peerColumns, 'brain');
|
|
234
|
-
// Companion indexes — idempotent CREATE INDEX IF NOT EXISTS.
|
|
235
|
-
for (const [table, idxName] of [
|
|
236
|
-
['brain_decisions', 'idx_brain_decisions_peer_scope'],
|
|
237
|
-
['brain_patterns', 'idx_brain_patterns_peer_scope'],
|
|
238
|
-
['brain_learnings', 'idx_brain_learnings_peer_scope'],
|
|
239
|
-
['brain_observations', 'idx_brain_observations_peer_scope'],
|
|
240
|
-
]) {
|
|
241
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS ${idxName} ON ${table} (peer_id, peer_scope)`);
|
|
242
|
-
}
|
|
243
|
-
// T1260: PSYCHE E3 — provenance_class on all four brain memory tables (M6 refusal gate).
|
|
244
|
-
// Drizzle migration 20260424000001_t1260-provenance-class handles fresh installs.
|
|
245
|
-
// ensureColumns here is the safety-net for installs where the journal reconciler
|
|
246
|
-
// already marked prior migrations applied before this column was added, or where
|
|
247
|
-
// the test runner uses a module-cached DB from before the migration ran.
|
|
248
|
-
const provenanceColumn = [{ name: 'provenance_class', ddl: "text DEFAULT 'swept-clean'" }];
|
|
249
|
-
ensureColumns(nativeDb, 'brain_decisions', provenanceColumn, 'brain');
|
|
250
|
-
ensureColumns(nativeDb, 'brain_patterns', provenanceColumn, 'brain');
|
|
251
|
-
ensureColumns(nativeDb, 'brain_learnings', provenanceColumn, 'brain');
|
|
252
|
-
ensureColumns(nativeDb, 'brain_observations', provenanceColumn, 'brain');
|
|
253
|
-
// T1826: Decision Storage Consolidation — ADR tracking + governance columns.
|
|
254
|
-
// Drizzle migration 20260504000001_t1826-decisions-v2 handles fresh installs, BUT
|
|
255
|
-
// node:sqlite's prepare() only executes the first SQL statement when multiple
|
|
256
|
-
// statements are joined without "--> statement-breakpoint" separators. The migration
|
|
257
|
-
// file has 7+ ALTER TABLE statements with no breakpoints, so only adr_number gets
|
|
258
|
-
// applied by Drizzle. ensureColumns here is the safety-net that guarantees all 7
|
|
259
|
-
// new columns exist, matching the pattern used by T1084, T1260, T1145, etc.
|
|
260
|
-
ensureColumns(nativeDb, 'brain_decisions', [
|
|
261
|
-
{ name: 'adr_number', ddl: 'integer' },
|
|
262
|
-
{ name: 'adr_path', ddl: 'text' },
|
|
263
|
-
{ name: 'supersedes', ddl: 'text' },
|
|
264
|
-
{ name: 'superseded_by', ddl: 'text' },
|
|
265
|
-
{ name: 'confirmation_state', ddl: "text NOT NULL DEFAULT 'proposed'" },
|
|
266
|
-
{ name: 'decided_by', ddl: "text NOT NULL DEFAULT 'agent'" },
|
|
267
|
-
{ name: 'validator_run_at', ddl: 'integer' },
|
|
268
|
-
], 'brain');
|
|
269
|
-
// T1826: Idempotent companion indexes for the new columns.
|
|
270
|
-
nativeDb.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_brain_decisions_adr_number
|
|
271
|
-
ON brain_decisions(adr_number)
|
|
272
|
-
WHERE adr_number IS NOT NULL`);
|
|
273
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_decisions_confirmation_state
|
|
274
|
-
ON brain_decisions(confirmation_state)`);
|
|
275
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_decisions_decided_by
|
|
276
|
-
ON brain_decisions(decided_by)`);
|
|
277
|
-
// T1001: brain_promotion_log — typed promotion audit trail.
|
|
278
|
-
// One row per observation evaluated (and promoted) by promoteObservationsToTyped().
|
|
279
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_promotion_log (
|
|
280
|
-
id TEXT PRIMARY KEY,
|
|
281
|
-
observation_id TEXT NOT NULL,
|
|
282
|
-
from_tier TEXT NOT NULL,
|
|
283
|
-
to_tier TEXT NOT NULL,
|
|
284
|
-
score REAL NOT NULL,
|
|
285
|
-
decided_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
286
|
-
decided_by TEXT NOT NULL DEFAULT 'composite-scorer',
|
|
287
|
-
rationale_json TEXT,
|
|
288
|
-
fulfilled_at TEXT,
|
|
289
|
-
fulfillment_note TEXT
|
|
290
|
-
)`);
|
|
291
|
-
// T1903: migrate existing brain_promotion_log tables to add fulfillment columns (idempotent).
|
|
292
|
-
try {
|
|
293
|
-
nativeDb.exec(`ALTER TABLE brain_promotion_log ADD COLUMN fulfilled_at TEXT`);
|
|
294
|
-
}
|
|
295
|
-
catch {
|
|
296
|
-
/* column already exists */
|
|
297
|
-
}
|
|
298
|
-
try {
|
|
299
|
-
nativeDb.exec(`ALTER TABLE brain_promotion_log ADD COLUMN fulfillment_note TEXT`);
|
|
300
|
-
}
|
|
301
|
-
catch {
|
|
302
|
-
/* column already exists */
|
|
303
|
-
}
|
|
304
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_promotion_log_observation
|
|
305
|
-
ON brain_promotion_log (observation_id)`);
|
|
306
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_promotion_log_decided_at
|
|
307
|
-
ON brain_promotion_log (decided_at)`);
|
|
308
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_promotion_log_to_tier
|
|
309
|
-
ON brain_promotion_log (to_tier)`);
|
|
310
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_promotion_log_score
|
|
311
|
-
ON brain_promotion_log (score)`);
|
|
312
|
-
// T1003: brain_backfill_runs — staged backfill audit log.
|
|
313
|
-
// CREATE IF NOT EXISTS so re-runs on existing databases are safe.
|
|
314
|
-
// Staged rows are held in rollback_snapshot_json until approved/rolled-back.
|
|
315
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_backfill_runs (
|
|
316
|
-
id TEXT PRIMARY KEY,
|
|
317
|
-
kind TEXT NOT NULL,
|
|
318
|
-
status TEXT NOT NULL DEFAULT 'staged',
|
|
319
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
320
|
-
approved_at TEXT,
|
|
321
|
-
rows_affected INTEGER NOT NULL DEFAULT 0,
|
|
322
|
-
rollback_snapshot_json TEXT,
|
|
323
|
-
source TEXT NOT NULL DEFAULT 'unknown',
|
|
324
|
-
target_table TEXT NOT NULL DEFAULT 'brain_observations',
|
|
325
|
-
approved_by TEXT
|
|
326
|
-
)`);
|
|
327
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_backfill_runs_status
|
|
328
|
-
ON brain_backfill_runs (status)`);
|
|
329
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_backfill_runs_kind
|
|
330
|
-
ON brain_backfill_runs (kind)`);
|
|
331
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_backfill_runs_created_at
|
|
332
|
-
ON brain_backfill_runs (created_at)`);
|
|
333
|
-
// T1145: Wave 5 Deriver Queue — deriver lineage + level columns on brain_observations.
|
|
334
|
-
// Drizzle migration 20260424000003_t1145-extend-brain-observations handles fresh installs.
|
|
335
|
-
// ensureColumns here is the safety-net for test DBs and existing installs where the
|
|
336
|
-
// journal reconciler may skip the ALTER TABLE migration.
|
|
337
|
-
ensureColumns(nativeDb, 'brain_observations', [
|
|
338
|
-
{ name: 'source_ids', ddl: 'text' },
|
|
339
|
-
{ name: 'times_derived', ddl: 'integer DEFAULT 1' },
|
|
340
|
-
{ name: 'level', ddl: "text DEFAULT 'explicit'" },
|
|
341
|
-
{ name: 'tree_id', ddl: 'integer' },
|
|
342
|
-
], 'brain');
|
|
343
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_observations_level ON brain_observations (level)`);
|
|
344
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_observations_tree_id ON brain_observations (tree_id)`);
|
|
345
|
-
// T1145: deriver_queue — durable background derivation work queue.
|
|
346
|
-
// CREATE IF NOT EXISTS so re-runs on existing databases are safe.
|
|
347
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS deriver_queue (
|
|
348
|
-
id TEXT PRIMARY KEY,
|
|
349
|
-
item_type TEXT NOT NULL,
|
|
350
|
-
item_id TEXT NOT NULL,
|
|
351
|
-
priority INTEGER NOT NULL DEFAULT 0,
|
|
352
|
-
status TEXT NOT NULL DEFAULT 'pending',
|
|
353
|
-
claimed_at TEXT,
|
|
354
|
-
claimed_by TEXT,
|
|
355
|
-
error_msg TEXT,
|
|
356
|
-
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
357
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
358
|
-
completed_at TEXT
|
|
359
|
-
)`);
|
|
360
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_deriver_queue_status_priority
|
|
361
|
-
ON deriver_queue (status, priority DESC, created_at ASC)`);
|
|
362
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_deriver_queue_item
|
|
363
|
-
ON deriver_queue (item_type, item_id)`);
|
|
364
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_deriver_queue_claimed_at
|
|
365
|
-
ON deriver_queue (claimed_at)`);
|
|
366
|
-
// T1146: brain_memory_trees — hierarchical RPTree clustering (W6 Dreamer Upgrade).
|
|
367
|
-
// CREATE IF NOT EXISTS so re-runs on existing databases are safe.
|
|
368
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_memory_trees (
|
|
369
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
370
|
-
depth INTEGER NOT NULL DEFAULT 0,
|
|
371
|
-
leaf_ids TEXT NOT NULL DEFAULT '[]',
|
|
372
|
-
centroid TEXT,
|
|
373
|
-
parent_id INTEGER REFERENCES brain_memory_trees(id) ON DELETE CASCADE,
|
|
374
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
375
|
-
updated_at TEXT
|
|
376
|
-
)`);
|
|
377
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_trees_parent ON brain_memory_trees (parent_id)`);
|
|
378
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_trees_depth ON brain_memory_trees (depth)`);
|
|
379
|
-
// T1615: brain_task_observations — join table linking brain_observations to task IDs.
|
|
380
|
-
// Enables cleo memory find queries to surface session context for a given task.
|
|
381
|
-
// CREATE IF NOT EXISTS so re-runs on existing databases are safe.
|
|
382
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_task_observations (
|
|
383
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
384
|
-
observation_id TEXT NOT NULL,
|
|
385
|
-
task_id TEXT NOT NULL,
|
|
386
|
-
link_type TEXT NOT NULL DEFAULT 'session-completed',
|
|
387
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
388
|
-
)`);
|
|
389
|
-
nativeDb.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_brain_task_obs_unique
|
|
390
|
-
ON brain_task_observations (observation_id, task_id)`);
|
|
391
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_task_obs_observation
|
|
392
|
-
ON brain_task_observations (observation_id)`);
|
|
393
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_task_obs_task
|
|
394
|
-
ON brain_task_observations (task_id)`);
|
|
395
|
-
// T11371: brain_attention — Tier-2 scope-keyed, decaying working-memory buffer
|
|
396
|
-
// (Epic T11288 · Saga T11283). The Drizzle migration
|
|
397
|
-
// 20260530000001_t11371-add-attention-table handles fresh installs; this
|
|
398
|
-
// self-healing CREATE IF NOT EXISTS is the safety-net for installs where the
|
|
399
|
-
// journal reconciler marked prior migrations applied before this table was
|
|
400
|
-
// added, or where the test runner uses a module-cached DB from before the
|
|
401
|
-
// migration ran (mirrors the brain_task_observations / deriver_queue pattern).
|
|
402
|
-
// `tags` is a JSONB BLOB (E4 jsonb<string[]>() helper) — read in-SQL via
|
|
403
|
-
// json_each(tags) / json(tags), NEVER JSON.parse off the raw BLOB.
|
|
404
|
-
nativeDb.exec(`CREATE TABLE IF NOT EXISTS brain_attention (
|
|
405
|
-
id TEXT PRIMARY KEY,
|
|
406
|
-
content TEXT NOT NULL,
|
|
407
|
-
session_id TEXT,
|
|
408
|
-
agent_id TEXT,
|
|
409
|
-
scope_kind TEXT NOT NULL,
|
|
410
|
-
scope_id TEXT NOT NULL,
|
|
411
|
-
tags BLOB DEFAULT (jsonb('[]')),
|
|
412
|
-
created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),
|
|
413
|
-
expires_at INTEGER,
|
|
414
|
-
decay_score REAL,
|
|
415
|
-
status TEXT NOT NULL DEFAULT 'open'
|
|
416
|
-
)`);
|
|
417
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_attention_scope
|
|
418
|
-
ON brain_attention (scope_kind, scope_id)`);
|
|
419
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_attention_session
|
|
420
|
-
ON brain_attention (session_id)`);
|
|
421
|
-
nativeDb.exec(`CREATE INDEX IF NOT EXISTS idx_brain_attention_status_expires
|
|
422
|
-
ON brain_attention (status, expires_at)`);
|
|
276
|
+
// The `drizzle-brain` set now includes `brain_task_observations` (T1615) via
|
|
277
|
+
// the forward migration `20260601000001_t11522-brain-task-observations`, so the
|
|
278
|
+
// previous post-hoc `CREATE TABLE IF NOT EXISTS` band-aid for it is no longer
|
|
279
|
+
// needed here (T11522 AC: post-hoc DDL → forward Drizzle migration).
|
|
423
280
|
}
|
|
424
281
|
/**
|
|
425
282
|
* Load the sqlite-vec extension into a native DatabaseSync instance.
|
|
@@ -486,163 +343,105 @@ async function initEmbeddingProvider(cwd) {
|
|
|
486
343
|
}
|
|
487
344
|
}
|
|
488
345
|
/**
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
* Uses `PRAGMA quick_check` rather than `integrity_check` — quick_check
|
|
492
|
-
* skips index-sort and out-of-order rowid scans, returning in milliseconds
|
|
493
|
-
* on a healthy DB. A live malformed schema (the T10260/T10265 incident
|
|
494
|
-
* pattern) surfaces here as either a throw from `prepare()` or a non-`ok`
|
|
495
|
-
* return value.
|
|
496
|
-
*
|
|
497
|
-
* @returns `true` when the DB passes quick_check, `false` otherwise.
|
|
498
|
-
* @task T10303
|
|
499
|
-
* @internal
|
|
500
|
-
*/
|
|
501
|
-
function probeBrainDbIntegrity(db) {
|
|
502
|
-
try {
|
|
503
|
-
const row = db.prepare('PRAGMA quick_check').get();
|
|
504
|
-
return row?.quick_check === 'ok';
|
|
505
|
-
}
|
|
506
|
-
catch {
|
|
507
|
-
// prepare() threw — schema is malformed (the T10260/T10265 signature).
|
|
508
|
-
return false;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Detect whether an open-time exception matches the brain.db malformation
|
|
513
|
-
* signature `ERR_SQLITE_ERROR errcode=11` (SQLITE_CORRUPT) — the live
|
|
514
|
-
* failure pattern that triggered Saga T10281.
|
|
346
|
+
* Initialize the project-scope BRAIN domain SQLite database (lazy, singleton).
|
|
515
347
|
*
|
|
516
|
-
*
|
|
517
|
-
*/
|
|
518
|
-
function isMalformationError(err) {
|
|
519
|
-
if (!(err instanceof Error))
|
|
520
|
-
return false;
|
|
521
|
-
const code = err.code;
|
|
522
|
-
const errcode = err.errcode;
|
|
523
|
-
if (code === 'ERR_SQLITE_ERROR' && errcode === 11)
|
|
524
|
-
return true;
|
|
525
|
-
const msg = err.message ?? '';
|
|
526
|
-
// Belt-and-suspenders: some node:sqlite versions stringify "malformed
|
|
527
|
-
// database schema" into the message even when errcode is unset.
|
|
528
|
-
return /malformed/i.test(msg);
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Open the brain.db with auto-recovery on malformation.
|
|
532
|
-
*
|
|
533
|
-
* Synchronous by design — recovery runs on the open-blocking critical path.
|
|
534
|
-
* The alternative is silent broken cognition (T10260, T10265).
|
|
348
|
+
* ## E6-L2 façade (T11522)
|
|
535
349
|
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
350
|
+
* Delegates the physical DB open to {@link openDualScopeDb}('project', cwd) —
|
|
351
|
+
* the canonical dual-scope chokepoint. The returned `NodeSQLiteDatabase` wraps
|
|
352
|
+
* the same `DatabaseSync` handle as the consolidated project `cleo.db` but is
|
|
353
|
+
* typed against the legacy brain schema (`brainSchema`, physical tables
|
|
354
|
+
* `brain_decisions`, …) so all existing brain callers compile and run without
|
|
355
|
+
* change. The legacy `drizzle-brain` migrations are still applied to this handle
|
|
356
|
+
* during the E3→E6 transition (additive / `IF NOT EXISTS` — idempotent on the
|
|
357
|
+
* consolidated DB) so the runtime-queried legacy physical tables (notably
|
|
358
|
+
* `deriver_queue`) co-exist with the consolidated `brain_*` tables.
|
|
542
359
|
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
recoverMalformedBrainDb({
|
|
551
|
-
corruptPath: dbPath,
|
|
552
|
-
snapshotDir: join(cleoDir, 'backups', 'snapshot'),
|
|
553
|
-
vacuumSnapshotDir: join(cleoDir, 'backups', 'sqlite'),
|
|
554
|
-
legacyArtifactDir: cleoDir,
|
|
555
|
-
quarantineRoot: join(cleoDir, 'quarantine'),
|
|
556
|
-
logger: getLogger('brain-recover'),
|
|
557
|
-
});
|
|
558
|
-
};
|
|
559
|
-
let nativeDb;
|
|
560
|
-
try {
|
|
561
|
-
nativeDb = tryOpen();
|
|
562
|
-
}
|
|
563
|
-
catch (err) {
|
|
564
|
-
if (!isMalformationError(err))
|
|
565
|
-
throw err;
|
|
566
|
-
runRecovery();
|
|
567
|
-
nativeDb = tryOpen();
|
|
568
|
-
}
|
|
569
|
-
if (!probeBrainDbIntegrity(nativeDb)) {
|
|
570
|
-
try {
|
|
571
|
-
nativeDb.close();
|
|
572
|
-
}
|
|
573
|
-
catch {
|
|
574
|
-
// close errors are non-fatal — handle terminal anyway
|
|
575
|
-
}
|
|
576
|
-
runRecovery();
|
|
577
|
-
nativeDb = tryOpen();
|
|
578
|
-
// One final check — if recovery couldn't produce a clean DB, we still
|
|
579
|
-
// return the handle. The downstream migration path will surface the
|
|
580
|
-
// failure with full context rather than silently degrading.
|
|
581
|
-
}
|
|
582
|
-
return nativeDb;
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* Initialize the brain.db SQLite database (lazy, singleton).
|
|
586
|
-
* Creates the database file and tables if they don't exist.
|
|
587
|
-
* Returns the drizzle ORM instance (async via sqlite-proxy).
|
|
360
|
+
* Brain-specific malformation auto-recovery (T10303 / Saga T10281) previously
|
|
361
|
+
* ran here against the standalone `brain.db` file. That file no longer backs the
|
|
362
|
+
* brain domain after this leaf — the brain tables live inside `cleo.db`, whose
|
|
363
|
+
* malformation recovery is a dual-scope-level concern (the brain-only
|
|
364
|
+
* quarantine/snapshot-restore pipeline would corrupt the co-resident `tasks_*` /
|
|
365
|
+
* `conduit_*` domains). The recovery primitive itself (`recoverMalformedBrainDb`)
|
|
366
|
+
* is retained for `doctor` use; only its wiring into this chokepoint is removed.
|
|
588
367
|
*
|
|
589
|
-
* Uses a promise guard so concurrent callers wait for the same
|
|
590
|
-
*
|
|
368
|
+
* Uses a promise guard so concurrent callers wait for the same initialization to
|
|
369
|
+
* complete (migrations are async).
|
|
591
370
|
*/
|
|
592
371
|
export async function getBrainDb(cwd) {
|
|
593
372
|
const requestedPath = getBrainDbPath(cwd);
|
|
594
|
-
// T1906: guard against prod-DB writes in test mode
|
|
373
|
+
// T1906: guard against prod-DB writes in test mode.
|
|
595
374
|
const { assertTestEnv } = await import('./data-accessor.js');
|
|
596
375
|
assertTestEnv(requestedPath);
|
|
597
|
-
// If singleton exists but points to different path, reset it
|
|
376
|
+
// If singleton exists but points to different path, reset it.
|
|
598
377
|
if (_db && _dbPath !== requestedPath) {
|
|
599
378
|
resetBrainDbState();
|
|
600
379
|
}
|
|
380
|
+
// Liveness guard (T11522): the brain domain shares the consolidated cleo.db
|
|
381
|
+
// handle with the tasks domain. The tasks side may have closed + re-opened the
|
|
382
|
+
// shared `DatabaseSync` (e.g. its `resetDbState()` / auto-recovery path) while
|
|
383
|
+
// our brain singleton still references the now-closed handle. Detect a stale
|
|
384
|
+
// (closed) handle and drop the singleton so we re-derive from the live
|
|
385
|
+
// openDualScopeDb cache below.
|
|
386
|
+
if (_db && (_nativeDb === null || !_nativeDb.isOpen)) {
|
|
387
|
+
resetBrainDbState();
|
|
388
|
+
}
|
|
601
389
|
if (_db)
|
|
602
390
|
return _db;
|
|
603
|
-
// If already initializing, wait for the in-flight init
|
|
391
|
+
// If already initializing, wait for the in-flight init.
|
|
604
392
|
if (_initPromise)
|
|
605
393
|
return _initPromise;
|
|
606
394
|
_initPromise = (async () => {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
//
|
|
610
|
-
|
|
611
|
-
//
|
|
612
|
-
|
|
613
|
-
//
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
// validated snapshot is restored; we then re-attempt the open ONCE.
|
|
620
|
-
const nativeDb = openBrainDbWithRecovery(dbPath, cwd);
|
|
395
|
+
// ── Dual-scope chokepoint delegation (T11522 · E6-L2) ─────────────────
|
|
396
|
+
// openDualScopeDb applies the pragma SSoT, creates the directory, runs the
|
|
397
|
+
// consolidated cleo-project migrations (which create the `brain_*` tables),
|
|
398
|
+
// and manages the singleton cache. We extract its native handle so we can
|
|
399
|
+
// re-wrap it with the legacy brain-schema for caller compatibility.
|
|
400
|
+
const dualHandle = await openDualScopeDb('project', cwd);
|
|
401
|
+
// Extract the underlying DatabaseSync. Drizzle exposes it via `$client`.
|
|
402
|
+
const nativeDb = dualHandle.db.$client ?? null;
|
|
403
|
+
if (!nativeDb) {
|
|
404
|
+
throw new Error('E6-L2: openDualScopeDb returned a handle without $client — ' +
|
|
405
|
+
'cannot extract DatabaseSync for legacy brain-schema wrapping.');
|
|
406
|
+
}
|
|
621
407
|
_nativeDb = nativeDb;
|
|
622
|
-
|
|
623
|
-
//
|
|
408
|
+
_dbPath = requestedPath;
|
|
409
|
+
// Load the sqlite-vec extension for vector similarity search (T5157). The
|
|
410
|
+
// dual-scope handle is opened with `allowExtension: true`, so loading is
|
|
411
|
+
// permitted. Non-fatal if unavailable — vec0 tables simply won't be created.
|
|
624
412
|
_vecLoaded = loadBrainVecExtension(nativeDb);
|
|
625
|
-
//
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
//
|
|
630
|
-
//
|
|
413
|
+
// Wrap the native handle with the legacy brain-schema drizzle instance so
|
|
414
|
+
// existing callers (brainSchema.* queries) continue to work unchanged.
|
|
415
|
+
const db = _getDrizzle()({ client: nativeDb, schema: brainSchema });
|
|
416
|
+
// Reconcile the LEGACY brain-domain schema inside the consolidated cleo.db.
|
|
417
|
+
// Since T11647 the consolidated `cleo.db` migration already creates every
|
|
418
|
+
// `brain_*` table in the LEGACY RUNTIME shape (epoch-ms integer timestamps,
|
|
419
|
+
// no SQL CHECK constraints — the exodus target was aligned to the runtime
|
|
420
|
+
// shape in `cleo-shared/brain.ts`). So this is now a no-op reconcile: it
|
|
421
|
+
// marks the `drizzle-brain` lineage applied and skips the migrate, leaving
|
|
422
|
+
// any exodus-migrated brain rows intact. The legacy standalone-`brain.db`
|
|
423
|
+
// path (DB with no consolidated brain tables) still runs the full
|
|
424
|
+
// `drizzle-brain` migrate. The pre-T11647 DROP+recreate path is retained as
|
|
425
|
+
// a defensive fallback for any DB still carrying the old consolidated shape.
|
|
426
|
+
// (T11522 · T11647)
|
|
427
|
+
establishLegacyBrainSchema(nativeDb, db);
|
|
428
|
+
// Create the vec0 virtual table for embeddings if the extension is loaded
|
|
429
|
+
// (T5157). Must run after migrations so the schema is consistent.
|
|
631
430
|
if (_vecLoaded) {
|
|
632
431
|
initializeBrainVec(nativeDb);
|
|
633
432
|
}
|
|
634
|
-
// Seed schema version for new databases (no-op if already set)
|
|
433
|
+
// Seed schema version for new databases (no-op if already set).
|
|
635
434
|
nativeDb
|
|
636
435
|
.prepare(`INSERT OR IGNORE INTO brain_schema_meta (key, value) VALUES ('schemaVersion', '${BRAIN_SCHEMA_VERSION}')`)
|
|
637
436
|
.run();
|
|
638
|
-
// Set singleton only after migrations complete
|
|
437
|
+
// Set singleton only after migrations complete.
|
|
639
438
|
_db = db;
|
|
640
|
-
// Wire the default embedding provider when vec is loaded and embedding is
|
|
641
|
-
// Best-effort, async, never blocks DB access. (T539)
|
|
439
|
+
// Wire the default embedding provider when vec is loaded and embedding is
|
|
440
|
+
// enabled. Best-effort, async, never blocks DB access. (T539)
|
|
642
441
|
if (_vecLoaded) {
|
|
643
442
|
setImmediate(() => {
|
|
644
443
|
initEmbeddingProvider(cwd).catch(() => {
|
|
645
|
-
// Non-fatal — embedding will be unavailable until next startup
|
|
444
|
+
// Non-fatal — embedding will be unavailable until next startup.
|
|
646
445
|
});
|
|
647
446
|
});
|
|
648
447
|
}
|
|
@@ -656,41 +455,40 @@ export async function getBrainDb(cwd) {
|
|
|
656
455
|
}
|
|
657
456
|
}
|
|
658
457
|
/**
|
|
659
|
-
* Close the brain
|
|
458
|
+
* Close the brain-domain database connection and release resources.
|
|
459
|
+
*
|
|
460
|
+
* ## E6-L2 (T11522)
|
|
461
|
+
*
|
|
462
|
+
* The brain domain now SHARES the consolidated project `cleo.db` handle with the
|
|
463
|
+
* tasks domain (both open it via {@link openDualScopeDb}, same cache key). This
|
|
464
|
+
* function therefore must NOT close the underlying `DatabaseSync` nor evict the
|
|
465
|
+
* dual-scope cache — doing so would break in-flight tasks-domain queries with
|
|
466
|
+
* "database is not open". It only drops the brain-domain singleton references;
|
|
467
|
+
* the shared handle's lifecycle is owned by `openDualScopeDb` and torn down by a
|
|
468
|
+
* coordinated reset (`closeAllDatabases` → `closeDb` → `_resetDualScopeDbCache`).
|
|
660
469
|
*/
|
|
661
470
|
export function closeBrainDb() {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
_nativeDb.close();
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
catch {
|
|
669
|
-
// Ignore close errors
|
|
670
|
-
}
|
|
671
|
-
_nativeDb = null;
|
|
672
|
-
}
|
|
471
|
+
// Drop only the brain singleton references. Do NOT close `_nativeDb` — it is
|
|
472
|
+
// the shared dual-scope handle, possibly still in use by the tasks domain.
|
|
473
|
+
_nativeDb = null;
|
|
673
474
|
_db = null;
|
|
674
475
|
_dbPath = null;
|
|
476
|
+
_initPromise = null;
|
|
675
477
|
_vecLoaded = false;
|
|
676
478
|
}
|
|
677
479
|
/**
|
|
678
|
-
* Reset brain
|
|
679
|
-
* Used during tests or when database file is recreated.
|
|
480
|
+
* Reset brain-domain singleton state without saving.
|
|
481
|
+
* Used during tests or when the database file is recreated.
|
|
680
482
|
* Safe to call multiple times.
|
|
483
|
+
*
|
|
484
|
+
* ## E6-L2 (T11522)
|
|
485
|
+
*
|
|
486
|
+
* Drops only the brain-domain singleton references — does NOT close the shared
|
|
487
|
+
* dual-scope `cleo.db` handle nor evict the dual-scope cache (that handle is
|
|
488
|
+
* shared with the tasks domain). Mirrors {@link closeBrainDb}.
|
|
681
489
|
*/
|
|
682
490
|
export function resetBrainDbState() {
|
|
683
|
-
|
|
684
|
-
try {
|
|
685
|
-
if (_nativeDb.isOpen) {
|
|
686
|
-
_nativeDb.close();
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
catch {
|
|
690
|
-
// Ignore close errors
|
|
691
|
-
}
|
|
692
|
-
_nativeDb = null;
|
|
693
|
-
}
|
|
491
|
+
_nativeDb = null;
|
|
694
492
|
_db = null;
|
|
695
493
|
_dbPath = null;
|
|
696
494
|
_initPromise = null;
|