Part of #992.
A rider finishes Sweet Spot 3×12 and has no way to ask the obvious question: was that better than last time? The ride summary stands alone, /history lists rides and draws the fitness and curve charts, and nothing puts today next to your own best.
This is the half of "comparisons" that needs no privacy argument at all — no other rider's data is involved, so nothing here touches rides-private-by-default. It can ship without waiting for #994.
Mockups: https://claude.ai/code/artifact/880fdc31-6238-4547-9d3a-b291cda3f50d — bottom left.
The shape
Sweet Spot 3×12 · today
today your best Δ
avg watts 214 209 +5
execution 91 % 88 % +3
energy 612 kJ 598 kJ +14
time in Z4+ 18:20 19:05 −0:45
20-minute power · 90 days
╭─────────────── 222 W
╱ ······· 90 days ago
Two comparisons, both against yourself:
- This ride against your best on the same workout. Same workout name, same rider. Δ column, no verdict attached to it.
- Your curve now against 90 days ago, which
/history already draws from progression.curve (d30 / d90 / all) — this puts the movement in words next to the ride that caused it.
RESEARCH.md §13.3 ranks power-curve bests fourth overall and says why they are the safe one:
Power-curve bests / PRs — monotonic, unambiguous, always good news; safest fitness signal we own.
Rules it has to keep
- Describe, never grade (ADR-0016, §13.4). A Δ of −0:45 is a number, not a failure. No judgment words, no red for "worse" —
--color-danger means something is wrong, and a slightly easier day is not wrong. Use the muted token.
- Execution is not difficulty. §13.4 is explicit: 100 % in-band on a recovery spin and on 5×5 VO2 are different achievements. Execution may sit in the table; it may not be summed, ranked, or presented as fitness.
- Scoped honestly. Every load-derived surface is labelled "based on your WattRoom rides" per ADR-0016, and this is one.
- Cold start. With one ride of a workout there is no "your best" — say so plainly rather than comparing a ride to itself. §13.4's small-N rule applies.
- No heart rate in anything that could become shareable (ADR-0008).
Where it goes
The ride detail page (/history/[id]) is the natural home — it is where a rider already lands after a session, and /history already owns both charts since #ADR-0020 folded progression into it. Do not add a fifth stat vocabulary: use the words #993's profile section settles on.
Acceptance criteria
Deliberately not in scope
Comparing riders to each other — that is room-scoped, needs #994 and probably an ADR, and is tracked under #992. Also out: importing outside activities to compare against, and any "you should have" suggestion (ADR-0016: nudges never gate, and this issue makes no nudges at all).
Related
#992 (epic), ADR-0016 (tone and scoping), RESEARCH.md §13.3 and §13.4, ADR-0020 (why this lives on /history), #993 (the vocabulary).
Part of #992.
A rider finishes Sweet Spot 3×12 and has no way to ask the obvious question: was that better than last time? The ride summary stands alone,
/historylists rides and draws the fitness and curve charts, and nothing puts today next to your own best.This is the half of "comparisons" that needs no privacy argument at all — no other rider's data is involved, so nothing here touches rides-private-by-default. It can ship without waiting for #994.
Mockups: https://claude.ai/code/artifact/880fdc31-6238-4547-9d3a-b291cda3f50d — bottom left.
The shape
Two comparisons, both against yourself:
/historyalready draws fromprogression.curve(d30/d90/all) — this puts the movement in words next to the ride that caused it.RESEARCH.md §13.3ranks power-curve bests fourth overall and says why they are the safe one:Rules it has to keep
--color-dangermeans something is wrong, and a slightly easier day is not wrong. Use the muted token.Where it goes
The ride detail page (
/history/[id]) is the natural home — it is where a rider already lands after a session, and/historyalready owns both charts since #ADR-0020 folded progression into it. Do not add a fifth stat vocabulary: use the words #993's profile section settles on.Acceptance criteria
make cigreen.Deliberately not in scope
Comparing riders to each other — that is room-scoped, needs #994 and probably an ADR, and is tracked under #992. Also out: importing outside activities to compare against, and any "you should have" suggestion (ADR-0016: nudges never gate, and this issue makes no nudges at all).
Related
#992 (epic), ADR-0016 (tone and scoping),
RESEARCH.md§13.3 and §13.4, ADR-0020 (why this lives on /history), #993 (the vocabulary).