Skip to content

tests: test-invocation-lifetime reads PID files before they are written, so a stopped-compiler check can pass on PID 0 #3432

Open

Description

@schlessera

Context

Found while fixing #3401. That issue's storage-inventory tests waited for a child's PID file with existsSync, then parsed it. writeFileSync creates the file before writing it, so a descheduled child could expose an empty file, and Number("") is 0. The same pattern exists in tests/test-invocation-lifetime.test.ts:

  • The fake tsc publishes tmp/compiler-pid with writeFileSync (line 47). The test waits on existsSync and reads it (tests/test-invocation-lifetime.test.ts:51-52). It then asserts OWNED_COMPILER_STOPPED with !existsSync(\/proc/${pid}`)(line 56). Withpid === 0, /proc/0` never exists, so the assertion passes vacuously and the test no longer checks that the owned compiler stopped.
  • tmp/survivor-pid is published with writeFileSync (line 68), awaited with existsSync and parsed (tests/test-invocation-lifetime.test.ts:71-72).

This is a false-green risk rather than a flake: the check can silently prove nothing under load. Not observed failing in CI. Found by auditing the bug class.

Acceptance criteria

  • Every PID file in tests/test-invocation-lifetime.test.ts that the test polls for and then parses is published atomically (temporary file then rename), or the reader accepts only a complete, newline-terminated positive PID (the shape tests/workspace-lease.test.ts already uses).
  • A forcing receipt shows the base reading PID 0 (a widened window between create and write), and shows the fix rejecting or never seeing the empty file.
  • A mutation receipt shows OWNED_COMPILER_STOPPED still fails when the owned compiler is left running.

Refs #3401.

Activity

  1. added this to the 0.45.0 milestone on Nov 3, 2026
  2. added
    type: testCoverage, harness or proof work with no behaviour change.
    area: ciCI workflows, the gates they run, release scripts, packaging.
    priority: p2Wanted, not scheduled. Pulled in when a milestone has room.
    on Nov 3, 2026
  3. self-assigned this
    on Nov 3, 2026
  4. schlessera commented on Nov 3, 2026

    @schlessera
    OwnerAuthor

    Claiming (token wi-3432-b4fb), branch fix/3432-invocation-pid-race. Collisions for tests/test-invocation-lifetime.test.ts: no path report; only shared-closure reports (38 open PRs, including #3433). Plan: publish every polled file in this test atomically (temp file, then rename), and make the PID reads refuse 0 or an unparsable value. The same file has two more instances besides the cited lines: tmp/nested-compiler, which can make NESTED_CANCEL_STOPS_COMPILER_BEFORE_OUTER_EXIT pass vacuously, and tmp/orphan/tmp/late. A repo-wide audit of the bug class will be filed separately.

  5. schlessera commented on Nov 3, 2026

    @schlessera
    OwnerAuthor

    Fix, forcing, mutation and loaded receipts are in draft #3439 (head 9ad632062). That PR is ready to confirm but held: main is green, but the integration lease is held by another candidate. To resume: once the lease is free, run bun scripts/integrate.ts confirm 3439 --issues schlessera/brain-kit#3432. The remaining instances of this bug class found by the repo-wide audit are filed as #3435. Releasing my claim (wi-3432-b4fb); #3439 is the resumable work.

  6. removed their assignment
    on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ciCI workflows, the gates they run, release scripts, packaging.priority: p2Wanted, not scheduled. Pulled in when a milestone has room.type: testCoverage, harness or proof work with no behaviour change.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions