Files
PaperClipAI/packages
DottaandClaude Opus 5.5 03eb49053f test(runner): bound Codex provider event waits by a hang ceiling, not 5s (#19306)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Rust runner drives provider processes such as Codex, and CI
tests it on Linux, macOS and Windows
> - The "Runner Rust (Windows x64)" job fails at random on pull requests
that do not touch the runner
> - The failures come from Codex provider integration tests that wait
for fake-provider events under a fixed five-second deadline
> - On a loaded Windows runner, process spawn, antivirus scans and
fsyncs of durable state make these exchanges take longer than five
seconds, so the wait stops before the event arrives
> - This pull request keeps each wait on its condition and changes the
deadline to a shared hang ceiling
> - The benefit is that unrelated pull requests do not fail on this job,
and a real hang still fails the test

## Linked Issues or Issue Description

**What happened?**
The "Runner Rust (Windows x64)" job failed on pull requests that do not
change the runner. Examples:
- Run 42073331106 (PR #19273) and run 42058757139:
`rejected_declared_completion_stays_failed_when_the_provider_completes`
panicked with `called Option::unwrap() on a None value`. The loop ended
at its 5 s deadline before `session.failed` and `run.terminal` arrived.
- Run 41892735530 (master): the same test failed in the same way.
- Runs 41718881566 and 41670873220:
`durable_descendant_lineage_survives_capacity_and_provider_restoration`
failed with "capacity exhaustion must become a specific durable recovery
reason". Its third phase waited only 5 s. An earlier phase of this test
already had a 30 s deadline with a comment about this contention.

**What did you expect?**
The tests wait until the fake provider produces the event. They fail
only when the provider hangs.

**Steps to reproduce**
Run `cargo test --release --workspace` for the runner on a contended
Windows x64 runner. The suite takes about 380 s there, and some tests
run for more than 60 s. The failures are intermittent.

## What Changed

- `tests/codex_provider.rs`: add `EVENT_WAIT_TIMEOUT` (120 s) and
`event_deadline()`. Replace all 50 fixed 5 s and 30 s wait deadlines
with `event_deadline()`. Each wait already stops when its condition
holds, so passing tests do not get slower.
-
`rejected_declared_completion_stays_failed_when_the_provider_completes`:
assert that the run reached `run.terminal`, and print the observed event
types if it did not. Replace the bare `unwrap()` on `session.failed`
with a message that names the scenario.
- `src/bin/fake-codex-app-server.rs`: the two background gate threads
used 5 s and 10 s bounds. A test releases a gate only after its own
waits succeed, so these bounds had the same problem. They now use one
`TEST_GATE_TIMEOUT` of 120 s.
- No production code changes. The two remaining `from_secs(5)` values
are the unused `max_runtime` in the test config and a Unix-only latency
assertion. Both stay the same.

## Verification

- `cargo test --release -p paperclip-runner-core --test codex_provider
--locked`: 109 passed, 0 failed, 2 ignored.
- I ran the two flaky tests 48 times, with 6 copies in parallel per
round to load the machine. All 48 runs passed.
- `cargo fmt --all --check`: clean.
- `cargo clippy -p paperclip-runner-core --test codex_provider --bin
fake-codex-app-server`: no new warnings in the changed lines. The lib
target already has clippy findings from the local toolchain (Rust 1.97).
They are not in the changed files, and CI does not run clippy.
- I did not reproduce the original failure on macOS. The slow condition
occurs only on the loaded Windows runner. The Windows CI job on this
pull request is the main check.

## Risks

- Low risk. The change affects only tests and the test fixture binary.
- If a test hangs for real, it now fails after 120 s and not after 5 s.
This makes a broken run slower, but the failure message stays the same.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, used through Claude
Code with tool use (shell, file edits, GitHub CLI).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 13:00:37 -06:00
..