A small patch release with one production drift-detection fix and a CI optimisation pass — no schema changes, drop-in upgrade from v0.35.x.
Bug Fixes
- Drift detection no longer freezes on workspaces with
plannedpeers — runs sitting inplannedawaiting operator confirm were treated as "busy" by drift detection, which blocked it forever. The workspace's latest-run status column would showapplied, so the bug was invisible from the dashboard but visible from the Health Issues banner ("Drift detection errored" stuck for weeks). Fixed by narrowing the busy-states gate to{planning, applying}— runs that actually consume a runner slot — and by resettingdrift_statustono_driftimmediately on every successful non-speculative apply (state == reality, so drift is zero). Health Issues clears on the next apply rather than waiting for the next drift interval.
CI
- Python Test critical path: 310s → ~156s (50% reduction). Sharded by directory matrix (
unit/services-api/integration), and the two mock-heavy shards now runpytest-xdist -n auto. Theintegrationshard stays serial (its session-scoped Postgres table-creation fixture races under xdist workers). - E2E Tests critical path: 136s → ~122s (10% reduction). Reduced from 4 shards to 2 (per-shard docker-compose stack boot dominates at 4 shards); each shard now uses 4 Playwright workers.
Code ↔ Tests Contract
Documented the project-wide test contract in CLAUDE.md and at load-bearing code sites (drift_detection_service._is_runner_busy, tests/services/test_summariser.py::TestNoStateLeakage, top of tests/conftest.py). Defines test tiers (unit / services-api / integration / E2E / Tilt smoke), what tier each kind of code change requires, and how the directory layout maps to the CI matrix. New code-review PR pattern: reference a specific contract rule rather than relitigating "should this have a test?" each time.
Status
Stable — drop-in upgrade from v0.35.x. No schema changes, no API breaks.
Full Changelog: v0.35.0...v0.35.1