@cleocode/core 2026.4.45 → 2026.4.47
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.js +84 -77
- package/dist/index.js.map +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +128 -109
- package/dist/internal.js.map +3 -3
- package/dist/memory/brain-lifecycle.d.ts +13 -6
- package/dist/memory/brain-lifecycle.d.ts.map +1 -1
- package/dist/memory/brain-maintenance.d.ts +11 -0
- package/dist/memory/brain-maintenance.d.ts.map +1 -1
- package/dist/store/db-helpers.d.ts +8 -3
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/package.json +18 -8
- package/src/internal.ts +16 -3
- package/src/memory/__tests__/brain-automation.test.ts +1 -0
- package/src/memory/__tests__/brain-lifecycle-tier-promotion.test.ts +367 -0
- package/src/memory/brain-lifecycle.ts +43 -32
- package/src/memory/brain-maintenance.ts +27 -2
- package/src/store/__tests__/db-helpers.test.ts +46 -6
- package/src/store/db-helpers.ts +25 -4
- package/src/store/sqlite-data-accessor.ts +2 -1
- package/src/tasks/__tests__/epic-auto-complete.test.ts +331 -0
- package/src/tasks/complete.ts +7 -4
package/dist/internal.js
CHANGED
|
@@ -11471,14 +11471,14 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11471
11471
|
const dbHashes = new Set(dbEntries.map((e) => e.hash));
|
|
11472
11472
|
const allLocalHashesPresentInDb = localMigrations.every((m2) => dbHashes.has(m2.hash));
|
|
11473
11473
|
if (allLocalHashesPresentInDb) {
|
|
11474
|
-
const
|
|
11475
|
-
|
|
11474
|
+
const log12 = getLogger(logSubsystem);
|
|
11475
|
+
log12.debug(
|
|
11476
11476
|
{ extra: orphanedEntries.length },
|
|
11477
11477
|
`Migration journal has ${orphanedEntries.length} entries for migrations not known to this install (DB is ahead). Skipping reconciliation.`
|
|
11478
11478
|
);
|
|
11479
11479
|
} else {
|
|
11480
|
-
const
|
|
11481
|
-
|
|
11480
|
+
const log12 = getLogger(logSubsystem);
|
|
11481
|
+
log12.warn(
|
|
11482
11482
|
{ orphaned: orphanedEntries.length },
|
|
11483
11483
|
`Detected stale migration journal entries from a previous CLEO version. Reconciling.`
|
|
11484
11484
|
);
|
|
@@ -11509,8 +11509,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11509
11509
|
return cols.some((c) => c.name === column);
|
|
11510
11510
|
});
|
|
11511
11511
|
if (allColumnsExist) {
|
|
11512
|
-
const
|
|
11513
|
-
|
|
11512
|
+
const log12 = getLogger(logSubsystem);
|
|
11513
|
+
log12.warn(
|
|
11514
11514
|
{ migration: migration.name, columns: alterMatches },
|
|
11515
11515
|
`Detected partially-applied migration ${migration.name} \u2014 columns exist but journal entry missing. Auto-reconciling.`
|
|
11516
11516
|
);
|
|
@@ -11528,8 +11528,8 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable, logSubsyst
|
|
|
11528
11528
|
for (const entry of unnamedEntries) {
|
|
11529
11529
|
const migrationName = hashToName.get(entry.hash);
|
|
11530
11530
|
if (!migrationName) continue;
|
|
11531
|
-
const
|
|
11532
|
-
|
|
11531
|
+
const log12 = getLogger(logSubsystem);
|
|
11532
|
+
log12.warn(
|
|
11533
11533
|
{ id: entry.id, hash: entry.hash, name: migrationName },
|
|
11534
11534
|
`Backfilling missing name on journal entry id=${entry.id} \u2014 Drizzle v1 beta requires name for applied-migration detection.`
|
|
11535
11535
|
);
|
|
@@ -11573,8 +11573,8 @@ function ensureColumns(nativeDb, tableName, requiredColumns, logSubsystem) {
|
|
|
11573
11573
|
const existingCols = new Set(columns.map((c) => c.name));
|
|
11574
11574
|
for (const req of requiredColumns) {
|
|
11575
11575
|
if (!existingCols.has(req.name)) {
|
|
11576
|
-
const
|
|
11577
|
-
|
|
11576
|
+
const log12 = getLogger(logSubsystem);
|
|
11577
|
+
log12.warn(
|
|
11578
11578
|
{ column: req.name },
|
|
11579
11579
|
`Adding missing column ${tableName}.${req.name} via ALTER TABLE`
|
|
11580
11580
|
);
|
|
@@ -13972,7 +13972,7 @@ function getDbPath(cwd) {
|
|
|
13972
13972
|
return join10(getCleoDirAbsolute(cwd), DB_FILENAME2);
|
|
13973
13973
|
}
|
|
13974
13974
|
async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
13975
|
-
const
|
|
13975
|
+
const log12 = getLogger("sqlite");
|
|
13976
13976
|
try {
|
|
13977
13977
|
const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks").get();
|
|
13978
13978
|
const taskCount = countResult?.cnt ?? 0;
|
|
@@ -13993,7 +13993,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
13993
13993
|
if (backupTaskCount < MIN_BACKUP_TASK_COUNT) {
|
|
13994
13994
|
return;
|
|
13995
13995
|
}
|
|
13996
|
-
|
|
13996
|
+
log12.warn(
|
|
13997
13997
|
{ dbPath, backupPath: newestBackup.path, backupTasks: backupTaskCount },
|
|
13998
13998
|
`Empty database detected with ${backupTaskCount}-task backup available. Auto-recovering from backup. This likely happened because git-tracked WAL/SHM files were overwritten during a branch switch (T5188).`
|
|
13999
13999
|
);
|
|
@@ -14011,7 +14011,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
14011
14011
|
const tempPath = dbPath + ".recovery-tmp";
|
|
14012
14012
|
copyFileSync4(newestBackup.path, tempPath);
|
|
14013
14013
|
renameSync(tempPath, dbPath);
|
|
14014
|
-
|
|
14014
|
+
log12.info(
|
|
14015
14015
|
{ dbPath, backupPath: newestBackup.path, restoredTasks: backupTaskCount },
|
|
14016
14016
|
"Database auto-recovered from backup successfully."
|
|
14017
14017
|
);
|
|
@@ -14021,7 +14021,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
|
|
|
14021
14021
|
runMigrations(restoredNativeDb, restoredDb);
|
|
14022
14022
|
_db = restoredDb;
|
|
14023
14023
|
} catch (err) {
|
|
14024
|
-
|
|
14024
|
+
log12.error({ err, dbPath }, "Auto-recovery from backup failed. Continuing with empty database.");
|
|
14025
14025
|
}
|
|
14026
14026
|
}
|
|
14027
14027
|
async function getDb(cwd) {
|
|
@@ -14055,7 +14055,7 @@ async function getDb(cwd) {
|
|
|
14055
14055
|
const { execFileSync: execFileSync14 } = await import("node:child_process");
|
|
14056
14056
|
const gitCwd = resolve3(dbPath, "..", "..");
|
|
14057
14057
|
const filesToCheck = [dbPath, dbPath + "-wal", dbPath + "-shm"];
|
|
14058
|
-
const
|
|
14058
|
+
const log12 = getLogger("sqlite");
|
|
14059
14059
|
for (const fileToCheck of filesToCheck) {
|
|
14060
14060
|
try {
|
|
14061
14061
|
execFileSync14("git", ["ls-files", "--error-unmatch", fileToCheck], {
|
|
@@ -14064,7 +14064,7 @@ async function getDb(cwd) {
|
|
|
14064
14064
|
});
|
|
14065
14065
|
const basename18 = fileToCheck.split(/[\\/]/).pop();
|
|
14066
14066
|
const relPath = fileToCheck.replace(gitCwd + sep, "");
|
|
14067
|
-
|
|
14067
|
+
log12.warn(
|
|
14068
14068
|
{ path: fileToCheck },
|
|
14069
14069
|
`${basename18} is tracked by project git \u2014 this risks data loss on branch switch. Resolution (ADR-013 \xA79): \`git rm --cached ${relPath}\` and rely on \`.cleo/backups/sqlite/\` snapshots + \`cleo backup add\` for recovery.`
|
|
14070
14070
|
);
|
|
@@ -15258,11 +15258,18 @@ var init_cross_db_cleanup = __esm({
|
|
|
15258
15258
|
|
|
15259
15259
|
// packages/core/src/store/db-helpers.ts
|
|
15260
15260
|
import { eq as eq4, inArray as inArray2 } from "drizzle-orm";
|
|
15261
|
-
async function upsertTask(db, row, archiveFields) {
|
|
15261
|
+
async function upsertTask(db, row, archiveFields, allowOrphanParent = false) {
|
|
15262
15262
|
if (row.parentId) {
|
|
15263
15263
|
const parent = await db.select({ id: tasks.id }).from(tasks).where(eq4(tasks.id, row.parentId)).limit(1).all();
|
|
15264
15264
|
if (parent.length === 0) {
|
|
15265
|
-
|
|
15265
|
+
if (allowOrphanParent) {
|
|
15266
|
+
row = { ...row, parentId: null };
|
|
15267
|
+
} else {
|
|
15268
|
+
log2.warn(
|
|
15269
|
+
{ taskId: row.id, parentId: row.parentId },
|
|
15270
|
+
"upsertTask: parentId references a non-existent task \u2014 parent relationship may be lost"
|
|
15271
|
+
);
|
|
15272
|
+
}
|
|
15266
15273
|
}
|
|
15267
15274
|
}
|
|
15268
15275
|
const values = archiveFields ? { ...row, ...archiveFields, status: "archived" } : row;
|
|
@@ -15406,10 +15413,13 @@ async function loadRelationsForTasks(db, tasks2) {
|
|
|
15406
15413
|
}
|
|
15407
15414
|
}
|
|
15408
15415
|
}
|
|
15416
|
+
var log2;
|
|
15409
15417
|
var init_db_helpers = __esm({
|
|
15410
15418
|
"packages/core/src/store/db-helpers.ts"() {
|
|
15411
15419
|
"use strict";
|
|
15420
|
+
init_logger();
|
|
15412
15421
|
init_tasks_schema();
|
|
15422
|
+
log2 = getLogger("db-helpers");
|
|
15413
15423
|
}
|
|
15414
15424
|
});
|
|
15415
15425
|
|
|
@@ -15743,7 +15753,7 @@ async function createSqliteDataAccessor(cwd) {
|
|
|
15743
15753
|
archiveReason: taskAny.archiveReason ?? "completed",
|
|
15744
15754
|
cycleTimeDays: taskAny.cycleTimeDays ?? null
|
|
15745
15755
|
};
|
|
15746
|
-
await upsertTask(db, row, archiveFields);
|
|
15756
|
+
await upsertTask(db, row, archiveFields, true);
|
|
15747
15757
|
depBatch.push({ taskId: task.id, deps: task.depends ?? [] });
|
|
15748
15758
|
}
|
|
15749
15759
|
await batchUpdateDependencies(db, depBatch, validDepIds);
|
|
@@ -16756,7 +16766,7 @@ async function ensureSequenceValid(cwd, options) {
|
|
|
16756
16766
|
if (!options?.validateSequence) return;
|
|
16757
16767
|
const check2 = await checkSequence(cwd);
|
|
16758
16768
|
if (!check2.valid) {
|
|
16759
|
-
|
|
16769
|
+
log3.warn({ counter: check2.counter, maxId: check2.maxIdInData }, "Sequence behind, repairing");
|
|
16760
16770
|
const repair = await repairSequence(cwd);
|
|
16761
16771
|
if (!repair.repaired && options.strict) {
|
|
16762
16772
|
throw new DataSafetyError(`Sequence repair failed: ${repair.message}`, "SEQUENCE_INVALID", {
|
|
@@ -16773,7 +16783,7 @@ async function checkpoint(context, cwd, options) {
|
|
|
16773
16783
|
stats.checkpoints++;
|
|
16774
16784
|
stats.lastCheckpoint = /* @__PURE__ */ new Date();
|
|
16775
16785
|
} catch (err) {
|
|
16776
|
-
|
|
16786
|
+
log3.warn({ err }, "Checkpoint failed (non-fatal)");
|
|
16777
16787
|
}
|
|
16778
16788
|
vacuumIntoBackup({ cwd }).catch(() => {
|
|
16779
16789
|
});
|
|
@@ -16835,7 +16845,7 @@ async function safeAppendLog(accessor, entry, cwd, options) {
|
|
|
16835
16845
|
stats.writes++;
|
|
16836
16846
|
await checkpoint("log entry", cwd, opts);
|
|
16837
16847
|
}
|
|
16838
|
-
var
|
|
16848
|
+
var log3, DataSafetyError, DEFAULT_SAFETY, stats;
|
|
16839
16849
|
var init_data_safety_central = __esm({
|
|
16840
16850
|
"packages/core/src/store/data-safety-central.ts"() {
|
|
16841
16851
|
"use strict";
|
|
@@ -16843,7 +16853,7 @@ var init_data_safety_central = __esm({
|
|
|
16843
16853
|
init_sequence();
|
|
16844
16854
|
init_git_checkpoint();
|
|
16845
16855
|
init_sqlite_backup();
|
|
16846
|
-
|
|
16856
|
+
log3 = getLogger("data-safety");
|
|
16847
16857
|
DataSafetyError = class extends Error {
|
|
16848
16858
|
constructor(message, code, context) {
|
|
16849
16859
|
super(message);
|
|
@@ -16883,7 +16893,7 @@ function isSafetyDisabled() {
|
|
|
16883
16893
|
}
|
|
16884
16894
|
function wrapWithSafety(accessor, cwd) {
|
|
16885
16895
|
if (isSafetyDisabled()) {
|
|
16886
|
-
|
|
16896
|
+
log4.warn(
|
|
16887
16897
|
"Safety disabled - emergency mode (CLEO_DISABLE_SAFETY=true). Data integrity checks bypassed."
|
|
16888
16898
|
);
|
|
16889
16899
|
return accessor;
|
|
@@ -16904,13 +16914,13 @@ function getSafetyStatus() {
|
|
|
16904
16914
|
enabled: true
|
|
16905
16915
|
};
|
|
16906
16916
|
}
|
|
16907
|
-
var
|
|
16917
|
+
var log4, SafetyDataAccessor;
|
|
16908
16918
|
var init_safety_data_accessor = __esm({
|
|
16909
16919
|
"packages/core/src/store/safety-data-accessor.ts"() {
|
|
16910
16920
|
"use strict";
|
|
16911
16921
|
init_logger();
|
|
16912
16922
|
init_data_safety_central();
|
|
16913
|
-
|
|
16923
|
+
log4 = getLogger("data-safety");
|
|
16914
16924
|
SafetyDataAccessor = class {
|
|
16915
16925
|
/** The underlying accessor being wrapped. */
|
|
16916
16926
|
inner;
|
|
@@ -16934,7 +16944,7 @@ var init_safety_data_accessor = __esm({
|
|
|
16934
16944
|
...config2
|
|
16935
16945
|
};
|
|
16936
16946
|
if (this.config.verbose) {
|
|
16937
|
-
|
|
16947
|
+
log4.debug({ engine: inner.engine }, "SafetyDataAccessor initialized");
|
|
16938
16948
|
}
|
|
16939
16949
|
}
|
|
16940
16950
|
/** The storage engine backing this accessor. */
|
|
@@ -16946,7 +16956,7 @@ var init_safety_data_accessor = __esm({
|
|
|
16946
16956
|
*/
|
|
16947
16957
|
logVerbose(message) {
|
|
16948
16958
|
if (this.config.verbose) {
|
|
16949
|
-
|
|
16959
|
+
log4.debug(message);
|
|
16950
16960
|
}
|
|
16951
16961
|
}
|
|
16952
16962
|
/**
|
|
@@ -21347,16 +21357,16 @@ async function queryAudit(options) {
|
|
|
21347
21357
|
error: row.errorMessage ?? void 0
|
|
21348
21358
|
}));
|
|
21349
21359
|
} catch (err) {
|
|
21350
|
-
|
|
21360
|
+
log5.warn({ err }, "Failed to query audit entries from SQLite");
|
|
21351
21361
|
return [];
|
|
21352
21362
|
}
|
|
21353
21363
|
}
|
|
21354
|
-
var
|
|
21364
|
+
var log5;
|
|
21355
21365
|
var init_audit = __esm({
|
|
21356
21366
|
"packages/core/src/audit.ts"() {
|
|
21357
21367
|
"use strict";
|
|
21358
21368
|
init_logger();
|
|
21359
|
-
|
|
21369
|
+
log5 = getLogger("audit");
|
|
21360
21370
|
}
|
|
21361
21371
|
});
|
|
21362
21372
|
|
|
@@ -43701,13 +43711,16 @@ async function runTierPromotion(projectRoot) {
|
|
|
43701
43711
|
try {
|
|
43702
43712
|
shortToMedium = typedAll(
|
|
43703
43713
|
nativeDb.prepare(`
|
|
43704
|
-
SELECT id, citation_count, quality_score
|
|
43714
|
+
SELECT id, citation_count, quality_score, verified
|
|
43705
43715
|
FROM ${table}
|
|
43706
43716
|
WHERE memory_tier = 'short'
|
|
43707
43717
|
AND invalid_at IS NULL
|
|
43708
43718
|
AND ${dateCol} < ?
|
|
43709
|
-
AND
|
|
43710
|
-
|
|
43719
|
+
AND (
|
|
43720
|
+
citation_count >= 3
|
|
43721
|
+
OR quality_score >= 0.7
|
|
43722
|
+
OR verified = 1
|
|
43723
|
+
)
|
|
43711
43724
|
`),
|
|
43712
43725
|
age24h
|
|
43713
43726
|
);
|
|
@@ -43717,13 +43730,15 @@ async function runTierPromotion(projectRoot) {
|
|
|
43717
43730
|
for (const row of shortToMedium) {
|
|
43718
43731
|
try {
|
|
43719
43732
|
nativeDb.prepare(`UPDATE ${table} SET memory_tier = 'medium', updated_at = ? WHERE id = ?`).run(now2, row.id);
|
|
43720
|
-
|
|
43721
|
-
|
|
43722
|
-
|
|
43723
|
-
|
|
43724
|
-
|
|
43725
|
-
|
|
43726
|
-
|
|
43733
|
+
let reason;
|
|
43734
|
+
if (row.citation_count >= 3) {
|
|
43735
|
+
reason = `citationCount=${row.citation_count} >= 3, age > 24h`;
|
|
43736
|
+
} else if ((row.quality_score ?? 0) >= 0.7) {
|
|
43737
|
+
reason = `qualityScore=${row.quality_score?.toFixed(2)} >= 0.70, age > 24h`;
|
|
43738
|
+
} else {
|
|
43739
|
+
reason = `verified=true, age > 24h`;
|
|
43740
|
+
}
|
|
43741
|
+
promoted.push({ id: row.id, table, fromTier: "short", toTier: "medium", reason });
|
|
43727
43742
|
} catch {
|
|
43728
43743
|
}
|
|
43729
43744
|
}
|
|
@@ -43731,13 +43746,12 @@ async function runTierPromotion(projectRoot) {
|
|
|
43731
43746
|
try {
|
|
43732
43747
|
mediumToLong = typedAll(
|
|
43733
43748
|
nativeDb.prepare(`
|
|
43734
|
-
SELECT id, citation_count, quality_score
|
|
43749
|
+
SELECT id, citation_count, quality_score, verified
|
|
43735
43750
|
FROM ${table}
|
|
43736
43751
|
WHERE memory_tier = 'medium'
|
|
43737
43752
|
AND invalid_at IS NULL
|
|
43738
43753
|
AND ${dateCol} < ?
|
|
43739
|
-
AND verified = 1
|
|
43740
|
-
AND citation_count >= 5
|
|
43754
|
+
AND (citation_count >= 5 OR verified = 1)
|
|
43741
43755
|
`),
|
|
43742
43756
|
age7d
|
|
43743
43757
|
);
|
|
@@ -43747,13 +43761,8 @@ async function runTierPromotion(projectRoot) {
|
|
|
43747
43761
|
for (const row of mediumToLong) {
|
|
43748
43762
|
try {
|
|
43749
43763
|
nativeDb.prepare(`UPDATE ${table} SET memory_tier = 'long', updated_at = ? WHERE id = ?`).run(now2, row.id);
|
|
43750
|
-
|
|
43751
|
-
|
|
43752
|
-
table,
|
|
43753
|
-
fromTier: "medium",
|
|
43754
|
-
toTier: "long",
|
|
43755
|
-
reason: `citationCount=${row.citation_count} >= 5, verified, age > 7d`
|
|
43756
|
-
});
|
|
43764
|
+
const reason = row.citation_count >= 5 ? `citationCount=${row.citation_count} >= 5, age > 7d` : `verified=true, age > 7d`;
|
|
43765
|
+
promoted.push({ id: row.id, table, fromTier: "medium", toTier: "long", reason });
|
|
43757
43766
|
} catch {
|
|
43758
43767
|
}
|
|
43759
43768
|
}
|
|
@@ -54112,9 +54121,7 @@ async function completeTask(options, cwd, accessor) {
|
|
|
54112
54121
|
const parent = await acc.loadSingleTask(task.parentId);
|
|
54113
54122
|
if (parent && parent.type === "epic" && !parent.noAutoComplete) {
|
|
54114
54123
|
const siblings = await acc.getChildren(parent.id);
|
|
54115
|
-
const allDone = siblings.every(
|
|
54116
|
-
(c) => c.id === task.id || c.status === "done" || c.status === "cancelled"
|
|
54117
|
-
);
|
|
54124
|
+
const allDone = siblings.length > 0 && siblings.every((c) => c.id === task.id || c.status === "done" || c.status === "cancelled");
|
|
54118
54125
|
if (allDone) {
|
|
54119
54126
|
parent.status = "done";
|
|
54120
54127
|
parent.completedAt = now2;
|
|
@@ -58253,7 +58260,7 @@ async function validateAndRepairSequence(cwd, config2 = {}) {
|
|
|
58253
58260
|
}
|
|
58254
58261
|
const repair = await repairSequence(cwd);
|
|
58255
58262
|
if (repair.repaired) {
|
|
58256
|
-
|
|
58263
|
+
log11.warn(
|
|
58257
58264
|
{ oldCounter: repair.oldCounter, newCounter: repair.newCounter },
|
|
58258
58265
|
"Sequence repaired"
|
|
58259
58266
|
);
|
|
@@ -58282,7 +58289,7 @@ async function triggerCheckpoint(context, cwd, config2 = {}) {
|
|
|
58282
58289
|
try {
|
|
58283
58290
|
await gitCheckpoint("auto", context, cwd);
|
|
58284
58291
|
} catch (err) {
|
|
58285
|
-
|
|
58292
|
+
log11.warn({ err }, "Checkpoint failed (non-fatal)");
|
|
58286
58293
|
}
|
|
58287
58294
|
vacuumIntoBackup({ cwd }).catch(() => {
|
|
58288
58295
|
});
|
|
@@ -58320,16 +58327,16 @@ async function safeDeleteTask(deleteFn, taskId, cwd, config2 = {}) {
|
|
|
58320
58327
|
return result;
|
|
58321
58328
|
}
|
|
58322
58329
|
async function forceCheckpointBeforeOperation(operation, cwd) {
|
|
58323
|
-
|
|
58330
|
+
log11.info({ operation }, "Forcing checkpoint before operation");
|
|
58324
58331
|
try {
|
|
58325
58332
|
await gitCheckpoint("manual", `pre-${operation}`, cwd);
|
|
58326
58333
|
} catch (err) {
|
|
58327
|
-
|
|
58334
|
+
log11.error({ err }, "Failed to create pre-operation checkpoint");
|
|
58328
58335
|
}
|
|
58329
58336
|
vacuumIntoBackup({ cwd, force: true }).catch(() => {
|
|
58330
58337
|
});
|
|
58331
58338
|
}
|
|
58332
|
-
var
|
|
58339
|
+
var log11, DEFAULT_CONFIG2, SafetyError;
|
|
58333
58340
|
var init_data_safety = __esm({
|
|
58334
58341
|
"packages/core/src/store/data-safety.ts"() {
|
|
58335
58342
|
"use strict";
|
|
@@ -58339,7 +58346,7 @@ var init_data_safety = __esm({
|
|
|
58339
58346
|
init_sqlite2();
|
|
58340
58347
|
init_sqlite_backup();
|
|
58341
58348
|
init_tasks_schema();
|
|
58342
|
-
|
|
58349
|
+
log11 = getLogger("data-safety");
|
|
58343
58350
|
DEFAULT_CONFIG2 = {
|
|
58344
58351
|
verifyWrites: true,
|
|
58345
58352
|
detectCollisions: true,
|
|
@@ -63649,11 +63656,11 @@ var require_core = __commonJS({
|
|
|
63649
63656
|
Ajv4.ValidationError = validation_error_1.default;
|
|
63650
63657
|
Ajv4.MissingRefError = ref_error_1.default;
|
|
63651
63658
|
exports.default = Ajv4;
|
|
63652
|
-
function checkOptions(checkOpts, options, msg,
|
|
63659
|
+
function checkOptions(checkOpts, options, msg, log12 = "error") {
|
|
63653
63660
|
for (const key in checkOpts) {
|
|
63654
63661
|
const opt = key;
|
|
63655
63662
|
if (opt in options)
|
|
63656
|
-
this.logger[
|
|
63663
|
+
this.logger[log12](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
63657
63664
|
}
|
|
63658
63665
|
}
|
|
63659
63666
|
function getSchEnv(keyRef) {
|
|
@@ -71017,7 +71024,7 @@ init_logger();
|
|
|
71017
71024
|
init_paths();
|
|
71018
71025
|
init_tasks_schema();
|
|
71019
71026
|
import { basename as basename6, relative as relative2 } from "node:path";
|
|
71020
|
-
var
|
|
71027
|
+
var log6 = getLogger("lifecycle:evidence");
|
|
71021
71028
|
async function recordEvidence(epicId, stage, uri, type, options) {
|
|
71022
71029
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
71023
71030
|
const stageId = `stage-${epicId}-${stage}`;
|
|
@@ -71044,7 +71051,7 @@ async function recordEvidence(epicId, stage, uri, type, options) {
|
|
|
71044
71051
|
description: options?.description ?? null
|
|
71045
71052
|
}).run();
|
|
71046
71053
|
} catch (err) {
|
|
71047
|
-
|
|
71054
|
+
log6.warn({ err }, "Failed to write evidence to SQLite");
|
|
71048
71055
|
}
|
|
71049
71056
|
return record2;
|
|
71050
71057
|
}
|
|
@@ -76782,7 +76789,7 @@ init_sqlite2();
|
|
|
76782
76789
|
init_tasks_schema();
|
|
76783
76790
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
76784
76791
|
import { and as and8, eq as eq11, sql as sql11 } from "drizzle-orm";
|
|
76785
|
-
var
|
|
76792
|
+
var log7 = getLogger("link-store");
|
|
76786
76793
|
async function getLinksByProvider(providerId, cwd) {
|
|
76787
76794
|
const db = await getDb(cwd);
|
|
76788
76795
|
const rows = await db.select().from(externalTaskLinks).where(eq11(externalTaskLinks.providerId, providerId));
|
|
@@ -76837,7 +76844,7 @@ async function ensureExternalTaskLinksTable(cwd) {
|
|
|
76837
76844
|
)
|
|
76838
76845
|
);
|
|
76839
76846
|
} catch (err) {
|
|
76840
|
-
|
|
76847
|
+
log7.warn({ err }, "Failed to ensure external_task_links table exists");
|
|
76841
76848
|
throw err;
|
|
76842
76849
|
}
|
|
76843
76850
|
}
|
|
@@ -76911,7 +76918,7 @@ init_brain_accessor();
|
|
|
76911
76918
|
init_brain_sqlite();
|
|
76912
76919
|
init_data_accessor();
|
|
76913
76920
|
init_registry3();
|
|
76914
|
-
var
|
|
76921
|
+
var log8 = getLogger("nexus:transfer");
|
|
76915
76922
|
async function previewTransfer(params) {
|
|
76916
76923
|
return executeTransferInternal({ ...params, dryRun: true });
|
|
76917
76924
|
}
|
|
@@ -77052,7 +77059,7 @@ async function executeTransferInternal(params) {
|
|
|
77052
77059
|
}
|
|
77053
77060
|
}
|
|
77054
77061
|
} catch (err) {
|
|
77055
|
-
|
|
77062
|
+
log8.warn(
|
|
77056
77063
|
{ err, linksCreated },
|
|
77057
77064
|
"Failed to create external_task_links during transfer \u2014 tasks were transferred successfully but provenance links could not be written"
|
|
77058
77065
|
);
|
|
@@ -77080,7 +77087,7 @@ async function executeTransferInternal(params) {
|
|
|
77080
77087
|
})
|
|
77081
77088
|
});
|
|
77082
77089
|
} catch (err) {
|
|
77083
|
-
|
|
77090
|
+
log8.warn({ err }, "nexus transfer audit write failed");
|
|
77084
77091
|
}
|
|
77085
77092
|
if (mode === "move") {
|
|
77086
77093
|
let archived = 0;
|
|
@@ -77093,7 +77100,7 @@ async function executeTransferInternal(params) {
|
|
|
77093
77100
|
});
|
|
77094
77101
|
archived++;
|
|
77095
77102
|
} catch (err) {
|
|
77096
|
-
|
|
77103
|
+
log8.warn({ err, taskId: entry.sourceId }, "failed to archive source task after transfer");
|
|
77097
77104
|
}
|
|
77098
77105
|
}
|
|
77099
77106
|
}
|
|
@@ -77131,7 +77138,7 @@ async function executeTransferInternal(params) {
|
|
|
77131
77138
|
}
|
|
77132
77139
|
}
|
|
77133
77140
|
} catch (err) {
|
|
77134
|
-
|
|
77141
|
+
log8.warn({ err }, "brain observation transfer failed");
|
|
77135
77142
|
}
|
|
77136
77143
|
result.brainObservationsTransferred = brainTransferred;
|
|
77137
77144
|
result.manifest.brainObservationsTransferred = brainTransferred;
|
|
@@ -77179,8 +77186,8 @@ async function loadProjectACL(projectPath) {
|
|
|
77179
77186
|
async function logAclFailure(projectPath) {
|
|
77180
77187
|
try {
|
|
77181
77188
|
const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
77182
|
-
const
|
|
77183
|
-
|
|
77189
|
+
const log12 = getLogger2("nexus.acl");
|
|
77190
|
+
log12.warn({ projectPath }, "Failed to load ACL configuration, defaulting to deny-all");
|
|
77184
77191
|
} catch {
|
|
77185
77192
|
}
|
|
77186
77193
|
}
|
|
@@ -77335,9 +77342,9 @@ async function executeOperation(operation, taskId, projectPath, accessor, direct
|
|
|
77335
77342
|
async function logRouteAudit(directive, projectName, taskId, operation, success2, error48) {
|
|
77336
77343
|
try {
|
|
77337
77344
|
const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
77338
|
-
const
|
|
77345
|
+
const log12 = getLogger2("nexus.route");
|
|
77339
77346
|
const level = success2 ? "info" : "warn";
|
|
77340
|
-
|
|
77347
|
+
log12[level](
|
|
77341
77348
|
{
|
|
77342
77349
|
directive: directive.verb,
|
|
77343
77350
|
agentId: directive.agentId,
|
|
@@ -85909,7 +85916,7 @@ init_data_accessor();
|
|
|
85909
85916
|
|
|
85910
85917
|
// packages/core/src/stats/workflow-telemetry.ts
|
|
85911
85918
|
init_logger();
|
|
85912
|
-
var
|
|
85919
|
+
var log9 = getLogger("workflow-telemetry");
|
|
85913
85920
|
async function queryTasks(cwd, since) {
|
|
85914
85921
|
try {
|
|
85915
85922
|
const { getDb: getDb4 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
|
|
@@ -85931,7 +85938,7 @@ async function queryTasks(cwd, since) {
|
|
|
85931
85938
|
}).from(tasks2).where(conditions.length > 0 ? and13(...conditions) : void 0).all();
|
|
85932
85939
|
return rows;
|
|
85933
85940
|
} catch (err) {
|
|
85934
|
-
|
|
85941
|
+
log9.warn({ err }, "Failed to query tasks for workflow telemetry");
|
|
85935
85942
|
return [];
|
|
85936
85943
|
}
|
|
85937
85944
|
}
|
|
@@ -85965,7 +85972,7 @@ async function queryCompletionAuditRows(cwd, since) {
|
|
|
85965
85972
|
return isComplete;
|
|
85966
85973
|
});
|
|
85967
85974
|
} catch (err) {
|
|
85968
|
-
|
|
85975
|
+
log9.warn({ err }, "Failed to query audit log for workflow telemetry");
|
|
85969
85976
|
return [];
|
|
85970
85977
|
}
|
|
85971
85978
|
}
|
|
@@ -87451,11 +87458,11 @@ import { join as join88 } from "node:path";
|
|
|
87451
87458
|
import { Readable } from "node:stream";
|
|
87452
87459
|
import { pipeline } from "node:stream/promises";
|
|
87453
87460
|
import { createGzip } from "node:zlib";
|
|
87454
|
-
var
|
|
87461
|
+
var log10 = getLogger("prune");
|
|
87455
87462
|
async function pruneAuditLog(cleoDir, config2) {
|
|
87456
87463
|
try {
|
|
87457
87464
|
if (!config2.auditRetentionDays || config2.auditRetentionDays <= 0) {
|
|
87458
|
-
|
|
87465
|
+
log10.debug("auditRetentionDays is 0 or unset; skipping audit prune");
|
|
87459
87466
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
87460
87467
|
}
|
|
87461
87468
|
const cutoff = new Date(Date.now() - config2.auditRetentionDays * 864e5).toISOString();
|
|
@@ -87466,7 +87473,7 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
87466
87473
|
const db = await getDb4(projectRoot);
|
|
87467
87474
|
const oldRows = await db.select().from(auditLog2).where(lt4(auditLog2.timestamp, cutoff));
|
|
87468
87475
|
if (oldRows.length === 0) {
|
|
87469
|
-
|
|
87476
|
+
log10.debug("No audit_log rows older than cutoff; nothing to prune");
|
|
87470
87477
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
87471
87478
|
}
|
|
87472
87479
|
let archivePath;
|
|
@@ -87484,17 +87491,17 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
87484
87491
|
const inStream = Readable.from([jsonlContent]);
|
|
87485
87492
|
await pipeline(inStream, gzip, outStream);
|
|
87486
87493
|
rowsArchived = oldRows.length;
|
|
87487
|
-
|
|
87494
|
+
log10.info(
|
|
87488
87495
|
{ archivePath, rowsArchived },
|
|
87489
87496
|
`Archived ${rowsArchived} audit rows to ${archivePath}`
|
|
87490
87497
|
);
|
|
87491
87498
|
} catch (archiveErr) {
|
|
87492
|
-
|
|
87499
|
+
log10.warn({ err: archiveErr }, "Failed to archive audit rows; continuing with deletion");
|
|
87493
87500
|
archivePath = void 0;
|
|
87494
87501
|
}
|
|
87495
87502
|
}
|
|
87496
87503
|
await db.delete(auditLog2).where(lt4(auditLog2.timestamp, cutoff)).run();
|
|
87497
|
-
|
|
87504
|
+
log10.info(
|
|
87498
87505
|
{ rowsDeleted: oldRows.length, cutoff },
|
|
87499
87506
|
`Pruned ${oldRows.length} audit_log rows older than ${cutoff}`
|
|
87500
87507
|
);
|
|
@@ -87504,7 +87511,7 @@ async function pruneAuditLog(cleoDir, config2) {
|
|
|
87504
87511
|
archivePath
|
|
87505
87512
|
};
|
|
87506
87513
|
} catch (err) {
|
|
87507
|
-
|
|
87514
|
+
log10.warn({ err }, "audit log pruning failed");
|
|
87508
87515
|
return { rowsArchived: 0, rowsDeleted: 0 };
|
|
87509
87516
|
}
|
|
87510
87517
|
}
|
|
@@ -96585,6 +96592,7 @@ async function runBrainMaintenance(projectRoot, options) {
|
|
|
96585
96592
|
skipDecay = false,
|
|
96586
96593
|
skipConsolidation = false,
|
|
96587
96594
|
skipReconciliation = false,
|
|
96595
|
+
skipTierPromotion = false,
|
|
96588
96596
|
skipEmbeddings = false,
|
|
96589
96597
|
onProgress
|
|
96590
96598
|
} = options ?? {};
|
|
@@ -96596,6 +96604,7 @@ async function runBrainMaintenance(projectRoot, options) {
|
|
|
96596
96604
|
observationsFixed: 0,
|
|
96597
96605
|
linksRemoved: 0
|
|
96598
96606
|
};
|
|
96607
|
+
const tierPromotionResult = { promoted: 0, evicted: 0 };
|
|
96599
96608
|
const embeddingsResult = {
|
|
96600
96609
|
processed: 0,
|
|
96601
96610
|
skipped: 0,
|
|
@@ -96622,6 +96631,13 @@ async function runBrainMaintenance(projectRoot, options) {
|
|
|
96622
96631
|
reconciliationResult.linksRemoved = raw.linksRemoved;
|
|
96623
96632
|
onProgress?.("reconciliation", 1, 1);
|
|
96624
96633
|
}
|
|
96634
|
+
if (!skipTierPromotion) {
|
|
96635
|
+
onProgress?.("tier-promotion", 0, 1);
|
|
96636
|
+
const raw = await runTierPromotion(projectRoot);
|
|
96637
|
+
tierPromotionResult.promoted = raw.promoted.length;
|
|
96638
|
+
tierPromotionResult.evicted = raw.evicted.length;
|
|
96639
|
+
onProgress?.("tier-promotion", 1, 1);
|
|
96640
|
+
}
|
|
96625
96641
|
if (!skipEmbeddings) {
|
|
96626
96642
|
const raw = await populateEmbeddings(projectRoot, {
|
|
96627
96643
|
onProgress: (current, total) => {
|
|
@@ -96636,6 +96652,7 @@ async function runBrainMaintenance(projectRoot, options) {
|
|
|
96636
96652
|
decay: decayResult,
|
|
96637
96653
|
consolidation: consolidationResult,
|
|
96638
96654
|
reconciliation: reconciliationResult,
|
|
96655
|
+
tierPromotion: tierPromotionResult,
|
|
96639
96656
|
embeddings: embeddingsResult,
|
|
96640
96657
|
duration: Date.now() - startTime
|
|
96641
96658
|
};
|
|
@@ -102838,7 +102855,7 @@ var LEGACY_FILES = [
|
|
|
102838
102855
|
"nexus-pre-cleo.db.bak"
|
|
102839
102856
|
];
|
|
102840
102857
|
function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride) {
|
|
102841
|
-
const
|
|
102858
|
+
const log12 = getLogger("cleanup-legacy");
|
|
102842
102859
|
const cleoHome = cleoHomeOverride ?? getCleoHome();
|
|
102843
102860
|
const removed = [];
|
|
102844
102861
|
const errors = [];
|
|
@@ -102848,30 +102865,30 @@ function detectAndRemoveLegacyGlobalFiles(cleoHomeOverride) {
|
|
|
102848
102865
|
if (fs5.existsSync(fullPath)) {
|
|
102849
102866
|
fs5.unlinkSync(fullPath);
|
|
102850
102867
|
removed.push(fileName);
|
|
102851
|
-
|
|
102868
|
+
log12.info({ file: fullPath }, "Removed legacy global file");
|
|
102852
102869
|
}
|
|
102853
102870
|
} catch (err) {
|
|
102854
102871
|
const message = err instanceof Error ? err.message : String(err);
|
|
102855
102872
|
errors.push({ file: fileName, error: message });
|
|
102856
|
-
|
|
102873
|
+
log12.warn({ file: fullPath, error: message }, "Failed to remove legacy global file");
|
|
102857
102874
|
}
|
|
102858
102875
|
}
|
|
102859
102876
|
return { removed, errors };
|
|
102860
102877
|
}
|
|
102861
102878
|
function detectAndRemoveStrayProjectNexus(projectRoot) {
|
|
102862
|
-
const
|
|
102879
|
+
const log12 = getLogger("cleanup-legacy");
|
|
102863
102880
|
const strayPath = path5.join(projectRoot, ".cleo", "nexus.db");
|
|
102864
102881
|
if (fs5.existsSync(strayPath)) {
|
|
102865
102882
|
try {
|
|
102866
102883
|
fs5.unlinkSync(strayPath);
|
|
102867
|
-
|
|
102884
|
+
log12.warn(
|
|
102868
102885
|
{ path: strayPath },
|
|
102869
102886
|
"Removed stray project-tier nexus.db (violates ADR-036 global-only contract)"
|
|
102870
102887
|
);
|
|
102871
102888
|
return { removed: true, path: strayPath };
|
|
102872
102889
|
} catch (err) {
|
|
102873
102890
|
const message = err instanceof Error ? err.message : String(err);
|
|
102874
|
-
|
|
102891
|
+
log12.warn(
|
|
102875
102892
|
{ path: strayPath, error: message },
|
|
102876
102893
|
"Failed to remove stray project-tier nexus.db \u2014 manual deletion may be required"
|
|
102877
102894
|
);
|
|
@@ -102964,7 +102981,7 @@ function brokenTimestamp() {
|
|
|
102964
102981
|
return `${now2.getFullYear()}${pad2(now2.getMonth() + 1)}${pad2(now2.getDate())}-${pad2(now2.getHours())}${pad2(now2.getMinutes())}${pad2(now2.getSeconds())}-${pad3(now2.getMilliseconds())}`;
|
|
102965
102982
|
}
|
|
102966
102983
|
function migrateSignaldockToConduit(projectRoot) {
|
|
102967
|
-
const
|
|
102984
|
+
const log12 = getLogger("migrate-signaldock-to-conduit");
|
|
102968
102985
|
const legacyPath = join112(projectRoot, ".cleo", "signaldock.db");
|
|
102969
102986
|
const conduitPath = join112(projectRoot, ".cleo", "conduit.db");
|
|
102970
102987
|
const globalSignaldockPath = join112(getCleoHome(), "signaldock.db");
|
|
@@ -102981,13 +102998,13 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
102981
102998
|
if (!needsSignaldockToConduitMigration(projectRoot)) {
|
|
102982
102999
|
return result;
|
|
102983
103000
|
}
|
|
102984
|
-
|
|
103001
|
+
log12.info({ projectRoot, legacyPath }, "T310 migration: starting signaldock.db \u2192 conduit.db");
|
|
102985
103002
|
let legacy = null;
|
|
102986
103003
|
try {
|
|
102987
103004
|
legacy = new DatabaseSync7(legacyPath, { readOnly: true });
|
|
102988
103005
|
} catch (err) {
|
|
102989
103006
|
const message = err instanceof Error ? err.message : String(err);
|
|
102990
|
-
|
|
103007
|
+
log12.error({ legacyPath, error: message }, "T310 migration: cannot open legacy signaldock.db");
|
|
102991
103008
|
result.errors.push({ step: "step-2-open-legacy", error: message });
|
|
102992
103009
|
result.status = "failed";
|
|
102993
103010
|
return result;
|
|
@@ -102995,7 +103012,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
102995
103012
|
try {
|
|
102996
103013
|
if (!integrityCheckPasses(legacy)) {
|
|
102997
103014
|
const msg = "Legacy signaldock.db failed PRAGMA integrity_check. Migration aborted \u2014 no changes written. Recovery: inspect the database with sqlite3 and attempt manual repair before re-running.";
|
|
102998
|
-
|
|
103015
|
+
log12.error({ legacyPath }, msg);
|
|
102999
103016
|
result.errors.push({ step: "step-3-legacy-integrity", error: msg });
|
|
103000
103017
|
result.status = "failed";
|
|
103001
103018
|
legacy.close();
|
|
@@ -103003,7 +103020,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103003
103020
|
}
|
|
103004
103021
|
} catch (err) {
|
|
103005
103022
|
const message = err instanceof Error ? err.message : String(err);
|
|
103006
|
-
|
|
103023
|
+
log12.error({ legacyPath, error: message }, "T310 migration: integrity_check threw on legacy DB");
|
|
103007
103024
|
result.errors.push({ step: "step-3-legacy-integrity", error: message });
|
|
103008
103025
|
result.status = "failed";
|
|
103009
103026
|
legacy.close();
|
|
@@ -103021,7 +103038,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103021
103038
|
getGlobalSalt();
|
|
103022
103039
|
} catch (err) {
|
|
103023
103040
|
const message = err instanceof Error ? err.message : String(err);
|
|
103024
|
-
|
|
103041
|
+
log12.error({ error: message }, "T310 migration: getGlobalSalt failed \u2014 migration aborted");
|
|
103025
103042
|
result.errors.push({ step: "step-6-global-salt", error: message });
|
|
103026
103043
|
result.status = "failed";
|
|
103027
103044
|
legacy.close();
|
|
@@ -103035,7 +103052,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103035
103052
|
conduit.exec("PRAGMA foreign_keys = OFF");
|
|
103036
103053
|
} catch (err) {
|
|
103037
103054
|
const message = err instanceof Error ? err.message : String(err);
|
|
103038
|
-
|
|
103055
|
+
log12.error({ conduitPath, error: message }, "T310 migration: failed to create conduit.db");
|
|
103039
103056
|
result.errors.push({ step: "step-7-create-conduit", error: message });
|
|
103040
103057
|
result.status = "failed";
|
|
103041
103058
|
legacy.close();
|
|
@@ -103081,7 +103098,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103081
103098
|
result.agentsCopied = agentsCountForConduit;
|
|
103082
103099
|
} catch (err) {
|
|
103083
103100
|
const message = err instanceof Error ? err.message : String(err);
|
|
103084
|
-
|
|
103101
|
+
log12.error({ error: message }, "T310 migration: conduit.db write failed \u2014 rolling back");
|
|
103085
103102
|
result.errors.push({ step: "step-8-conduit-write", error: message });
|
|
103086
103103
|
result.status = "failed";
|
|
103087
103104
|
try {
|
|
@@ -103102,7 +103119,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103102
103119
|
try {
|
|
103103
103120
|
if (!integrityCheckPasses(conduit)) {
|
|
103104
103121
|
const msg = "conduit.db failed PRAGMA integrity_check after write";
|
|
103105
|
-
|
|
103122
|
+
log12.error({ conduitPath }, msg);
|
|
103106
103123
|
result.errors.push({ step: "step-10-conduit-integrity", error: msg });
|
|
103107
103124
|
result.status = "failed";
|
|
103108
103125
|
conduit.close();
|
|
@@ -103117,7 +103134,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103117
103134
|
}
|
|
103118
103135
|
} catch (err) {
|
|
103119
103136
|
const message = err instanceof Error ? err.message : String(err);
|
|
103120
|
-
|
|
103137
|
+
log12.error({ error: message }, "T310 migration: conduit.db integrity_check threw");
|
|
103121
103138
|
result.errors.push({ step: "step-10-conduit-integrity", error: message });
|
|
103122
103139
|
result.status = "failed";
|
|
103123
103140
|
if (conduit) {
|
|
@@ -103139,7 +103156,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103139
103156
|
globalDb.exec("PRAGMA foreign_keys = OFF");
|
|
103140
103157
|
} catch (err) {
|
|
103141
103158
|
const message = err instanceof Error ? err.message : String(err);
|
|
103142
|
-
|
|
103159
|
+
log12.error(
|
|
103143
103160
|
{ globalSignaldockPath, error: message },
|
|
103144
103161
|
"T310 migration: cannot open global signaldock.db"
|
|
103145
103162
|
);
|
|
@@ -103178,7 +103195,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103178
103195
|
result.agentsCopied = agentsCopiedToGlobal;
|
|
103179
103196
|
} catch (err) {
|
|
103180
103197
|
const message = err instanceof Error ? err.message : String(err);
|
|
103181
|
-
|
|
103198
|
+
log12.error(
|
|
103182
103199
|
{ error: message },
|
|
103183
103200
|
"T310 migration: global signaldock.db write failed \u2014 rolling back"
|
|
103184
103201
|
);
|
|
@@ -103196,7 +103213,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103196
103213
|
try {
|
|
103197
103214
|
if (!integrityCheckPasses(globalDb)) {
|
|
103198
103215
|
const msg = "Global signaldock.db failed PRAGMA integrity_check after write";
|
|
103199
|
-
|
|
103216
|
+
log12.error({ globalSignaldockPath }, msg);
|
|
103200
103217
|
result.errors.push({ step: "step-14-global-integrity", error: msg });
|
|
103201
103218
|
result.status = "failed";
|
|
103202
103219
|
globalDb.close();
|
|
@@ -103211,7 +103228,7 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103211
103228
|
}
|
|
103212
103229
|
} catch (err) {
|
|
103213
103230
|
const message = err instanceof Error ? err.message : String(err);
|
|
103214
|
-
|
|
103231
|
+
log12.error({ error: message }, "T310 migration: global signaldock.db integrity_check threw");
|
|
103215
103232
|
result.errors.push({ step: "step-14-global-integrity", error: message });
|
|
103216
103233
|
result.status = "failed";
|
|
103217
103234
|
if (globalDb) {
|
|
@@ -103230,21 +103247,21 @@ function migrateSignaldockToConduit(projectRoot) {
|
|
|
103230
103247
|
result.bakPath = bakPath;
|
|
103231
103248
|
} catch (err) {
|
|
103232
103249
|
const message = err instanceof Error ? err.message : String(err);
|
|
103233
|
-
|
|
103250
|
+
log12.error(
|
|
103234
103251
|
{ legacyPath, bakPath, error: message },
|
|
103235
103252
|
"T310 migration: rename to .pre-t310.bak failed \u2014 legacy file left in place (harmless)"
|
|
103236
103253
|
);
|
|
103237
103254
|
result.errors.push({ step: "step-16-rename-bak", error: message });
|
|
103238
103255
|
}
|
|
103239
|
-
|
|
103256
|
+
log12.info(
|
|
103240
103257
|
{ projectRoot, agentsCopied: result.agentsCopied, conduitPath, bakPath: result.bakPath },
|
|
103241
103258
|
`T310 migration complete: ${result.agentsCopied} agents migrated to global, conduit.db created`
|
|
103242
103259
|
);
|
|
103243
|
-
|
|
103260
|
+
log12.warn(
|
|
103244
103261
|
{},
|
|
103245
103262
|
"T310 migration: API keys have been re-keyed. External systems holding old API keys (CI env vars, remote agent configs) must be updated."
|
|
103246
103263
|
);
|
|
103247
|
-
|
|
103264
|
+
log12.info(
|
|
103248
103265
|
{ legacyPath, bakPath: result.bakPath, conduitPath },
|
|
103249
103266
|
"T310 migration recovery: if problems occur, rename .pre-t310.bak to signaldock.db and delete conduit.db to re-run migration."
|
|
103250
103267
|
);
|
|
@@ -110531,9 +110548,11 @@ export {
|
|
|
110531
110548
|
routing_exports as routing,
|
|
110532
110549
|
runAllMigrations,
|
|
110533
110550
|
runBrainMaintenance,
|
|
110551
|
+
runConsolidation,
|
|
110534
110552
|
runDoctorFixes,
|
|
110535
110553
|
runMigration,
|
|
110536
110554
|
runReleaseGates,
|
|
110555
|
+
runTierPromotion,
|
|
110537
110556
|
runUpgrade,
|
|
110538
110557
|
safestop,
|
|
110539
110558
|
sanitizeContent,
|