fix(server): release completed pull request sweep data#25177

merged3
main
fix/issue-25172
opened4d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

Every completed one-minute pull-request sweep can remain reachable through Effect stack frames retained by a cached lookup fiber. On an isolated headless server with 31 stopped thread projections linked to one open PR, successive completed sweeps retained one then two groups Maps after full GC.

Change

Use untraced function wrappers with explicit named spans for the two helpers defined inside each sweep. This releases sweep inputs while preserving the existing tracing span names and polling behavior. Add a collection regression that keeps a lookup fiber cached after the sweep finishes.

Scope and approval

Fixes pingdotgg/t3code#25172

Triaged bug via the automated issue flow: #25172. Focused server retention fix; no client, contract, authentication, or persisted-state changes.

Verification

  • Regression on the baseline implementation: expected zero surviving link objects, actual 30. Exact red command and failure.
  • Final head: all 49 reactor tests pass, including the collection regression. Command and output.
  • vp run check:changed passed format, lint, both knip checks, GraphQL, affected typechecks, and focused tests. Focused tests passed again after merging current main.
  • Two independent reviews returned MERGE without blocking findings. Final proof audit returned SUFFICIENT.
Real headless server measurementBeforeAfter
Retained sweep Maps after completed sweep 1 / full GC10
Retained sweep Maps after completed sweep 2 / full GC20
Helper tracing span names exportedPresentPreserved

Evidence index, runtime transcript, counters, provenance, and fixture script. Server-only change: visual fixture matrix is empty. Baseline runtime was captured at 0ad399c6c5; fixed runtime at 15b7291404, whose changed server files are byte-identical at final head 57a7bd0a8d. Upstream changes merged afterward were client-only.

Real-data seeding hit a VM database migration-history mismatch, so runtime proof uses synthetic stopped threads. The baseline contained 30 synthetic threads plus the bootstrap thread; after used 31 synthetic threads. This verifies retention and release, not the reporter's full 18,736-link workload or exact growth rate. Raw heaps are not published because they may contain credentials. CI and hosted review gates remain pending; no bugfix label will be added before they pass.

Models: Claude Opus 5.5 and GPT-6.1-sol, through T3 Code's Claude and Codex harnesses.

Checks

23 successful · 13 skipped
All checks passed
57a7bd0

Added 3 commits

  • test(server): a finished pull request sweep must not stay reachable from cache fibers0341b4f
  • fix(server): finished pull request sweeps no longer stay in memory15b7291
  • Merge remote-tracking branch 'origin/main' into fix/issue-2517257a7bd0
Synced from GitHub

Approvability

Verdict: Approved at 57a7bd0

Macroscope's review found this PR approvable — This is a narrowly scoped server memory-retention fix that changes only Effect wrapper instrumentation, preserving existing spans and pull-request synchronization behavior. A focused regression test verifies that completed sweep data can be collected when a cache retains the lookup fiber.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: f4e1407 · PR result: 57a7bd0 · 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.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between f4e140764fba579ccb77a3dabe2dd0bcee98d037 and 57a7bd0a8dda42029eab327ecdac478dce334cae.

External image Files selected for processing: 2
  • apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts
  • apps/server/src/orchestration-v2/PullRequestSyncReactor.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 pull-request sync helpers now use untraced Effect functions with explicit spans. A new test runs a cache-backed sweep, clears the snapshot, and checks that no SweptLink objects remain.

Changes: Sweep retention

Layer / File(s)Summary
Span handling and retention test
apps/server/src/orchestration-v2/PullRequestSyncReactor.ts, apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts
syncEntry and syncGroup use Effect.fnUntraced with explicit spans. The test runs a cache-backed sweep and checks for remaining SweptLink objects after clearing the snapshot.

Priority: External image Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested labels: size:S

Suggested reviewers: t3dotgg, maria-rcks

Merge Risk: External image Minimal · up to 57a7b

No actionable merge-blocking risk was identified; the change is ready for normal checks.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title is concise, specific, and accurately describes the server fix that releases completed pull-request sweep data.
Description checkPassedThe description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the retention issue, links the triaged issue, documents focused tests and measurements…
Linked Issues checkPassedIssue [#25172] requires completed PullRequestSyncReactor.sweep runs to release the groups map and its thread and link data. The change replaces the sweep-local Effect.fn closures for syncEntry…
Out of Scope Changes checkPassedThe reviewed changes are limited to PullRequestSyncReactor.ts and its regression test. The implementation changes Effect tracing and closure retention for the server pull-request sweep. The test val…
Full details: Description check

Explanation

The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the retention issue, links the triaged issue, documents focused tests and measurements, and states verification limits and pending gates.

Full details: Linked Issues check

Explanation

Issue [#25172] requires completed PullRequestSyncReactor.sweep runs to release the groups map and its thread and link data. The change replaces the sweep-local Effect.fn closures for syncEntry and syncGroup with Effect.fnUntraced wrappers and explicit Effect.withSpan calls. The existing span names remain PullRequestSyncReactor.syncEntry and PullRequestSyncReactor.syncGroup. The new regression keeps a cache lookup fiber alive and verifies that 30 swept link objects become collectible. The reported reactor and focused checks also pass.

Full details: Out of Scope Changes check

Explanation

The reviewed changes are limited to PullRequestSyncReactor.ts and its regression test. The implementation changes Effect tracing and closure retention for the server pull-request sweep. The test validates collection behavior under a retained cache fiber. These changes directly support issue [#25172]. No unrelated client, contract, authentication, or persisted-state changes are present in the reviewed diff.

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.