From 4b338d337111f14b005cf79799eef012f8a73160 Mon Sep 17 00:00:00 2001 From: Logan Johnson Date: Sat, 12 Sep 2026 12:09:59 -0400 Subject: [PATCH] fix(beehive): publish manager-credential fixture PID marker atomically The orchestration test polls for the fixture's readiness marker with existsSync and then reads the PID. The fixture published the marker with a single writeFileSync, so a child descheduled between the internal open and write exposed a zero-byte file; Number('') is 0 and process.kill(0, 0) probes the caller's process group, so the protected ESRCH assertion failed with "Missing expected exception" while the production SIGKILL plus awaited-close teardown had demonstrably worked. Publish through a staging file and renameSync, the same atomic pattern as the blocker() fixture in credential-helper.test.ts, so a reader that sees the marker always sees the complete owned PID. Assertions, poll budget, timeout and production behavior are unchanged; negative controls in the task triage report show broken kill or broken awaited-close still fail the protected assertion. Signed-off-by: Logan Johnson --- beehive/test/manager-credential-fixture.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/beehive/test/manager-credential-fixture.ts b/beehive/test/manager-credential-fixture.ts index 8ac36bc216..e8377462ef 100644 --- a/beehive/test/manager-credential-fixture.ts +++ b/beehive/test/manager-credential-fixture.ts @@ -1,5 +1,10 @@ -import { writeFileSync } from 'node:fs'; +import { renameSync, writeFileSync } from 'node:fs'; process.once('message', (value: any) => { - if (value.wait) { writeFileSync(value.marker, String(process.pid)); setInterval(() => {}, 1000); } + // Publish the PID atomically (staging file + rename) so the marker never + // exists in a partially-published state: a reader that sees the marker must + // see the complete PID, never an empty file (Number('') === 0 would probe the + // caller's process group instead of the owned child). Same pattern as the + // atomic blocker() fixture in credential-helper.test.ts. + if (value.wait) { const pending = `${value.marker}.pending`; writeFileSync(pending, String(process.pid)); renameSync(pending, value.marker); setInterval(() => {}, 1000); } else { process.send?.({ ok: true, secret: null, node: process.versions.node, overrides: process.env.NODE_OPTIONS }); process.disconnect(); } });