Files
Maximilian Roos 166e1190ba refactor(perf): canonicalize wt-perf prune-fixture layering + completion config (#3548)
## What

Three behavior-preserving canonicalizations of the `wt-perf` benchmark
fixtures, from a design pass on "why does prune need its own generator,
and can the fixtures consolidate?"

1. **Share the prune-population layer.** `create_prune_repo_at`
(synthetic) and `create_prune_real_repo_at` (rust-scale) both layered
the same two populations onto their base repo — `add_diverged_backdrop`
(the scanned-but-never-removed backdrop) + `add_squash_merged` (the
removable candidates). Extracted into `add_prune_populations`, so the
base repo (synthetic `create_repo_at` vs. rust clone) is now the *only*
thing the two fixtures differ in, spelled out once instead of twice.

2. **Canonicalize `completion.rs` onto `RepoConfig::branches`.** Its two
inline `RepoConfig` literals were exactly `RepoConfig::branches(50, 0)`
(one with `worktrees` overridden), so they now use the canonical preset
via struct-update instead of respelling all seven fields.

3. **Document the fixture → bench mapping.** `benches/CLAUDE.md` listed
the `wt-perf setup` handles in one section and the bench groups in
another with nothing connecting them, so a bench and its fixture (`full`
and `mixed`) read as overlapping names for the same thing. Added a
mapping table and the rule behind it.

## Why this is the whole safe consolidation

The design question was whether prune could drop its bespoke generator
for a "standard one with different params" — ideally one diverse repo
serving prune *and* the other benches. The answer is that prune's
generator is **already** a thin composition (`create_repo_at` + two
additive layers), and it can't fold into the shared `mixed`/`full`
fixture without breaking three prune-specific invariants: a
known/cleanly-separated candidate count (the destructive `live` path
re-creates exactly the consumed candidates), untracked-only dirt (the
`git reset --mixed` index-heal depends on it — `mixed`'s staged-dirt
states violate it), and a provably-unintegrated backdrop. And benchmark
fixtures optimize for *attribution*, not realism: the uniform
single-axis fixtures (`worktree_scaling`, etc.) exist precisely because
the diverse `full` fixture can't localize a regression, so diversifying
them would lose that.

On the `full`/`mixed` naming specifically: they can't be canonicalized
to one name, because fixtures and benches are **many-to-one** —
`RepoConfig::typical` alone backs five bench groups (`skeleton`,
`worktree_scaling`, `first_output`, `picker_preview`, `remove_e2e`), two
of which sit in the same file measuring different things. `full`/`mixed`
only looks 1:1 by coincidence. Renaming also isn't free:
`.github/scripts/criterion-to-jsonl.py` keys each time-series row by the
criterion output path (`<group>/<id>`) for the daily gist append, so a
rename orphans that series. Documented rather than renamed.

## Proposed follow-up (not in this PR)

The one remaining real duplication is two *implementations* of
"two-sided-diverged population forked across history depth":
`add_diverged_backdrop` (plumbing-based, scales to rust) vs. the
diverged branch states inside `create_mixed_repo` (checkout-based,
synthetic-only). They can't naively merge — the checkout path would make
`prune-real` take minutes per branch — but a shared plumbing primitive
could back both. That rewrites a carefully-tuned fixture feeding the
`full` bench with **no shape-assertion test to catch drift**, so I'd
land a fixture-shape test first (count refs by state + assert
integration status). Happy to do it if wanted.

## Verification

fmt `--check` clean; `clippy -p wt-perf --all-targets` and `clippy
--bench completion` clean; `pre-commit` clean on the doc; `cargo test -p
wt-perf` passes (incl. the prune-fixture tests
`squash_merged_fixture_is_content_integrated` /
`prune_fixture_state_classifies_lifecycle`, which exercise
`create_prune_repo_at` → `add_prune_populations`); all benches build.
Table contents verified against the code by grep.

> _This was written by Claude Code on behalf of Maximilian Roos_

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 18:40:00 -07:00
..