Sync 2 Inkeep OSS Changes - #833
Merged
Merged
Conversation
… (#2928) * fix(auth): survive a dropped sign-in stream instead of failing (#803) GitHub sign-in failed with "Sign-in stream ended without confirmation" when the loopback connection between the browser and the local server blipped. Two things turned a transient drop into a permanent failure. The stream carried zero bytes from the moment the device code appeared until authorization finished, which is what idle-connection reapers look for: SSL-inspection agents, VPN local proxies, tab-backgrounding. The envelope now heartbeats a ping line every 15s; consumers skip it and it never terminates the stream. The disconnect also SIGTERM'd the device-flow subprocess, so a user who authorized on github.com afterwards stored no token and had nothing to recover. A disconnect is now a detach: the flow runs on and the client reconnects via the auth-status relay to pick up a token that landed while it was gone. The property the old kill protected, don't store a token after the user backed out, moves onto an explicit signal: POST /api/local-op/auth/cancel, which the modal fires on close. That is the lifetime model the desktop IPC transport already had, where a vanished renderer never killed the flow and only an explicit cancel did; HTTP was the outlier because a socket close was the only signal it had. Also drives the countdown off the expires_in GitHub actually issued. It counted down from a hardcoded 2 minutes and claimed "Code expired" while the code had ~13 minutes left, which was also the window in which recovery could succeed. The device-flow subprocess timeout moves to 16 minutes for the same reason: 10 minutes cut the flow short of the code's own life. * refactor(auth): drop the cancel slot guard, back off recovery polls Two follow-ups from self-review of the #803 fix. The cancel endpoint had a concurrency slot like its local-op siblings, but those guard a subprocess spawn and this one spawns nothing and does no IO. Its body runs with no await in it, so two concurrent cancels cannot interleave and the second reads a null slot and no-ops. The guard bought nothing and added a failure mode that inverts the endpoint's purpose: a 429'd cancel leaves the flow running, which is exactly what the caller asked to stop. Wrapped in catchErrors so an unexpected throw still lands as a typed 500. Recovery polling now backs off 2s to 10s instead of a fixed 3s. Each poll spawns an auth status subprocess server-side, so a fixed interval cost ~300 spawns across a code's full 15-minute life. Backoff keeps that under ~100 while the early polls, when the user is most likely to be finishing up, stay fast. * fix(auth): make stream detach and recovery-probe failures observable Both from review. The recovery loop swallowed every status-probe error, so a recovery that was broken the whole time and a user who simply never authorized both ended at the same expiry message 15 minutes later, with nothing to tell them apart. It warns now, matching the bounded-warn pattern the NDJSON line-drop in the same file uses. Server-side, a detached flow was invisible until something displaced it. It now logs a structured auth-stream-detached event, but only for a GENUINE detach. An unconditional log would fire on every normal cancel too: the client POSTs the cancel and then aborts the stream, so the socket closes while the child is still winding down from the SIGTERM. A detach event that fires on routine teardown tells an operator nothing about whether an intermediary is cutting streams. The slot-ownership check is what separates the two, since an explicit cancel has already cleared the slot and a displaced flow no longer owns it. The cancel test now mirrors the real client's POST-then-abort ordering, which is what makes that check load-bearing; without it the test goes red. * fix(auth): log a failed cancel POST Third observability item from review, same class as the other two. A cancel that never lands leaves a device-flow child running for up to 16 minutes, and the environments this fix targets are exactly the ones where a loopback POST might not make it. Still best-effort: the flow's own timeout and fresh-start displacement remain the backstops. GitOrigin-RevId: 09df6361d357b68d762ec9360072d34a095b8c7e
…750) Two-channel model: stable = production = done. Beta cut advances the Linear release to the started 'Beta' stage; stable promotion just completes it, landing in the pipeline's completed stage (renamed from 'Released' to 'Stable'). Drops the intermediate 'update stage=Stable' so there's no confusing third state. Requires (one-time, Linear UI): delete the started 'Stable' stage, then rename the completed 'Released' stage to 'Stable'. GitOrigin-RevId: 4d6362b721517ed1a545e4fbcc1990f63bf0f95f
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.
Copybara-translated 2 Inkeep OSS changes. Rebase-merge this PR so the prepared commits land directly on public main.
Commits: