docs: describe the shipped timeout architecture (#2319 round 14)

Three comments still said transport-internal discovery has no
client-side wrapper, or that the wrapper must never be applied to the
transport fetch. Round 11 made both false, and the second actively
tells a caller to do the opposite of what InspectorClient does — while
hiding that isExempt is the safety-critical part.

- createRemoteFetch's marker comment now gives the real reason the
  reconstruction matters: both ends run the same budget, so this path
  is the backend winning the race, most plausibly a backgrounded tab
  throttling setTimeout while the server's fires on schedule. Which
  deadline fired must not decide whether the error names its endpoint.
- The body-buffering comment now says buffering is the second reason
  isExempt is not optional on a mixed chain, since an exempt request
  skips it and an SSE body stays open rather than being drained.
- The matching test comment is reframed as testing the proxy boundary
  independently of which deadline wins.

The PR description is rewritten around what is actually shipped: both
chains bounded and differing only in the exemption, the per-request
envelope that replaced the fetchTimeoutMs option, and the three
mutation-verified tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YFnM6RqB4nXqNysgUYmjmq
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-11 05:42:00 -04:00
commit 93965936ba

View file

@ -184,9 +184,14 @@ export function createRemoteFetch(options: RemoteFetchOptions): typeof fetch {
// rebuild the typed error from its marker so the `instanceof` checks
// downstream — most importantly the one that lets a stalled probe escape
// `withRfc8414OidcCompat` — still see a timeout for what it is (#2319,
// Copilot). This is the only path on which such a timeout can reach the
// browser without a client-side wrapper having fired first: the discovery
// the SDK runs from inside the transport has no wrapper at all.
// Copilot).
//
// Both ends run the same budget, so the client's race usually settles
// first and this path is not taken. It matters when the backend's timer
// wins anyway — most plausibly a backgrounded tab, where the browser
// throttles `setTimeout` while the server's fires on schedule. Without
// this, which of two equal deadlines happened to fire would decide
// whether the error carried its endpoint.
let parsed: unknown;
try {
parsed = JSON.parse(text);