A "HTTP 429: The usage limit has been reached" turn offered only Retry and
never said when a retry would work, so users guessed or babysat the app
(#98852). The provider already tells us: Retry-After / resets_at /
retry_after are parsed into the turn's error context (extract_api_error_context)
and honoured by the backoff, but the datum died there.
- agent/turn_recovery.py::_stamp_limit_reset: both terminal paths
(max_retries_exhausted_result, nonretryable_client_error_result) stamp
failure_resets_at (epoch s) on the failed result and append one plain line
("Limit resets at 14:05 (in 1h 00m).") to final_response, which every text
surface (CLI, Ink TUI, messaging gateway) renders.
- agent/error_surface.py: result path forwards failure_resets_at as
surface.resets_at; the exception path derives it from the same context.
- tui_gateway/contracts/events.py::ErrorSurface.resets_at + regenerated
apps/shared gateway-contract outputs.
- apps/desktop lib/error-surface.ts: parse resets_at -> resetsAt,
formatLimitReset("HH:mm (in 1h 05m)", null once passed), diagnostics line;
the error card renders "Limit resets at …" next to Retry (i18n copy in every
full locale).
- Docs: website/docs/user-guide/desktop.md error-card section.
Informational only: no scheduled or automatic retry is added — firing a turn
unattended on a subscription is the maintainer's call (#98872, #103048).