From 2b5e3f9c7ddffcfc6f32ed9c238863f588848bd5 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Mon, 12 Oct 2026 15:50:50 -0500 Subject: [PATCH] =?UTF-8?q?docs(events,rust):=20MODULE=5FAPI=201.14.0's=20?= =?UTF-8?q?multiple=20param;=20permission=20rewards=20built=20(PLAN=5FREDE?= =?UTF-8?q?SIGNS=20=C2=A712.10)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - website/MODULE_API.md: 1.14.0 in §1.1 and the changelog — `multiple: true` with `max` on a string/int action param, the JSON-array value, a bare value as a list of one, refused on a duration, a template input and a list example; the catalog serves both keys; the editor's multi-select; Module-uo unaffected. §2.4's registerEventActions line names it. - website/EVENTS.md §F: the param that holds several values and its control. - modules/rust/PLAN_REDESIGNS.md §12.10: built in website#213 and Module-Rust#42, with the eight points settled in code, overrulable. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY --- modules/rust/PLAN_REDESIGNS.md | 28 ++++++++++++++++++++++++++ website/EVENTS.md | 10 ++++++++++ website/MODULE_API.md | 36 ++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/modules/rust/PLAN_REDESIGNS.md b/modules/rust/PLAN_REDESIGNS.md index b3cc494..91827cf 100644 --- a/modules/rust/PLAN_REDESIGNS.md +++ b/modules/rust/PLAN_REDESIGNS.md @@ -1814,3 +1814,31 @@ On both rigs, with a plugin that registers a perk (NightVision or similar): - run a *Permissions for good* step; see it stay after the run ends, show in the permission manager with its note, and go when staff delete it; - unload the plugin and see the step refuse the permission by name. + +### 12.10 Built (2026-10-12) + +Built to §12.2–§12.5 in two PRs, core first: website#213 (MODULE_API 1.14.0, the `multiple` flag and the +editor's multi-select, with Module-uo's frozen-manifest proof in its body) and Module-Rust#42 (the source, the two +steps and the two budgets, in a new `server/eventPermRewards.js`, with `ci/core-ref.json` pinned to #213 until it +merges). A core at #213 with the module installed registered it, and its own spec path validated and priced both +steps. These points the design left open were settled in the code, and are named here so they can be overruled: + +- **The two steps share one param list** (§12.5's "the same params"), each with its own message example: *"You + can use /nv until the event ends"* and *"…from now on"*. `confirm` is the last param, and a new step starts with + it off, so it must be ticked on purpose. +- **Only a real `true` ticks it.** A step written by hand with `"confirm": "true"` is refused like an unticked + one. A string is not the author's tick. +- **A server that has reported no catalogue yet is a wait, not a refusal.** It has not had a permission sync since + it was added, so the step is retried rather than refused for every permission by name. +- **The picker uses the first owner any server reports** for a permission. Two servers that disagree about which + plugin registered a name would be a renamed plugin, and the name is one row either way. +- **A permission is matched without case and stored lower case**, which is how Oxide and Carbon store one. The + picker shows the catalogue's own spelling. +- **Give tells a retry from a staff member's grant by its note.** A grant already there that carries this step's + note is counted as *given*, not *already held*, so a retry after a lost answer reports what the first attempt + did. Lend finds its rows by step, as a kit reward does. +- **Give's message goes to every recipient**, including one who already held every permission: the sentence + is still true for them. +- **The permission manager marks a for-good grant** with a chip, *given by event run N, step M*, from the + grant's note. It is turned off like any staff grant. A lent permission keeps its *from an event* chip and its + locked toggle, because the run's teardown takes it back. diff --git a/website/EVENTS.md b/website/EVENTS.md index 2317fb9..4a6db59 100644 --- a/website/EVENTS.md +++ b/website/EVENTS.md @@ -1107,6 +1107,16 @@ is a JSON editor with better fonts. shows under the field while that row is the chosen value — advice such as *"9 of 41 linked players have used this kit up"*. It is never a rule; the save path does not read it. +**A param may hold several values** (MODULE_API 1.14.0; Rust PLAN_REDESIGNS §12.3, D344): +`multiple: true`, with an optional `max` (1 to 100, 20 when left out), on a `string` or `int` param +that is not a duration and not a template's input. The step stores a JSON array — a bare value is a +list of one, duplicates are dropped in order, `required` means at least one — and `perform()` and +`cost()` receive the array. The editor's control is a **multi-select**: the chosen values as chips +above a grouped checklist with a filter box, over the source's own rows and in the source's order; +the typeahead adding a chip per pick for a `searchable` source; a tag box, a value per Enter, with +no source or one that cannot answer. The first user is Rust's permission rewards, one step giving +several permissions. + ### Integration Kit A fifth chapter, obeying the kit's own rule — teach and link out, re-specify nothing. The four things diff --git a/website/MODULE_API.md b/website/MODULE_API.md index 491f4ed..14f029d 100644 --- a/website/MODULE_API.md +++ b/website/MODULE_API.md @@ -26,13 +26,41 @@ 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.13.0' +const MODULE_API_VERSION = '1.14.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.14.0 — a param that holds several values** (`website/EVENTS.md` §F; Rust +`modules/rust/PLAN_REDESIGNS.md` §12.3, D344). One optional flag and no removal, so minor. + +- **`multiple: true` on an action param**, with an optional **`max`** (1 to 100; 20 when left out). + Only on a `string` or `int` param. Registration refuses it on any other type, on a param that is a + `duration`, on a template's inputs, and with a list as the `example`: the example stays one value, + because it is the placeholder of the box one value is typed into. A `max` without `multiple` is + refused too. +- **The value is a JSON array.** Each item is checked as the type's literal; an empty item is + refused; duplicates are dropped and the first kept, so the order the author picked in is the order + stored; more than `max` is refused with the number. **A bare value is read as a list of one**, so a + spec written by hand or over the API does not trip on it. `required` means at least one; an + optional list left empty is left out of the step's params. +- **`perform()` and `cost()` receive the array.** The budget switchboard prices an action's examples + to find its dimensions, and prices a multiple param's example as a list of one. +- **The catalog serves `multiple` and `max`** beside the rest of the param (`GET + /admin/events/catalog`). A param that does not say `multiple` is served without either key, as it + was declared. +- **The editor draws a multi-select.** Chips for the chosen values above a grouped checklist with a + filter box when the param has a source that answered; the typeahead when the source is + `searchable`, each pick a chip; a tag box, a value per Enter, with no source or one that failed. + Ticking past `max` is refused in words. A new step holds the example as a list of one. The run + console shows a list as its values joined by commas. + +**Module-uo is unaffected.** It declares `^1.10.0` and no multiple param; its actions come out of +the registry without the keys and its steps are checked, stored and drawn as before. The frozen- +manifest proof was run against this core (website PR body). + **1.13.0 — the event step editor** (`website/EVENTS.md` §F, §I; Rust `modules/rust/PLAN_REDESIGNS.md` §2, D192). Four additions and no removal, so minor. Each is optional, and each is a declaration the editor, core's own page, renders. @@ -419,6 +447,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.14.0 — a param's `multiple`** (`website/EVENTS.md` §F; Rust PLAN_REDESIGNS §12.3, D344). An +action param may hold a list of `string` or `int` values, at most `max`; one optional flag, so minor; +see §1.1. Module-uo's `^1.10.0` still resolves. + **1.13.0 — the event step editor** (`website/EVENTS.md` §F, §I; Rust PLAN_REDESIGNS §2). `registerEventTemplates`, a param's `duration`, a lease's `example` and an option's `note`; four optional additions, so minor; see §1.1. Module-uo's `^1.10.0` still resolves. @@ -838,7 +870,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 +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 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