Context
The engine runs one subprocess per rule, sequentially (engine.evaluate → _run_check). On the normal commit path (a handful of staged files) this is instantaneous and correct. But becwright check --all on a large repo with many rules pays N sequential process starts + N full scans.
(The docs now state this honestly — see the Performance and limits section added in #77 — but stating a limit is not the same as removing it.)
Proposal
Rules are independent by design (each gets its own file list and subprocess), so they can run concurrently:
concurrent.futures.ThreadPoolExecutor around _run_check calls in evaluate — threads are enough since the work is subprocess-bound, no new dependency needed.
- Keep output ordering deterministic: collect results, print in rule order.
BECWRIGHT_CHECK_TIMEOUT semantics unchanged (per check).
Acceptance
Context
The engine runs one subprocess per rule, sequentially (
engine.evaluate→_run_check). On the normal commit path (a handful of staged files) this is instantaneous and correct. Butbecwright check --allon a large repo with many rules pays N sequential process starts + N full scans.(The docs now state this honestly — see the Performance and limits section added in #77 — but stating a limit is not the same as removing it.)
Proposal
Rules are independent by design (each gets its own file list and subprocess), so they can run concurrently:
concurrent.futures.ThreadPoolExecutoraround_run_checkcalls inevaluate— threads are enough since the work is subprocess-bound, no new dependency needed.BECWRIGHT_CHECK_TIMEOUTsemantics unchanged (per check).Acceptance
check --allwall-clock on a many-rule repo ≈ slowest rule, not the sum