From 2ba3fc2ff4bf006e93c601fc6e7acf79d33cd633 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 10 May 2026 04:17:54 +0100 Subject: [PATCH] refactor: keep matrix legacy mutations out of runtime barrel --- docs/refactor/database-first.md | 3 ++ extensions/matrix/src/doctor.test.ts | 37 +++++++++++++------ extensions/matrix/src/doctor.ts | 8 ++-- .../matrix/src/matrix-migration.runtime.ts | 4 +- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/docs/refactor/database-first.md b/docs/refactor/database-first.md index a1038526c14..97de60d81a8 100644 --- a/docs/refactor/database-first.md +++ b/docs/refactor/database-first.md @@ -731,6 +731,9 @@ sessionId}` and session key context. - Matrix startup maintenance no longer moves legacy Matrix files. Startup only reports pending migration state and tells the operator to run `openclaw doctor --fix`; the snapshot/import/delete step remains doctor-owned. +- Matrix runtime migration barrels expose read-only detection/status helpers + only. The legacy state/crypto mutation helpers are imported by Matrix doctor + directly instead of being part of the runtime-heavy API surface. - Matrix migration snapshot reuse markers now live in SQLite plugin state instead of `matrix/migration-snapshot.json`; doctor can still reuse the same verified pre-migration archive without writing a sidecar state file. diff --git a/extensions/matrix/src/doctor.test.ts b/extensions/matrix/src/doctor.test.ts index a9789c5eb27..15c28955246 100644 --- a/extensions/matrix/src/doctor.test.ts +++ b/extensions/matrix/src/doctor.test.ts @@ -12,15 +12,28 @@ import { runMatrixDoctorSequence, } from "./doctor.js"; -vi.mock("./matrix-migration.runtime.js", async () => { - const actual = await vi.importActual( - "./matrix-migration.runtime.js", - ); +vi.mock("./legacy-state.js", async () => { + const actual = await vi.importActual("./legacy-state.js"); + return { + ...actual, + autoMigrateLegacyMatrixState: vi.fn(async () => ({ changes: [], warnings: [] })), + }; +}); + +vi.mock("./legacy-crypto.js", async () => { + const actual = await vi.importActual("./legacy-crypto.js"); + return { + ...actual, + autoPrepareLegacyMatrixCrypto: vi.fn(async () => ({ changes: [], warnings: [] })), + }; +}); + +vi.mock("./migration-snapshot.js", async () => { + const actual = + await vi.importActual("./migration-snapshot.js"); return { ...actual, maybeCreateMatrixMigrationSnapshot: vi.fn(), - autoMigrateLegacyMatrixState: vi.fn(async () => ({ changes: [], warnings: [] })), - autoPrepareLegacyMatrixCrypto: vi.fn(async () => ({ changes: [], warnings: [] })), resolveMatrixMigrationStatus: vi.fn(() => ({ legacyState: null, legacyCrypto: { inspectorAvailable: true, warnings: [], plans: [] }, @@ -119,24 +132,26 @@ describe("matrix doctor", () => { }); it("surfaces matrix sequence warnings and repair changes", async () => { - const runtimeApi = await import("./matrix-migration.runtime.js"); - vi.mocked(runtimeApi.resolveMatrixMigrationStatus).mockReturnValue({ + const legacyState = await import("./legacy-state.js"); + const legacyCrypto = await import("./legacy-crypto.js"); + const migrationSnapshot = await import("./migration-snapshot.js"); + vi.mocked(migrationSnapshot.resolveMatrixMigrationStatus).mockReturnValue({ legacyState: null, legacyCrypto: { inspectorAvailable: true, warnings: [], plans: [] }, pending: true, actionable: true, }); - vi.mocked(runtimeApi.maybeCreateMatrixMigrationSnapshot).mockResolvedValue({ + vi.mocked(migrationSnapshot.maybeCreateMatrixMigrationSnapshot).mockResolvedValue({ archivePath: "/tmp/matrix-backup.tgz", created: true, markerKey: "current", }); - vi.mocked(runtimeApi.autoMigrateLegacyMatrixState).mockResolvedValue({ + vi.mocked(legacyState.autoMigrateLegacyMatrixState).mockResolvedValue({ migrated: true, changes: ["Migrated legacy sync state"], warnings: [], }); - vi.mocked(runtimeApi.autoPrepareLegacyMatrixCrypto).mockResolvedValue({ + vi.mocked(legacyCrypto.autoPrepareLegacyMatrixCrypto).mockResolvedValue({ migrated: true, changes: ["Prepared recovery key export"], warnings: [], diff --git a/extensions/matrix/src/doctor.ts b/extensions/matrix/src/doctor.ts index c829a96dfb3..35301fc2936 100644 --- a/extensions/matrix/src/doctor.ts +++ b/extensions/matrix/src/doctor.ts @@ -10,14 +10,12 @@ import { normalizeCompatibilityConfig as normalizeMatrixCompatibilityConfig, } from "./doctor-contract.js"; import { autoMigrateLegacyMatrixCredentials } from "./legacy-credentials.js"; +import { autoPrepareLegacyMatrixCrypto, detectLegacyMatrixCrypto } from "./legacy-crypto.js"; +import { autoMigrateLegacyMatrixState, detectLegacyMatrixState } from "./legacy-state.js"; import { - autoMigrateLegacyMatrixState, - autoPrepareLegacyMatrixCrypto, - detectLegacyMatrixCrypto, - detectLegacyMatrixState, maybeCreateMatrixMigrationSnapshot, resolveMatrixMigrationStatus, -} from "./matrix-migration.runtime.js"; +} from "./migration-snapshot.js"; import { isRecord } from "./record-shared.js"; function hasConfiguredMatrixChannel(cfg: OpenClawConfig): boolean { diff --git a/extensions/matrix/src/matrix-migration.runtime.ts b/extensions/matrix/src/matrix-migration.runtime.ts index b163f2fbb19..55dcc3fa38a 100644 --- a/extensions/matrix/src/matrix-migration.runtime.ts +++ b/extensions/matrix/src/matrix-migration.runtime.ts @@ -1,5 +1,5 @@ -export { autoMigrateLegacyMatrixState, detectLegacyMatrixState } from "./legacy-state.js"; -export { autoPrepareLegacyMatrixCrypto, detectLegacyMatrixCrypto } from "./legacy-crypto.js"; +export { detectLegacyMatrixState } from "./legacy-state.js"; +export { detectLegacyMatrixCrypto } from "./legacy-crypto.js"; export { hasActionableMatrixMigration, hasPendingMatrixMigration,