# Reference patch — 02-simplified-group-debts

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/SplitwiseApi.java` (a full revised interface, now including
   `simplifiedDebts(String)`) and `../contract-delta/Settlement.java` (new) onto `contract/`.
   Contract files are given, so nothing there is charged.
2. **Add** `DebtSimplifier.java` (in this directory) to `reference/src/`. New file, so
   `measureChange` charges nothing for it — this is where the whole greedy algorithm lives.
3. **Edit** `reference/src/SplitwiseSystem.java`: one import, and one new override.

`edits.json` beside this file is the exact 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 replacements applied, fed to
`measureChange(baseline, current)`.

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

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

## Two designs were measured, and the cheaper one was kept

This is the curveball the authoring brief calls out as the one that might genuinely need a new
collaborator rather than a new strategy, and the one to be honest about if it turns out to cost
more than a curveball should. It did not, but two shapes for the small amount of plumbing it does
need were measured before picking one, exactly because "it compiled and passed" is not the same
question as "is this the cheaper design":

- **Kept:** `SplitwiseSystem.simplifiedDebts` builds the `Map<String, Long>` of net positions
  itself, in a four-line loop over `Group.members()` and `Group.netBalanceOf(String)` — both
  already public, both already used to answer `netBalanceOf` one member at a time. Measured at
  **10 lines, one file.**
- **Considered and dropped:** add a `Group.netPositions()` method that does the same loop
  internally, then have `SplitwiseSystem` call that instead of looping itself. This reads slightly
  more like "the group knows its own net positions," and it is a perfectly defensible design — but
  it touches two files instead of one (the new method in `Group.java` plus the override in
  `SplitwiseSystem.java`) and cost 4 more lines to say the same thing. Measured at **14 lines, two
  files.**

Neither design opens `Ledger` or any `SplitCalculator` — the pairwise ledger already answered
"what is this member's net position" one member at a time, via `netBalanceOf`, and this curveball
only needed to ask that question for everyone at once. That reuse is what kept both candidate
designs cheap; the choice between them was only ever about which file should own a four-line loop.

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

`Ledger` never learns about a third person — see its own class doc. `DebtSimplifier` is hand of a
plain map to a plain map: it does not know what a group, an expense or a member id even is beyond
a `String` key, which is what makes it independently testable and exactly why it did not need to
live inside `Group` or `Ledger` to do its job.

**What a candidate is most likely to get wrong here** is reaching for this algorithm too early —
building it into the pairwise ledger from the start "in case it's needed later." The base problem
never asks for it, and `Ledger`'s class doc says as much: a ledger that tried to answer both the
pairwise question and the group-wide one would be answering two questions with one method, which
is exactly the shape of class that gets harder to change every time either question does.
