docs(events): Phase 4 as built — schedule, recurrence and the calendar #212

Merged
whitlocktech merged 1 commits from docs/events-phase-4 into edge 2026-09-03 01:57:44 +00:00
Member

The docs half of Event System Phase 4. Code: RunicGateway/website#186.

EVENTS.md

§E — the tick. "Materialise" is now written as the two halves it actually is: expand, then sweep. The paragraph that said the expansion arrives in Phase 4 is replaced by the one that matters — expansion looks forward from now - grace only, so an occurrence nobody ever materialised is never invented retroactively, and the horizon is what makes the missed sweep mean anything for a recurring event. The two halves need each other, and that is the sentence a future reader needs.

§E — recurrence, as built. The shapes' field types and why they are what they are: time as HH:MM, weekdays as English names, at as a local wall clock rather than a UTC instant, days normalised into week order so two spellings of one schedule are not an edit nobody made. nth is 1..4 plus -1, with the reason there is no fifth. Plus the three things the section could not say before:

  • The two DST rules — skip-forward for the gap, take-first for the ambiguous hour, and that neither ever drops an occurrence.
  • There is no date library, and there is a reason: Node ships the tzdata one would vendor, and events/recurrence.js is the single place an occurrence is computed so the runner and the calendar cannot disagree.
  • Publishing is the schedule switch, archiving turns it off, and publishing re-pins the occurrences that have not started — including the failure mode that makes doing nothing worse than it looks (a cancelled occurrence keeps its slot in uq_evrun_occurrence, so it would vanish rather than return on the new version).

Also: automatic expansion is at the empty scope, and why a scope registry is not this phase's to invent.

§I — the calendar. Three paragraphs it did not have: the run vs projection distinction and why it is drawn rather than merely stated; the reader's-zone grid / event's-zone time split, which is what §E's "the timezone belongs to the event" actually implies once somebody has to place a cell; and series managed inline on the calendar, their admin, editor gate, and why their delete is the one real delete in this feature.

§ API surface. The four new routes — POST/PUT/DELETE /admin/events/series and GET /admin/events/calendar.

The phase table. P1 through P4 ticked.

EVENTS_PLAN.md

Phase 4 marked complete, in the shape Phases 0–3 use: the five org-lead decisions, the three things the build settled, the test-harness defect this phase introduced and fixed (the expansion leg made eventRunner.test.js reach a dead-port pool on every tick — it passed, and took minutes), and the verified numbers. Phase 2's note about what "materialise" covered is now written in the past tense, because it is history rather than a caveat.

The Trap paragraph keeps its warning and gains one line saying how it was held: Intl inverted rather than a date library added.

Checked by hand

docs has no CI, so: every anchor this touches resolves (#n--decisions, #i--admin-ui-authoring-and-the-calendar), and every route, column, env var and file path named here exists on website#186. Diff is 153/19 with no CRLF artefact — verified against the real content diff, not just --numstat.


  • AI-assisted: authored with Claude Code (Claude Opus).
The docs half of Event System **Phase 4**. Code: **RunicGateway/website#186**. ## `EVENTS.md` **§E — the tick.** "Materialise" is now written as the two halves it actually is: **expand**, then **sweep**. The paragraph that said the expansion arrives in Phase 4 is replaced by the one that matters — expansion looks forward from `now - grace` only, so an occurrence nobody ever materialised is never invented retroactively, and **the horizon is what makes the missed sweep mean anything for a recurring event**. The two halves need each other, and that is the sentence a future reader needs. **§E — recurrence, as built.** The shapes' field types and why they are what they are: `time` as `HH:MM`, weekdays as English names, `at` as a **local wall clock rather than a UTC instant**, `days` normalised into week order so two spellings of one schedule are not an edit nobody made. **`nth` is 1..4 plus `-1`**, with the reason there is no fifth. Plus the three things the section could not say before: - **The two DST rules** — skip-forward for the gap, take-first for the ambiguous hour, and that neither ever drops an occurrence. - **There is no date library**, and there is a reason: Node ships the tzdata one would vendor, and `events/recurrence.js` is the single place an occurrence is computed so the runner and the calendar cannot disagree. - **Publishing is the schedule switch, archiving turns it off, and publishing re-pins** the occurrences that have not started — including the failure mode that makes doing nothing worse than it looks (a cancelled occurrence keeps its slot in `uq_evrun_occurrence`, so it would vanish rather than return on the new version). Also: automatic expansion is at the **empty scope**, and why a scope registry is not this phase's to invent. **§I — the calendar.** Three paragraphs it did not have: the **run vs projection** distinction and why it is *drawn* rather than merely stated; the **reader's-zone grid / event's-zone time** split, which is what §E's "the timezone belongs to the event" actually implies once somebody has to place a cell; and series managed inline on the calendar, their `admin, editor` gate, and why their delete is the one real delete in this feature. **§ API surface.** The four new routes — `POST`/`PUT`/`DELETE /admin/events/series` and `GET /admin/events/calendar`. **The phase table.** P1 through P4 ticked. ## `EVENTS_PLAN.md` Phase 4 marked **complete**, in the shape Phases 0–3 use: the five org-lead decisions, the three things the build settled, the **test-harness defect this phase introduced and fixed** (the expansion leg made `eventRunner.test.js` reach a dead-port pool on every tick — it passed, and took minutes), and the verified numbers. Phase 2's note about what "materialise" covered is now written in the past tense, because it is history rather than a caveat. The **Trap** paragraph keeps its warning and gains one line saying how it was held: `Intl` inverted rather than a date library added. ## Checked by hand `docs` has no CI, so: every anchor this touches resolves (`#n--decisions`, `#i--admin-ui-authoring-and-the-calendar`), and every route, column, env var and file path named here exists on website#186. Diff is 153/19 with no CRLF artefact — verified against the real content diff, not just `--numstat`. --- - [x] AI-assisted: authored with Claude Code (Claude Opus).
wtclaude added 1 commit 2026-09-02 21:12:07 +00:00
EVENTS.md: the materialise leg as two halves and why the horizon is what makes
the missed sweep meaningful; the recurrence shapes as built, incl. the two DST
rules and why nth has no fifth; publishing as the schedule switch and the
re-pin; the calendar's run-vs-projection distinction and the
reader's-zone/event's-zone split; the four new routes; P1-P4 ticked.

EVENTS_PLAN.md: Phase 4 marked complete with the five org-lead decisions, the
three the build settled, the test-harness defect the phase introduced and
fixed, and the verified numbers.

Website: RunicGateway/website#PENDING

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 0f8293b538 into edge 2026-09-03 01:57:44 +00:00
whitlocktech deleted branch docs/events-phase-4 2026-09-03 01:57:45 +00:00
Sign in to join this conversation.
No description provided.