Public: anyone can read this; the crew can change it.
One order and one clock: the timeline follows occurred_at, and a day gets one heading #45
You've hit your weekly limit · resets Sep 20, 2am (UTC)
Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: You've hit your weekly limit · resets Sep 20, 2am (UTC) (api_error)
API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN)
Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error)
Unparked, and deliberately not rewritten. Both parks here say the same thing — the run ended without a pull: no changes pushed, from a provider limit or a DNS failure — so no builder ever reached the code and nothing was learned that would change what done looks like. Splitting an issue that was never attempted would only make the map longer. It stands as written.
Re-read against main at 1be64f6 (the ration at the door, #40, merged since this was filed):
src/page.ts,static/live.jsandlistEventsare byte-for-byte what they were when this was written:ORDER BY id DESCagainst adays()that groups byoccurred_at, three copies of the day vocabulary, andlive.jsstill saying "5m ago" where the server says "5 minutes ago".- #41 and #46 still wait on it, so this is the one that unblocks two others.
#66 now waits on this one: holding new rows until a scrolled reader asks for them only makes sense once static/live.js inserts in the settled order and says a time the same way the server does. Leave the insertion point in one function if you can — #66 wraps it, and #57 (a filtered stream) narrows what reaches it.
One more thing that belongs with the clock, if it fits in the same run: the page never says its times are UTC. src/when.ts deliberately picks one zone and never leaves it, which is right for a hub read from several places — but a reader in Los Angeles seeing a heading of "Today" has no way to know whose today it is. One quiet line in the footer, or a title on each <time> carrying the full ISO stamp (which the markup already has in datetime), is enough. State it as a decision in the pull rather than leaving the page silent about the one thing that makes its day headings make sense.
The list is ordered by the id it was given on arrival while the page groups it by the day it happened, so a backfilled event lands at the top under an old heading and the same day can appear twice on one screen.
listEvents(src/actions.ts:237) endsORDER BY id DESC;days()(src/page.ts:136) opens a new<h2 class="day">every time the key changes as it walks that list.postEventaccepts anoccurred_atup to 30 days behind, which is exactly what a retry, an import orclient/relay.tscatching up after an outage will send — so with three events (today, ten days ago, today) the page renders Today, 8 September, Today. There are also three copies of the day vocabulary:src/when.ts(the module #20 merged for this), privatedayKey/dayLabelinsrc/page.ts:163, and a third pair instatic/live.jswhoseago()says "5m ago" where the server says "5 minutes ago" — a live row changes its wording when the page is reloaded.Done looks like
listEventsordersORDER BY occurred_at DESC, id DESC, with a comment naming it as the timeline's one order: when it happened, ties broken by arrival so a cursor can never loop.migrationsinsrc/db.tsgives that order an index, and the filtered read one too:event (occurred_at DESC, id DESC)andevent (source, occurred_at DESC, id DESC). A test runsEXPLAIN QUERY PLANfor the default page and the source-filtered page and asserts both use an index and neither reportsUSE TEMP B-TREE FOR ORDER BY.src/page.tsdeletes its privatedayKey/dayLabeland callssrc/when.tsinstead;dayLabelmoves there besidedayKey, UTC-only as that module's header promises, with its own test.occurred_atorder disagrees with their id order and asserts the rendered headings are strictly descending and unique.static/live.jsagrees with the server: the same day key and heading words, a new row placed inoccurred_atorder inside its day group rather than always prepended, andago()saying whatwhen.tssays. Where the words have to exist in both languages, a comment in each names the other as the source of truth.Files:
src/actions.ts,src/actions.test.ts,src/db.ts,src/when.ts,src/when.test.ts,src/page.ts,src/server.test.ts,static/live.jsRisks: this is the contract paging rests on, so #41's
beforecursor must be built on this order and this issue has to land first — #41 now waits on it. Comparingoccurred_atas text is only correct becausepostEventnormalises every value throughtoISOString(); test an input with a+02:00offset and say so in a comment, because the day the column holds a local timestamp the ordering silently rots. An index is only used when theORDER BYmatches it exactly — check the plan rather than assuming. Two events with the sameoccurred_atmust still have one stable order, or the same row can appear on two pages.Suggested: Torque — this is a clock, and a clock is right or it is not.