/** * SQLite store for the NEXUS domain via drizzle-orm/node-sqlite + node:sqlite * (DatabaseSync). * * ## Dual-scope residency split (ADR-090 · T11648 — runtime read half) * * The nexus domain is now SPLIT across the two consolidated `cleo.db` files: * * - **GRAPH (project scope):** the four code-graph tables (`nexus_nodes`, * `nexus_relations`, `nexus_contracts`, `nexus_code_index`) + the * `nexus_relation_weights` plasticity sibling live in * `/.cleo/cleo.db` — the portable per-project living brain. * This is where exodus WRITES them (`resolveTableTargetScope` in * `store/exodus/table-name-map.ts`), so the runtime READS them from there too. * - **REGISTRY/identity (global scope):** the six cross-project tables * (`nexus_project_registry`, `nexus_project_id_aliases`, `nexus_user_profile`, * `nexus_sigils`, `nexus_audit_log`, `nexus_schema_meta`) stay in the GLOBAL * `cleo.db` under {@link getCleoHome} (ADR-090 §2.2). * * `getNexusDb()` opens the PROJECT scope as `main` (via {@link openDualScopeDb} * ('project')) and ATTACHes the GLOBAL `cleo.db` under * {@link NEXUS_GLOBAL_ATTACH_ALIAS}. SQLite's bare-name resolution then routes * each query to the correct file with ZERO accessor changes: graph tables exist * in `main` (project) and resolve there; registry/identity tables are absent * from `main` and fall through to the attached GLOBAL db. The GLOBAL db also * carries empty graph tables (frozen T11363 migration leftovers), correctly * SHADOWED by `main`. * * ### Why this fix (T11648) * * T11538/T11539 moved the graph schema to PROJECT scope and routed exodus there, * but the runtime READ accessors still opened the GLOBAL handle — so after a * `cleo exodus migrate` the project held 24k+ `nexus_nodes` while the runtime * read 0 from global (`cleo nexus search-code` / `context` returned empty). This * module is the deferred runtime half: it reads the graph from the SAME scope * exodus writes it. * * This preserves the prior guarantees: * - Every nexus-domain open flows through the single pragma SSoT (ADR-068/069). * - DB Open Guard Gate 3 (`scripts/lint-no-direct-db-open.mjs`) stays green: the * only native open is inside `dual-scope-db.ts` (the ATTACH below is a SQL * statement on an already-chokepointed handle, not a `new DatabaseSync(`). * * ## COMPLETE-CUTOVER to prefixed `nexus_*` tables (T11578 · AC3) * * The nexus runtime READ + WRITE path targets PREFIXED consolidated tables. The * five PROJECT graph tables are owned by the consolidated cleo-project migration; * the six GLOBAL registry/identity tables by the consolidated cleo-global * migration. The former legacy drop/rebuild (`establishLegacyNexusSchema`) and * BARE registry tables (`project_registry`, …) are GONE. The runtime schema * barrel `schema/nexus-schema.ts` maps every export symbol to its prefixed * physical name — accessors need ZERO change. * * The `drizzle-nexus` migration set carries ONLY the delta the consolidated * migration cannot model: the `nexus_symbols_fts` FTS5 virtual table + its three * `nexus_nodes` triggers, the `nexus_relation_weights` plasticity-partition * sibling (T11545), and the `_nexus_meta` health-probe table (the reconcile * sentinel). The destructive half of the plasticity partition is applied * idempotently at open by `ensureNexusRelationWeights` (a no-op for the * already-narrow project-scope `nexus_relations`). * * @adr ADR-036 — registry/identity is global-only (relaxed for the 4 graph * tables by ADR-090 §2.4). * @adr ADR-090 — nexus code-graph residency global→project scope split. * @task T5365 * @task T11524 - E6-L4: route getNexusDb through the dual-scope chokepoint * @task T11578 - AC3: COMPLETE-CUTOVER nexus runtime → prefixed nexus_* tables * @task T11648 - ADR-090 runtime read half: route graph reads to project scope */ import type { DatabaseSync } from 'node:sqlite'; import type { NodeSQLiteDatabase } from 'drizzle-orm/node-sqlite'; import * as nexusSchema from './schema/nexus-schema.js'; /** Schema version for newly created nexus databases. Single source of truth. */ export declare const NEXUS_SCHEMA_VERSION = "1.0.0"; /** * Returns the nexus GRAPH DB path — the consolidated PROJECT `cleo.db` * (`/.cleo/cleo.db`), where the four code-graph tables * (`nexus_nodes`, `nexus_relations`, `nexus_contracts`, `nexus_code_index`) and * the `nexus_relation_weights` plasticity sibling physically reside post the * ADR-090 residency split (T11538/T11539). * * ## ADR-090 residency move — runtime read half (T11648) * * Exodus WRITES the graph tables to PROJECT scope (per `resolveTableTargetScope` * in `store/exodus/table-name-map.ts`); this resolver routes the runtime READ * path to the SAME scope so the migrated graph is visible. Previously this * returned the GLOBAL `cleo.db` (`resolveDualScopeDbPath('global')`), which left * `cleo nexus search-code` / `context` reading the empty global graph tables — * the T11538/T11539 runtime-half gap this fix closes. The cross-project * registry/identity tables stay GLOBAL and are reached via the * {@link NEXUS_GLOBAL_ATTACH_ALIAS} attach (see {@link getNexusRegistryDbPath}). * * @param cwd - Optional working directory used to resolve the owning project * root (forwarded to {@link resolveDualScopeDbPath}('project', cwd)). * @task T307 * @epic T299 * @task T11648 (ADR-090 runtime read half — route graph reads to project scope) * @why ADR-090 §2.1/§2.4 supersedes ADR-036's global-only assertion FOR THE * GRAPH TABLES ONLY. The graph is per-project and must live in the portable * `.cleo/cleo.db`; the registry/identity tables remain global-asserted in * {@link getNexusRegistryDbPath}. */ export declare function getNexusDbPath(cwd?: string): string; /** * Returns the cross-project nexus REGISTRY/identity DB path — the consolidated * GLOBAL `cleo.db` under `getCleoHome()`. * * The registry/identity tables (`nexus_project_registry`, * `nexus_project_id_aliases`, `nexus_user_profile`, `nexus_sigils`, * `nexus_audit_log`, `nexus_schema_meta`) are genuinely global (ADR-090 §2.2) * and MUST stay under `getCleoHome()`. The ADR-036 global-only assertion is * retained here as defence-in-depth (it was relaxed only for the four graph * tables, now homed in PROJECT scope via {@link getNexusDbPath}). * * @task T11648 (ADR-090 — registry stays global-asserted) * @adr ADR-036 — registry/identity is global-only. * @throws {Error} If the resolved path is not under `getCleoHome()`. */ export declare function getNexusRegistryDbPath(): string; /** * Resolve the absolute path to the drizzle-nexus migrations folder inside * @cleocode/core, using ESM-native module resolution (T1177). * * Delegates to {@link resolveCorePackageMigrationsFolder} which handles * bundled dist/, workspace dev, and global-install layouts uniformly via * `import.meta.resolve()` + `createRequire().resolve()` fallback. */ export declare function resolveNexusMigrationsFolder(): string; /** * Returns the absolute path that, if present, indicates the install carries * the nested-nexus structural bug. ALWAYS `/nexus/nexus.db`. * * Exposed for tests; production callers should use * {@link detectAndWarnOnNestedNexus} instead. * * @task T10321 * @adr ADR-086 */ export declare function getNestedNexusSentinelPath(): string; /** * Detect the presence of the nested-nexus structural bug and emit a one-shot * warning via the canonical pino logger if found. * * The function is non-blocking and non-throwing — it never alters the * outcome of the surrounding `getNexusDb()` open. The canonical consolidated * open proceeds normally regardless of whether the nested debris is present. * * Idempotency: the first call for a given nested path emits the warning; * subsequent calls within the same process are no-ops. Tests can reset the * gate via {@link _resetNestedNexusWarningGate}. * * @returns `true` when the warning fired on this call; `false` otherwise. * * @task T10321 * @adr ADR-086 */ export declare function detectAndWarnOnNestedNexus(): boolean; /** * Reset the one-shot warning gate. Tests only — production callers MUST NOT * use this. * * @internal * @task T10321 */ export declare function _resetNestedNexusWarningGate(): void; /** * Initialize the consolidated PROJECT `cleo.db` (the nexus GRAPH home) with the * GLOBAL `cleo.db` ATTACHed for registry/identity reads, plus the nexus DELTA * schema within it (lazy, singleton). * * ## ADR-090 residency move — runtime read half (T11648) * * The four code-graph tables (`nexus_nodes`, `nexus_relations`, `nexus_contracts`, * `nexus_code_index`) + the `nexus_relation_weights` plasticity sibling now live * in PROJECT scope (`/.cleo/cleo.db`) — that is where exodus WRITES * them. The runtime READ path therefore opens the PROJECT scope as `main` so the * graph is visible (previously it opened GLOBAL and read empty graph tables — * the T11538/T11539 gap). The cross-project registry/identity tables stay GLOBAL; * we open GLOBAL first (so its consolidated migration creates them) then ATTACH * it under {@link NEXUS_GLOBAL_ATTACH_ALIAS} so the registry/identity accessors — * which reference bare names (`nexus_project_registry`, `nexus_user_profile`, * `nexus_sigils`, `nexus_project_id_aliases`, `nexus_audit_log`, * `nexus_schema_meta`) — resolve via SQLite's bare-name fall-through to the * attached GLOBAL db. ADR-036's global-only assertion is relaxed for the four * graph tables ONLY (registry stays global-asserted in {@link getNexusRegistryDbPath}). * * Uses a promise guard so concurrent callers wait for the same initialization to * complete (migrations are async). * * @task T307 * @task T11524 (E6-L4 — dual-scope chokepoint delegation) * @task T11578 (AC3 — prefixed `nexus_*` tables) * @task T11648 (ADR-090 runtime read half — project-scope graph + global attach) */ export declare function getNexusDb(): Promise>; /** * Close the nexus-domain database connection and release resources. * * ## E6-L4 (T11524) · ADR-090 runtime read half (T11648) * * The nexus GRAPH domain now SHARES the consolidated PROJECT `cleo.db` handle * with the other project-tier domains (tasks/brain/conduit — all open it via * {@link openDualScopeDb}('project'), same cache key), with the GLOBAL `cleo.db` * ATTACHed for registry/identity reads. This function therefore must NOT close * the underlying `DatabaseSync` nor evict the dual-scope cache — doing so would * break in-flight queries from those siblings with "database is not open". It * only drops the nexus-domain singleton references; the shared handle's lifecycle * (and the global ATTACH) is owned by `openDualScopeDb` and torn down by a * coordinated reset (`closeAllDatabases` → `_resetDualScopeDbCache`). */ export declare function closeNexusDb(): void; /** * Reset nexus singleton state without saving. * Used during tests or when the database file is recreated. * Safe to call multiple times. * * ## E6-L4 (T11524) · ADR-090 runtime read half (T11648) * * Drops only the nexus-domain singleton references — does NOT close the shared * dual-scope PROJECT `cleo.db` handle nor evict the dual-scope cache (that handle * is shared with the other project-tier domains). Mirrors {@link closeNexusDb}. */ export declare function resetNexusDbState(): void; /** * Get the underlying node:sqlite DatabaseSync instance for the nexus domain. * Useful for direct PRAGMA calls or raw SQL operations. * Returns null if the database hasn't been initialized. */ export declare function getNexusNativeDb(): DatabaseSync | null; export type { NodeSQLiteDatabase }; /** * Re-export nexus schema for external use. */ export { nexusSchema }; //# sourceMappingURL=nexus-sqlite.d.ts.map