docs(events): Phase 10 as built — the integrations, and a ceiling per firing #218

Merged
whitlocktech merged 1 commits from docs/events-phase-10 into edge 2026-09-04 18:23:57 +00:00
Member

The docs half of website#192. Five files.

EVENTS.md — §F gains "What Phase 10 settled", and §D/§J are corrected to what was built

Four findings, three of them rules rather than facts about events:

  • A firing may carry a ceiling of its own, and it may only ever NARROW. A trigger's declared ceiling is a property of the KIND of event; a rehearsal is a property of the occasion. §I promised an event could be "run for real with announcements ceilinged to staff" and nothing implemented it — a rehearsal fires exactly the same trigger as the real thing, so it would have mailed every subscriber. The emit envelope now takes an optional ceiling and the send-time G24 gate applies meet(declared, emitted).
  • Two incomparable ceilings refuse rather than resolve. meet('owner', 'staff') is null — they have no common descendant, which is the whole argument ceilings.js is built on — so the gate refuses every rule. §5.1a rule 3's posture, reused rather than re-argued.
  • A module reports participants on the success envelope, beside its resources. There is no ctx.events.participants and no route: a second write path into a run core is mid-tick on would be a second thing that can race the claim.
  • A trigger's description is read by a RECIPIENT, not only by an operator. It is the structural projection's intro fallback, so a line that names its own audience ends up in that audience's inbox.
  • A trigger that is not also a STREAM has no push, and says nothing about it. Push delivery is stream-keyed, so a rule naming push on a trigger-only id publishes a tickle to nobody while the send log records it sent. Every stream must be a trigger; a trigger need not be a stream.

§D's event_run_participants row is now as built (member_key NOT NULL, DECIMAL(18,4) score, rank_atrank is reserved from MariaDB 10.2). §J's Engagement, News, Player-profiles and Leaderboards rows move from planned to built.

MODULE_API.md — two envelope members, folded into 1.10.0 in place

participants on an action's success envelope, and ceiling on ctx.events.emit's. Not a 1.11.0 bump: main declares 1.9.0, so 1.10.0 has not shipped and the org lead's 2026-09-03 rule — a protocol owes a bump once it has landed on main; while it is on edge it is amended in place — applies for the third time. The whole event contract still reaches an author as one number. (I described this as 1.11.0 when I put the decision to the org lead; the rule they had already set says otherwise, and this follows the rule.)

EVENTS_PLAN.md — Phase 10 as built

The six decisions, the four things the tree corrected about the plan (core's seed mechanism is not the module-facing one; the ceilings are §J's; the row is §8.5 not §8.6; two rules seeded not seven), the live walk, and the three defects it found — the dead push channel, the description that reached a recipient, and affectedRows under CLIENT_FOUND_ROWS. Plus the one caught before it shipped: a session variable is not a transaction when query() takes a pool connection per call.

ENGAGEMENT.md §8.5 — the row this resolves

"Come back for X — a scheduled event is starting" moves from "needs a manual/scheduled trigger type" to built, and says why it has push when the other six event. triggers do not.

BACKEND_DESIGN.md — the eleventh event table

The section preamble now names which of the later tables have landed in which phase rather than listing them as pending, and event_runs gains results_published_at.

Notes

  • docs has no CI; links and anchors checked by hand.

  • CRLF preserved throughoutgit diff --numstat reports 61/126/42/1/17 added lines against real content diffs rather than whole-file rewrites, and the tree holds no bare LF and no \r\r\n.

  • AI-assisted: Claude Code (Opus 5).

Code: RunicGateway/website#192.

🤖 Generated with Claude Code

