Repository navigation
Conversation
There was a problem hiding this comment.
The fix works: I reproduced #58543 with real [email protected] and the issue's script. On the base, the V1 import emptied the session's session_message rows (4 → 0, the messages endpoint returned []). With this PR all 4 rows survive and the messages endpoint returns them. The new test fails on the base and passes here, and test/v1-migration.test.ts passes in full (37/37). I couldn't run the type check because my local Bun lacks bun check.
The public API is unchanged.
Two migration edge cases are worth fixing (details inline):
- Sessions copied during the schema step skip the importer's project attribution and relative-directory fix. In my run the session moved from its resolved project to
global. - A session with both legacy
message/partrows and nativesession_messagerows now has its legacy messages dropped instead of its native ones.
The fix lives in an already shipped migration. That works for 1.19 databases that haven't upgraded yet, which is the case this targets. As the description notes, databases that already ran it can't be recovered.
| `) | ||
| // 1.19's /api/session already writes V2 messages in this database. | ||
| // Preserve their sessions before moving the projection's foreign key. | ||
| yield* tx.run(` |
There was a problem hiding this comment.
This copies session rows straight into session_v2, so these sessions skip the importer's handling: reassigning missing projects, resolving global sessions to their directory's project (#56322) and fixing relative directories (#57618). The importer then sees them as imported and never revisits them.
In the issue's reproduction, the base ends up with the session under its resolved project (92de9e…, with a project row). With this PR it stays project_id = 'global' and no project row is created. Could the schema step keep only the session_message rows (for example in a temporary table), and leave creating session_v2 rows to the importer?
| }) | ||
| .run() | ||
| // Native V2 history (including 1.19 API sessions) is already authoritative. | ||
| if (nextID.imported) return |
There was a problem hiding this comment.
imported is now true for every session the schema step copied, i.e. any session with native session_message rows, so the legacy message/part import is skipped for all of them. A session with rows in both stores (for example a legacy session later continued through /api/session in 1.19) would lose its legacy history. On the base it lost the native messages instead.
Skipping only when the session has no legacy message/part rows would keep the current behaviour for mixed sessions. Merging both would be better still.
|
Addressed both findings in f2898ff. The schema step now stages only native messages in a durable table; session creation still goes through the importer’s ownership and relative-directory handling. The importer merges legacy history before native history (native wins for shared IDs), then drops staging atomically with completion. Added real SQLite coverage for attribution, relative paths, mixed history, duplicate IDs and an interrupted insert/resume. Both migration suites pass, including 560 randomized repetitions; the full core run has the same 74 local-environment failures as unmodified dev, with no new failures. |
There was a problem hiding this comment.
Both earlier points are addressed. Native 1.19 messages are now staged during the schema step and merged by the importer, so project attribution and directory handling still apply, and mixed sessions keep both legacy and native history.
I re-ran the #58543 reproduction from source on the same 1.19.3 database. All 4 session_message rows survive and the messages endpoint returns them. The session gets its resolved directory project, as on the base, and the staging table is dropped when the import finishes. test/v1-migration.test.ts passes (37/37). I couldn't run the type check because my local Bun lacks bun check.
The public API is unchanged.
No new concerns.
Issue for this PR
Closes #58543
Type of change
What does this PR do?
Preserve messages created through 1.19's
/api/sessionwhen upgrading to V2. There are two deletion points: the August table split drops the existing projection, and the V1 importer later rebuilds it from empty legacy tables.Stage the native messages durably during the split, then let the existing importer resolve project ownership and relative directories. Merge legacy history before native history, preferring native rows for shared IDs. Native-only message sequences, JSON content, session metadata and usage are preserved. The staging table and completion marker commit together, so interrupted imports can resume; already imported
opencode-next.dbsessions remain authoritative.This prevents loss during migration; it cannot reconstruct messages already deleted from an upgraded database without the original data. Late V1 writes after migration (#57080) remain separate.
How did you verify your code works?
v1.19.3, native-only, legacy-only, mixed history, shared message IDs, project attribution and relative directories. It also interrupts a message insert, verifies rollback and the durable cursor, then resumes and verifies idempotence and staging cleanup. The original regression fails ondev; mixed-history coverage also fails on the initial PR revision.dev: 6676 passed, 49 skipped, the exact same 74 failures (local Git transport guard and shell/config fixtures); no new failing cases.bun run checkpassed (lint and 34 workspace typechecks); formatting and diff checks passed. Bun 1.4.4, macOS. No live provider or user database used.AI-assisted implementation and verification.
Checklist
Added by the opencode bot (AI-generated).
Related: #57000, #58041, #50130