Problem
The pytest plugin heals candidates one at a time:
https://github.com/Johin2/self-heal/blob/main/src/self_heal/pytest_plugin.py#L127-L131
Each candidate is an independent, network-bound LLM round-trip, often several attempts deep. A suite with eight @pytest.mark.heal failures pays all eight sequentially, so a run that could take one round-trip's wall clock takes eight. This is the difference between --heal being something you run on every red suite and something you run when you have a coffee break.
Proposal
Run candidates concurrently with a bounded worker pool.
--heal-workers N (default something conservative like 4, 1 restores today's behavior).
- Use threads: the work is I/O-bound on the provider, and the existing async proposer paths can be driven from a thread pool without restructuring the loop.
- Keep terminal output deterministic by buffering each candidate's report and flushing in the original candidate order, not completion order.
Acceptance criteria
- Candidates are healed concurrently up to the worker limit.
- Reported output ordering is identical to the sequential run.
--heal-apply writes are serialized; two candidates in the same file must not race on the patch.
- A failure in one candidate cannot abort the others.
--heal-workers 1 is byte-identical to current behavior.
Notes
The apply-path serialization matters more than it looks: with #58 landed, two failing methods in one class are two candidates pointing at the same file.
Problem
The pytest plugin heals candidates one at a time:
https://github.com/Johin2/self-heal/blob/main/src/self_heal/pytest_plugin.py#L127-L131
Each candidate is an independent, network-bound LLM round-trip, often several attempts deep. A suite with eight
@pytest.mark.healfailures pays all eight sequentially, so a run that could take one round-trip's wall clock takes eight. This is the difference between--healbeing something you run on every red suite and something you run when you have a coffee break.Proposal
Run candidates concurrently with a bounded worker pool.
--heal-workers N(default something conservative like 4,1restores today's behavior).Acceptance criteria
--heal-applywrites are serialized; two candidates in the same file must not race on the patch.--heal-workers 1is byte-identical to current behavior.Notes
The apply-path serialization matters more than it looks: with #58 landed, two failing methods in one class are two candidates pointing at the same file.