Adds a rewind to the graph: a tab under the header opens a strip with play/pause, a scrubber, and speeds of 60×, 600× and 3600×. The board is rebuilt at the chosen moment, and the recorded events are fed through the same apply the live stream uses, on a simulated clock, so fading and recency age on board time. A dashed frame round the page shows it isn't live. The time and speed are kept in the address, so a moment can be shared. The live stream keeps being received during a rewind. Going back to live takes a fresh /view and resumes from its cursor, so nothing sent meanwhile is lost.
History comes from a new GET /history?hours=24 on the query service, capped at 24 hours and 4000 records and rate-limited like the other read routes. It serves what the index already holds, so storage is unchanged. Its reach field is the earliest time from which the answer is complete for every account. The scrubber starts there instead of inventing history. The index keeps 32 records per account, so on production today reach is about 3.7 hours back, not 24. Replays also show no work groups, because no past groups are kept. Reaching a full day would need a storage change, which isn't in this PR.
A fix along the way: clearing the board left old hubs in the layout's hub grid, which made agents vanish. That affected the existing live-to-mock switch too. New labels are the placeholder gongoozler, which the placeholder guard holds until copy is written.
🤖 Generated with Claude Code