A harness gate test whose head sha matches no CI run spins forever instead of failing #508
Labels
No labels
agent-ready
bug
contract
documentation
duplicate
enhancement
good first issue
help wanted
invalid
needs-human
needs-input
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
iterative-works/iw-cli#508
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A
PhasePrHarnessTestcase that reachesCiGate.pollwith a forge head sha matching no run in the scriptedCiSnapshotdoes not fail. It spins inCiGate.loop, heartbeating the card throughReviewStateWrite.tryUpdateon every turn, and never stops.Observed 2026-09-03 while writing the tests for #467: twenty minutes of a test JVM at ~190% CPU, killed by hand.
jstackputmaininReviewStateValidator.validateunderCiGate.heartbeat->CiGate.loop->PhasePr.gate.Root cause
The real gate is bounded by a wall-clock budget.
FakeClockdoes not advance on its own, so in a harness test that budget never expires. The gate is right; the fixture gives a mistyped test no way to end, and munit's per-test timeout does not fire because the test is making progress, not blocking.Why it matters
The failure mode is indistinguishable from a hung build: no assertion, no output, no exit. It costs whoever hits it the time to find a JVM and read its stack before they learn they scripted a sha wrong.
Options
FakeClockon eachfetchCiSnapshotcall, so a wait in a harness test ends the way a real one does.The first keeps the fake honest about the passage of time and needs no new concept. Either way the fix belongs in
core/test/fixtures/FakeCommandEnv.scala, not inCiGate.