@cleocode/core 2026.5.132 → 2026.5.134
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +2 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +59 -1
- package/dist/output.js.map +1 -1
- package/dist/sentient/daemon-entry.d.ts +6 -0
- package/dist/sentient/daemon-entry.d.ts.map +1 -1
- package/dist/sentient/daemon-entry.js +10 -1
- package/dist/sentient/daemon-entry.js.map +1 -1
- package/dist/sentient/daemon.d.ts +16 -0
- package/dist/sentient/daemon.d.ts.map +1 -1
- package/dist/sentient/daemon.js +11 -1
- package/dist/sentient/daemon.js.map +1 -1
- package/dist/sentient/index.d.ts +1 -0
- package/dist/sentient/index.d.ts.map +1 -1
- package/dist/sentient/index.js +4 -0
- package/dist/sentient/index.js.map +1 -1
- package/dist/sentient/propose-tick.d.ts +101 -0
- package/dist/sentient/propose-tick.d.ts.map +1 -1
- package/dist/sentient/propose-tick.js +284 -0
- package/dist/sentient/propose-tick.js.map +1 -1
- package/dist/sentient/tick.d.ts +23 -0
- package/dist/sentient/tick.d.ts.map +1 -1
- package/dist/sentient/tick.js +63 -8
- package/dist/sentient/tick.js.map +1 -1
- package/dist/store/exodus/index.d.ts +16 -0
- package/dist/store/exodus/index.d.ts.map +1 -0
- package/dist/store/exodus/index.js +16 -0
- package/dist/store/exodus/index.js.map +1 -0
- package/dist/store/exodus/migrate.d.ts +41 -0
- package/dist/store/exodus/migrate.d.ts.map +1 -0
- package/dist/store/exodus/migrate.js +416 -0
- package/dist/store/exodus/migrate.js.map +1 -0
- package/dist/store/exodus/plan.d.ts +44 -0
- package/dist/store/exodus/plan.d.ts.map +1 -0
- package/dist/store/exodus/plan.js +178 -0
- package/dist/store/exodus/plan.js.map +1 -0
- package/dist/store/exodus/status.d.ts +22 -0
- package/dist/store/exodus/status.d.ts.map +1 -0
- package/dist/store/exodus/status.js +88 -0
- package/dist/store/exodus/status.js.map +1 -0
- package/dist/store/exodus/types.d.ts +169 -0
- package/dist/store/exodus/types.d.ts.map +1 -0
- package/dist/store/exodus/types.js +21 -0
- package/dist/store/exodus/types.js.map +1 -0
- package/dist/store/exodus/verify.d.ts +34 -0
- package/dist/store/exodus/verify.d.ts.map +1 -0
- package/dist/store/exodus/verify.js +168 -0
- package/dist/store/exodus/verify.js.map +1 -0
- package/dist/store/open-cleo-db.d.ts +51 -4
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +56 -2
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +1 -1
- package/dist/store/schema/cleo-global/signaldock.d.ts +1 -1
- package/dist/store/schema/cleo-shared/brain.d.ts +1 -1
- package/package.json +12 -12
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus status reporter.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusStatus()` returns a structured view of the current exodus state
|
|
5
|
+
* without performing any reads or writes beyond stat() calls.
|
|
6
|
+
*
|
|
7
|
+
* @task T11248 (E5 · AC3 · SG-DB-SUBSTRATE-V2)
|
|
8
|
+
* @saga T11242
|
|
9
|
+
*/
|
|
10
|
+
import type { ExodusStatusResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Return a structured status report for the exodus subsystem.
|
|
13
|
+
*
|
|
14
|
+
* This is a read-only operation — no mutations occur.
|
|
15
|
+
*
|
|
16
|
+
* @param cwd - Working directory used to resolve the project root.
|
|
17
|
+
* @returns {@link ExodusStatusResult}
|
|
18
|
+
*
|
|
19
|
+
* @task T11248 (AC3)
|
|
20
|
+
*/
|
|
21
|
+
export declare function runExodusStatus(cwd?: string): ExodusStatusResult;
|
|
22
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA0CpE;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB,CA4BhE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus status reporter.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusStatus()` returns a structured view of the current exodus state
|
|
5
|
+
* without performing any reads or writes beyond stat() calls.
|
|
6
|
+
*
|
|
7
|
+
* @task T11248 (E5 · AC3 · SG-DB-SUBSTRATE-V2)
|
|
8
|
+
* @saga T11242
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { resolveCleoDir } from '../../paths.js';
|
|
13
|
+
import { resolveDualScopeDbPath } from '../dual-scope-db.js';
|
|
14
|
+
import { buildExodusPlan } from './plan.js';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Journal reader (mirrors logic in migrate.ts — kept local for zero coupling)
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const JOURNAL_FILENAME = 'exodus-journal.json';
|
|
19
|
+
function readJournal(stagingDir) {
|
|
20
|
+
const p = join(stagingDir, JOURNAL_FILENAME);
|
|
21
|
+
if (!existsSync(p))
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function findStagingDirs(cleoDir) {
|
|
31
|
+
try {
|
|
32
|
+
return readdirSync(cleoDir, { withFileTypes: true })
|
|
33
|
+
.filter((e) => e.isDirectory() && e.name.startsWith('exodus-staging-'))
|
|
34
|
+
.map((e) => join(cleoDir, e.name))
|
|
35
|
+
.sort()
|
|
36
|
+
.reverse(); // most-recent first
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function safeBytes(p) {
|
|
43
|
+
try {
|
|
44
|
+
return statSync(p).size;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Main status runner
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Return a structured status report for the exodus subsystem.
|
|
55
|
+
*
|
|
56
|
+
* This is a read-only operation — no mutations occur.
|
|
57
|
+
*
|
|
58
|
+
* @param cwd - Working directory used to resolve the project root.
|
|
59
|
+
* @returns {@link ExodusStatusResult}
|
|
60
|
+
*
|
|
61
|
+
* @task T11248 (AC3)
|
|
62
|
+
*/
|
|
63
|
+
export function runExodusStatus(cwd) {
|
|
64
|
+
const plan = buildExodusPlan(cwd);
|
|
65
|
+
const cleoDir = resolveCleoDir(cwd);
|
|
66
|
+
// Find staging directories
|
|
67
|
+
const stagingDirs = findStagingDirs(cleoDir);
|
|
68
|
+
const latestStaging = stagingDirs[0] ?? null;
|
|
69
|
+
const journal = latestStaging ? readJournal(latestStaging) : null;
|
|
70
|
+
const projectDbPath = resolveDualScopeDbPath('project', cwd);
|
|
71
|
+
const globalDbPath = resolveDualScopeDbPath('global');
|
|
72
|
+
const sourcesInfo = plan.sources.map((s) => ({
|
|
73
|
+
name: s.name,
|
|
74
|
+
path: s.path,
|
|
75
|
+
exists: existsSync(s.path),
|
|
76
|
+
bytes: safeBytes(s.path),
|
|
77
|
+
}));
|
|
78
|
+
return {
|
|
79
|
+
hasStaging: latestStaging !== null,
|
|
80
|
+
stagingDir: latestStaging,
|
|
81
|
+
journal,
|
|
82
|
+
projectDbExists: existsSync(projectDbPath),
|
|
83
|
+
globalDbExists: existsSync(globalDbPath),
|
|
84
|
+
sourcesPresent: sourcesInfo.some((s) => s.exists),
|
|
85
|
+
sources: sourcesInfo,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/store/exodus/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the `cleo exodus` migration subsystem.
|
|
3
|
+
*
|
|
4
|
+
* The exodus subsystem migrates data from the legacy multi-DB fleet
|
|
5
|
+
* (tasks.db · brain.db · conduit.db · nexus.db · signaldock.db · skills.db)
|
|
6
|
+
* into the consolidated dual-scope `cleo.db` (project + global).
|
|
7
|
+
*
|
|
8
|
+
* @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
|
|
9
|
+
* @saga T11242
|
|
10
|
+
* @adr ADR-068, ADR-069
|
|
11
|
+
*/
|
|
12
|
+
/** The two consolidated target scopes. */
|
|
13
|
+
export type ExodusScope = 'project' | 'global';
|
|
14
|
+
/**
|
|
15
|
+
* Descriptor for one legacy source database.
|
|
16
|
+
*
|
|
17
|
+
* Each legacy DB maps to a scope (project or global) and a set of tables
|
|
18
|
+
* that will be copied into the consolidated `cleo.db` for that scope.
|
|
19
|
+
*/
|
|
20
|
+
export interface LegacyDbDescriptor {
|
|
21
|
+
/** Logical name for display / logging. */
|
|
22
|
+
readonly name: string;
|
|
23
|
+
/** Absolute path to the legacy `.db` file. */
|
|
24
|
+
readonly path: string;
|
|
25
|
+
/** Consolidated target scope that will receive this DB's tables. */
|
|
26
|
+
readonly targetScope: ExodusScope;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Per-table migration status tracked inside the staging journal
|
|
30
|
+
* (`exodus-journal.json`).
|
|
31
|
+
*/
|
|
32
|
+
export type TableMigrationStatus = 'pending' | 'done' | 'skipped';
|
|
33
|
+
/** Journal entry for one source table. */
|
|
34
|
+
export interface JournalTableEntry {
|
|
35
|
+
readonly sourceDb: string;
|
|
36
|
+
readonly tableName: string;
|
|
37
|
+
status: TableMigrationStatus;
|
|
38
|
+
rowsCopied: number;
|
|
39
|
+
/** ISO-8601 timestamp of last update. */
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
/** Error message if status ended in a non-retryable skip. */
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Contents of `.cleo/exodus-staging-<iso>/exodus-journal.json`.
|
|
46
|
+
*
|
|
47
|
+
* Written before the migration begins and updated atomically after each table
|
|
48
|
+
* copy so that a crash can be resumed from the last completed table.
|
|
49
|
+
*/
|
|
50
|
+
export interface ExodusJournal {
|
|
51
|
+
/** Exodus format version — bump when the schema changes. */
|
|
52
|
+
readonly version: 1;
|
|
53
|
+
/** cleo package version at the time the migration was started. */
|
|
54
|
+
readonly cleoVersion: string;
|
|
55
|
+
/** Drizzle v1.0.0-rc.3 schema hash (constant — used for cross-version guard). */
|
|
56
|
+
readonly targetSchemaVersion: string;
|
|
57
|
+
/** Node.js version at migration time. */
|
|
58
|
+
readonly nodeVersion: string;
|
|
59
|
+
/** SQLite version at migration time. */
|
|
60
|
+
readonly sqliteVersion: string;
|
|
61
|
+
/** ISO-8601 timestamp when the journal was first created. */
|
|
62
|
+
readonly startedAt: string;
|
|
63
|
+
/** ISO-8601 timestamp of last update. */
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
/** Per-table progress entries. Ordered by (sourceDb, tableName). */
|
|
66
|
+
tables: JournalTableEntry[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Result of a single `ExodusTable` copy operation.
|
|
70
|
+
*
|
|
71
|
+
* Returned by `copyTable` and collected into the migration report.
|
|
72
|
+
*/
|
|
73
|
+
export interface TableCopyResult {
|
|
74
|
+
readonly sourceDb: string;
|
|
75
|
+
readonly tableName: string;
|
|
76
|
+
readonly rowsCopied: number;
|
|
77
|
+
readonly skipped: boolean;
|
|
78
|
+
readonly reason?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Top-level exodus plan — computed by `buildExodusPlan()` before any writes.
|
|
82
|
+
*
|
|
83
|
+
* Carries all pre-flight information including disk-space check results so
|
|
84
|
+
* that `--dry-run` can print a rich preview.
|
|
85
|
+
*/
|
|
86
|
+
export interface ExodusPlan {
|
|
87
|
+
/** The legacy source descriptors that will participate in the migration. */
|
|
88
|
+
readonly sources: LegacyDbDescriptor[];
|
|
89
|
+
/** Combined size of all source DB files in bytes. */
|
|
90
|
+
readonly totalSourceBytes: number;
|
|
91
|
+
/** Available disk bytes on the target filesystem. */
|
|
92
|
+
readonly availableBytes: number;
|
|
93
|
+
/** Whether the 3× free-disk pre-flight passes. */
|
|
94
|
+
readonly diskPreflight: boolean;
|
|
95
|
+
/** Absolute path to the staging directory. */
|
|
96
|
+
readonly stagingDir: string;
|
|
97
|
+
/** Whether a staging directory from a previous run was found (resume mode). */
|
|
98
|
+
readonly resumeFromStaging: boolean;
|
|
99
|
+
/** Absolute path to the target project cleo.db. */
|
|
100
|
+
readonly projectDbPath: string;
|
|
101
|
+
/** Absolute path to the target global cleo.db. */
|
|
102
|
+
readonly globalDbPath: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Result returned by `runExodusMigrate()`.
|
|
106
|
+
*/
|
|
107
|
+
export interface ExodusMigrateResult {
|
|
108
|
+
readonly ok: boolean;
|
|
109
|
+
readonly tables: TableCopyResult[];
|
|
110
|
+
readonly stagingDir: string;
|
|
111
|
+
readonly backupPaths: string[];
|
|
112
|
+
/** Error message if `ok === false`. */
|
|
113
|
+
readonly error?: string;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Per-table verification entry produced by `runExodusVerify()`.
|
|
117
|
+
*/
|
|
118
|
+
export interface VerifyTableResult {
|
|
119
|
+
readonly tableName: string;
|
|
120
|
+
readonly scope: ExodusScope;
|
|
121
|
+
/** Row count in the source legacy DB. */
|
|
122
|
+
readonly sourceCount: number;
|
|
123
|
+
/** Row count in the consolidated cleo.db. */
|
|
124
|
+
readonly targetCount: number;
|
|
125
|
+
/** xxhash3-based ordered canonical-JSON digest (hex). */
|
|
126
|
+
readonly sourceHash: string;
|
|
127
|
+
readonly targetHash: string;
|
|
128
|
+
readonly hashMatch: boolean;
|
|
129
|
+
readonly countMatch: boolean;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Result returned by `runExodusVerify()`.
|
|
133
|
+
*/
|
|
134
|
+
export interface ExodusVerifyResult {
|
|
135
|
+
readonly ok: boolean;
|
|
136
|
+
readonly tables: VerifyTableResult[];
|
|
137
|
+
readonly error?: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Status returned by `runExodusStatus()`.
|
|
141
|
+
*/
|
|
142
|
+
export interface ExodusStatusResult {
|
|
143
|
+
/** Whether a staging journal exists from a previous (possibly incomplete) run. */
|
|
144
|
+
readonly hasStaging: boolean;
|
|
145
|
+
readonly stagingDir: string | null;
|
|
146
|
+
readonly journal: ExodusJournal | null;
|
|
147
|
+
/** Whether the consolidated project-scope cleo.db already exists. */
|
|
148
|
+
readonly projectDbExists: boolean;
|
|
149
|
+
/** Whether the consolidated global-scope cleo.db already exists. */
|
|
150
|
+
readonly globalDbExists: boolean;
|
|
151
|
+
/** Whether all source legacy DBs exist. */
|
|
152
|
+
readonly sourcesPresent: boolean;
|
|
153
|
+
readonly sources: Array<{
|
|
154
|
+
name: string;
|
|
155
|
+
path: string;
|
|
156
|
+
exists: boolean;
|
|
157
|
+
bytes: number;
|
|
158
|
+
}>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Canonical schema version tag embedded in the exodus journal.
|
|
162
|
+
*
|
|
163
|
+
* This constant represents the Drizzle v1.0.0-rc.3 target schema "epoch"
|
|
164
|
+
* for the dual-scope consolidation (T11245 · E2 · SG-DB-SUBSTRATE-V2).
|
|
165
|
+
* The exact value is a stable marker — not a live hash — so that import
|
|
166
|
+
* refuses cross-version migration unless `--force-cross-version` is passed.
|
|
167
|
+
*/
|
|
168
|
+
export declare const EXODUS_TARGET_SCHEMA_VERSION: "drizzle-v1.0.0-rc.3/dual-scope/2026-05";
|
|
169
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the `cleo exodus` migration subsystem.
|
|
3
|
+
*
|
|
4
|
+
* The exodus subsystem migrates data from the legacy multi-DB fleet
|
|
5
|
+
* (tasks.db · brain.db · conduit.db · nexus.db · signaldock.db · skills.db)
|
|
6
|
+
* into the consolidated dual-scope `cleo.db` (project + global).
|
|
7
|
+
*
|
|
8
|
+
* @task T11248 (E5 · SG-DB-SUBSTRATE-V2)
|
|
9
|
+
* @saga T11242
|
|
10
|
+
* @adr ADR-068, ADR-069
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Canonical schema version tag embedded in the exodus journal.
|
|
14
|
+
*
|
|
15
|
+
* This constant represents the Drizzle v1.0.0-rc.3 target schema "epoch"
|
|
16
|
+
* for the dual-scope consolidation (T11245 · E2 · SG-DB-SUBSTRATE-V2).
|
|
17
|
+
* The exact value is a stable marker — not a live hash — so that import
|
|
18
|
+
* refuses cross-version migration unless `--force-cross-version` is passed.
|
|
19
|
+
*/
|
|
20
|
+
export const EXODUS_TARGET_SCHEMA_VERSION = 'drizzle-v1.0.0-rc.3/dual-scope/2026-05';
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/store/exodus/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4JH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,wCAAiD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus verification engine.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusVerify()` checks equivalence between source legacy DBs and the
|
|
5
|
+
* consolidated dual-scope `cleo.db` after a migration.
|
|
6
|
+
*
|
|
7
|
+
* ## Equivalence checks (AC7)
|
|
8
|
+
*
|
|
9
|
+
* Per-table:
|
|
10
|
+
* 1. `COUNT(*)` parity — source and target row counts must match.
|
|
11
|
+
* 2. Ordered canonical-JSON digest — SELECT all rows ORDER BY rowid, JSON-
|
|
12
|
+
* stringify each row, SHA-256 the concatenation (truncated to 32 hex).
|
|
13
|
+
*
|
|
14
|
+
* @task T11248 (E5 · AC7 · SG-DB-SUBSTRATE-V2)
|
|
15
|
+
* @saga T11242
|
|
16
|
+
*/
|
|
17
|
+
import type { ExodusVerifyResult, LegacyDbDescriptor } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Run equivalence verification after an exodus migration.
|
|
20
|
+
*
|
|
21
|
+
* Opens source DBs read-only and the consolidated target DBs read-only, then
|
|
22
|
+
* compares row counts and canonical-JSON digests per table.
|
|
23
|
+
*
|
|
24
|
+
* @param sources - Legacy source descriptors (from `buildExodusPlan()`).
|
|
25
|
+
* @param projectDbPath - Absolute path to the consolidated project `cleo.db`.
|
|
26
|
+
* @param globalDbPath - Absolute path to the consolidated global `cleo.db`.
|
|
27
|
+
* @param onProgress - Optional progress callback.
|
|
28
|
+
*
|
|
29
|
+
* @returns {@link ExodusVerifyResult}
|
|
30
|
+
*
|
|
31
|
+
* @task T11248 (AC7)
|
|
32
|
+
*/
|
|
33
|
+
export declare function runExodusVerify(sources: LegacyDbDescriptor[], projectDbPath: string, globalDbPath: string, onProgress?: (msg: string) => void): ExodusVerifyResult;
|
|
34
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/store/exodus/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAkDpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GACjC,kBAAkB,CA4GpB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exodus verification engine.
|
|
3
|
+
*
|
|
4
|
+
* `runExodusVerify()` checks equivalence between source legacy DBs and the
|
|
5
|
+
* consolidated dual-scope `cleo.db` after a migration.
|
|
6
|
+
*
|
|
7
|
+
* ## Equivalence checks (AC7)
|
|
8
|
+
*
|
|
9
|
+
* Per-table:
|
|
10
|
+
* 1. `COUNT(*)` parity — source and target row counts must match.
|
|
11
|
+
* 2. Ordered canonical-JSON digest — SELECT all rows ORDER BY rowid, JSON-
|
|
12
|
+
* stringify each row, SHA-256 the concatenation (truncated to 32 hex).
|
|
13
|
+
*
|
|
14
|
+
* @task T11248 (E5 · AC7 · SG-DB-SUBSTRATE-V2)
|
|
15
|
+
* @saga T11242
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync } from 'node:fs';
|
|
18
|
+
import { createRequire } from 'node:module';
|
|
19
|
+
import { getLogger } from '../../logger.js';
|
|
20
|
+
import { openCleoDbSnapshot } from '../open-cleo-db.js';
|
|
21
|
+
const log = getLogger('exodus-verify');
|
|
22
|
+
const _require = createRequire(import.meta.url);
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Digest helper (AC7)
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/**
|
|
27
|
+
* Compute an ordered canonical-JSON SHA-256 digest (32 hex chars) for all rows
|
|
28
|
+
* in a table.
|
|
29
|
+
*
|
|
30
|
+
* Rows are fetched `ORDER BY rowid` so the ordering is deterministic. Each row
|
|
31
|
+
* is canonicalized as `JSON.stringify(row)` and appended to the hash.
|
|
32
|
+
*/
|
|
33
|
+
function computeTableDigest(db, tableName) {
|
|
34
|
+
const { createHash } = _require('node:crypto');
|
|
35
|
+
const hasher = createHash('sha256');
|
|
36
|
+
const rows = db.prepare(`SELECT * FROM "${tableName}" ORDER BY rowid`).all();
|
|
37
|
+
for (const row of rows) {
|
|
38
|
+
hasher.update(JSON.stringify(row));
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
count: rows.length,
|
|
42
|
+
hash: hasher.digest('hex').slice(0, 32),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Table listing
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
function listTables(db) {
|
|
49
|
+
const rows = db
|
|
50
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name")
|
|
51
|
+
.all();
|
|
52
|
+
return rows.map((r) => r.name);
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Main verify runner
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
/**
|
|
58
|
+
* Run equivalence verification after an exodus migration.
|
|
59
|
+
*
|
|
60
|
+
* Opens source DBs read-only and the consolidated target DBs read-only, then
|
|
61
|
+
* compares row counts and canonical-JSON digests per table.
|
|
62
|
+
*
|
|
63
|
+
* @param sources - Legacy source descriptors (from `buildExodusPlan()`).
|
|
64
|
+
* @param projectDbPath - Absolute path to the consolidated project `cleo.db`.
|
|
65
|
+
* @param globalDbPath - Absolute path to the consolidated global `cleo.db`.
|
|
66
|
+
* @param onProgress - Optional progress callback.
|
|
67
|
+
*
|
|
68
|
+
* @returns {@link ExodusVerifyResult}
|
|
69
|
+
*
|
|
70
|
+
* @task T11248 (AC7)
|
|
71
|
+
*/
|
|
72
|
+
export function runExodusVerify(sources, projectDbPath, globalDbPath, onProgress) {
|
|
73
|
+
const tableResults = [];
|
|
74
|
+
let overallOk = true;
|
|
75
|
+
// Check target DBs exist
|
|
76
|
+
if (!existsSync(projectDbPath)) {
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
tables: [],
|
|
80
|
+
error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!existsSync(globalDbPath)) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
tables: [],
|
|
87
|
+
error: `Consolidated global cleo.db not found at ${globalDbPath}. Run 'cleo exodus migrate' first.`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
|
|
91
|
+
const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
|
|
92
|
+
try {
|
|
93
|
+
for (const src of sources) {
|
|
94
|
+
if (!existsSync(src.path)) {
|
|
95
|
+
onProgress?.(`Skipping ${src.name} (not present)`);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
|
|
99
|
+
const targetSnap = src.targetScope === 'project' ? projectSnap : globalSnap;
|
|
100
|
+
const scope = src.targetScope;
|
|
101
|
+
try {
|
|
102
|
+
const sourceTables = listTables(srcSnap.db);
|
|
103
|
+
const targetTables = new Set(listTables(targetSnap.db));
|
|
104
|
+
for (const tableName of sourceTables) {
|
|
105
|
+
onProgress?.(`Verifying ${src.name}.${tableName}…`);
|
|
106
|
+
if (!targetTables.has(tableName)) {
|
|
107
|
+
// Table missing in target (E6 will populate it — treat as skipped rows = 0)
|
|
108
|
+
const srcResult = computeTableDigest(srcSnap.db, tableName);
|
|
109
|
+
const result = {
|
|
110
|
+
tableName,
|
|
111
|
+
scope,
|
|
112
|
+
sourceCount: srcResult.count,
|
|
113
|
+
targetCount: 0,
|
|
114
|
+
sourceHash: srcResult.hash,
|
|
115
|
+
targetHash: '',
|
|
116
|
+
hashMatch: srcResult.count === 0, // only ok if source was empty
|
|
117
|
+
countMatch: srcResult.count === 0,
|
|
118
|
+
};
|
|
119
|
+
if (!result.countMatch) {
|
|
120
|
+
overallOk = false;
|
|
121
|
+
log.warn({ tableName, sourceDb: src.name }, 'Table missing in consolidated DB');
|
|
122
|
+
}
|
|
123
|
+
tableResults.push(result);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const srcDigest = computeTableDigest(srcSnap.db, tableName);
|
|
127
|
+
const tgtDigest = computeTableDigest(targetSnap.db, tableName);
|
|
128
|
+
const countMatch = srcDigest.count === tgtDigest.count;
|
|
129
|
+
const hashMatch = srcDigest.hash === tgtDigest.hash;
|
|
130
|
+
if (!countMatch || !hashMatch) {
|
|
131
|
+
overallOk = false;
|
|
132
|
+
log.warn({
|
|
133
|
+
tableName,
|
|
134
|
+
srcCount: srcDigest.count,
|
|
135
|
+
tgtCount: tgtDigest.count,
|
|
136
|
+
countMatch,
|
|
137
|
+
hashMatch,
|
|
138
|
+
}, 'Equivalence check failed');
|
|
139
|
+
}
|
|
140
|
+
tableResults.push({
|
|
141
|
+
tableName,
|
|
142
|
+
scope,
|
|
143
|
+
sourceCount: srcDigest.count,
|
|
144
|
+
targetCount: tgtDigest.count,
|
|
145
|
+
sourceHash: srcDigest.hash,
|
|
146
|
+
targetHash: tgtDigest.hash,
|
|
147
|
+
hashMatch,
|
|
148
|
+
countMatch,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
srcSnap.close();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
159
|
+
log.error({ err }, 'Exodus verify failed');
|
|
160
|
+
return { ok: false, tables: tableResults, error };
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
projectSnap.close();
|
|
164
|
+
globalSnap.close();
|
|
165
|
+
}
|
|
166
|
+
return { ok: overallOk, tables: tableResults };
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/store/exodus/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,11 +21,24 @@
|
|
|
21
21
|
* ```typescript
|
|
22
22
|
* import { openCleoDb } from '@cleocode/core/store/open-cleo-db';
|
|
23
23
|
*
|
|
24
|
+
* // Dual-scope consolidated cleo.db (D1″ lifecycle — E3/E4 exodus):
|
|
25
|
+
* const projHandle = await openCleoDb('project', cwd);
|
|
26
|
+
* const globHandle = await openCleoDb('global');
|
|
27
|
+
*
|
|
28
|
+
* // Legacy 8-role API (deprecated — use 'project'|'global' for new code):
|
|
24
29
|
* const handle = await openCleoDb('tasks', cwd);
|
|
25
30
|
* // use handle.db (DatabaseSync) ...
|
|
26
31
|
* await handle.close();
|
|
27
32
|
* ```
|
|
28
33
|
*
|
|
34
|
+
* ## Dual-scope delegation (T11517 · E3)
|
|
35
|
+
*
|
|
36
|
+
* When called with `'project'` or `'global'` as the role, `openCleoDb` delegates
|
|
37
|
+
* directly to {@link openDualScopeDb} from `./dual-scope-db.ts`, returning a
|
|
38
|
+
* `CleoDbHandle`-shaped wrapper. This is the preferred API for all new code
|
|
39
|
+
* after the E3 exodus. The legacy 8-role CleoDbRole API is retained as a
|
|
40
|
+
* deprecated shim for one migration cycle (E6 removes it).
|
|
41
|
+
*
|
|
29
42
|
* ## Snapshot opener (read-only, no migrations)
|
|
30
43
|
*
|
|
31
44
|
* For short-lived read-only opens (backup verification, schema integrity
|
|
@@ -34,12 +47,25 @@
|
|
|
34
47
|
* migrations and singleton management, so the caller owns the handle's
|
|
35
48
|
* lifecycle directly.
|
|
36
49
|
*
|
|
37
|
-
* @task T9047, T9685
|
|
50
|
+
* @task T9047, T9685, T11517
|
|
38
51
|
* @adr ADR-068, ADR-069
|
|
39
52
|
*/
|
|
40
53
|
import type { DatabaseSync } from 'node:sqlite';
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
import type { DualScope } from './dual-scope-db.js';
|
|
55
|
+
/**
|
|
56
|
+
* Canonical roles for the CLEO SQLite databases (ADR-068).
|
|
57
|
+
*
|
|
58
|
+
* ### Preferred (dual-scope, D1″ — E3 exodus)
|
|
59
|
+
* - `'project'` — consolidated per-project `cleo.db` (delegates to {@link openDualScopeDb})
|
|
60
|
+
* - `'global'` — consolidated per-user `cleo.db` (delegates to {@link openDualScopeDb})
|
|
61
|
+
*
|
|
62
|
+
* ### Legacy 8-role API (deprecated — kept for one migration cycle until E6)
|
|
63
|
+
* The legacy roles below are retained as shims during the E3→E6 transition.
|
|
64
|
+
* New code MUST use `'project'` or `'global'` instead.
|
|
65
|
+
*
|
|
66
|
+
* @task T11517 (E3-T1 · SG-DB-SUBSTRATE-V2)
|
|
67
|
+
*/
|
|
68
|
+
export type CleoDbRole = DualScope | 'tasks' | 'brain' | 'sessions' | 'signaldock' | 'conduit' | 'nexus' | 'skills' | 'llmtxt';
|
|
43
69
|
/** Handle returned by {@link openCleoDb}. */
|
|
44
70
|
export interface CleoDbHandle {
|
|
45
71
|
db: unknown;
|
|
@@ -76,11 +102,32 @@ export type DBHandle = CleoDbHandle;
|
|
|
76
102
|
*/
|
|
77
103
|
export declare function validateProjectIdConsistency(role: CleoDbRole, db: unknown, cwd?: string): void;
|
|
78
104
|
/**
|
|
79
|
-
* Open (or create) a CLEO database by canonical role.
|
|
105
|
+
* Open (or create) a CLEO database by canonical role or dual-scope selector.
|
|
106
|
+
*
|
|
107
|
+
* ## Dual-scope delegation (preferred — T11517 · E3)
|
|
108
|
+
*
|
|
109
|
+
* When called with `'project'` or `'global'`, this function delegates to
|
|
110
|
+
* {@link openDualScopeDb} from `./dual-scope-db.ts`. The returned handle
|
|
111
|
+
* wraps the typed Drizzle client as `CleoDbHandle.db` for backward compat
|
|
112
|
+
* with legacy callers that treat `db` as an opaque `unknown`.
|
|
113
|
+
*
|
|
114
|
+
* ```ts
|
|
115
|
+
* // Preferred for new code after E3 exodus:
|
|
116
|
+
* const handle = await openCleoDb('project', cwd);
|
|
117
|
+
* const handle = await openCleoDb('global');
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* ## Legacy 8-role API (deprecated)
|
|
121
|
+
*
|
|
122
|
+
* The legacy role strings (`'tasks'`, `'brain'`, `'signaldock'`, …) remain
|
|
123
|
+
* functional as deprecated shims for existing callers. E6 will remove them.
|
|
80
124
|
*
|
|
81
125
|
* Single chokepoint for all DB opens. Applies pragma SSoT at open time.
|
|
82
126
|
* Enforces the worktree-isolation guard (T9806) on top of T9803's path-layer
|
|
83
127
|
* THROWS-on-orphan fix.
|
|
128
|
+
*
|
|
129
|
+
* @task T9047, T9685, T11517
|
|
130
|
+
* @adr ADR-068, ADR-069
|
|
84
131
|
*/
|
|
85
132
|
export declare function openCleoDb(role: CleoDbRole, cwd?: string): Promise<CleoDbHandle>;
|
|
86
133
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-cleo-db.d.ts","sourceRoot":"","sources":["../../src/store/open-cleo-db.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"open-cleo-db.d.ts","sourceRoot":"","sources":["../../src/store/open-cleo-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAUpD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,UAAU,GAElB,SAAS,GAET,OAAO,GACP,OAAO,GACP,UAAU,GACV,YAAY,GACZ,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,CAAC;AAYb,6CAA6C;AAC7C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,4CAA4C;AAC5C,MAAM,MAAM,QAAQ,GAAG,YAAY,CAAC;AAqGpC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAoD9F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA4DtF;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAErE;AAMD,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,EAAE,EAAE,YAAY,CAAC;IACjB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CA8BtB"}
|