ReviewOS

also looking at this

stacks/drone

test: retain native purge fixture lifecycle observations

#56
Merged chris wants to merge codex/purge-fixture-lifecycle into main
38 files +1820 -172

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

tests/helpers/public-safety-purge-fixture.tsmodified+16-4
Changes to tests/helpers/public-safety-purge-fixture.ts
@@ -2,19 +2,31 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises'
22import { tmpdir } from 'node:os'
33import { join } from 'node:path'
44
5/** Await one guarded native fixture and own its terminal process boundary. */
6export async function runPurgeQualificationFixture(name: string, timeoutMs: number): Promise<{ code: number, stdout: string, stderr: string }> {
5/**
6 * Await one guarded native fixture. Elapsed time includes output drain; the
7 * deadline marker and observed signal are separate facts, not a causal verdict.
8 */
9export async function runPurgeQualificationFixture(name: string, timeoutMs: number): Promise<{ code: number, stdout: string, stderr: string, lifecycle: Readonly<{ pid: number, timeoutMs: number, deadlineFired: boolean, elapsedMs: number, signal: string | number | null }> }> {
710 if (!['purge-faults', 'purge-critical', 'purge-budget', 'purge-capacity', 'purge-sql', 'purge-relations', 'purge-seal', 'purge-bounds', 'purge-mixed', 'purge-namespace-identity'].includes(name)) throw new Error('Unknown qualification fixture')
811 const root = await mkdtemp(join(tmpdir(), `drone-incident-access-${name}-`))
912 let child: ReturnType<typeof Bun.spawn> | undefined
1013 try {
1114 const config = join(root, 'bunfig.toml'); await writeFile(config, 'preload=[]\n')
15 const started = performance.now()
16 let deadlineFired = false
1217 const running = Bun.spawn([process.execPath, `--config=${config}`, '--no-env-file', `${import.meta.dir}/../fixtures/public-safety-access/${name}.ts`], { cwd: root, env: { ...process.env, APP_ENV: 'test', NODE_ENV: 'test', DB_CONNECTION: 'sqlite', DB_DATABASE_PATH: join(root, 'access.sqlite') }, stdout: 'pipe', stderr: 'pipe' })
1318 child = running
14 const timer = setTimeout(() => { if (running.exitCode === null) running.kill('SIGKILL') }, timeoutMs)
19 const timer = setTimeout(() => {
20 if (running.exitCode !== null) return
21 deadlineFired = true
22 running.kill('SIGKILL')
23 console.error('PURGE_FIXTURE_DEADLINE', JSON.stringify({ fixture: name, pid: running.pid, timeoutMs, elapsedMs: performance.now() - started, requestedSignal: 'SIGKILL' }))
24 }, timeoutMs)
1525 try {
1626 const [code, stdout, stderr] = await Promise.all([running.exited, new Response(running.stdout).text(), new Response(running.stderr).text()])
17 return { code, stdout, stderr }
27 const lifecycle = Object.freeze({ pid: running.pid, timeoutMs, deadlineFired, elapsedMs: performance.now() - started, signal: running.signalCode ?? null })
28 if (code !== 0) console.error('PURGE_FIXTURE_EXIT', JSON.stringify({ fixture: name, code, ...lifecycle }))
29 return { code, stdout, stderr, lifecycle }
1830 }
1931 finally { clearTimeout(timer) }
2032 }