fix: kill chromium's process group before removing its profile #93

Merged
yuris merged 1 commit from fix-html5-teardown into main 2026-08-21 10:32:52 +00:00
Owner

Fixes the #81 flake at its cause. Blocks #92 (and every PR) now that #91 made the HTML5 tier gate.

It was never a smoke failure. The tail #91's new self-report captured shows every phase PASSing on both loads of the identity-persistence check, and then:

[Error: ENOTEMPTY: directory not empty, rmdir '/tmp/nix-shell.sEhlPE/stdb-chromium-UsNCpq/Default']

Teardown signalled only the process it holds a handle to. Chromium's renderer and utility processes are what write the profile, and they do not die with their parent — so rm walked the tree against live writers.

Chromium now gets its own process group and teardown signals the group, then waits for the parent to be reaped before removing the directory.

Measured on this box against a tree with a surviving grandchild writer, 8 races per mode:

teardown result
parent-only kill (before) 7 of 8 ENOTEMPTY
parent kill + rm maxRetries: 3 1 of 8 ENOTEMPTY
process-group kill (this PR) 0 of 8

Worth recording that the retry route was tried and rejected: it papers over the race without closing it, which is why the fix is the group kill and rm keeps its plain options.

Why it surfaced now: #91 dropped continue-on-error from the HTML5 step, so a teardown crash fails the job instead of leaving a footnote. It failed on v2 on run #230 and on v1 on run #232 — alternating wires, which is the signature of a race rather than a protocol problem. That also means gating worked exactly as intended: it turned an invisible footnote into a diagnosable failure on its second run.

Verified: both tiers green locally (v1 and v2, PASS plus identity survived a reload).

Fixes the #81 flake at its cause. Blocks #92 (and every PR) now that #91 made the HTML5 tier gate. **It was never a smoke failure.** The tail #91's new self-report captured shows every phase PASSing on both loads of the identity-persistence check, and then: ``` [Error: ENOTEMPTY: directory not empty, rmdir '/tmp/nix-shell.sEhlPE/stdb-chromium-UsNCpq/Default'] ``` Teardown signalled only the process it holds a handle to. Chromium's renderer and utility processes are what write the profile, and they do not die with their parent — so `rm` walked the tree against live writers. Chromium now gets its own process group and teardown signals the **group**, then waits for the parent to be reaped before removing the directory. Measured on this box against a tree with a surviving grandchild writer, 8 races per mode: | teardown | result | | --- | --- | | parent-only kill (before) | 7 of 8 `ENOTEMPTY` | | parent kill + `rm` `maxRetries: 3` | 1 of 8 `ENOTEMPTY` | | process-group kill (this PR) | 0 of 8 | Worth recording that the retry route was tried and rejected: it papers over the race without closing it, which is why the fix is the group kill and `rm` keeps its plain options. **Why it surfaced now:** #91 dropped `continue-on-error` from the HTML5 step, so a teardown crash fails the job instead of leaving a footnote. It failed on v2 on run #230 and on v1 on run #232 — alternating wires, which is the signature of a race rather than a protocol problem. That also means gating worked exactly as intended: it turned an invisible footnote into a diagnosable failure on its second run. Verified: both tiers green locally (v1 and v2, PASS plus identity survived a reload).
fix: kill chromium's process group before removing its profile
All checks were successful
ci / ci (pull_request) Successful in 20s
conformance / conformance (v1) (pull_request) Successful in 2m50s
conformance / conformance (v2) (pull_request) Successful in 2m45s
1b044baac4
The HTML5 tier's flake (#81) is not a smoke failure. Every phase PASSes, both
loads of the identity-persistence check complete, and then the harness dies:

  [Error: ENOTEMPTY: directory not empty,
   rmdir '/tmp/nix-shell.sEhlPE/stdb-chromium-UsNCpq/Default']

teardown signalled only the process it holds a handle to, but chromium's
renderer and utility processes are what write the profile and they do not die
with their parent. So `rm` walked the tree against live writers.

Chromium now gets its own process group and teardown signals the group, then
waits for the parent to be reaped before removing the directory. Measured on
this box against a tree with a surviving grandchild writer, 8 races each:
parent-only kill failed 7 of 8 with ENOTEMPTY, group kill failed 0 of 8. Node's
`rm` retry options paper over the same race without closing it (1 of 8 still
failed at maxRetries: 3), so this fixes the cause instead.

Why it surfaced now: #91 dropped `continue-on-error` from the HTML5 step, so a
teardown crash fails the job instead of leaving a footnote. It failed on v2 on
one run and on v1 on the next, which is the race, not a wire.

Verified: both tiers green locally, v1 and v2.
yuris merged commit c46cd42727 into main 2026-08-21 10:32:52 +00:00
yuris deleted branch fix-html5-teardown 2026-08-21 10:32:52 +00:00
Sign in to join this conversation.
No description provided.