Repository navigation
Conversation
… leaves it viewed Host-backed viewed-file writes went straight to the provider, while environment-backed ones queue per change request. Two presses on the same change request run as concurrent RPCs, and the first GitHub press also looks up the pull request's node id, so a quick tick then untick could land on GitHub in reverse order and leave the file marked viewed. Route host writes through the same per-change-request order gate the environment path already uses. Writes on different change requests stay concurrent. Implemented by Claude Opus 5.5 via the Hermes ACP harness in T3 Code.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On a GitHub pull request, tick a file as viewed and then untick it shortly after. GitHub can end up with the file marked viewed, even though the last thing you did was untick it.
setFilesViewedinapps/server/src/pullRequest/pullRequestViewedFiles.tsalready has a per-change-request order gate,inFilesViewedOrder, so that a slow tick cannot overwrite a later untick. Only the environment-backed branch (GitLab and others) goes through it. The host-backed branch (GitHub,viewedFiles: "host") calls the provider write directly.Why the race happens in the real process:
apps/web/src/components/pullRequest/filesViewedStore.ts,flush). Each flush sendspullRequests.setFilesViewedwithout waiting for the previous flush to settle. Two flushes on one change request can be in flight at the same time, and so can presses from a second client (desktop plus mobile).RpcServerdefault concurrency (WS_RPC_SERVER_OPTIONSsets no limit), so both requests run at the same time in one server process. Nothing betweenws.tsand the provider orders them: thewithRateLimitBackoffwrapper only checks rate limits.GitHubPullRequestApi.setPullRequestFilesViewedfirst resolves the pull request's node id. That id is cached after the first lookup, so the first press on a change request makes one more GraphQL round trip than later presses. A tick followed by an untick therefore tends to reach GitHub in reverse order.Change
Route host-backed writes through the existing
inFilesViewedOrder(project, number, …)gate, the one the environment branch already uses. Presses on one change request now reach the host in the order they were made. The gate is keyed per change request, so writes on different change requests still run at the same time. One server file changes (+12/−8, including a comment update); tests +84.Scope and approval
This is a focused fix for an obvious bug, the "very small, focused fix" exception in CONTRIBUTING. The file already states the intended behavior ("Serialize presses so slower tick lookups cannot overwrite later unticks") and implements it for one of its two branches. The fix applies that existing behavior to the other branch. It adds no new mechanism, setting, or product behavior. Duplicate search on 2026-11-02 (open and recently closed PRs and issues: "viewed", "files viewed", "setFilesViewed", "viewed race", …) found no PR or issue for this. Open upstream PR
24151touches the same file but changes revision baselines for environment marks and does not touch the host branch.Verification
Base:
47f2c8d29e981c7723467efe137ee19e91df924e(upstream main). Linux, Node 26.12.1, pnpm 12.14.0.New tests are in
apps/server/src/pullRequest/PullRequestService.test.tsand run through the realPullRequestServicewith a fake GitHub host provider. ADeferredholds the tick's host write, which stands in for the node-id lookup. There are no sleeps.TestClockonly advances fibers, following the existing environment-ordering test.host viewed writes on one change request land in the order they were pressed: start tick (held), start untick, release the tick, then assert the host writes are[tick, untick]and that the file reads back asunviewed.a slow host viewed write does not hold up another change request(control): while a write on change request 10 is held, a write on change request 11 completes.RED on base (test file only, fix not applied):
The untick reached the host first, and the tick then overwrote it.
GREEN with the fix:
The control passes both before and after the fix, so the gate does not serialize across change requests. The
-t "host viewed write"filter also matches the existingpartial host viewed writes …test, which is the third test that passes.Also run:
cd apps/server && vp test run src/pullRequest/: 6 files, 141 tests passed.cd apps/server && tsc --noEmit --singleThreaded: exit 0.vp lint --report-unused-disable-directivesandvp fmton the two changed files: clean. The pre-commit hook (fmt,lint,knip:check) passed.Not checked
Implemented by Claude Opus 5.5 via the Hermes ACP harness in T3 Code.