Problem
Valid plugin fixtures intermittently become PL002 errors because the external Claude plugin validation surface reports Claude plugin validation timed out after 3 seconds. The same failure has blocked unrelated exact-SHA gates.
Reproduced observable
At Todo 12 SHA caa111a3540b0a48076a682c95e505e13b8f00d9:
uv run pytest
ERROR [PL002] (plugin-validation): Claude plugin validation timed out after 3 seconds
8 failed, 1610 passed, 10 skipped
EXIT=1
Rerunning the six non-benchmark failures sequentially with coverage and repository addopts disabled still produced five PL002 timeout failures:
uv run pytest -o addopts= --no-cov <six exact node ids> -q
5 failed, 1 passed
EXIT=1
Todo 17 SHA 8df691fea721d794beddd434537f853308af44de independently recorded the same PL002 timeout class: 4 failed, 1607 passed, 10 skipped, exit 1.
Green baselines also exist: Todo 12 SHA df0e9c7... passed 1617 passed, 10 skipped in 96.54s; Todo 17 SHA 89d4149... passed 1611 passed, 10 skipped in 189.92s; Todo 9 SHA 3dca6c6... reports a full-suite exit 0. This establishes variability but does not establish causality.
Required outcome
Make PL002 timeout behavior deterministic and keep valid-plugin fixtures from failing solely because an external validation process crosses an undocumented test-sensitive wall-clock boundary. Preserve a real integration check for the vendor command; do not turn every fixture test into an external timing test.
Implementation-ready scope
- Add a failing-first test at the subprocess boundary that distinguishes a successful-but-slow vendor result from a real timeout/failure. Control elapsed behavior without sleeping or depending on host load.
- Move ordinary rule/CLI fixture coverage onto a deterministic process seam or retained result fixture so unrelated tests do not depend on the live vendor command finishing inside three seconds.
- Keep one explicitly marked integration scenario that invokes the real vendor validator and reports unavailable/slow external state distinctly from a product PL002 finding.
- Source any production timeout from a documented contract or explicit configuration. Do not merely increase the literal until the current machine passes.
- Keep PL002 mapping for genuine vendor validation failures unchanged.
Acceptance
- The new negative control fails on the current three-second-dependent behavior and passes after the repair.
- Valid plugin fixtures are green in both
-n 0 and repository-default xdist runs without relying on wall-clock luck.
- A controlled genuine timeout still produces exactly one PL002 result with the expected message and exit behavior.
- A controlled non-timeout vendor failure retains its existing PL002 classification.
- The explicitly marked real-vendor integration scenario has a clear skip/unavailable contract and cannot turn unrelated unit/fixture tests red.
uv run prek run --all-files and three consecutive uv run pytest runs pass on a quiet host; retain exact exits and durations.
Related, not duplicate
ULTRAQA classification
flaky-test: CONFIRMED variable suite outcome across retained red and green runs; cause unverified.
hung-command: NOT OBSERVED. Every cited command terminated with an explicit exit; the observable is a bounded three-second child-process timeout.
stale-state: REJECTED. Evidence is keyed to exact SHAs and the live issue search was refreshed before filing.
misleading-success: CONTROLLED. Only receipts containing command summary plus explicit exit are treated as passes; a green focused cache/action test is not substituted for full-suite status.
Manual QA evidence
80-pl002-backlog-manual-qa.txt extracts the exact timeout observable, isolated rerun result, and last-success baselines from retained terminal receipts. It reports MANUAL_QA=PASS.
Cleanup
This investigation starts no server, subprocess under test, or temporary fixture. Final process/state receipt is retained alongside the report.
Problem
Valid plugin fixtures intermittently become PL002 errors because the external Claude plugin validation surface reports
Claude plugin validation timed out after 3 seconds. The same failure has blocked unrelated exact-SHA gates.Reproduced observable
At Todo 12 SHA
caa111a3540b0a48076a682c95e505e13b8f00d9:Rerunning the six non-benchmark failures sequentially with coverage and repository addopts disabled still produced five PL002 timeout failures:
Todo 17 SHA
8df691fea721d794beddd434537f853308af44deindependently recorded the same PL002 timeout class:4 failed, 1607 passed, 10 skipped, exit 1.Green baselines also exist: Todo 12 SHA
df0e9c7...passed1617 passed, 10 skipped in 96.54s; Todo 17 SHA89d4149...passed1611 passed, 10 skipped in 189.92s; Todo 9 SHA3dca6c6...reports a full-suite exit 0. This establishes variability but does not establish causality.Required outcome
Make PL002 timeout behavior deterministic and keep valid-plugin fixtures from failing solely because an external validation process crosses an undocumented test-sensitive wall-clock boundary. Preserve a real integration check for the vendor command; do not turn every fixture test into an external timing test.
Implementation-ready scope
Acceptance
-n 0and repository-default xdist runs without relying on wall-clock luck.uv run prek run --all-filesand three consecutiveuv run pytestruns pass on a quiet host; retain exact exits and durations.Related, not duplicate
ULTRAQA classification
flaky-test: CONFIRMED variable suite outcome across retained red and green runs; cause unverified.hung-command: NOT OBSERVED. Every cited command terminated with an explicit exit; the observable is a bounded three-second child-process timeout.stale-state: REJECTED. Evidence is keyed to exact SHAs and the live issue search was refreshed before filing.misleading-success: CONTROLLED. Only receipts containing command summary plus explicit exit are treated as passes; a green focused cache/action test is not substituted for full-suite status.Manual QA evidence
80-pl002-backlog-manual-qa.txtextracts the exact timeout observable, isolated rerun result, and last-success baselines from retained terminal receipts. It reportsMANUAL_QA=PASS.Cleanup
This investigation starts no server, subprocess under test, or temporary fixture. Final process/state receipt is retained alongside the report.