# Reference patch — 01-weighted-shares

The answer key for how the reference absorbs this change, and the thing that makes `budget.json`
reproducible. **Never shipped to the candidate.**

1. **Overlay** `../contract-delta/SplitType.java` onto `contract/` — the enum gains one constant,
   `SHARES`. Contract files are given, so nothing there is charged.
2. **Add** `WeightedSplit.java` (in this directory) to `reference/src/`. New file, so
   `measureChange` charges nothing for it.
3. **Edit** `reference/src/SplitwiseFactory.java`, in `standardCalculators()`:

   ```diff
            return Map.of(
                    SplitType.EQUAL, new EqualSplit(),
                    SplitType.EXACT, new ExactSplit(),
   -                SplitType.PERCENTAGE, new PercentageSplit());
   +                SplitType.PERCENTAGE, new PercentageSplit(),
   +                SplitType.SHARES, new WeightedSplit());
   ```

`edits.json` beside this file is the same edit in machine-readable form, so the measurement can be
re-run: baseline is `reference/src/*.java`, current is the same files with the `reference-patch`
`*.java` added and `edits.json`'s replacement applied, fed to `measureChange(baseline, current)`.

Measured: `reference_diff = 3` (2 added, 1 removed, one file touched), so
`diff_budget = max(3, 3 + ceil(3/2)) = 5`.

Both the curveball suite (4 tests) and the base suite (29 tests) are green after the patch —
33 tests, no regression.

## Where the requirement landed, and where it did not

`SplitEngine`, `SplitwiseSystem`, `Group` and `Ledger` were not opened. Dispatch, sequencing,
membership and the pairwise ledger have no opinion about how many split types exist, which is the
whole point of routing `SplitType -> SplitCalculator` through a `Map` instead of a `switch`: a
`switch` without a `default` would have forced `SplitEngine` to grow a new case the day the
contract grew a constant, and one with a `default` would have silently mis-handled the new type
instead of failing loudly the moment it was forgotten.

`WeightedSplit` needed no new arithmetic of its own beyond the one proportional-division line —
`Shares.byParticipant` already checks that a shares list names exactly the participants it should,
and `RemainderAllocator.closeGap` already closes whatever gap flooring leaves behind. Both were
built for `PercentageSplit` in the base problem, not anticipated for this curveball; they turned
out to be reusable because "resolve a total into per-participant amounts that must add up exactly"
is the same shape of problem every time, whatever the numbers going in mean.

**What a candidate is most likely to get wrong here** is not the proportional arithmetic — it is
having nowhere to put a fourth split type except inside whatever method already has an
`if (splitType == EQUAL) ... else if (splitType == EXACT) ...` chain in it. That chain is a rewrite
every time a type is added; a registered calculator is not.
