Commit Graph

9 Commits

Author SHA1 Message Date
426e9bfbfb docs(events): Phase 7 as built -- the module contract at MODULE_API 1.10.0
Code: RunicGateway/website#189.

MODULE_API.md gains 1.10.0 in three places: the number itself, the entry in
Part 1 with the four call shapes and the six rules that come with them, and
the four names in 2.4's call list with the contract-rather-than-
implementation notes beside them.

EVENTS.md F is marked built, with a new subsection recording what the build
settled -- the open unit vocabulary, the undeclared-dimension refusal and
why it has its own code, why example-pricing survives the arrival of a
budget registry, why restore cannot be read, and why an option source that
refuses answers 200. K's Phase 7 note becomes what shipped. The API surface
table's option-source row is filled in, and the absent-routes list is down
to cleanup.

EVENTS_PLAN.md: Phase 7 complete, in the shape phases 0-6 use -- the four
org-lead decisions, the three things the build settled, the throwaway-module
proof, the React defect only the browser could find, and the route the docs
caught the code building one segment shallower than this file specifies.

Checked by hand (docs has no CI): every anchor resolves, and every route,
identifier and file path named here exists on website#189.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6t8mrAWhZU5vnyYgZTMtL
2026-09-03 14:16:19 -05:00
aa8752ef65 docs(events): Phase 6 as built — enablement, caps and mayInvoke
EVENTS.md

§D — the two tables move from "arrive with a later phase" to built, with the
two facts that are not obvious from the column list: a missing settings row is
the risk-class default rather than "disabled", and a NULL cap is uncapped and
still a row, so a MISSING row keeps its one meaning. event_versions gains
verified_at/verified_by, and the note on why two mutable columns do not break
an immutable table.

§E — a new subsection, "Enablement and caps, in front of every dispatch": where
the check sits and why, the retry that does not pay twice (and the failure that
gets no refund), the partial spend that is unwound, the budget seeded from every
phase at creation, the tightest cap, and the one place a demoted user's access
deliberately is not re-checked.

§K — the amendment. "Nothing above notify" becomes "nothing that changes the
world", with the reason: read literally it shipped core.wait disabled. The same
line is the role floor. Plus mayInvoke as built — why user and run may be null,
why the cap check can write, why the role floor is in the model rather than in
middleware, and the example-pricing stand-in until registerEventBudgets lands.

§I, §L, § API surface and § Observability — the switchboard and the dry run
marked built; the two refusal rows and the held-occurrence row; the three new
log kinds and the run's fourth derived field; why the whole-plan cost check is
the one finding no other path makes.

