eb6a4dc3

Scale the sqitch tests' timeout with the number of changes

Fixes the sydtest side of https://github.com/NorfairKing/nix-ci/issues/772. Replaces #153, which split the per-change test into one test per change; that turned the mutation coverage phase quadratic for the same headroom this gets in two lines.

## The bug

The sqitch sanity checks shell out to sqitch once or more per change, so their work grows with the plan, while sydtest's per-test timeout is one fixed 60 second budget. With nix-ci's 28 changes that is roughly a hundred process spawns in one budget. Under `nix flake check` the machine is oversubscribed, process spawns degrade worst under exactly that, and the check failed intermittently with a `<<timeout>>` naming a different change each time. The budget also covers less of the job with every migration added.

## The fix

`withPlanScaledTimeout` multiplies the configured per-test timeout by the number of changes in the plan, so the headroom per change stays constant as the plan grows. It scales what the caller configured rather than replacing it, so `--timeout` still means something and `DoNotTimeout` stays `DoNotTimeout`.

Exported, because the schema-equality check in `sydtest-sqitch-postgres-persistent` deploys the whole plan and has the same problem.

## Test

`gives the sqitch tests a timeout that scales with the number of changes` inspects the declared test forest and applies the scaling function to both `Timeout` constructors, asserting the 3-change toy plan triples a budget and leaves `DoNotTimeout` alone. It needs no postgres. Committed failing first (f736a871), where there is no timeout node at all.

No test for the timeout firing: that would be a wall-clock race, and what went wrong is structural.

## Things to check

- **The scaling factor is one whole per-test timeout per change**, so the default gives nix-ci's plan 28 x 60 s. That is loose for catching a genuine hang: a wedged sqitch now takes up to that long to fail, times retries. The alternative is a magic per-change constant in seconds, which is wrong on exactly the slow machines this is meant to tolerate.
- **Sizing the timeout reads the plan at spec-definition time**, so an unreadable `sqitch.plan` or a typo'd grandfather tag now throws there rather than failing one test. The message from `readSqitchPlan` is unchanged and explicit.
- **Whether the whole-plan cycle test should scale too.** It is under the same node, so it does. Its work is linear in the plan as well, but it is a single deploy/revert/deploy rather than per-change, so it is getting more headroom than it needs.
forwardCompatibilitymutation-dead-disablemutation-manifest-examplemutation-sydtest-mutation-examplemutation-sydtest-mutation-example-crosspre-commitreleaseshellconfiguredevShelldefaultmutation-sydtest-mutation-example-diffrelease-to-hackagex86_64-linux