fix(browser): serve waits for chrome, keeps its stderr, and reaps its own Xvfb (DIVE-4400) - #67
Conversation
|
Still wanted — this fix never landed and |
… own Xvfb (DIVE-4400) `serve` backgrounded chrome with `>/dev/null 2>&1 &`, wrote chrome_pid=$! unconditionally and printed success. A chrome that trapped in its first millisecond was therefore indistinguishable from a healthy one to `ls`, to the stack row and to `viewer` — and the only surface that told the truth was the customer's Connect press, which 502'd. - _pid_live: a reaped-pending zombie answers `kill -0` with success, so the one moment we need the truth is the one moment kill -0 cannot give it. /proc says Z. - serve waits, bounded, for the process to still exist before writing a pidfile or printing anything; on death it dies E_UNAVAILABLE carrying chrome's own stderr (kept in the profile at 0600 instead of discarded). - a failed serve reaps the Xvfb it started, so it leaves no orphan display for _display_free to hop past forever. - _probe's "UNKNOWN (probe did not load)" now names what chrome said and STAMPS the profile, so `ls` can tell it from "never probed". Tests: tests/browser_plugin_unit.sh T10u — control arm (a chrome that stays up still serves, its Xvfb left running), then the defect: rc 69, no success line, chrome's two stderr lines handed back, no pidfile, Xvfb reaped, and the dashboard's own `viewer` call refusing. 208 passed / 0 failed. Mutants: dropping the reap fails exactly the orphan arm; restoring the old print-and-return shape fails six. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…(DIVE-4610)
Rebasing the DIVE-4400 serve-liveness fix onto today's main is textually clean
and semantically NOT: 537 passed / 3 failed against a 531 / 0 control at
origin/main. All three are the same shape -- T15d2, T15e and T16g assert that a
screenshot or a run PUTS THE CUSTOMER'S BROWSER BACK, and their fake chrome
exits the instant it is launched. Before this fix `serve` printed success and
wrote a pidfile for a chrome that was already gone, so those arms were reading
the pidfile of a browser that had died; after it, `serve` correctly refuses, and
the arms were measuring the fake's lifetime rather than the product's restore.
So the rig's fakes now identify a serve launch POSITIVELY -- headed (no
--headless) and sized (--window-size) -- and exec sleep, the same way SRVBIN
already does for the T10 serve arms and the T10u control does for its own. It is
matched positively on purpose: a negative match ("no --headless") catches
`doctor`'s --version and `auth`'s headed window, both foreground, and hangs the
suite forever.
That surfaced a second, older leak. There is no DISPLAY in CI, which is the
normal case on a managed box, so T2e's `auth x` takes the server-mode path and
STARTS A SERVE for profile x. That serve was previously a lie and thus invisible;
with a fake that stays up it is real, and a served profile answers `status` with
"UNKNOWN (served on :N)" by design -- silently converting T4c and T11d, the two
positive controls for the word `authenticated`, into assertions about a leak.
T2e now stops what it started.
540 passed, 0 failed on the rebased tree. Reverting bin/browser to origin/main
under these same tests reds exactly 6 arms, all T10u, and nothing else.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63c0bb7 to
c5381bf
Compare
|
Rebased onto The rebase was textually clean and semantically not, which is why it was not a blind
The 3 failures were one shape: The rig now identifies a serve launch positively — headed (no That exposed a second, older leak: CI has no Not merged blind and not forced green: CI runs at 🤖 Generated with Claude Code |
DIVE-4400 arm 1 —
servemust not print success until Chrome is aliveMeasured on our canary (exact-swallow, 2026-09-13 04:0x–04:2xZ):
5dive browser serve linkedin.comprintedserving linkedin.com on :375 (persistent …)and left no Chrome process atall — only the Xvfb it started.
browser lslisted the site, the stack statusread
state=ok / store=ready, and the only surface that told the truth was acustomer pressing Connect on the live dashboard and getting a 502.
bin/browserbackgrounded Chrome with>/dev/null 2>&1 &, wrotechrome_pid=$!unconditionally, printed success, and judged liveness by theXvfb pid. A Chrome that dies in the first millisecond was indistinguishable
from a healthy one, and its stderr was discarded before anyone could read it.
This PR
servewaits for the pid,kill -0s it after a beat, and on failure exitsnon-zero with Chrome's own stderr (no longer sent to
/dev/null).servereaps the Xvfb it started, so it no longer leaves anorphan display that pushes the next
_display_freeprobe to:376,:377, …(two such orphans were standing on the canary).
Evidence
tests/browser_plugin_unit.sh— 208 passed / 0 failed (199 before, +9 arms).Mutants, anchored to individual arms:
T10u …and REAPS THE Xvfb it startedline, both stderr lines, the pidfile, the reap)
Controls, because a negative arm that cannot fail is arm-counting: T10u first
runs a Chrome that stays up on the same rig and asserts
servesucceeds andits Xvfb is left running. The fake Xvfb records its own pid (
execkeepsit) — "no display was left behind" cannot be read off the product's pidfile,
because a correct failure deletes that file.
Not claimed
Not re-measured on the canary: that box's Chrome is still broken (a
libc6upgrade pending reboot — the trigger, not the defect) and this host has no
browser stack installed. The on-box re-measure —
serverefusing, the rowreading degraded, Connect still 502 but now visibly — is owed and is the
real acceptance for DIVE-4355.
Arm 2 (the stack health row) is 5dive-ai/5dive-api's companion PR.
🤖 Generated with Claude Code