fix(gitlab): share merge request reads across detail and checks#24392

merged4
main
fix/issue-24190
opened6d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 6h ago

Problem

Opening a GitLab merge request fetched both its detail and project merge settings, then fetched the same detail again for checks. In the real web app, detail and checks spawned three glab processes within about one second, spending the shared GitLab request budget.

Change

Cache successful project merge settings for 15 minutes and merge request reads for 60 seconds, with bounded caches keyed by checkout and repository. Detail and checks share reads. Writes and explicit or post-turn refreshes clear MR reads before service cache revisions change. Execution-time permission checks remain fresh.

Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/24190

GitCafe: https://git.cafe/pingdotgg/t3code/issues/24190

Triaged bug via the automated issue flow. This fixes the reported GitLab read duplication; other providers and the wire contract are unchanged.

Verification

  • Red at b176399d63: two focused regression tests failed with project reads 3 instead of 1 and MR reads 2 instead of 1. Red command output.
  • Green at 3631d874a1: vp test run packages/source-control-gitlab passed 116 tests; vp test run apps/server/src/pullRequest/PullRequestService.test.ts passed 89 tests. Includes fresh permission changes, cache expiry, write invalidation and Deferred-controlled refresh races. Green command output.
  • Scoped core, GitLab and server typechecks passed. Touched-file lint passed with one pre-existing warning. Both independent final reviewers found no blockers.

Server-only evidence; no render paths changed, so the visual fixture matrix is empty.

Real app sequenceBeforeAfter
Detail then immediate checksTwo detail subprocesses plus one checks subprocessOne MR read and one project-settings read; immediate checks adds none. Cold identity lookup is separately reported.
Checks after 20 secondsNot sampled separatelyNo additional subprocesses
Detail after 65 secondsNot sampled separatelyOne MR read; settings reused; immediate checks adds none
Explicit refreshNot sampled separatelyFresh MR read immediately; settings reused

Baseline runtime transcript · Final runtime transcript · Evidence and uploaded drivers · Test evidence index.

Verified on Linux through the real dev web app and authenticated GitLab CLI. A transient glab exit 1 during the first expiry attempt is retained in the evidence; the recovery and a separate clean expiry cycle succeeded. Baseline subprocess spans lack endpoint arguments; final evidence includes sanitized endpoint samples. No client-specific behavior changed.

Models and harnesses: Claude Opus 5.5 through Claude Code for tests and implementation; GPT-6.1-Sol through Codex for issue lead and proof; both for independent reviews, orchestrated through T3 Code.

Checks

24 successful · 15 skipped
All checks passed
3631d87

Added 4 commits

  • fix(gitlab): merge request pages no longer re-read the project and detail on every view30986e7
  • fix(server): refreshes drop provider merge request reads before readers can see them3631d87
  • fix(gitlab): refreshes and finished turns re-read merge requests; writes check fresh accessac270ce
  • test(gitlab): reproduce issue 24190 repeated merge request readsb176399
Synced from GitHub

Approvability

Verdict: Approved at 3631d87

Macroscope's review found this PR approvable — This focused GitLab fix deduplicates merge-request and project-settings reads with bounded TTL caches while preserving fresh permission checks and clearing cached reads around writes and refreshes. The added service hook and tests keep the behavior contained to the existing pull-request flow.

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: 27e0c68 · PR result: 3631d87 · 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 27e0c684c585f955252d65f06206dd11a143bff5 and 3631d874a15bad86a5aa209441210ece421b79f8.

External image Files selected for processing: 5
  • apps/server/src/pullRequest/PullRequestService.test.ts
  • apps/server/src/pullRequest/PullRequestService.ts
  • packages/source-control-core/src/server/PullRequestProvider.ts
  • packages/source-control-gitlab/src/server/GitLabPullRequestProvider.test.ts
  • packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

Walkthrough

The GitLab provider now caches merge-request details and project merge capabilities. Provider writes and pull-request service refresh operations invalidate cached reads. Tests cover cache reuse, expiration, scoped invalidation, and reads during refresh.

Changes: GitLab read cache

Layer / File(s)Summary
Provider cache and invalidation
packages/source-control-core/src/server/PullRequestProvider.ts, packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts, packages/source-control-gitlab/src/server/GitLabPullRequestProvider.test.ts
The provider API adds optional read invalidation. GitLab caches detail and project capability reads, invalidates detail entries around writes, and tests cache reuse, expiration, and invalidation.
Service refresh invalidation
apps/server/src/pullRequest/PullRequestService.ts, apps/server/src/pullRequest/PullRequestService.test.ts
The service forwards scoped or global invalidations to providers during refresh. Tests verify invalidation calls and check that reads during refresh do not retain stale details.

Priority: External image Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: t3dotgg, macroscopeapp

Merge Risk: External image Minimal · up to 3631d

No substantiated merge-blocking issue remains; merge after normal checks.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title is concise, follows the repository's conventional commit style, and clearly describes the main change: sharing GitLab merge request reads across detail and checks.
Description checkPassedThe description covers the problem, change, scope and approval, and verification. It includes focused test results, runtime evidence, known limitations, and tool details.
Linked Issues checkPassedIssue #24190 has two active coding objectives. GitLabPullRequestProvider caches successful project merge capabilities for 15 minutes and merge-request details for 60 seconds. The detail cache is key…
Out of Scope Changes checkPassedThe changes stay within issue #24190 and its stated area. The core provider interface and PullRequestService changes add the invalidation hook required to clear provider-held GitLab reads during wri…
Full details: Linked Issues check

Explanation

Issue #24190 has two active coding objectives. GitLabPullRequestProvider caches successful project merge capabilities for 15 minutes and merge-request details for 60 seconds. The detail cache is keyed by checkout, repository, and number. getChangeRequestChecks uses the same detail cache as getChangeRequest, so detail, checks, and the sync read path can share the read. Writes and refresh invalidation clear cached reads. getViewerPermissions reads directly, which preserves fresh execution-time permission checks. Added tests cover cache reuse, expiry, checkout isolation, write invalidation, scoped invalidation, and permission freshness. The proposed rate-limit-header follow-up is not required by the issue.

Full details: Out of Scope Changes check

Explanation

The changes stay within issue #24190 and its stated area. The core provider interface and PullRequestService changes add the invalidation hook required to clear provider-held GitLab reads during writes and refreshes. The GitLab implementation and focused regression tests support the cache behavior. No unrelated provider, client render path, or wire-contract change is shown in the supplied change summary.

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.