Reported after the revert: the app loads, the old layout is back, history lists — and the socket
never reaches connected.
The two doors disagreed. `createClient` accepts a token from seven places: window.officerBearerToken,
two body datasets, an `?officerToken=` query param, PERTENTO_EDITOR_AUTH_TOKEN, localStorage and
sessionStorage. The chat socket url read exactly one of them, `localStorage.BEARER_TOKEN`, so a
token held anywhere else authenticated every HTTP request and left the WebSocket with a bare
`?token=`.
That failure is silent and reads as a dead server: verified here, an empty token closes with 1002
"Expected 101 status code", and the hook's retry loop repeats it forever. Nothing logs a missing
credential, so the app looks fine in every way except the one that matters.
Resolution is now one exported function, `resolveBearerToken`, used by both. The point is that it
cannot be re-spelled: this bug is the second spelling drifting from the first.
Predates the tabs work and survived reverting it, which is the evidence it was never a panes bug.
Not fixed here, same shape, left alone deliberately: Terminal, Desktop, AudioStreamPlayer, the
pipeline and task runners, JobDetail and EmailList all build socket or fetch urls from
`localStorage.BEARER_TOKEN` directly and will fail identically for the same user.
Typecheck clean. 600 pass, 2 fail — cliamp and pty, unchanged and unrelated. Not verified in a
browser; Andre has the only client that reproduces it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>