# Reference patch — 01-a-third-export-format

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/ExportFormat.java` onto `contract/` — it replaces the file of the
   same name, adding the `XML` constant. Contract files are given, so nothing here is charged.
2. **Add** `XmlExporter.java` (in this directory) to `reference/src/`. A new file, so
   `measureChange` charges nothing for it.
3. **Add one line** to `reference/src/CustomerSatisfactionFactory.java`, in `standardExporters()`:

   ```diff
            exporters.put(ExportFormat.JSON, new JsonExporter());
   +        exporters.put(ExportFormat.XML, new XmlExporter());
   ```

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

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

Both the curveball suite (6 tests) and the base suite (15 tests) are green after the patch. **No
base assertion is invalidated** — CSV and JSON export exactly as they did, because
`CsvExporter` and `JsonExporter` were not touched.

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

`Exporter`, `CsvExporter`, `JsonExporter`, `Rounding`, `Summaries` and `SatisfactionDesk` were
**not opened**. Two decisions in the base design are what reduced a third export format to one
line:

- **`Exporter` is an interface with one pure method**, so a new format is a new implementation and
  nothing calls it by name except the registry. `exportMonthly` never branches on the format itself
  — it looks the exporter up and delegates — so there is no `switch` statement anywhere that a third
  case could be missing from.
- **`CustomerSatisfactionFactory.standardExporters()` exposes the registry as a map**, built once
  and handed to the desk, rather than a private detail `SatisfactionDesk` constructs for itself.
  Adding a format is adding an entry, at the one place that already lists every format there is.
- **`Rounding` is shared.** `XmlExporter` calls the same `Rounding.twoDecimalPlaces` that `CsvExporter`
  and `JsonExporter` call, so "the same half-up rule as csv and json" — stated in the requirement
  and asserted by this curveball's rounding test — is true by construction. A third exporter that
  rolled its own `String.format` call would risk drifting from the other two the first time someone
  changed one of them.

**What this would have cost with a `switch (format)` inside `exportMonthly`:** a new `case XML ->`
arm, in the file every existing format already has to pass through — an edit to the class the
requirement is not really about, and the shape the interviewer is checking whether you reach for.
