# Reference patch — 02-priority-call

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/HallPanelApi.java` onto `contract/HallPanelApi.java`. Contract
   files are given, so nothing here is charged.
2. **Add** `UrgentStopOrders.java` (in this directory) to `reference/src/`. New file, free.
3. **Four edits to `reference/src/ElevatorSystem.java`**, mechanised in `edits.json`:

   ```diff
        private final FloorAccess access;
   +    private final UrgentStopOrders orders;
   ```
   ```diff
            Objects.requireNonNull(orders, "orders");
   +        this.orders = new UrgentStopOrders(orders);
   ```
   ```diff
   -            built.add(new Lift(id, capacityPerLift, orders.forLift(id)));
   +            built.add(new Lift(id, capacityPerLift, this.orders.forLift(id)));
   ```
   ```diff
   +    @Override
   +    public int priorityCall(int floor, Direction direction) {
   +        int liftId = hallCall(floor, direction);
   +        orders.escalate(liftId, floor);
   +        return liftId;
   +    }
   +
        @Override
        public boolean carCall(int liftId, int destinationFloor) {
   ```

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

## Why this one costs more than the others, stated plainly

Curveballs 1 and 3 cost 2 lines each. This one costs 10, and that is the honest number rather than a
seam failure. Six of the ten are the new contract method itself — a signature, three statements and
two braces — and **every** candidate pays those, which is exactly why the budget carries them. The
remaining four are the wiring that gives `priorityCall` something to talk to.

What the seams do buy is the part that is not there:

- **`Lift.java` is untouched.** No urgency field, no `escalate` method, no edit to the private
  `target()` helper. The obvious implementation — a second `TreeSet` of urgent floors inside the car,
  consulted before the normal order — is a perfectly reasonable answer that also passes all five
  tests, and it was measured for comparison: **14 lines across two files** (8 in `Lift.java`
  including an edit to the method that decides every lift's next move, 6 in `ElevatorSystem.java`)
  against this patch's 10 in one. That is the difference the seam is worth here, and it is smaller
  than usual. Say so in the defence rather than pretending otherwise.
- **The rule underneath still applies.** `UrgentStopOrders` decorates whatever `StopOrders` was
  injected, so it composes with curveball 1's express shafts and curveball 3's home floor instead of
  replacing either.
- **"Priority is spent on arrival" needs no notification.** The decorator calls
  `retainAll(pending)` every time it is consulted, so a mark dies with the stop it belonged to. No
  lifecycle hook was added to `StopOrder`, and the lift and the decorator cannot end up disagreeing
  about what has been served — which is the bug the obvious implementation invites.

## Verified after the patch

- The curveball suite: 5 tests, green.
- The base suite: 18 tests, green — this change is purely additive.
- The concurrency suite: `survived: true`, `kind: "clean"`. Worth checking rather than assuming,
  because `escalate` is the one place in the design where two threads touch a collection without a
  shared lock; that is why the per-lift mark set is a `ConcurrentSkipListSet`.
