docs(website): demo mode step 2 built — DM18, MODULE_API 1.19.0
DM18 (org lead, 2026-10-24): core's event save never asked a module about a step's params, so the console-command deny list's save-time refusal is a new core hook, demoRefuses(params), asked at create, save and publish on the demo. MODULE_API 1.19.0. - DEMO_MODE.md: §3.4 says where the save-time check lives; DM18 row; step 2 marked built (website#224, Module-Rust#62) with the module's bridge recognition and fail-closed rules; the Rust fixture section. - MODULE_API.md: 1.19.0 in §1.1, the changelog, the registerEventActions signature and the action rules. - BACKEND_DESIGN.md §5.1: event steps on the demo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -26,13 +26,27 @@ here extends the contract first, in this file, before the module is written agai
|
||||
Core exports a single integer-major semver string from `server/src/modules/version.js`:
|
||||
|
||||
```js
|
||||
const MODULE_API_VERSION = '1.18.0'
|
||||
const MODULE_API_VERSION = '1.19.0'
|
||||
```
|
||||
|
||||
The client half carries the same number (`client/src/modules/version.js`) and a test asserts the two
|
||||
agree. Duplicated rather than fetched because the value has to be on `window.__rg` before the first
|
||||
module chunk evaluates, which is earlier than any network round trip could answer.
|
||||
|
||||
**1.19.0 — the public demo refuses a step at save** (`website/DEMO_MODE.md` §3.4, DM18). One optional
|
||||
member on an event action, so minor.
|
||||
|
||||
- **`demoRefuses(params)`** (§2.4, `registerEventActions`): a function of a step's checked params that
|
||||
returns a sentence, or `null` to let the step through. Asked only with `DEMO_MODE` on, for every step
|
||||
when a definition is created, saved or published. The first sentence refuses the whole write
|
||||
`403 { code: 'DEMO_LOCKED', message: <the sentence>, errors: [<the sentence>] }`, so core's one
|
||||
refusal toast shows it. A hook that throws refuses too, with core's own sentence, because a lock that
|
||||
cannot decide fails closed.
|
||||
- The hook covers the **save**. The module still refuses in `perform()` (behind `ctx.demoMode`),
|
||||
because a step can be saved before the module's list grows.
|
||||
- A module that declares it needs `coreApi` `^1.19.0`: an older core rejects nothing but never calls
|
||||
it, so the save would go through. Module-uo's `^1.10.0` still resolves and declares none.
|
||||
|
||||
**1.18.0 — the public demo** (`website/DEMO_MODE.md` §3.2, §3.4, §7.3; website#222). Three optional
|
||||
additions and no removal, so minor. With `DEMO_MODE` unset, none of them changes anything a module sees,
|
||||
except that `demoLocks` is validated.
|
||||
@@ -538,6 +552,10 @@ branches lacks — so it is the only place `permits` is true between two values
|
||||
between `admin` and `owner`, `members` or `subscribers`. `permits`, `meet` and `meetAll` are otherwise
|
||||
unchanged, and so is every rule about composition narrowing rather than widening.
|
||||
|
||||
**1.19.0 — a step refused at save on the demo** (`website/DEMO_MODE.md` §3.4, DM18). An event action's
|
||||
optional `demoRefuses(params)`, asked at create, save and publish with `DEMO_MODE` on; one optional
|
||||
member, so minor; see §1.1. Module-uo's `^1.10.0` still resolves.
|
||||
|
||||
**1.18.0 — the public demo** (`website/DEMO_MODE.md` §3.2, §3.4, §7.3). `demoLocks` in `module.json`,
|
||||
`ctx.demoMode` and `api.onDemoSeed`; three optional additions, so minor; see §1.1. Module-uo's
|
||||
`^1.10.0` still resolves.
|
||||
@@ -981,7 +999,7 @@ api.registerSlashCommands([{ name, description, options, access, handler }]) //
|
||||
api.registerEventTriggers([{ id, label, kind, subjectKey, audience, ceiling, version, variables }]) // 1.7.0
|
||||
api.registerAudiences([{ id, label, params, ceiling, resolve }]) // 1.7.0
|
||||
api.registerEngagementSeeds({ templates, ruleGroups }) // 1.9.0
|
||||
api.registerEventActions([{ id, label, risk, reversible, cost, params, perform, revert, reconcile, progress }]) // 1.10.0; progress 1.12.0; a param's duration 1.13.0; a param's multiple + max 1.14.0; a failure's retryAfterMs 1.15.0; a dry run's detail.warnings 1.16.0
|
||||
api.registerEventActions([{ id, label, risk, reversible, cost, params, perform, revert, reconcile, progress, demoRefuses }]) // 1.10.0; progress 1.12.0; a param's duration 1.13.0; a param's multiple + max 1.14.0; a failure's retryAfterMs 1.15.0; a dry run's detail.warnings 1.16.0; demoRefuses 1.19.0
|
||||
api.registerEventBudgets([{ id, label, unit }]) // 1.10.0
|
||||
api.registerEventLeases([{ id, label, type, min, max, values, example, target, maxDurationMs, read, apply, restore, inForce }]) // 1.10.0; example 1.13.0
|
||||
api.registerEventOptionSources([{ id, label, searchable, resolve }]) // 1.10.0; a row's note 1.13.0
|
||||
@@ -1396,6 +1414,13 @@ rather than implementation and belong here:
|
||||
would hide what the line describes answers `null` for that reader; a public page must never say
|
||||
what the module's own pages would hide. Core gives it 2 s and drops a late answer. It is a read: it
|
||||
must change nothing, and it may be called every few seconds for as long as a run is live.
|
||||
- **`demoRefuses(params)` is the demo's save-time lock, and it is not the only one** (1.19.0). Asked
|
||||
only with `DEMO_MODE` on, at create, save and publish, with the step's checked params; a sentence
|
||||
refuses the write `403 DEMO_LOCKED` and is shown as written, so phrase it for the person saving
|
||||
(`"quit" is turned off on the demo site.`). It is a pure check: no database, no game, nothing changed.
|
||||
A throw refuses. Because a definition can predate the list it is checked against, the module checks
|
||||
again in `perform()` behind `ctx.demoMode`. It never leaves the process: the catalog strips it with
|
||||
the other callables.
|
||||
- **A template is a shortcut past the editor, never a second way to make an event** (1.13.0). What
|
||||
`build()` returns is validated as a spec and opened as an unsaved draft; the author saves it
|
||||
through the same route, with the same checks, as one they typed. So a template cannot make a
|
||||
|
||||
Reference in New Issue
Block a user