# Reference patch — 01-catch-all

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** `CatchAllSegment.java` (in this directory) to `reference/src/` — a fourth, non-capturing
   `Segment` with the worst rank (3), so it only ever wins when nothing better is compatible.
2. **Apply** `edits.json` to `Segment.java`, `PatternCompiler.java` and `CompiledRoute.java`.
3. No contract change. `register`, `match` and `handle` keep their existing signatures — `**` is
   just new syntax inside a pattern string, recognised by the same compiler that already turns
   `:name` and `*` into segments.

Measured: `reference_diff = 16`, `touchedFiles = 3`, `newFiles = 1` (the ten contract files that
also appear in a from-scratch compile are not part of this count — see the measuring script),
so `diff_budget = max(3, 16 + ceil(16/2)) = 24`. Both the curveball suite (4 tests) and the base
suite (23 tests) are green after the patch.

## Where the requirement landed, and why it is not zero

Three earlier decisions kept this small rather than free:

- **`SpecificityMatchPolicy` needed no change at all.** Its comparator already walks two rank
  vectors position by position and falls back to comparing lengths — a rule that was unreachable
  in the base problem (every compatible pair has equal-length vectors there) but was written
  generically anyway, because "lower rank wins, leftmost first" is the natural way to state
  precedence, not a speculative addition for a feature that did not exist yet. It is exactly the
  tie-break a variable-length pattern needs, and it needed zero lines here.
- **`Router` needed no change at all.** It only ever calls `CompiledRoute.tryMatch` and
  `MatchPolicy.pickBest` — it has no idea segments have kinds, let alone how many.
- **The one genuine new fact** is that a pattern can now match a *variable* number of trailing
  segments, and that fact has to live somewhere: `CompiledRoute.tryMatch`'s length check goes
  from "path and pattern have the same number of segments" to "path has at least as many as the
  pattern's fixed prefix, plus one" when the pattern ends in `**`. That is a genuine change to
  what "compatible" means for one method, not a design gap — no seam removes the need to say it.

**What was deliberately not done to shrink the number further:** a `Segment.consumesRest()`
method could have been added to the base design *before* this curveball existed, which would have
let this patch cost nothing. That was rejected on the same grounds `shopping-cart`'s decision log
rejects a speculative `StackingRule`: the base problem never needed it, and a method with one real
implementation and two others hard-coded to `false` is the single-implementation smell with
nothing to show for it yet. Paying 16 measured lines now, honestly, is the correct trade against
inventing generality the requirement had not yet asked for.

## What a candidate is most likely to get wrong here

Registering `**` anywhere but last and not rejecting it, and forgetting that "one or more" means
a pattern ending in `**` must never match its own bare prefix (`/files/**` must not match
`/files`). Both are asserted directly by the curveball tests.
