Hand a mutation child only the mutation it is asked about A mutation child was pointed at the run's own augmented manifest, so every child parsed every other mutation's record, covering-test list and source context in order to find the single record it needed. The cost is linear in the file's size, and the file grows with the project: 3.7MB on nix-ci's `leader-data`, 15MB on its `leader`. Measured on the `leader` suite, one child against a mutation covered by one test: | manifest the child is pointed at | wall | maxRSS | |---|---|---| | the run's own (12MB) | 3.06 s | 565 MB | | a directory holding its own record | 1.21 s | 142 MB | The test that child runs takes 0.1 s, and sydtest's own summary for it says `Sum of test runtimes: 0.10 seconds, Test suite took: 1.13 seconds`. The parse is also mostly parallel GC work, so it costs far more in CPU than its own wall time suggests, and that is what makes it crowd out the other children on a busy machine rather than only slowing its own. The parent has the record in hand and already makes a temp directory per child, so it now writes the record there, together with the baselines of the tests that child will consider, and points the child at that. Nothing about the child protocol changes. ### Measurements Both drivers built from this tree, one with the change and one without, so the patch is the only variable. Each run is the real mutation phase of a nix-ci check, outside nix, against the same instrumented test executables and the same coverage directories, at eight jobs. `leader-data`, 1460 mutations, alternating the two drivers twice (machine busy with other builds, so wall drifts): | | wall | CPU (user+sys) | |---|---|---| | before, round 1 | 378.9 s | 4465 s | | after, round 1 | 235.4 s | 1645 s | | before, round 2 | 389.4 s | 4338 s | | after, round 2 | 295.5 s | 1998 s | `leader`, 2949 mutations, on an idle machine: | | wall | CPU (user+sys) | maxRSS | |---|---|---|---| | before | 2455 s | 23751 s | 2.59 GB | | after | 2018 s | 5860 s | 2.21 GB | So **CPU falls by 59% and 75%**, and wall by 31% and 18%. The two differ because at eight jobs on a 64-core machine there are cores to spare for the parse, so it hurts wall only a little while it is idle and a lot while it is not: CI runs several of these checks at once, which is the loaded case. Every run above produced identical verdicts, compared as the sorted list of mutation id to outcome: `leader-data` 1354 killed / 106 controls passed / 0 survivors, `leader` 2736 killed / 16 timed out / 213 controls passed / 0 survivors. ### Tests `MutateSpec` gains a regression test: a stand-in suite exe copies the directory it was pointed at, and the test asserts it holds the one mutation and the one baseline rather than the two the run knows about. It fails without the change (`Passed: 8, Failed: 1`) and passes with it.