D342-D346 (docs#342). Two steps over the permission mirror's own tables, so
no plugin, sidecar or protocol change:
- rust.perm.lend, "Permissions until the event ends": a kit reward's lease,
one rust_perm_run_grants row per recipient per permission, the message on
one row each; change/ledger with rust.kit.entitle's revert and reconcile;
budget rust.permissions.
- rust.perm.give, "Permissions for good": a standing rust_perm_grants row per
website user per permission, scoped to the step's server, source `event`,
note "event run <run>, step <step>"; a grant already there is left alone,
and a retry's own grants are counted as given; the message rides a
notice-only run-grant row; irreversible/none; budget rust.permissions.kept.
- Both: several permissions through core's `multiple` param (MODULE_API
1.14.0, at most 10); a required "I am sure" toggle refused unticked in the
dry run and at run time, naming the permissions (D343); a permission the
server's catalogue lacks refused by name; a blank message tells nobody.
- rust.options.permissions: the enabled servers' catalogues, grouped by the
registering plugin (by prefix when none), sorted plugin then permission
without case, a row noted "Only on X" when not on every server.
- Permission manager: an event-given grant shows "given by event run N,
step M"; staff turn it off like any grant.
- coreApi ^1.14.0; ci/core-ref.json pinned to website#213's head until it
merges; engagement-triggers.json regenerated; routes.manifest.json
unchanged (no new routes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
website#212 (MODULE_API 1.13.0) merged as ca7ec53, whose tree is the
same as the branch head e58857c this repo was pinned to while it was
open. Only the pin moves; routes.manifest.json is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
PLAN_REDESIGNS §2, the Rust half (D164, D192, D332, D333):
- rust.template.kit_weekend (core registerEventTemplates, MODULE_API 1.13.0):
inputs kit/minutes/message/delivery; one phase advance after the weekend,
core.lease rust.group.permission default/<kit permission> + rust.kit.entitle
linked. Steps only where the kit can use them; validated by the real core.
- rust.kit.entitle: recipients 'linked' (every linked player who has played
on the server, no tally, refused past the bound), optional message ({kit})
and delivery, stored per row (rust_perm_run_grants.notice*).
- perm.sync notices: the untold set to the picked account, keyed
run:step:user, in the digest; the report's noticesTold marks them told.
- rust.options.grouppermissions notes a kit's permission rows via kits.uses
(cached a minute per server; a failure is no note).
- duration: 'minutes' on rust.zone.open and rust.participation.open; the
group-permission lease's value example is true.
- protocol 13 -> 14, coreApi ^1.13.0; ci/core-ref.json pinned to website#212's
head while it is open; engagement-triggers.json regenerated (coreApi line).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
The job cloned a MODULE_API 1.10.0 main and the loader refused the module
("needs core API ^1.11.0, this core is 1.10.0"), so it added no routes and
failed by construction. Pinned to #209's head (cc1f49a), where the job's own
steps pass: core alone 280 routes up to date, with this module 49 routes all
documented. Re-pin to #209's main merge sha once it lands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
Phase 2 of docs/modules/rust/PLAN.md. Phase 1 built five guards and ran them by
hand; this repo had no workflows at all, so nothing gated the branch that gets
released and there was no way to release it.
Three pieces:
- **release.yml** — the derived-version engine link, installer and Module-uo
already run (conventional-commit subjects since the newest tag; module.json's
version survives as a floor; workflow_dispatch as the backdoor), assembling the
bundle from an include list and publishing the tarball, the install manifest
carrying its sha256, and SHA256SUMS. The tag is the number that ships and CI
stamps it into the bundle's own module.json.
- **pr-checks.yml** — server tests, check:imports, check:bundle, check:swagger,
the client build, client tests and check:externals, plus frozen-manifest.
- **frozen-manifest** — clones core at the sha pinned in ci/core-ref.json,
generates its route table without this module and with it, and takes the
difference. It ran locally against that exact ref: six routes, all documented,
no core route moved. That is the first proof by a running core that /rust
collides with nothing — phase 1 could only check it by reading, because core
mounts /status and /version at a tier root where the loader's own collision
probe cannot see them.
The bundle carries no node_modules, because the shipped half declares no runtime
dependencies (org lead, phase 2). checkBundle.js holds both halves of that: the
include list still covers everything server/index.js reaches, and no dependency
has appeared without the release learning to pack it. Verified by breaking it —
dropping "model" from the list names the exact edit and exits 1.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4