Skip to content

PRD-7886: stop stale branch claim wedging every document (#3380) - #1120

Merged
inkeep-oss-sync[bot] merged 1 commit into
mainfrom
copybara/sync
Aug 9, 2026
Merged

PRD-7886: stop stale branch claim wedging every document (#3380)#1120
inkeep-oss-sync[bot] merged 1 commit into
mainfrom
copybara/sync

Conversation

@inkeep-oss-sync

Copy link
Copy Markdown
Contributor

Copybara-translated 1 Inkeep OSS change. Rebase-merge this PR so the prepared commit lands directly on public main.

* PRD-7886: stop stale branch claim wedging every document

The onAuthenticate branch gate compared a client's expectedBranch claim
against getActiveBranch(), which starts as the DocumentDurabilityState
"main" default and only becomes the workspace's real HEAD branch once
initAsync runs switchReconciledBaseScope. WebSocket connections are
accepted from the moment createServer returns, so on a workspace whose
branch is not main, every cold-boot connect was rejected as a branch
mismatch against a placeholder the server had no business comparing
against. The rejection recycled the client pool, which re-armed the same
30s load budget against a server still inside the same window, and every
document in the workspace timed out. Restarting the app replayed the
identical race, so there was no user-reachable workaround.

Park the gate on the same readiness promise handleServerInfo already
awaits before comparing, and only when a claim is actually present so
token-less clients pay nothing. Keep the handler responsive on a degraded
boot with the same catch handleServerInfo uses.

Also let DocumentErrorBoundary clear itself when the document it is
reporting a reach failure for later reaches synced. Recovery already
happened on the reporter's machine seven seconds after the boundary
latched, and the screen stayed up for another 36 minutes. Scoped to reach
failures: a bridge setup failure also leaves a provider reporting synced
but with observers that never wired, so clearing on that signal would
swap the error screen for a silently non-functional editor.

* Drop the error-boundary auto-recovery, keep the branch gate fix

The auto-recovery cleared a reach-failure fallback as soon as the doc's
provider reported synced. Seven docs-open e2e tests pin the opposite
contract on purpose: a reach error stays until the user retries, goes
back, or navigates away, and QA-024 specifically pins that revisiting an
errored doc re-renders the error from the cached rejection. Those tests
arm a rejection against a provider that then syncs normally, so the
recovery fired immediately and the fallback never rendered.

Changing that contract means rewriting those tests and deciding what
revisiting an errored doc should now do, which is a product call and not
something to smuggle into a fix for a user-facing wedge. Reverted here
and written up in the PR body instead.

The branch gate fix, its regression tests, and the server-info branch
adoption tests are unaffected.

* Gate the branch claim check on branch resolution, not full boot

The gate parked on the server's readiness promise, which settles only at
the end of initAsync: the HEAD-drift upstream import, the backlink cold
rebuild, the O(n) watcher seed walk, the tag reconcile and the sync
engine all sit in front of it. WebSocket admission happens long before
that, and every returning tab carries a branch claim from localStorage,
so the previous shape put the entire boot pipeline ahead of the first
document sync on every branch, not just non-main ones. On a large
workspace that tail can outlive the client's 30 second sync budget,
which recycles the provider into a fresh park and leaves the same error
screen the fix was written to remove.

The gate now parks on a dedicated deferred settled the moment
switchReconciledBaseScope has aligned durability state with HEAD, which
is the only value it reads. The deferred also settles on the initAsync
failure path so a boot that dies before the alignment cannot hang
admission, and the park is bounded: if it expires, the branch is read
straight off HEAD rather than compared against the main placeholder, and
an unreadable HEAD skips the check instead of judging the claim against
a guess.

Adds a regression test that pins admission settling before the rest of
boot does. It fails against the previous shape.

GitOrigin-RevId: 8b948cf4b7799fa36b365498a6a31050fe4f7745
@inkeep-oss-sync
inkeep-oss-sync Bot merged commit 1dba80f into main Aug 9, 2026
@inkeep-oss-sync
inkeep-oss-sync Bot deleted the copybara/sync branch August 9, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant