71c4bcf7af
The catch-up machinery already re-ran jobs missed during gateway downtime, but the late execution rendered as an ordinary on-time success — no scheduled-vs-actual time, no lateness, no disposition (issue #99879, the visibility half). - Due-scan now persists a `last_dispatch` stamp on every recurring dispatch: scheduled_at, dispatched_at, lateness_seconds, and kind (on_time / late / catch_up, classified against the ticker tolerance and the schedule's catch-up grace window). Manual triggers and one-shots are not stamped (no scheduled instant to be late against / retired beyond grace). - `hermes cron list` renders a per-job Dispatch line; late/catch-up runs show "⚠ catch-up after missed fire: scheduled ..., ran ... (31m late)". - `hermes cron status` calls out jobs whose last dispatch was late or a catch-up, in both the built-in ticker and external provider paths. CLI surface only — no new tools, no policy engine. Addresses the visibility half of #99879.