@cleocode/core 2026.6.4 → 2026.6.6
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/docs/export-document.js +189 -137
- package/dist/docs/export-document.js.map +2 -2
- package/dist/llm/api-mode.d.ts +64 -0
- package/dist/llm/api-mode.d.ts.map +1 -0
- package/dist/llm/api-mode.js +72 -0
- package/dist/llm/api-mode.js.map +1 -0
- package/dist/llm/api.d.ts.map +1 -1
- package/dist/llm/api.js +6 -37
- package/dist/llm/api.js.map +1 -1
- package/dist/llm/auxiliary-fallback.d.ts.map +1 -1
- package/dist/llm/auxiliary-fallback.js +24 -38
- package/dist/llm/auxiliary-fallback.js.map +1 -1
- package/dist/llm/model-runner.d.ts +127 -0
- package/dist/llm/model-runner.d.ts.map +1 -0
- package/dist/llm/model-runner.js +282 -0
- package/dist/llm/model-runner.js.map +1 -0
- package/dist/llm/plugin-facade.js +29391 -1473
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/role-executor.d.ts +6 -5
- package/dist/llm/role-executor.d.ts.map +1 -1
- package/dist/llm/role-executor.js +40 -86
- package/dist/llm/role-executor.js.map +1 -1
- package/dist/llm/role-resolver.d.ts +28 -1
- package/dist/llm/role-resolver.d.ts.map +1 -1
- package/dist/llm/role-resolver.js +10 -0
- package/dist/llm/role-resolver.js.map +1 -1
- package/dist/llm/session-factory.d.ts +4 -6
- package/dist/llm/session-factory.d.ts.map +1 -1
- package/dist/llm/session-factory.js +6 -72
- package/dist/llm/session-factory.js.map +1 -1
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/llm/system-resolver.js +6 -0
- package/dist/llm/system-resolver.js.map +1 -1
- package/dist/llm/tool-loop.d.ts.map +1 -1
- package/dist/llm/tool-loop.js +9 -32
- package/dist/llm/tool-loop.js.map +1 -1
- package/dist/memory/dialectic-evaluator.d.ts +13 -6
- package/dist/memory/dialectic-evaluator.d.ts.map +1 -1
- package/dist/memory/dialectic-evaluator.js +18 -7
- package/dist/memory/dialectic-evaluator.js.map +1 -1
- package/dist/memory/llm-backend-resolver.d.ts +23 -3
- package/dist/memory/llm-backend-resolver.d.ts.map +1 -1
- package/dist/memory/llm-backend-resolver.js +135 -0
- package/dist/memory/llm-backend-resolver.js.map +1 -1
- package/dist/release/reconcile.d.ts +61 -0
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +187 -2
- package/dist/release/reconcile.js.map +1 -1
- package/dist/store/exodus/column-transforms.d.ts +248 -0
- package/dist/store/exodus/column-transforms.d.ts.map +1 -0
- package/dist/store/exodus/column-transforms.js +444 -0
- package/dist/store/exodus/column-transforms.js.map +1 -0
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +5 -267
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/verify-migration.d.ts.map +1 -1
- package/dist/store/exodus/verify-migration.js +61 -3
- package/dist/store/exodus/verify-migration.js.map +1 -1
- package/package.json +12 -12
|
@@ -31695,6 +31695,162 @@ var init_open_cleo_db = __esm({
|
|
|
31695
31695
|
}
|
|
31696
31696
|
});
|
|
31697
31697
|
|
|
31698
|
+
// packages/core/src/store/exodus/column-transforms.ts
|
|
31699
|
+
function typeDefaultLiteral(colType) {
|
|
31700
|
+
const upper = colType.toUpperCase();
|
|
31701
|
+
if (upper.includes("INT")) return "0";
|
|
31702
|
+
if (upper.includes("REAL") || upper.includes("FLOAT") || upper.includes("DOUBLE")) return "0.0";
|
|
31703
|
+
if (upper.includes("BLOB")) return "x''";
|
|
31704
|
+
return "''";
|
|
31705
|
+
}
|
|
31706
|
+
function enumNormExpr(targetTableName, col, srcRef) {
|
|
31707
|
+
const key = `${targetTableName}.${col}`;
|
|
31708
|
+
const fn = ENUM_NORMALIZATIONS.get(key);
|
|
31709
|
+
return fn ? fn(srcRef) : null;
|
|
31710
|
+
}
|
|
31711
|
+
function numericClampExpr(targetTableName, col, srcRef) {
|
|
31712
|
+
const key = `${targetTableName}.${col}`;
|
|
31713
|
+
const fn = NUMERIC_CLAMPS.get(key);
|
|
31714
|
+
return fn ? fn(srcRef) : null;
|
|
31715
|
+
}
|
|
31716
|
+
function buildEpochToIsoExpr(srcRef) {
|
|
31717
|
+
return `CASE WHEN ${srcRef} IS NULL THEN NULL WHEN ${srcRef} < ${EPOCH_SECONDS_THRESHOLD} THEN strftime('%Y-%m-%dT%H:%M:%fZ', ${srcRef}, 'unixepoch') ELSE strftime('%Y-%m-%dT%H:%M:%fZ', ${srcRef}/1000.0, 'unixepoch') END`;
|
|
31718
|
+
}
|
|
31719
|
+
function detectIsoGlobColumns(db, tableName, targetSchema = "main") {
|
|
31720
|
+
const escapedTable = tableName.replace(/'/g, "''");
|
|
31721
|
+
const row = db.prepare(
|
|
31722
|
+
`SELECT sql FROM "${targetSchema}".sqlite_master WHERE type='table' AND name='${escapedTable}'`
|
|
31723
|
+
).get();
|
|
31724
|
+
if (!row?.sql) return /* @__PURE__ */ new Set();
|
|
31725
|
+
const isoColumns = /* @__PURE__ */ new Set();
|
|
31726
|
+
ISO_CHECK_REGEX.lastIndex = 0;
|
|
31727
|
+
for (const match of row.sql.matchAll(ISO_CHECK_REGEX)) {
|
|
31728
|
+
isoColumns.add(match[1]);
|
|
31729
|
+
}
|
|
31730
|
+
return isoColumns;
|
|
31731
|
+
}
|
|
31732
|
+
function isIntegerSourceType(srcType) {
|
|
31733
|
+
const upper = srcType.toUpperCase();
|
|
31734
|
+
return upper.includes("INT") || upper === "" || upper === "NUMERIC";
|
|
31735
|
+
}
|
|
31736
|
+
function buildDigestExpr(targetTableName, col, srcType, isoGlobCols) {
|
|
31737
|
+
const srcRef = `"${col}"`;
|
|
31738
|
+
if (isoGlobCols.has(col) && isIntegerSourceType(srcType)) {
|
|
31739
|
+
return buildEpochToIsoExpr(srcRef);
|
|
31740
|
+
}
|
|
31741
|
+
const clampExpr = numericClampExpr(targetTableName, col, srcRef);
|
|
31742
|
+
if (clampExpr !== null) return clampExpr;
|
|
31743
|
+
const normExpr = enumNormExpr(targetTableName, col, srcRef);
|
|
31744
|
+
if (normExpr !== null) return normExpr;
|
|
31745
|
+
return srcRef;
|
|
31746
|
+
}
|
|
31747
|
+
var ENUM_NORMALIZATIONS, NUMERIC_CLAMPS, ISO_CHECK_REGEX, EPOCH_SECONDS_THRESHOLD;
|
|
31748
|
+
var init_column_transforms = __esm({
|
|
31749
|
+
"packages/core/src/store/exodus/column-transforms.ts"() {
|
|
31750
|
+
"use strict";
|
|
31751
|
+
ENUM_NORMALIZATIONS = /* @__PURE__ */ new Map([
|
|
31752
|
+
// --- task_commits.link_source -------------------------------------------
|
|
31753
|
+
// 'commit-message' → 'commit-subject' (pre-T9506 legacy value)
|
|
31754
|
+
[
|
|
31755
|
+
"tasks_task_commits.link_source",
|
|
31756
|
+
(src) => `CASE ${src} WHEN 'commit-message' THEN 'commit-subject' ELSE ${src} END`
|
|
31757
|
+
],
|
|
31758
|
+
// --- architecture_decisions.status (case + date-suffix normalization) ----
|
|
31759
|
+
// 'Accepted', 'ACCEPTED', 'approved', 'Accepted (2026-04-18)', … → 'accepted'
|
|
31760
|
+
// 'Proposed', 'PROPOSED' → 'proposed'
|
|
31761
|
+
// 'Superseded', 'SUPERSEDED' → 'superseded'
|
|
31762
|
+
[
|
|
31763
|
+
"tasks_architecture_decisions.status",
|
|
31764
|
+
(src) => `CASE WHEN lower(${src}) = 'accepted' OR lower(${src}) LIKE 'accepted %' OR lower(${src}) = 'approved' THEN 'accepted' WHEN lower(${src}) = 'proposed' THEN 'proposed' WHEN lower(${src}) = 'superseded' THEN 'superseded' WHEN lower(${src}) = 'deprecated' THEN 'deprecated' ELSE ${src} END`
|
|
31765
|
+
],
|
|
31766
|
+
// --- brain_* enum normalizations REMOVED (T11647) -----------------------
|
|
31767
|
+
// The brain memory family now lands in the consolidated cleo.db in its LEGACY
|
|
31768
|
+
// RUNTIME shape — INTEGER epoch timestamps and, critically, NO SQL CHECK
|
|
31769
|
+
// constraints (the `text({ enum })` unions are enforced only at the
|
|
31770
|
+
// application layer, exactly as the runtime `drizzle-brain` tables are). With
|
|
31771
|
+
// no brain CHECK constraint to satisfy, exodus MUST copy every brain enum
|
|
31772
|
+
// value VERBATIM — coercing them (e.g. source_type 'observer-compressed'/
|
|
31773
|
+
// 'sleep-consolidation' → 'agent', type 'observation'/'proposal'/'pattern' →
|
|
31774
|
+
// nearest) would now be unnecessary data CORRUPTION, not a constraint fix.
|
|
31775
|
+
// The previous brain entries (brain_observations.{source_type,type},
|
|
31776
|
+
// brain_decisions.{confirmation_state,decision_category,confidence,outcome,
|
|
31777
|
+
// decided_by}) are therefore deleted. The non-brain entries below still apply
|
|
31778
|
+
// because those consolidated tables retain their CHECK constraints.
|
|
31779
|
+
// --- tasks_token_usage.transport (T11548 → REMOVED T11649) ---------------
|
|
31780
|
+
// NO normalization. 'mcp' is a first-class transport origin (MCP-gateway
|
|
31781
|
+
// requests) and is preserved verbatim. The consolidated CHECK enum was WIDENED
|
|
31782
|
+
// to include 'mcp' (canonical TOKEN_USAGE_TRANSPORTS SSoT + forward migration
|
|
31783
|
+
// 20260602000002_t11649-token-usage-transport-mcp), so the value lands without
|
|
31784
|
+
// coercion. The earlier 'mcp' → 'agent' mapping was a silent semantic alteration
|
|
31785
|
+
// of ~194 rows (count-preserving, NOT integrity-preserving) — see T11649.
|
|
31786
|
+
// (brain_decisions.{decision_category,confidence} normalizations removed —
|
|
31787
|
+
// T11647: brain target = runtime shape with no CHECK; copy values verbatim.)
|
|
31788
|
+
// --- tasks_commits.conventional_type (T11548 + T11578) -------------------
|
|
31789
|
+
// The consolidated CHECK enum is feat/fix/chore/docs/refactor/test/build/ci/
|
|
31790
|
+
// perf/revert/breaking. Real git history carries non-conventional subjects:
|
|
31791
|
+
// - 'style' → 'chore' (pre-T11548 mapping; no 'style' in enum).
|
|
31792
|
+
// - 'merge'/'release' → 'chore' (T11578): merge + release commits are
|
|
31793
|
+
// maintenance-class; the precise semantic is preserved by the dedicated
|
|
31794
|
+
// `is_merge_commit` / `is_release_commit` boolean columns, so collapsing
|
|
31795
|
+
// `conventional_type` to the maintenance catch-all 'chore' is lossless at
|
|
31796
|
+
// the row grain. Without this the 'merge'/'release' rows violate the CHECK,
|
|
31797
|
+
// `INSERT OR IGNORE` drops the WHOLE commits table, and the exodus-on-open
|
|
31798
|
+
// data-continuity gate aborts the cutover (T11578 CI regression).
|
|
31799
|
+
// - any OTHER out-of-enum value → 'chore' (defensive: future non-conventional
|
|
31800
|
+
// subjects must never re-break the zero-deficit gate; the boolean flags and
|
|
31801
|
+
// raw subject text remain the precise provenance).
|
|
31802
|
+
[
|
|
31803
|
+
"tasks_commits.conventional_type",
|
|
31804
|
+
(src) => `CASE WHEN ${src} IS NULL THEN NULL WHEN ${src} IN ('feat', 'fix', 'chore', 'docs', 'refactor', 'test', 'build', 'ci', 'perf', 'revert', 'breaking') THEN ${src} ELSE 'chore' END`
|
|
31805
|
+
],
|
|
31806
|
+
// --- tasks_task_relations.relation_type (T11548) -------------------------
|
|
31807
|
+
// 'grouped-by' → 'groups' (enum: related/blocks/duplicates/absorbs/fixes/extends/
|
|
31808
|
+
// supersedes/groups). 4 rows.
|
|
31809
|
+
[
|
|
31810
|
+
"tasks_task_relations.relation_type",
|
|
31811
|
+
(src) => `CASE ${src} WHEN 'grouped-by' THEN 'groups' ELSE ${src} END`
|
|
31812
|
+
],
|
|
31813
|
+
// --- tasks_lifecycle_stages.stage_name (T11548) --------------------------
|
|
31814
|
+
// Legacy camelCase / past-tense values → canonical snake_case stage names.
|
|
31815
|
+
// 'implemented' → 'implementation', 'qaPassed' → 'validation',
|
|
31816
|
+
// 'testsPassed' → 'testing'. 3 rows.
|
|
31817
|
+
[
|
|
31818
|
+
"tasks_lifecycle_stages.stage_name",
|
|
31819
|
+
(src) => `CASE ${src} WHEN 'implemented' THEN 'implementation' WHEN 'qaPassed' THEN 'validation' WHEN 'testsPassed' THEN 'testing' ELSE ${src} END`
|
|
31820
|
+
],
|
|
31821
|
+
// --- tasks_architecture_decisions.gate_status (T11548) ------------------
|
|
31822
|
+
// 'passed (T5313 consensus)' → 'passed', 'approved' → 'passed'
|
|
31823
|
+
// (enum: pending/passed/failed/waived). 2 rows.
|
|
31824
|
+
[
|
|
31825
|
+
"tasks_architecture_decisions.gate_status",
|
|
31826
|
+
(src) => `CASE WHEN ${src} LIKE 'passed%' THEN 'passed' WHEN ${src} = 'approved' THEN 'passed' ELSE ${src} END`
|
|
31827
|
+
],
|
|
31828
|
+
// --- tasks_evidence_ac_bindings.binding_type (T11548) -------------------
|
|
31829
|
+
// Values with a 'validator:...' prefix → 'direct'
|
|
31830
|
+
// (enum: direct/satisfies/coverage). 3 rows.
|
|
31831
|
+
// Strip the namespace prefix introduced before the enum was tightened.
|
|
31832
|
+
[
|
|
31833
|
+
"tasks_evidence_ac_bindings.binding_type",
|
|
31834
|
+
(src) => `CASE WHEN ${src} LIKE 'validator:%' THEN 'direct' ELSE ${src} END`
|
|
31835
|
+
]
|
|
31836
|
+
// (brain_decisions.{outcome,decided_by} normalizations removed — T11647:
|
|
31837
|
+
// brain target = runtime shape with no CHECK; legacy values like 'accepted',
|
|
31838
|
+
// 'rejected', 'prime' now survive VERBATIM instead of being coerced.)
|
|
31839
|
+
]);
|
|
31840
|
+
NUMERIC_CLAMPS = /* @__PURE__ */ new Map([
|
|
31841
|
+
// --- brain_weight_history.delta_weight (T11782) -------------------------
|
|
31842
|
+
// +Inf → 1.0 (max canonical reinforcement), -Inf → -1.0 (max canonical
|
|
31843
|
+
// depression), NaN → 0.0 (no-op delta). Finite values pass through.
|
|
31844
|
+
[
|
|
31845
|
+
"brain_weight_history.delta_weight",
|
|
31846
|
+
(src) => `CASE WHEN ${src} = 9e999 THEN 1.0 WHEN ${src} = -9e999 THEN -1.0 WHEN ${src} != ${src} THEN 0.0 ELSE ${src} END`
|
|
31847
|
+
]
|
|
31848
|
+
]);
|
|
31849
|
+
ISO_CHECK_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+IS\s+NULL\s+OR\s+"[^"]+"\s+GLOB\s+'\[0-9/gi;
|
|
31850
|
+
EPOCH_SECONDS_THRESHOLD = 1e11;
|
|
31851
|
+
}
|
|
31852
|
+
});
|
|
31853
|
+
|
|
31698
31854
|
// packages/core/src/store/exodus/table-name-map.ts
|
|
31699
31855
|
function resolveTableTargetScope(sourceName, legacyTable, sourceScope) {
|
|
31700
31856
|
if (inferSourceKind(sourceName) === "nexus" && NEXUS_GRAPH_PROJECT_TABLES.has(legacyTable)) {
|
|
@@ -32120,23 +32276,6 @@ function makeAttachAlias(name2, index2) {
|
|
|
32120
32276
|
const safe = name2.replace(/[^a-z0-9]/gi, "_").replace(/_+/g, "_").slice(0, 20);
|
|
32121
32277
|
return `_src_${safe}_${index2}`;
|
|
32122
32278
|
}
|
|
32123
|
-
function typeDefaultLiteral(colType) {
|
|
32124
|
-
const upper = colType.toUpperCase();
|
|
32125
|
-
if (upper.includes("INT")) return "0";
|
|
32126
|
-
if (upper.includes("REAL") || upper.includes("FLOAT") || upper.includes("DOUBLE")) return "0.0";
|
|
32127
|
-
if (upper.includes("BLOB")) return "x''";
|
|
32128
|
-
return "''";
|
|
32129
|
-
}
|
|
32130
|
-
function enumNormExpr(targetTableName, col, srcRef) {
|
|
32131
|
-
const key = `${targetTableName}.${col}`;
|
|
32132
|
-
const fn = ENUM_NORMALIZATIONS.get(key);
|
|
32133
|
-
return fn ? fn(srcRef) : null;
|
|
32134
|
-
}
|
|
32135
|
-
function numericClampExpr(targetTableName, col, srcRef) {
|
|
32136
|
-
const key = `${targetTableName}.${col}`;
|
|
32137
|
-
const fn = NUMERIC_CLAMPS.get(key);
|
|
32138
|
-
return fn ? fn(srcRef) : null;
|
|
32139
|
-
}
|
|
32140
32279
|
function epochUnitForSource(sourceName) {
|
|
32141
32280
|
const key = sourceName.toLowerCase();
|
|
32142
32281
|
for (const [pattern, unit] of SOURCE_EPOCH_UNITS) {
|
|
@@ -32144,22 +32283,6 @@ function epochUnitForSource(sourceName) {
|
|
|
32144
32283
|
}
|
|
32145
32284
|
return "seconds";
|
|
32146
32285
|
}
|
|
32147
|
-
function buildEpochToIsoExpr(srcRef) {
|
|
32148
|
-
return `CASE WHEN ${srcRef} IS NULL THEN NULL WHEN ${srcRef} < ${EPOCH_SECONDS_THRESHOLD} THEN strftime('%Y-%m-%dT%H:%M:%fZ', ${srcRef}, 'unixepoch') ELSE strftime('%Y-%m-%dT%H:%M:%fZ', ${srcRef}/1000.0, 'unixepoch') END`;
|
|
32149
|
-
}
|
|
32150
|
-
function detectIsoGlobColumns(db, tableName, targetSchema = "main") {
|
|
32151
|
-
const escapedTable = tableName.replace(/'/g, "''");
|
|
32152
|
-
const row = db.prepare(
|
|
32153
|
-
`SELECT sql FROM "${targetSchema}".sqlite_master WHERE type='table' AND name='${escapedTable}'`
|
|
32154
|
-
).get();
|
|
32155
|
-
if (!row?.sql) return /* @__PURE__ */ new Set();
|
|
32156
|
-
const isoColumns = /* @__PURE__ */ new Set();
|
|
32157
|
-
ISO_CHECK_REGEX.lastIndex = 0;
|
|
32158
|
-
for (const match of row.sql.matchAll(ISO_CHECK_REGEX)) {
|
|
32159
|
-
isoColumns.add(match[1]);
|
|
32160
|
-
}
|
|
32161
|
-
return isoColumns;
|
|
32162
|
-
}
|
|
32163
32286
|
function buildSelectExpr(attachAlias, legacyTable, targetTableName, col, srcType, tgtInfo, isoGlobCols) {
|
|
32164
32287
|
const srcRef = `"${attachAlias}"."${legacyTable}"."${col}"`;
|
|
32165
32288
|
const srcUpper = srcType.toUpperCase();
|
|
@@ -32618,7 +32741,7 @@ async function migrateScope(scope, sources, targetNativeDb, journal, stagingDir,
|
|
|
32618
32741
|
}
|
|
32619
32742
|
}
|
|
32620
32743
|
}
|
|
32621
|
-
var log2, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME,
|
|
32744
|
+
var log2, LOCK_SENTINEL_SUFFIX, JOURNAL_FILENAME, SOURCE_EPOCH_UNITS;
|
|
32622
32745
|
var init_migrate = __esm({
|
|
32623
32746
|
"packages/core/src/store/exodus/migrate.ts"() {
|
|
32624
32747
|
"use strict";
|
|
@@ -32626,110 +32749,12 @@ var init_migrate = __esm({
|
|
|
32626
32749
|
init_ensure_config();
|
|
32627
32750
|
init_dual_scope_db();
|
|
32628
32751
|
init_open_cleo_db();
|
|
32752
|
+
init_column_transforms();
|
|
32629
32753
|
init_table_name_map();
|
|
32630
32754
|
init_types();
|
|
32631
32755
|
log2 = getLogger("exodus-migrate");
|
|
32632
32756
|
LOCK_SENTINEL_SUFFIX = ".exodus-lock";
|
|
32633
32757
|
JOURNAL_FILENAME = "exodus-journal.json";
|
|
32634
|
-
ENUM_NORMALIZATIONS = /* @__PURE__ */ new Map([
|
|
32635
|
-
// --- task_commits.link_source -------------------------------------------
|
|
32636
|
-
// 'commit-message' → 'commit-subject' (pre-T9506 legacy value)
|
|
32637
|
-
[
|
|
32638
|
-
"tasks_task_commits.link_source",
|
|
32639
|
-
(src) => `CASE ${src} WHEN 'commit-message' THEN 'commit-subject' ELSE ${src} END`
|
|
32640
|
-
],
|
|
32641
|
-
// --- architecture_decisions.status (case + date-suffix normalization) ----
|
|
32642
|
-
// 'Accepted', 'ACCEPTED', 'approved', 'Accepted (2026-04-18)', … → 'accepted'
|
|
32643
|
-
// 'Proposed', 'PROPOSED' → 'proposed'
|
|
32644
|
-
// 'Superseded', 'SUPERSEDED' → 'superseded'
|
|
32645
|
-
[
|
|
32646
|
-
"tasks_architecture_decisions.status",
|
|
32647
|
-
(src) => `CASE WHEN lower(${src}) = 'accepted' OR lower(${src}) LIKE 'accepted %' OR lower(${src}) = 'approved' THEN 'accepted' WHEN lower(${src}) = 'proposed' THEN 'proposed' WHEN lower(${src}) = 'superseded' THEN 'superseded' WHEN lower(${src}) = 'deprecated' THEN 'deprecated' ELSE ${src} END`
|
|
32648
|
-
],
|
|
32649
|
-
// --- brain_* enum normalizations REMOVED (T11647) -----------------------
|
|
32650
|
-
// The brain memory family now lands in the consolidated cleo.db in its LEGACY
|
|
32651
|
-
// RUNTIME shape — INTEGER epoch timestamps and, critically, NO SQL CHECK
|
|
32652
|
-
// constraints (the `text({ enum })` unions are enforced only at the
|
|
32653
|
-
// application layer, exactly as the runtime `drizzle-brain` tables are). With
|
|
32654
|
-
// no brain CHECK constraint to satisfy, exodus MUST copy every brain enum
|
|
32655
|
-
// value VERBATIM — coercing them (e.g. source_type 'observer-compressed'/
|
|
32656
|
-
// 'sleep-consolidation' → 'agent', type 'observation'/'proposal'/'pattern' →
|
|
32657
|
-
// nearest) would now be unnecessary data CORRUPTION, not a constraint fix.
|
|
32658
|
-
// The previous brain entries (brain_observations.{source_type,type},
|
|
32659
|
-
// brain_decisions.{confirmation_state,decision_category,confidence,outcome,
|
|
32660
|
-
// decided_by}) are therefore deleted. The non-brain entries below still apply
|
|
32661
|
-
// because those consolidated tables retain their CHECK constraints.
|
|
32662
|
-
// --- tasks_token_usage.transport (T11548 → REMOVED T11649) ---------------
|
|
32663
|
-
// NO normalization. 'mcp' is a first-class transport origin (MCP-gateway
|
|
32664
|
-
// requests) and is preserved verbatim. The consolidated CHECK enum was WIDENED
|
|
32665
|
-
// to include 'mcp' (canonical TOKEN_USAGE_TRANSPORTS SSoT + forward migration
|
|
32666
|
-
// 20260602000002_t11649-token-usage-transport-mcp), so the value lands without
|
|
32667
|
-
// coercion. The earlier 'mcp' → 'agent' mapping was a silent semantic alteration
|
|
32668
|
-
// of ~194 rows (count-preserving, NOT integrity-preserving) — see T11649.
|
|
32669
|
-
// (brain_decisions.{decision_category,confidence} normalizations removed —
|
|
32670
|
-
// T11647: brain target = runtime shape with no CHECK; copy values verbatim.)
|
|
32671
|
-
// --- tasks_commits.conventional_type (T11548 + T11578) -------------------
|
|
32672
|
-
// The consolidated CHECK enum is feat/fix/chore/docs/refactor/test/build/ci/
|
|
32673
|
-
// perf/revert/breaking. Real git history carries non-conventional subjects:
|
|
32674
|
-
// - 'style' → 'chore' (pre-T11548 mapping; no 'style' in enum).
|
|
32675
|
-
// - 'merge'/'release' → 'chore' (T11578): merge + release commits are
|
|
32676
|
-
// maintenance-class; the precise semantic is preserved by the dedicated
|
|
32677
|
-
// `is_merge_commit` / `is_release_commit` boolean columns, so collapsing
|
|
32678
|
-
// `conventional_type` to the maintenance catch-all 'chore' is lossless at
|
|
32679
|
-
// the row grain. Without this the 'merge'/'release' rows violate the CHECK,
|
|
32680
|
-
// `INSERT OR IGNORE` drops the WHOLE commits table, and the exodus-on-open
|
|
32681
|
-
// data-continuity gate aborts the cutover (T11578 CI regression).
|
|
32682
|
-
// - any OTHER out-of-enum value → 'chore' (defensive: future non-conventional
|
|
32683
|
-
// subjects must never re-break the zero-deficit gate; the boolean flags and
|
|
32684
|
-
// raw subject text remain the precise provenance).
|
|
32685
|
-
[
|
|
32686
|
-
"tasks_commits.conventional_type",
|
|
32687
|
-
(src) => `CASE WHEN ${src} IS NULL THEN NULL WHEN ${src} IN ('feat', 'fix', 'chore', 'docs', 'refactor', 'test', 'build', 'ci', 'perf', 'revert', 'breaking') THEN ${src} ELSE 'chore' END`
|
|
32688
|
-
],
|
|
32689
|
-
// --- tasks_task_relations.relation_type (T11548) -------------------------
|
|
32690
|
-
// 'grouped-by' → 'groups' (enum: related/blocks/duplicates/absorbs/fixes/extends/
|
|
32691
|
-
// supersedes/groups). 4 rows.
|
|
32692
|
-
[
|
|
32693
|
-
"tasks_task_relations.relation_type",
|
|
32694
|
-
(src) => `CASE ${src} WHEN 'grouped-by' THEN 'groups' ELSE ${src} END`
|
|
32695
|
-
],
|
|
32696
|
-
// --- tasks_lifecycle_stages.stage_name (T11548) --------------------------
|
|
32697
|
-
// Legacy camelCase / past-tense values → canonical snake_case stage names.
|
|
32698
|
-
// 'implemented' → 'implementation', 'qaPassed' → 'validation',
|
|
32699
|
-
// 'testsPassed' → 'testing'. 3 rows.
|
|
32700
|
-
[
|
|
32701
|
-
"tasks_lifecycle_stages.stage_name",
|
|
32702
|
-
(src) => `CASE ${src} WHEN 'implemented' THEN 'implementation' WHEN 'qaPassed' THEN 'validation' WHEN 'testsPassed' THEN 'testing' ELSE ${src} END`
|
|
32703
|
-
],
|
|
32704
|
-
// --- tasks_architecture_decisions.gate_status (T11548) ------------------
|
|
32705
|
-
// 'passed (T5313 consensus)' → 'passed', 'approved' → 'passed'
|
|
32706
|
-
// (enum: pending/passed/failed/waived). 2 rows.
|
|
32707
|
-
[
|
|
32708
|
-
"tasks_architecture_decisions.gate_status",
|
|
32709
|
-
(src) => `CASE WHEN ${src} LIKE 'passed%' THEN 'passed' WHEN ${src} = 'approved' THEN 'passed' ELSE ${src} END`
|
|
32710
|
-
],
|
|
32711
|
-
// --- tasks_evidence_ac_bindings.binding_type (T11548) -------------------
|
|
32712
|
-
// Values with a 'validator:...' prefix → 'direct'
|
|
32713
|
-
// (enum: direct/satisfies/coverage). 3 rows.
|
|
32714
|
-
// Strip the namespace prefix introduced before the enum was tightened.
|
|
32715
|
-
[
|
|
32716
|
-
"tasks_evidence_ac_bindings.binding_type",
|
|
32717
|
-
(src) => `CASE WHEN ${src} LIKE 'validator:%' THEN 'direct' ELSE ${src} END`
|
|
32718
|
-
]
|
|
32719
|
-
// (brain_decisions.{outcome,decided_by} normalizations removed — T11647:
|
|
32720
|
-
// brain target = runtime shape with no CHECK; legacy values like 'accepted',
|
|
32721
|
-
// 'rejected', 'prime' now survive VERBATIM instead of being coerced.)
|
|
32722
|
-
]);
|
|
32723
|
-
NUMERIC_CLAMPS = /* @__PURE__ */ new Map([
|
|
32724
|
-
// --- brain_weight_history.delta_weight (T11782) -------------------------
|
|
32725
|
-
// +Inf → 1.0 (max canonical reinforcement), -Inf → -1.0 (max canonical
|
|
32726
|
-
// depression), NaN → 0.0 (no-op delta). Finite values pass through.
|
|
32727
|
-
[
|
|
32728
|
-
"brain_weight_history.delta_weight",
|
|
32729
|
-
(src) => `CASE WHEN ${src} = 9e999 THEN 1.0 WHEN ${src} = -9e999 THEN -1.0 WHEN ${src} != ${src} THEN 0.0 ELSE ${src} END`
|
|
32730
|
-
]
|
|
32731
|
-
]);
|
|
32732
|
-
ISO_CHECK_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+IS\s+NULL\s+OR\s+"[^"]+"\s+GLOB\s+'\[0-9/gi;
|
|
32733
32758
|
SOURCE_EPOCH_UNITS = /* @__PURE__ */ new Map([
|
|
32734
32759
|
["conduit", "seconds"],
|
|
32735
32760
|
["brain", "milliseconds"],
|
|
@@ -32740,7 +32765,6 @@ var init_migrate = __esm({
|
|
|
32740
32765
|
["nexus", "milliseconds"],
|
|
32741
32766
|
["skills", "milliseconds"]
|
|
32742
32767
|
]);
|
|
32743
|
-
EPOCH_SECONDS_THRESHOLD = 1e11;
|
|
32744
32768
|
}
|
|
32745
32769
|
});
|
|
32746
32770
|
|
|
@@ -32923,11 +32947,21 @@ function orderByClause(db, tableName) {
|
|
|
32923
32947
|
}
|
|
32924
32948
|
return "rowid";
|
|
32925
32949
|
}
|
|
32926
|
-
function computeTableDigest(db, tableName, columns) {
|
|
32950
|
+
function computeTableDigest(db, tableName, columns, transform) {
|
|
32927
32951
|
const { createHash: createHash3 } = _require("node:crypto");
|
|
32928
32952
|
const hasher = createHash3("sha256");
|
|
32929
32953
|
const orderBy = orderByClause(db, tableName);
|
|
32930
|
-
|
|
32954
|
+
let selectClause;
|
|
32955
|
+
if (columns !== null && columns.length > 0) {
|
|
32956
|
+
selectClause = columns.map((c) => {
|
|
32957
|
+
if (transform === void 0) return `"${c}"`;
|
|
32958
|
+
const srcType = transform.srcTypeByCol.get(c) ?? "";
|
|
32959
|
+
const expr = buildDigestExpr(transform.targetTableName, c, srcType, transform.isoGlobCols);
|
|
32960
|
+
return `${expr} AS "${c}"`;
|
|
32961
|
+
}).join(", ");
|
|
32962
|
+
} else {
|
|
32963
|
+
selectClause = "*";
|
|
32964
|
+
}
|
|
32931
32965
|
let rows;
|
|
32932
32966
|
try {
|
|
32933
32967
|
rows = db.prepare(`SELECT ${selectClause} FROM "${tableName}" ORDER BY ${orderBy}`).all();
|
|
@@ -32962,6 +32996,17 @@ function sharedColumnsSorted(srcDb, srcTable, tgtDb, tgtTable) {
|
|
|
32962
32996
|
return null;
|
|
32963
32997
|
}
|
|
32964
32998
|
}
|
|
32999
|
+
function buildSourceDigestTransform(srcDb, srcTable, tgtDb, targetTableName) {
|
|
33000
|
+
try {
|
|
33001
|
+
const srcTypeByCol = new Map(
|
|
33002
|
+
srcDb.prepare(`PRAGMA table_info("${srcTable}")`).all().map((r) => [r.name, r.type])
|
|
33003
|
+
);
|
|
33004
|
+
const isoGlobCols = detectIsoGlobColumns(tgtDb, targetTableName);
|
|
33005
|
+
return { targetTableName, srcTypeByCol, isoGlobCols };
|
|
33006
|
+
} catch {
|
|
33007
|
+
return void 0;
|
|
33008
|
+
}
|
|
33009
|
+
}
|
|
32965
33010
|
function listTables2(db) {
|
|
32966
33011
|
const rows = db.prepare(
|
|
32967
33012
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
|
|
@@ -33209,7 +33254,13 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress) {
|
|
|
33209
33254
|
targetSnap.db,
|
|
33210
33255
|
targetTableName
|
|
33211
33256
|
);
|
|
33212
|
-
const
|
|
33257
|
+
const srcTransform = buildSourceDigestTransform(
|
|
33258
|
+
srcSnap.db,
|
|
33259
|
+
legacyTableName,
|
|
33260
|
+
targetSnap.db,
|
|
33261
|
+
targetTableName
|
|
33262
|
+
);
|
|
33263
|
+
const srcDigest = computeTableDigest(srcSnap.db, legacyTableName, cols, srcTransform);
|
|
33213
33264
|
const tgtDigest = computeTableDigest(targetSnap.db, targetTableName, cols);
|
|
33214
33265
|
const countMatch = srcDigest.count === tgtDigest.count;
|
|
33215
33266
|
const hashMatch = srcDigest.hash === tgtDigest.hash;
|
|
@@ -33322,6 +33373,7 @@ var init_verify_migration = __esm({
|
|
|
33322
33373
|
init_src();
|
|
33323
33374
|
init_logger2();
|
|
33324
33375
|
init_open_cleo_db();
|
|
33376
|
+
init_column_transforms();
|
|
33325
33377
|
init_table_name_map();
|
|
33326
33378
|
log3 = getLogger("verify-migration");
|
|
33327
33379
|
_require = createRequire3(import.meta.url);
|