Skip to content

flake: shared timing substrate in src/orchestrator/factory.test.ts fails 3 different tests nondeterministically #342

Description

@khaliqgant

Summary

src/orchestrator/factory.test.ts"releases a late placement when another owner reclaimed the lifecycle (#303)" fails intermittently at roughly a 30% rate on main, with no code change between runs.

Measurement

Sampled by running that single test repeatedly with vitest run -t, nothing else changed between runs:

arm failures
clean origin/main (cbb3d32) 3 of 8
an unrelated feature branch 1 of 8

Consecutive runs on identical code produced exit=0 then exit=1, which is the definition of a flake rather than a regression.

The failure

AssertionError: expected [Function] to throw error matching
  /was released while .* was still spawn…/
but got 'Dispatch lifecycle ownership lost imm…'

Both outcomes are real code paths; which one wins appears to depend on ordering between the release and the ownership check. The test asserts the release message specifically, so whenever the ownership-lost path wins the race the assertion fails.

Why it is worth fixing rather than tolerating

A ~30% flake in the main orchestrator suite makes every PR's CI close to a coin toss, and it fails inside the largest suite in the repo — so the natural reading is "this PR broke something." I hit it on an unrelated change and had to spend 16 test runs across two arms proving it was not mine. Everyone who touches this repo will pay that cost, or worse, will not pay it and will merge on a re-run without checking.

It also erodes exactly the signal this codebase depends on most: that a red check means something. This repo already has one red check on every PR (the request job's HTTP 403, fixed by #340) that people have learned to scroll past. A second habitual red is how a real failure gets ignored.

Suggested direction

Make the assertion accept either terminal outcome, or pin the ordering the test means to exercise, rather than asserting one side of a race. I have deliberately not changed it here — the test encodes intent from #303 and its author should decide which outcome it is meant to prove.

Found while working on #341.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions