fix(server): upgrade preview databases with peer-link migration collisions#25293
Problem
Preview 3511/3516 databases record peer-link migrations at 68–70. Starting current main against that history fails before the server listens because required migrations ShellStopRequestIndex and ThreadMessageSearch would be skipped.
Change
Recognize this exact preview history and, in one transaction, move its peer-link migration records to 70–72 and apply the missing main migrations 68/69. Preserve the existing peer-link schema and data without replaying its DDL. Leave unrecognized histories subject to the existing migration guard.
Scope and approval
Fixes pingdotgg/t3code#25289
Triaged bug explicitly enqueued by Julius via the automated issue flow: #25289.
Verification
- Red regression failed on main with the reported migration collision; green regression preserves a fenced peer-link row and its waiting-link index and verifies a second run changes nothing. A near-match history is rejected without mutation.
- After merging current main, 17 tests passed across
Migrations.test.ts,reconcileV2PreviewMigration.test.ts, andinitializeV2Database.test.ts. vp run check:changed: format, lint, GraphQL, knip, affected typechecks and adjacent tests passed.- Real runtime reproduction used an isolated SQLite backup from a read-only source. Before: snapshot migration and dev-server startup failed with the collision. After: snapshot migration applied 68/69; the pruned database started successfully and completed orchestration recovery with all counts zero. Live userdata was never modified.
- Sanitized red/before/after runtime transcript and schema verification. Runtime evidence was captured at the fix commit; the subsequent main merge did not change the three migration/test files.
- Both independent reviews found no blockers; proof audit passed. Server-only change: visual capture matrix is empty. Main still logs the existing warning for peer-link records 70–72, whose implementations are only on preview; the repaired numbering matches preview 3702.
Models: Claude Opus 5.5 and GPT-6.1, through T3 Code's Claude Agent and Codex harnesses.
Checks
Added 3 commits
Approvability
Verdict: Approved at b8c5346
Macroscope's review found this PR approvable — This is a focused migration compatibility fix that repairs only recognized preview histories while leaving current and unknown database histories protected by existing guards. The included tests cover upgrade behavior, preservation of peer-link data, idempotence, and refusal of unexpected histories.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review.
External image Recent review info
External image Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-25289
- File: .coderabbit.config.ts
- Commit: b8c5346
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
06d1b085-1507-4653-94d8-09f686ed0bb8
External image Commits
Reviewing files that changed from the base of the PR and between c3888da8b4fa39b5edd3d0aa69479068647413cf and b8c53460752e6fe3d7fa237643e24e9adbff8dc6.
External image Files selected for processing: 3
apps/server/src/persistence/Migrations.test.tsapps/server/src/persistence/Migrations.tsapps/server/src/persistence/reconcilePeerLinkPreviewMigration.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
Walkthrough
The migration runner now reconciles a specific peer-link preview migration history before regular migrations. Tests cover successful upgrades, preservation of peer-link data and indexes, repeated runs, and rejection of a history that does not match the expected sequence.
Changes: Peer-link migration upgrade
Layer / File(s) Summary Reconcile preview migration history
apps/server/src/persistence/reconcilePeerLinkPreviewMigration.ts,apps/server/src/persistence/Migrations.ts,apps/server/src/persistence/Migrations.test.tsThe reconciliation checks whether migration history matches the expected preview sequence. On a match, it shifts preview records to IDs 70–72, applies migrations 68 and 69, and returns their records to the runner. The runner skips reconciliation when the inclusive migration limit is below 69. Tests verify the upgrade, preserved data and index, no-op repeat run, and rejection of a mismatched history. Priority: External image Normal
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Possibly related PRs
- pingdotgg/t3code#25058: Handles the same preview migration history during dev-database import.
- pingdotgg/t3code#24343: Adds migration 069, which this reconciliation applies.
- pingdotgg/t3code#24665: Routes dev database migration-history handling through
runMigrations.
Suggested labels:
size:MSuggested reviewers:
t3dotgg,macroscopeapp
Merge Risk: External image Minimal · up to b8c53
The exact preview database history has a transactional upgrade path, with no identified issue requiring a fix before merge.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title is concise, uses conventional commit format, and clearly describes the server fix for preview database migration collisions. Description check Passed The description includes all required sections. It explains the problem, implementation, scope and approval, focused verification, runtime validation, and agent details. Linked Issues check Passed Issue #25289requires recognition of the exact 68–70 peer-link history, relocation to 70–72, and application of migrations 68 and 69 without replaying peer-link DDL. `reconcilePeerLinkPreviewMigration…Out of Scope Changes check Passed The changed files are limited to the migration integration, the focused peer-link history reconciliation, and regression tests. The reconciliation and tests directly support issue #25289. No unrelated…Full details: Linked Issues check
Explanation
Issue
#25289requires recognition of the exact 68–70 peer-link history, relocation to 70–72, and application of migrations 68 and 69 without replaying peer-link DDL.reconcilePeerLinkPreviewMigrationmatches IDs 55–70 exactly, updates peer-link records in reverse order, runsShellStopRequestIndexandThreadMessageSearchin one transaction, and inserts their history records.Migrations.tsinvokes this reconciliation before the regular loader. Tests verify data and the waiting-link index remain, the second run is a no-op, and a near-match is rejected without mutation.
Full details: Out of Scope Changes check
Explanation
The changed files are limited to the migration integration, the focused peer-link history reconciliation, and regression tests. The reconciliation and tests directly support issue
#25289. No unrelated product behavior or unrelated files are shown in the reviewed changes.
Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | 4.9 KiB | 5.0 KiB | +30 B (+0.6%) | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | +30 B (+2.5%) | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | 20.8 KiB | 20.9 KiB | +41 B (+0.2%) | 29.3 KiB | ✅ |
| Codex | Live turn messages | 1 | 2 | +1 (+100.0%) | 8 | ✅ |
| Claude | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | 21.2 KiB | 21.2 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Claude | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
Baseline: c3888da · PR result: b8c5346 · Source CI: success
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.