Method · Staple why sentences
How we write the one-line summary on each staple.
A deterministic decision tree — special first, then big mover, then steady, then fallback.
The decision tree
Every staple page carries a short “why this week” sentence under the headline. The sentence is generated weekly from the live data — never hand-written per issue — so the publication can grow without copy work scaling with it. The generator walks four branches, in order, and stops at the first one that fires:
- Special — if the cheapest valid pack at either store carries the discount marker this week, the sentence names the store and the discount.
- Big mover — if the headline per-basis price at either store has moved at least 5% since the previous Friday snapshot, the sentence names the move and the direction. We name the per-basis price (per-kg / per-L / per-each), never pack price.
- Steady — if neither of the above fires and we have at least four weeks of price history at both stores, the sentence acknowledges the staple is sitting still this week.
- Fallback— if none of the above can fire (typically because the price-history table is still thin), we render a per-staple evergreen sentence held in the page’s code as a last resort.
What it doesn’t say
The sentence never invents a trend the data can’t support. If we don’t have four weeks of history at both stores, we don’t use a week-on-week framing. If a pool has fewer than three SKUs, the sentence stays generic — single-SKU pools can’t move a representative price. The R3 thin-pool rule fires here too: we’d rather sound dull than confident-and-wrong.
Acceptance gate
In a typical week, at least seven of the nine staples should produce a data-driven sentence (special / mover / steady). When that fraction drops, it’s usually a sign the corpus is thinner than we thought — we treat the gap as a signal, not as a copywriting task.
Source
Generator code lives at apps/web/src/lib/watch/staple-why-generator.ts. Open-source for the reader who wants to walk the tree themselves.