diff --git a/extensions/matrix/doctor-contract-api.test.ts b/extensions/matrix/doctor-contract-api.test.ts index b9ebf4c748f2..628f9c0bac23 100644 --- a/extensions/matrix/doctor-contract-api.test.ts +++ b/extensions/matrix/doctor-contract-api.test.ts @@ -765,7 +765,7 @@ describe("matrix doctor contract state migrations", () => { await expect(migration.detectLegacyState(createMigrationParams(stateDir))).resolves.toBeNull(); }); - it("records an empty legacy scan and then skips historical databases", async () => { + it("records an empty legacy scan silently and then skips historical databases", async () => { const stateDir = tempDirs.make("openclaw-matrix-doctor-"); const migration = migrationById("matrix-inbound-dedupe-to-claimable-dedupe"); const params = createMigrationParams(stateDir); @@ -773,10 +773,10 @@ describe("matrix doctor contract state migrations", () => { await expect(migration.detectLegacyState(params)).resolves.toEqual({ preview: ["Matrix inbound dedupe legacy sources need a one-time migration scan"], }); + // Fresh installs scan nothing: the durable receipt is recorded (proven by + // the historical-database skip below) without a user-visible change line. await expect(migration.migrateLegacyState(params)).resolves.toEqual({ - changes: [ - "Recorded Matrix inbound dedupe migration completion (0 SQLite roots, 0 JSON roots scanned)", - ], + changes: [], warnings: [], }); const lateDatabasePath = path.join( diff --git a/extensions/matrix/doctor-contract-api.ts b/extensions/matrix/doctor-contract-api.ts index df3c61fffb43..524d6bf9f9a8 100644 --- a/extensions/matrix/doctor-contract-api.ts +++ b/extensions/matrix/doctor-contract-api.ts @@ -346,9 +346,13 @@ export const stateMigrations: PluginDoctorStateMigration[] = [ } try { await recordMatrixInboundDedupeMigrationCompletion(params.context, params.env); - changes.push( - `Recorded Matrix inbound dedupe migration completion (${sources.sqliteRoots.length} SQLite roots, ${sources.jsonRoots.length} JSON roots scanned)`, - ); + // Fresh installs scan zero roots; keep the durable receipt silent + // there so onboarding doesn't report a migration that touched nothing. + if (sources.sqliteRoots.length + sources.jsonRoots.length > 0) { + changes.push( + `Recorded Matrix inbound dedupe migration completion (${sources.sqliteRoots.length} SQLite roots, ${sources.jsonRoots.length} JSON roots scanned)`, + ); + } } catch (err) { warnings.push( `Failed recording Matrix inbound dedupe migration completion: ${String(err)}`,