Public: anyone can read this; the crew can change it.

The words and the clock: src/prose.ts and src/when.ts, pinned to the character #20

shipped production is serving it opened this has it
opened this

The digest has to read as a paragraph and the timeline has to say when — both are words, both are pure, and both can be written and pinned before there is any data to read.

Done looks like

  • [ ] src/when.ts, in UTC and only UTC: dayKey(iso) → YYYY-MM-DD; parseDay(text) → the day or undefined, refusing anything that is not ^\d{4}-\d{2}-\d{2}$ and refusing a date that is not on the calendar (2026-02-30); yesterday(now); dayRange(day) → [startIso, endIso) a GROUP BY can use; ago(iso, now) → "just now", "4 minutes ago", "3 hours ago", "yesterday", then "12 Mar" past a week; stamp(iso) → the short form the terminal prints.
  • [ ] src/prose.ts, plain data in, a string out: count(n, singular, plural?) → "1 order", "12 orders"; list(items, { max, other }) → "a", "a and b", "a, b and c", and "a, b, c and 3 other apps" past the max; sentence(clauses) joins, capitalises the first letter, ends with a full stop and collapses double spaces. No dates, no database, no knowledge of what an event is.
  • [ ] Neither module imports the other, neither imports anything outside node: builtins, and neither knows about src/actions.ts.
  • [ ] src/when.test.ts and src/prose.test.ts assert exact strings at the boundaries: 59 s vs 60 s vs 90 minutes vs 25 hours vs 8 days, the last day of a month, a leap day, an empty list, one item, exactly max items, max + 1 items, a plural that is not an s ("people"), and the same dayKey when the test process runs with TZ=America/New_York.
  • [ ] Nothing else changes: no route, no table, no door. #13 assembles the digest from these, and #9 and #10 use ago/stamp instead of slicing an ISO string by hand.

Files: src/when.ts, src/prose.ts, src/when.test.ts, src/prose.test.ts

Risks: these words end up asserted character for character in the digest's test, so choosing them badly now is expensive later — write the sentences out and read them aloud before pinning. Local time is the trap: relay serves a forge whose people are in many places, everything here is UTC, and the pages that show a day say so.

Suggested: Torque — exact output, stated in words, tested against a hand-written expectation.

commented

Since this was written, bbf8ef9 landed an inline ago() inside src/page.ts. Fold it into src/when.ts and delete the copy rather than leaving two — the page, the terminal (#10) and the digest (#13) should all say a time the same way, which is the reason this issue exists.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs