# Reference patch — 03-home-floor

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

1. **Add** `HomeFloorOrders.java` (in this directory) to `reference/src/`. New file, free.
2. **Change one line** in `reference/src/ElevatorSystem.java`, in the convenience constructor
   (mechanised in `edits.json`):

   ```diff
                    new NearestAlignedPolicy(),
   -                StopOrders.same(new ScanOrder()),
   +                new HomeFloorOrders(1, StopOrders.same(new ScanOrder())),
                    FloorAccess.everyFloor());
   ```

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

## Why it is one line

Two decisions in the base reference pay for this one, and both were made for stated reasons rather
than in anticipation of this change:

- **`StopOrder` returns an `OptionalInt`, and the floor it returns need not be pending.** So "go
  somewhere nobody called from" is an ordinary answer rather than a case `Lift.step()` has to know
  about. `step()` is untouched.
- **The route rule is a per-lift factory, not a single object.** So a decorator can wrap it whole, and
  it composes: put curveball 1's express shafts or curveball 2's urgent marks alongside this and all
  three still work, because each of them delegates to the rule underneath.

Three of the requirement's clauses cost literally nothing:

- *"Going home is not a stop"* — the decorator never adds anything to the lift's work list, so
  `pendingStops` keeps meaning "what this lift owes people".
- *"A real call always wins"* — the moment `pending` is non-empty, the decorator steps aside.
- *"It starts heading home again afterwards"* — the decorator is consulted every tick, so resuming is
  not a state to remember.

**What it costs a design without those seams.** A lift whose `step()` reads
`if (stops.isEmpty()) { direction = IDLE; return; }` has to grow a home floor, a branch, and then a
second branch for "am I going home or serving somebody" — inside the method that moves every lift.
The likely bug is inserting floor 1 into the pending set as a fake stop, which then leaks out through
`pendingStops` and makes an idle lift look busy to the dispatcher's least-busy tie-break.

## One deliberate base-suite divergence

After this patch the base suite is **17 of 18**, and the failure is:

> `direction reads the way it is travelling and IDLE once it has nothing left`

That test asserts *"and it stays where it finished"*. This requirement is precisely the instruction
that it must **not** stay where it finished. The failure is the requirement change landing, not a
defect — `REQUIREMENT-CHANGE.md` warns the candidate about it in as many words, and the Phase 4 grade
comes from this curveball's suite plus the measured diff, not from re-running an acceptance check the
interviewer has just withdrawn. The other 17 base checks stay green, which is the real signal: this
change is confined to what an *idle* lift does.
