fix(rust): every notice says which server, clan or player it is about
All checks were successful
PR Checks / client-build (pull_request) Successful in 18s
PR Checks / frozen-manifest (pull_request) Successful in 43s
PR Checks / server-tests (pull_request) Successful in 7m48s

The live walk rendered a generic in-app notice as "A server came online.
A server's game started..." Core's structural projection falls back to
the trigger's label and description when the payload has no title, and
on a multi-server site that never says which server. Core's rule is that
the payload wins, so every trigger now declares `title` and `intro`, and
the emitter writes the sentence ("Oxide rig is online"). An operator's
own template can still ignore it and use the parts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-23 13:37:05 -05:00
parent 285db0baa7
commit 648d3fd2e1
4 changed files with 302 additions and 3 deletions

View File

@@ -56,6 +56,22 @@ const V1 = 1
// ── Shared variables ───────────────────────────────────────────────────────
// **Every trigger carries its own headline.** Most rules here point at core's
// generic `notify.event` / `inapp.event`, and core's structural projection fills
// `title` and `intro` from the trigger's LABEL and DESCRIPTION only when the
// payload does not define them — "the payload wins, the projection fills gaps"
// (ENGAGEMENT.md §4.6.1). Without these two, the phase-10 walk rendered a
// multi-server site's notice as "A server came online. A server's game
// started…" — true, and useless, because it never said which. The emitter
// writes the sentence (`emit.js` `headline`); an operator's own template can
// still ignore it and interpolate the parts.
const HEADLINE = [
{ name: 'title', type: 'string', required: false, example: 'Main is back online',
description: 'A one-line headline naming what happened and where. Core generic bodies use it as the title.' },
{ name: 'intro', type: 'string', required: false, example: 'Main is back up and taking players.',
description: 'One sentence of detail. Core generic bodies use it as the body.' },
]
const SERVER = [
{ name: 'serverId', type: 'string', required: true, example: 'main',
description: 'The server the event happened on, as configured in Admin -> Rust. Also the cooldown subject for broadcasts.' },
@@ -93,6 +109,7 @@ const RAID = {
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'building', type: 'string', required: true, example: '8113',
description: 'The base, as the id of its tool cupboard. The cooldown subject.' },
{ name: 'structure', type: 'string', required: true, example: 'door',
@@ -128,6 +145,7 @@ const BROADCASTS = [
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'wipeId', type: 'string', required: true, example: '1790142840-3000-1234',
description: 'The new wipe\'s identity.' },
],
@@ -141,7 +159,7 @@ const BROADCASTS = [
audience: 'subscribers',
ceiling: 'everyone',
version: V1,
variables: [...SERVER],
variables: [...SERVER, ...HEADLINE],
},
{
id: 'rust.server.offline',
@@ -152,7 +170,7 @@ const BROADCASTS = [
audience: 'subscribers',
ceiling: 'everyone',
version: V1,
variables: [...SERVER],
variables: [...SERVER, ...HEADLINE],
},
{
id: 'rust.leaderboard.topped',
@@ -165,6 +183,7 @@ const BROADCASTS = [
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'leader', type: 'string', required: true, example: 'Marisol',
description: 'The new leader\'s in-game name.' },
{ name: 'kills', type: 'int', required: true, example: 42,
@@ -189,6 +208,7 @@ const ACCOUNT = {
ceiling: 'owner',
version: V1,
variables: [
...HEADLINE,
{ name: 'steamId', type: 'string', required: true, example: '76561198000000001',
description: 'The Steam account that was linked. Also the cooldown subject.' },
{ name: 'player', type: 'string', required: false, example: 'Marisol',
@@ -220,6 +240,7 @@ const CLANS = [
variables: [
...CLAN,
...SERVER,
...HEADLINE,
{ name: 'member', type: 'string', required: false, example: 'Darrow',
description: 'Who left.' },
],
@@ -236,6 +257,7 @@ const CLANS = [
variables: [
...CLAN,
...SERVER,
...HEADLINE,
{ name: 'member', type: 'string', required: false, example: 'Darrow',
description: 'Who was removed.' },
{ name: 'by', type: 'string', required: false, example: 'Marisol',
@@ -254,6 +276,7 @@ const CLANS = [
variables: [
...CLAN,
...SERVER,
...HEADLINE,
{ name: 'by', type: 'string', required: false, example: 'Marisol',
description: 'Who disbanded it.' },
],
@@ -274,6 +297,7 @@ const MODERATION = [
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'steamId', type: 'string', required: true, example: '76561198000000002',
description: 'The reported player\'s Steam id. The cooldown subject.' },
{ name: 'player', type: 'string', required: false, example: 'Darrow',
@@ -299,6 +323,7 @@ const MODERATION = [
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'steamId', type: 'string', required: true, example: '76561198000000002',
description: 'The banned player\'s Steam id. The cooldown subject.' },
{ name: 'player', type: 'string', required: false, example: 'Darrow',
@@ -318,6 +343,7 @@ const MODERATION = [
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'steamId', type: 'string', required: true, example: '76561198000000002',
description: 'The player\'s Steam id. The cooldown subject.' },
{ name: 'player', type: 'string', required: false, example: 'Darrow',
@@ -337,6 +363,7 @@ const MODERATION = [
version: V1,
variables: [
...SERVER,
...HEADLINE,
{ name: 'steamId', type: 'string', required: true, example: '76561198000000002',
description: 'The Steam id that tried to connect. The cooldown subject.' },
{ name: 'player', type: 'string', required: false, example: 'Darrow',