EVENTS_PLAN.md — Phase 6 complete in the shape Phases 0–5 use: the four org-lead
decisions, the two derived calls flagged for review, the three things the build
settled, the one thing this phase deliberately cannot demonstrate with a module
(registerEventActions is Phase 7's seam), the two defects the live walk found,
the verified numbers and the walk itself.

Checked by hand — docs has no CI: every anchor resolves, and every route,
column, env var and file path named here exists on website#XXX. Diff is
151/23 and 118/2 with no CRLF artefact, verified against the real content diff
rather than --numstat alone.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6t8mrAWhZU5vnyYgZTMtL
2026-09-03 05:51:19 -05:00
957d662a2f docs(events): Phase 5 as built - conditions, phase advancement and the panel
EVENTS.md gains the eleventh table, a new SS-E subsection on advance conditions
and the two writers a gate has, the diagnosis panel in SS-I, the "a condition
never fires" row in SS-L, and the observability rows for the gate table and its
three new log kinds. The `advance` route leaves the not-built list; the catalog
route now serves triggers.

The SS-D count said "nine" over a list of ten from the revision that added
`event_series`; with the gate table it is eleven, and it now says so.

EVENTS_PLAN.md marks Phase 5 complete in the shape Phases 0-4 use: the four
org-lead decisions, the three things the build settled, the MariaDB
left-to-right SET evaluation defect that only a real database found, the live
walk, and the three defects that walk turned up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6t8mrAWhZU5vnyYgZTMtL
2026-09-02 22:11:30 -05:00
9410181560 docs(events): Phase 4 as built - schedule, recurrence and the calendar
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>
2026-09-02 16:10:50 -05:00
261cce6423 docs(events): Phase 3 as built — the minimal admin surface
EVENTS.md: the six controls that exist and the two that do not, and why;
retry as one control with its two guards; what a cancel does to a parked cue;
the run status re-read between steps; the two derived response fields.

EVENTS_PLAN.md: Phase 3 complete, the four org-lead decisions, and the three
things the build settled — including the mid-batch pause defect and the retry
guard that was reading the wrong end of the phase.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6t8mrAWhZU5vnyYgZTMtL
2026-09-02 08:39:52 -05:00
76b2276d36 docs(events): Phase 2 as built - the runner
The docs half of Event System Phase 2. Pairs with `RunicGateway/website`
`feat/events-phase-2`.

EVENTS.md gains what the runner settled: the parked step (`running` with a NULL
lease), the two success-envelope members `await: 'human'` and `holdFor`, the
answer for a run whose concurrency key is held, `n` in §L's `retry(n)`, the rule
that all three `on_failure` dispositions write the step `failed`, and the health
transition on the first retry rather than the eventual failure.

EVENTS_PLAN.md marks Phase 2 complete and records the four org-lead decisions
and the three things the build settled on its own.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 06:32:15 -05:00
9ba119dc5a docs(events): Phase 1 as built — schema, CRUD and the core action registry
The docs half of RunicGateway/website#<n>. Three files.

**BACKEND_DESIGN.md** gains the six event tables, column by column, and the
eleven admin routes. Written where the other table groups are, in the same
shape, because the argument for a column belongs beside the column.

**EVENTS.md** records four things the build settled that §D and §F had left
open:

  - `event_definitions.spec`, the working copy. §D's column list does not name
    one because §D describes what a PUBLISHED event is made of — but "editing a
    draft is free; no version exists yet" means the draft has to live somewhere,
    and it cannot be an `event_versions` row: that table is immutable and a run
    pins one, so a mutable unpublished row in it would be exactly what
    versioning exists to prevent.
  - A param's `example` is REQUIRED, on optional params too, the same rule
    `registerEventTriggers` makes of a variable's example and for the same
    reason: it is the authoring form's placeholder, one word at declaration
    time and unreconstructable afterwards.
  - The authoring side of dormancy. §F said what happens at DISPATCH; the save
    path draws the same line one step earlier, in the shape `engagement_rules`
    established — a saved step may keep an unregistered action, a new step may
    not add one, and a dormant step blocks the publish rather than the save.
  - Publish re-validates against the registries as they stand at that moment,
    not from the save that wrote the spec.

Plus two routes the § API surface table did not name — `GET /admin/events/:id`
(the list serves a summary; the editor needs the tree) and `GET
/admin/events/series` (a form cannot offer a value it cannot enumerate) — and a
note stating which of that table's rows Phase 1 deliberately did not build.

**EVENTS_PLAN.md** marks Phase 1 complete, names those four settlements, and
states the two deliberate absences so a reviewer does not read them as gaps:
the live run controls are not stubbed, and core's three `perform()` bodies
answer `{ ok: false }` rather than `{ ok: true }` — `ok: true` on an action
that did nothing is a recorded world change that did not occur.

`api-route-inventory.json` is NOT resynced here. It has been stale since
engagement Phase 2 and is 47 routes behind; catching it up in this PR would
bury a 13-route change under an unrelated 47.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-01 23:28:26 -05:00
cc6775e20b docs(events): Phase 0 — the eleven decisions, and the two documents they reach into
Closes the second half of EVENTS_PLAN.md Phase 0. All of EVENTS.md §N1–N11 were
answered by the org lead on 2026-09-01, before any code, which lifts the ⚠ gate
from P11 and P12 and unblocks P1.

Nine went the way §N recommended. Two did not, and each changes a phase:

- N2 — publishing a version and starting a run are `admin` only; a moderator
  keeps live control of a run already in flight (cancel, abort) and nothing
  more. Start and stop are deliberately not the same gate: starting commits the
  deployment to everything a definition contains, unattended, while cancelling
  is incident response. §K's table and the API surface table are updated, and
  P3 and P6 carry it.
- N4 — this deployment is single-instance and not planned to change, so P2 does
  not build the `--scale app=2` test. Every claim path in §E is built exactly as
  specified regardless — the unique index and the CAS equally protect a tick
  that overruns into the next one, and the lease and its reclaim recover a step
  whose process died mid-dispatch. §E records what to build first if this
  deployment is ever scaled.

N1 was taken in full, item grants included, which is a reversal of two separate
lines in ADMIN_CONTROLS.md §8 rather than one. §8's cut list names "item/gold
grants" explicitly and separately from world building, so the new §8a amendment
says both out loud rather than letting the grant ride along on the creation
reopening. §8's bullet is left standing verbatim — it is the decision that was
actually taken — with a pointer to the amendment, and §1's thesis paragraph gets
the same pointer. Loot-table changes and arbitrary [set / [get / [add stay
permanently excluded, along with the rest of the Tier-H moderation verbs.

N3 gives ENGAGEMENT.md §7.1 Q6's "no evaluator yet" an owner: the Event System
runner becomes the `kind: 'scheduled'` evaluator, built in that workstream's P2.
Nothing in the engagement contract changes.

One consequence was derived rather than decided and is flagged for review:
POST /admin/events/:id/verify moves to `admin, editor` rather than staying with
`start`. A dry run dispatches nothing, and the author who wrote the definition
is who should price it against the caps before asking an admin to publish.

Verified: every relative link and anchor in the four touched files resolves,
including the renamed §N anchor (#n--decisions) and the new #8a. The docs repo
has no CI workflow, so the plan's "docs CI link check" was run by hand.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-01 20:52:37 -05:00
0aeb54d9a0 docs(events): the Event System design of record and its phased plan
Two documents for a game-agnostic Event System: an engine for scheduled,
bounded, audited changes to a live game world, driven by the staff who
already run the site.

EVENTS.md is the design of record. It surveys what the eight repos already
provide, records what they do not, and proposes the architecture: core owns
the engine, a module owns the meaning, and the seam is declaration plus
dispatch rather than a string core interprets. Two findings shape it. An
event does not edit the world, it holds a LEASE with a game-side deadline
and a compare-and-set restore, so baseline returns even if the website never
comes home. And a reward is an ordinary module action, optional per module,
whose reversibility is the module's business.

EVENTS_PLAN.md decides order: seventeen phases, what each ships on its own
merit, how each is proved, and the traps in each. Fourteen of them reach the
game only to announce, over verbs the write plane already carries, and need
no decision beyond P0; only P11 and P12 are gated on the ADMIN_CONTROLS.md
Section 8 amendment.

This discharges the first half of P0. The decisions -- N1 through N11, and
the Section 8 amendment itself -- remain, and they are the part that gates
the two world-changing phases.

Every codebase claim was read from the working trees on 2026-09-01. Where a
document and the code disagreed, both are recorded rather than quietly
resolved: ARCHITECTURE.md places the SSE fan-out in core when it is entirely
module-uo's, and rust-dryrun.md asserts the Android app feature-detects on
/public/modules when it hardcodes a module path instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6t8mrAWhZU5vnyYgZTMtL
2026-09-01 20:29:04 -05:00