feat(rust): the rewards — tally, kit reward, chat and the news leg (phase 13b, protocol 10) #16

Merged
whitlocktech merged 2 commits from feat/phase-13b-rewards into edge 2026-09-24 13:02:19 +00:00
Member

What & why

Phase 13b (PLAN.md §29; decisions D98–D108).

  • rust.participation.open / .collect: the game counts who takes part in an event, and collect records them as the run's participants, keyed by Steam id with the website user where linked.
  • rust.kit.entitle rewards a kit to the people one of five modes picks (D101): everyone who scored, top N, a minimum score, N at random (seeded by the step's key), or the top X per cent. Ties are kept in, and an unlinked winner is named as missed.
    • The rewards are rows in the new rust_perm_run_grants, which the permission push unions with admin grants (D84), so reverting an event never removes an admin's grant.
    • Each reward is also one extra use of the kit, sent as credits on the permission sync (D103).
    • It raises rust.kit.entitled, deferred from phase 10 (D64), with a new rewards-v1 rule group.
  • rust.announce says a line on one server or every server (D105).
  • The rust.chat announce leg says a published news post only on servers whose switch is on (D104). The switch is rust_servers.announce_news, set from a new "News in game chat" card on Admin → Rust visibility (D106).
  • Budgets and dropdowns: budgets rust.grants and rust.announcements; the rust.options.kits source and five fixed-choice sources, since core has no enum param type.
  • Other changes:
    • Protocol 10.
    • ci/bundle.json gains eventRewards.js.
    • The swagger fragment and engagement-triggers.json are regenerated.
    • purge.sql covers the new table.
  • A second commit lowercases the option-source ids. Real core's id grammar refused the whole module at boot, which the fake api in the unit tests never checks. A test now pins every registered id to that grammar.

How it was tested

  • Server: 311 tests pass (including new rewards.test.js, the permission union and credit tests, and the news switch). check:imports, check:bundle, check:swagger and check:engagement all pass.
  • Client: the build passes, 41 tests pass, and check:externals passes.
  • Walked against real core on main with both rigs; results in PLAN.md §29.7:
    • every recipient mode;
    • the admin-granted permission survives an event's revert;
    • credits applied and withdrawn through real Kits;
    • a restart and a wipe;
    • chat to one server and to every server with one down;
    • the news leg with switches on, off, and all off;
    • Carbon.
  • Not walked: anything that needs a person in game (see PLAYER_WALK.md's rewards walk).

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • AI tools were used. Tool(s): Claude Code (Claude Opus 5.5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a Co-Authored-By trailer.

License

  • I agree that my contribution is licensed under GPL-3.0-or-later.

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

## What & why Phase 13b (`PLAN.md` §29; decisions D98–D108). - **`rust.participation.open` / `.collect`**: the game counts who takes part in an event, and collect records them as the run's participants, keyed by Steam id with the website user where linked. - **`rust.kit.entitle`** rewards a kit to the people one of five modes picks (D101): everyone who scored, top N, a minimum score, N at random (seeded by the step's key), or the top X per cent. Ties are kept in, and an unlinked winner is named as missed. - The rewards are rows in the new `rust_perm_run_grants`, which the permission push unions with admin grants (D84), so reverting an event never removes an admin's grant. - Each reward is also one extra use of the kit, sent as `credits` on the permission sync (D103). - It raises `rust.kit.entitled`, deferred from phase 10 (D64), with a new `rewards-v1` rule group. - **`rust.announce`** says a line on one server or every server (D105). - **The `rust.chat` announce leg** says a published news post only on servers whose switch is on (D104). The switch is `rust_servers.announce_news`, set from a new "News in game chat" card on Admin → Rust visibility (D106). - **Budgets and dropdowns**: budgets `rust.grants` and `rust.announcements`; the `rust.options.kits` source and five fixed-choice sources, since core has no enum param type. - **Other changes**: - Protocol 10. - `ci/bundle.json` gains `eventRewards.js`. - The swagger fragment and `engagement-triggers.json` are regenerated. - `purge.sql` covers the new table. - **A second commit** lowercases the option-source ids. Real core's id grammar refused the whole module at boot, which the fake `api` in the unit tests never checks. A test now pins every registered id to that grammar. ## How it was tested - Server: 311 tests pass (including new `rewards.test.js`, the permission union and credit tests, and the news switch). `check:imports`, `check:bundle`, `check:swagger` and `check:engagement` all pass. - Client: the build passes, 41 tests pass, and `check:externals` passes. - **Walked against real core on `main` with both rigs**; results in `PLAN.md` §29.7: - every recipient mode; - the admin-granted permission survives an event's revert; - credits applied and withdrawn through real Kits; - a restart and a wipe; - chat to one server and to every server with one down; - the news leg with switches on, off, and all off; - Carbon. - **Not walked**: anything that needs a person in game (see `PLAYER_WALK.md`'s rewards walk). ## Checklist - [x] I have read CONTRIBUTING.md. - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [x] AI tools were used. Tool(s): `Claude Code (Claude Opus 5.5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` trailer. ## License - [x] I agree that my contribution is licensed under GPL-3.0-or-later. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 2 commits 2026-09-24 12:50:27 +00:00
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
fix(rust): lowercase the reward option-source ids, and test the grammar
All checks were successful
PR Checks / client-build (pull_request) Successful in 20s
PR Checks / frozen-manifest (pull_request) Successful in 50s
PR Checks / server-tests (pull_request) Successful in 7m45s
42029734ad
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
whitlocktech merged commit ac0bcd850a into edge 2026-09-24 13:02:19 +00:00
whitlocktech deleted branch feat/phase-13b-rewards 2026-09-24 13:02:22 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Module-Rust#16
No description provided.