The docs half of `website#192`. Five files. ## `EVENTS.md` — §F gains "What Phase 10 settled", and §D/§J are corrected to what was built Four findings, three of them rules rather than facts about events: - **A firing may carry a ceiling of its own, and it may only ever NARROW.** A trigger's declared ceiling is a property of the KIND of event; a rehearsal is a property of the occasion. §I promised an event could be *"run for real with announcements ceilinged to `staff`"* and nothing implemented it — a rehearsal fires exactly the same trigger as the real thing, so it would have mailed every subscriber. The emit envelope now takes an optional `ceiling` and the send-time G24 gate applies `meet(declared, emitted)`. - **Two incomparable ceilings refuse rather than resolve.** `meet('owner', 'staff')` is null — they have no common descendant, which is the whole argument `ceilings.js` is built on — so the gate refuses every rule. §5.1a rule 3's posture, reused rather than re-argued. - **A module reports participants on the success envelope, beside its resources.** There is no `ctx.events.participants` and no route: a second write path into a run core is mid-tick on would be a second thing that can race the claim. - **A trigger's `description` is read by a RECIPIENT, not only by an operator.** It is the structural projection's `intro` fallback, so a line that names its own audience ends up in that audience's inbox. - **A trigger that is not also a STREAM has no push, and says nothing about it.** Push delivery is stream-keyed, so a rule naming `push` on a trigger-only id publishes a tickle to nobody while the send log records it sent. **Every stream must be a trigger; a trigger need not be a stream.** §D's `event_run_participants` row is now as built (`member_key` NOT NULL, `DECIMAL(18,4)` score, `rank_at` — `rank` is reserved from MariaDB 10.2). §J's Engagement, News, Player-profiles and Leaderboards rows move from planned to built. ## `MODULE_API.md` — two envelope members, folded into 1.10.0 in place `participants` on an action's success envelope, and `ceiling` on `ctx.events.emit`'s. **Not a 1.11.0 bump**: `main` declares 1.9.0, so 1.10.0 has not shipped and the org lead's 2026-09-03 rule — *a protocol owes a bump once it has landed on `main`; while it is on `edge` it is amended in place* — applies for the third time. The whole event contract still reaches an author as one number. (I described this as 1.11.0 when I put the decision to the org lead; the rule they had already set says otherwise, and this follows the rule.) ## `EVENTS_PLAN.md` — Phase 10 as built The six decisions, the four things the tree corrected about the plan (core's seed mechanism is not the module-facing one; the ceilings are §J's; the row is §8.5 not §8.6; two rules seeded not seven), the live walk, and the three defects it found — the dead push channel, the `description` that reached a recipient, and `affectedRows` under `CLIENT_FOUND_ROWS`. Plus the one caught before it shipped: a session variable is not a transaction when `query()` takes a pool connection per call. ## `ENGAGEMENT.md` §8.5 — the row this resolves *"Come back for X — a scheduled event is starting"* moves from ❌ *"needs a manual/scheduled trigger type"* to ✅ built, and says why it has push when the other six `event.` triggers do not. ## `BACKEND_DESIGN.md` — the eleventh event table The section preamble now names which of the later tables have landed in which phase rather than listing them as pending, and `event_runs` gains `results_published_at`. ## Notes - `docs` has no CI; links and anchors checked by hand. - **CRLF preserved throughout** — `git diff --numstat` reports 61/126/42/1/17 added lines against real content diffs rather than whole-file rewrites, and the tree holds no bare LF and no `\r\r\n`. - [x] AI-assisted: Claude Code (Opus 5). Code: RunicGateway/website#192. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wtclaude added 1 commit 2026-09-04 18:08:06 +00:00
Five files. `EVENTS.md` §F gains "What Phase 10 settled" and §D/§J are corrected
to what was built; `EVENTS_PLAN.md` records the phase as built with its six
decisions, the live walk and the three defects it found; `MODULE_API.md` folds
two envelope members into 1.10.0 in place; `ENGAGEMENT.md` §8.5's "come back for
X" row is resolved; `BACKEND_DESIGN.md` gains the eleventh event table and the
two columns Phase 10 put on tables that already existed.

The four contract findings, three of which are rules rather than facts about
events:

- a firing may carry a ceiling of its own and it may only ever NARROW, applied
  at the send-time G24 gate as meet(declared, emitted). §I promised a rehearsal
  "ceilinged to staff" and nothing implemented it;
- two incomparable ceilings refuse rather than resolve, which is §5.1a rule 3
  reused rather than re-argued;
- a module reports participants on the success envelope and there is no other
  door;
- a trigger that is not also a STREAM has no push and says nothing about it, so
  every stream must be a trigger while a trigger need not be a stream.

And a trigger's `description` is read by a recipient, not only by an operator:
it is the structural projection's `intro` fallback, so a line naming its own
audience ends up in that audience's inbox.

- [x] AI-assisted: Claude Code (Opus 5).

Code: RunicGateway/website#TBD.

Co-Authored-By: Claude <noreply@anthropic.com>

🤖 Generated with [Claude Code](https://claude.com/claude-code)
whitlocktech merged commit 6cb54ecdb7 into edge 2026-09-04 18:23:57 +00:00
whitlocktech deleted branch docs/events-phase-10 2026-09-04 18:23:58 +00:00
Sign in to join this conversation.
No description provided.