PLAN.md §33, D134-D143. Protocol 12.
- Chat titles (D135-D137): per-server rules (stat, top N, text, colour)
that rank the current wipe, and a mode (first | all | up to N). Worked
out once in model/titles and read three ways: pushed whole to the game by
a new titleSync loop (on change, restart or wipe), and on every
leaderboard row as `titles`. Admin: PUT /servers/:id/titles.
- Group styles (D138, D139): a site group may carry all twelve BetterChat
fields (rust_perm_group_chat). They ride perm.sync with `expect` from the
pushed ledger, which gains a value column; a field changed in game is a
`chat-field` drift row with the game's value, adopted into the style or
put back. A withdrawn style is one `chat-group` retirement, never for
`default`, cleared from the ledger only once BetterChat removed it.
- The voice (D140): one fleet setting naming a styled group; news and
rust.announce chat lines carry its format and the plugin says them with
no sender. Admin: GET/PUT /voice.
- Popups (D141, D142): rust.announce gains `delivery` (still version 1,
from rust.options.delivery); each server gains news_delivery beside the
news switch; `popup-unavailable` is not retried.
- GET /servers/:id/integrations reads, live, which optional mods a server
has loaded. README lists BetterChat and PopupNotifications as optional.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
The first boot against real core refused the whole module at register:
`rust.options.runZones` fails core's EVENT_ID grammar, which is lowercase
dotted segments only. The fake api validates none of it, so 310 green
tests said nothing. The four fixed-choice sources and the chat-server
source are renamed, and entry.test now holds every action, budget,
lease and option-source id against a copy of the grammar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
Four event verbs and the announce leg, per PLAN.md §29:
- rust.participation.open / .collect: the plugin counts who takes part
(seconds, kills or both, in a zone this run opened or the whole server)
and collect files them as the run's participants, keyed by Steam id.
- rust.kit.entitle: the five recipient modes (D101), rows in the new
rust_perm_run_grants (D84) unioned into the permission push, one extra
use of the kit per reward as site-held credits on perm.sync (D103),
and the rust.kit.entitled notice deferred from phase 10 (D64).
- rust.announce: one server or every server (D105).
- rust.chat announce leg, speaking only on servers whose new news switch
is on (D104) - a card on Admin -> Rust visibility (D106).
Budgets rust.grants and rust.announcements; the kit source and four
fixed-choice sources (core has no enum param type). rust_perm_run_grants
carries core's idempotency key so a revert of a lost answer can find its
rows. Protocol 10.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY