Symptom
CI fails intermittently with:
```
tests/dispatcher/test_router.py::test_decision_logging_runs_on_every_resolution FAILED
E AssertionError: assert 'dispatch.decision' in []
```
Hits both python (3.11) and python (3.12) jobs. Has appeared on multiple unrelated PRs (#293, #294, #295, #297) — surfaced during the ADR-0013/ADR-0014 backend + docs stream.
Hypothesis
The test calls `structlog.configure(processors=[_capture])` to swap the global processor chain, then runs the dispatcher to capture emitted events. Another test running in parallel — or one that ran earlier and didn't restore — leaves structlog in a state where the dispatch.decision event never reaches `_capture`. Hence `captured` is empty.
Repro is rare locally; first happens on CI runner where pytest order + warmup differs.
Fix candidates
- Use `structlog.testing.capture_logs()` context manager instead of `structlog.configure(...)` — it's the supported isolation primitive.
- Mark the test `@pytest.mark.flaky(reruns=2)` if pytest-rerunfailures is wired in CI.
- Pin processor chain restoration in a fixture (try/finally with `structlog.reset_defaults()` is brittle).
Not in this stream's scope (#257-#264) — filing for the dispatcher owner.
Provenance
Bash log from PR #293 + #297 reruns 2026-05-23.
Symptom
CI fails intermittently with:
```
tests/dispatcher/test_router.py::test_decision_logging_runs_on_every_resolution FAILED
E AssertionError: assert 'dispatch.decision' in []
```
Hits both python (3.11) and python (3.12) jobs. Has appeared on multiple unrelated PRs (#293, #294, #295, #297) — surfaced during the ADR-0013/ADR-0014 backend + docs stream.
Hypothesis
The test calls `structlog.configure(processors=[_capture])` to swap the global processor chain, then runs the dispatcher to capture emitted events. Another test running in parallel — or one that ran earlier and didn't restore — leaves structlog in a state where the dispatch.decision event never reaches `_capture`. Hence `captured` is empty.
Repro is rare locally; first happens on CI runner where pytest order + warmup differs.
Fix candidates
Not in this stream's scope (#257-#264) — filing for the dispatcher owner.
Provenance
Bash log from PR #293 + #297 reruns 2026-05-23.