Conversation
Old desktop builds (0.0.35-0.0.38) swept idle threads into "settled" and stamped settled_at with the sweep time instead of the thread's real last activity. Migration 046 only caught the server-side version of this bug (#10937). The client-attributed sweeps stayed broken, both in the legacy V1 table and, after import, in the V2 projection. Add migration 057. It detects a burst of at least 10 distinct threads settled within two minutes by one of the affected builds, using gap-based clustering so a later, unrelated manual settle just outside the sweep does not get pulled in. That is the correctness gap Macroscope flagged on the earlier, now-closed PR #10975. The migration repairs projection_threads.settled_at for threads not yet imported into V2, and patches orchestration_v2_projection_threads' JSON copy for threads already imported before this fix shipped. Reuses the detection shape (affected app versions, cutoff date, burst threshold) from Guillermo Casanova's closed PR, rewritten for the V2 projection and with a non-chaining cluster test instead of the pivot-window check that PR's review flagged. Co-Authored-By: Guillermo Casanova <75276669+Gigioxx@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR adds a startup migration that uses substantial heuristic SQL to classify historical settlement bursts and permanently rewrites timestamps in both V1 and V2 projections. The cross-projection data repair and durable user-visible impact warrant human review. Notes:
You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 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.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 🧰 Additional context used📚 Code guidelines (1)No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughMigration 57 repairs qualifying client-attributed settlement timestamps in the V1 and V2 thread projections. It leaves historical event payloads unchanged and adds coverage for migration registration, repaired cases, excluded cases, and repeat execution. ChangesSettlement timestamp repair
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Suggested reviewers: Merge Risk: 🔵 Low · up to A legacy manual archive interleaved within a qualifying sweep could appear to have settled earlier in the projection. This is a narrow data-quality risk; the original event history remains available. Architecture SummaryArchitecture risk: 🔵 Low · up to The change affects 1 system. Changed systems: Architecture concerns Review detailsSystems and components
Before / after behavior
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Problem
Desktop builds 0.0.35 to 0.0.38 settled idle threads from the client in one burst and stamped each thread's settled time with the sweep time instead of its last activity. Those threads still sit in the sidebar's Settled section with the wrong age, bunched together as if they were all closed at the same moment. Migration 046 repaired the server-attributed version of this, but it skips client-attributed events on purpose, so these were never fixed. The V1 to V2 import then copied the bad values into V2 (#10937).
Change
New migration 057 finds the client-attributed sweeps and puts the real last-activity time back:
thread.settledV1 events withactor_kind = 'client', an app version from 0.0.35 to 0.0.38, before 2026-09-05, where the event'ssettledAtequals itsoccurred_at(the sweep's stamp).projection_threads.settled_atfor threads not imported yet, andsettledAtinsideorchestration_v2_projection_threads.payload_jsonfor threads already imported into V2.This rebuilds #10975 by @Gigioxx on current main, which has one migration chain for V1 and V2. 056 was the last migration on main.
Scope and approval
Closes #10937. The issue is triaged and accepted. Julius's triage confirmed the gap in 046 and the discriminators used here: client actor, the affected app versions, the cutoff date, and a dense burst.
Verification
There's no new UI. The bug is old data in existing databases, so the evidence is the migration test run against both branches. The test seeds a 12-thread client sweep plus the cases that must not change, then runs every migration.
Before (main 1e2ecbd, with the new test file copied in): the swept thread keeps the sweep time.
expected '2026-09-04T13:33:00.000Z' to equal '2026-04-01T00:00:00.000Z'.10975-before.mp4
After (this PR): passes.
10975-after.mp4
vp test run apps/server/src/persistence/Migrations/057_RepairClientSettlementTimestamps.test.tscovers:The neighboring migration tests (046, 054, 055, 056) pass.
055_OrchestrationV2.test.tschanges only because it lists the migrations by count. Scopedtscand lint are clean.Not checked: a real database from an affected 0.0.35 to 0.0.38 install. An independent review also replayed the original audit fixture through migration 57 and saw every swept thread repaired.
Made with Claude Opus 5.5 in Claude Code (T3 Code).
🤖 Generated with Claude Code