Bounded test lanes¶
ZapTrace classifies every collected pytest item into exactly one primary lane. The committed policy is config/test-lanes.json; tests not listed by an explicit rule enter the unit lane. This keeps new tests visible without silently dropping them from CI.
| Lane | Purpose | Pull-request budget |
|---|---|---|
unit |
Pure, fast behavior and calculation tests | 600 s |
integration |
Cross-module, API, MCP, policy, and service contracts | 900 s |
benchmark |
Deterministic benchmark, convergence, and performance evidence | 900 s |
hardware |
EDA formats, generated boards, corpus conversion, and manufacturing evidence | 900 s |
external_tool |
Docker, KiCad, ngspice, and other delegated executables | 600 s |
native |
Rust extension and native-boundary verification | 600 s |
The coverage-enabled unit lane and the heavy benchmark and hardware lanes are split by whole test module. config/test-duration-baseline.json stores measured module durations; the greedy allocator assigns the longest modules first to the currently lightest shard. A module never moves between shards because of collection order. Python 3.12 CI uses three unit shards, while benchmark and hardware use two shards each.
Local commands¶
task test-lane-policy
task test-unit
task test-integration
task test-benchmark
task test-hardware
task test-external-tool
task test-native
A direct shard run uses one-based indexes:
uv run pytest -p tests.lane_policy \
--lane "benchmark" \
--lane-shard-index 1 \
--lane-shard-count 2 \
--require-lane-execution \
--lane-report test-lane-benchmark-1.json
Each CI lane publishes JUnit XML and a JSON report containing the selected modules, collected inventory, pass/fail/skip counts, elapsed time, runtime budget, projected historical duration, and shard identity. Required heavy lanes fail when empty or entirely skipped. External prerequisite confidence is reinforced by the dedicated KiCad oracle, container, Rust build, and validation-environment gates; a skip is evidence, never a pass claim.
Refreshing duration weights¶
Run the affected lane with pytest duration reporting, then update only the measured modules:
uv run pytest -p tests.lane_policy --lane "unit" --durations=0
uv run pytest -p tests.lane_policy --lane "benchmark" --durations=0
uv run pytest -p tests.lane_policy --lane "hardware" --durations=0
Record the measurement date and host class in config/test-duration-baseline.json. Do not use random or hash-only sharding for bounded lanes because it ignores observed cost and recreates long-tail jobs.
Dated migration evidence¶
The baseline inventory, measured shard runs, runtime budgets, and measurement limitations are retained in docs/reports/test-lane-evidence-2026-07-27.json. The report is dated development evidence, not a cross-machine performance guarantee; GitHub Actions job conclusions remain authoritative.
Release policy¶
Tagged releases execute all six lanes explicitly with cumulative coverage, using the same committed three-way unit and two-way benchmark/hardware shard boundaries as pull-request CI. The release job then emits coverage.json and applies the critical-runtime coverage policy. No primary lane or configured shard may be removed from the release command list without failing the repository policy tests.