Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
mergedhumanPR #273Other

test(participants): wait for the seller's ack before asserting it

Follow-up to #264–#272, from the same correctness audit of main at df0b5f1.

Author

JamesCarnley avatar

@JamesCarnley

github profile →
Status
Merged
Merged on
Sep 14
Branch
fix/test-participants-seller-ack-race

Description

The pitch.

Follow-up to #264–#272, from the same correctness audit of `main` at `df0b5f1`.
This is a test-only change. It merges cleanly with the other open PRs.

### Problem

`tests/test_participants.py::test_buyer_and_seller_complete_clean_run` fails
intermittently with `assert len(seller_acks) == 1` → `0`. It failed CI on `main`
on 2026-09-05 (run 33956097284) and on the first Python 3.12 job of #271.

The seller sends its reply before it records its own ack
(`participants/base.py`). The buyer returns as soon as it has checked that
reply, so the test's single read of the events can happen before the seller's
ack exists. Joining the seller thread would not help, because the seller keeps
polling until its deadline.

### Change

The test now polls the events endpoint for up to 5 s until the seller's applied
ack appears, then makes the same assertions. If the ack never arrives, it still
fails with the same message. No product code changes.

I scanned `tests/` for the same pattern. The only similar test, the MCP test in
`test_adapters.py`, joins the buyer thread, which acks before returning, so it
is not affected.

### Verification

- **Deterministic race** (a 1 s delay injected before the seller's ack, in a
  scratch copy only): the old test fails 5 of 5 runs and the new test passes 5
  of 5.
- **Loops on unchanged product code:** the old test failed 2 of 100 runs; the new
  test passed 300 of 300.
- Full suite: 817 passed, twice.

### Scope

Scope is the participants test only. The sibling flake in
`tests/test_e2e.py::test_crash_restart_run_end_to_end` has the same symptom but
a different cause, so no wait in that test can fix it: under load the restarted
seller loses its 1.5 s lease between applying the work and acknowledging it, its
applied acknowledgement is refused as a stale fence, and the redelivered work is
then recorded only as a duplicate with no application record. That is a
product-side attribution bug and is fixed separately.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Try it

Open PR on GitHubView diff

Checkout locally

git fetch origin pull/273/head:pr-273
git checkout pr-273