# Reference patch — 01-ratings-age

The answer key for how the reference absorbs this change. **Never shipped to the candidate.**

1. **Add** `RecencyWeightedStrategy.java` (in this directory) to `reference/src/`. New file, so
   `measureChange` charges nothing for it. It implements `AveragingStrategy` exactly like
   `SimpleMeanStrategy` does, just with a different `nextRating` formula: a straight 50/50 blend
   of the current average and the new rating.
2. **Add** `AgingRatingSystemFactory.java` (in this directory) to `reference/src/`. Also new. It
   wires the same `InMemoryAgentRatingBook` and `StandardRankingOrder` classes the standard
   factory uses, with `RecencyWeightedStrategy` in place of `SimpleMeanStrategy`.
3. `contract-delta/Entry.java` is the given, revised entry point — `createWithAging()` points at
   `AgingRatingSystemFactory.standard()`. Contract files are excluded from the diff measurement, so
   this line is free.

Nothing that existed before this requirement was opened. `AgentRatingBook`,
`InMemoryAgentRatingBook`, `RankingOrder`, `StandardRankingOrder`, `Rankings`, `RatingSystem` and
`RatingSystemFactory` were not touched.

Measured: `reference_diff = 0` (two new files, zero existing files touched), so
`diff_budget = max(3, 0 + ceil(0/2)) = 3`, the floor.

## Why this cost nothing

`AveragingStrategy`'s two methods take and return only the boundary type `AgentRating` — never a
raw rating history, never the book that stores it. That is the entire "incremental average versus
recompute" decision this problem's reference makes: because the standard strategy already carries
no more state than `(average, count)`, a wildly different update rule is still expressible as
"given the current `(average, count)`, produce the next one" — the exact shape
`RecencyWeightedStrategy.nextRating` needed, with no new field and no new collaborator.

The shortcut this curveball is built to catch is a design that instead recomputes an agent's
average from a stored list of raw ratings on every read (the shape `customer-satisfaction`
deliberately chose, for its own good reasons — see this problem's `DECISION_LOG.md`). That shape
would have made "ratings age" a genuinely bigger change: every stored `Rating` would need a
position or a weight, and the read path would need to iterate the whole history and apply decay
on every call, rather than folding one number into another once, at write time.
