docs(events): Phase 10 as built — the integrations, and a ceiling per firing
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)
This commit is contained in:
@@ -1119,10 +1119,22 @@ Design of record: [`TEAMS.md`](TEAMS.md) Parts 2 and 5. The contract surface a m
|
||||
|
||||
### The six event tables — the engine's, game-agnostic (events phase 1)
|
||||
|
||||
Design of record: [`EVENTS.md`](EVENTS.md) §D. Nine core tables are specified there; **six land in
|
||||
Phase 1** — the ones that do not depend on the module contract. `event_action_settings`,
|
||||
`event_run_budget`, `event_run_resources` and `event_run_participants` arrive with the phases that
|
||||
give them a writer, rather than as empty tables nothing reads.
|
||||
Design of record: [`EVENTS.md`](EVENTS.md) §D, which is where the full column list of every event
|
||||
table lives. **Six land in Phase 1** — the ones that do not depend on the module contract — and are
|
||||
spelled out below. The rest arrive with the phase that gives each a writer, rather than as empty
|
||||
tables nothing reads: `event_run_phase_gates` in Phase 5, `event_action_settings` and
|
||||
`event_run_budget` in Phase 6, `event_run_resources` in Phase 8, and **`event_run_participants` in
|
||||
Phase 10** — `run_id` + a module-opaque `member_key` that is `UNIQUE` together, a nullable `user_id`
|
||||
that `SET NULL`s so a record of what happened survives an account deletion, a `DECIMAL(18,4)` score
|
||||
and a `rank_at` written only when results are published. Core writes it and sources none of it: a
|
||||
`member_key` → account mapping is one game's, and a module reports both halves on its action's
|
||||
success envelope.
|
||||
|
||||
Phase 10 also put two columns on tables that already existed — `event_runs.results_published_at`
|
||||
(below) and a nullable `announce_jobs.run_id`, which is what lets an event announce a post the news
|
||||
pipeline has already announced without either job standing on the other's toes. Everything that
|
||||
means *"the post's job"* — the post admin panel, its retry button, `posts.announced_at` — still means
|
||||
the one with a NULL `run_id`.
|
||||
|
||||
Core owns the engine; a module owns the meaning. No column below carries a game noun: an action id,
|
||||
a `scope`, a resource kind and a budget dimension are opaque strings core stores and never
|
||||
@@ -1202,6 +1214,7 @@ makes a run reproducible and an audit answerable after the definition has moved
|
||||
| params | JSON NULL | |
|
||||
| rehearsal | TINYINT(1) NOT NULL DEFAULT 0 | dispatches for real; excluded from the public calendar and from participation history |
|
||||
| started_at / ended_at | DATETIME NULL | |
|
||||
| results_published_at | DATETIME NULL | when the run's results table was last ranked and published (phase 10). A stamp rather than a status: *"may I show this table"* and *"when was it settled"* are the same column. `core.results.publish` re-stamps rather than guarding on NULL, because a second publication after a late correction is a real one |
|
||||
| claimed_by / claim_expires_at | VARCHAR(64) NULL / DATETIME NULL | the lease. Written by the runner |
|
||||
| started_by | INT NULL FK→users(id) ON DELETE SET NULL | |
|
||||
| last_error | VARCHAR(500) NULL | |
|
||||
|
||||
Reference in New Issue
Block a user