docs(modules): the presence fix - nothing names who is online by default
modules/rust/PLAN.md gains §23: the org lead's rule (2026-09-22) that nothing names who is online by default, the five decisions it needed (D42-D46), the fourth surface the rule reached (the leaderboard's lastSeen), the viewer re-read from the users row, and a defect four phases old that the walk found - every empty state in module-rust rendered as a blank box, because core's EmptyState renders children and the Integration Kit's template teaches title/message. rust-link/PROTOCOL.md reclassifies six §8.4 kinds from public to presence - public with an operator-chosen audience - with no wire change. android/PLAN.md records the app's half as an amendment to M14. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -445,12 +445,12 @@ Every kind protocol 2 defines, and the hook behind it. **`class` is not a field
|
||||
|
||||
| `kind` | Hook | `class` | Carries |
|
||||
|---|---|---|---|
|
||||
| `player.connected` | `OnPlayerConnected` | public | steamId, name |
|
||||
| `player.disconnected` | `OnPlayerDisconnected` | public | steamId, name, reason, sessionSec |
|
||||
| `player.respawned` | `OnPlayerRespawned` | public | steamId |
|
||||
| `player.death` | `OnPlayerDeath` | public | victim, attacker, attackerType, weapon, distance, grid |
|
||||
| `player.chat` | `OnPlayerChat` | public | steamId, name, channel, message |
|
||||
| `player.tally` | *aggregate* — see §8.6 | public | steamId, gathered{}, npcKills, structures |
|
||||
| `player.connected` | `OnPlayerConnected` | **presence** | steamId, name |
|
||||
| `player.disconnected` | `OnPlayerDisconnected` | **presence** | steamId, name, reason, sessionSec |
|
||||
| `player.respawned` | `OnPlayerRespawned` | **presence** | steamId |
|
||||
| `player.death` | `OnPlayerDeath` | **presence** | victim, attacker, attackerType, weapon, distance, grid |
|
||||
| `player.chat` | `OnPlayerChat` | **presence** | steamId, name, channel, message |
|
||||
| `player.tally` | *aggregate* — see §8.6 | **presence** | steamId, gathered{}, npcKills, structures |
|
||||
| `entity.destroyed` | `OnEntityDeath` on owned building blocks | **staff** | ownerId, prefab, grid, attacker |
|
||||
| `player.reported` | `OnPlayerReported` | **staff** | reporter, target, subject, message, type |
|
||||
| `player.banned` / `player.unbanned` | `OnUserBanned` / `OnUserUnbanned` | **staff** | id, name, **ip**, reason |
|
||||
@@ -486,6 +486,14 @@ So: the table in §8.4 is the specification, `module-rust` holds the allowlist,
|
||||
its allowlist against this document, so adding a kind here without classifying it there fails a
|
||||
build rather than shipping an IP address to a public page.
|
||||
|
||||
**`presence` is `public` with an audience an operator chooses** (added 2026-09-22, [`PLAN.md`](../modules/rust/PLAN.md) §23).
|
||||
The six kinds marked so each say that a *named* player was on the server at a given moment, and the
|
||||
org lead's rule is that nothing names who is online by default: `module-rust` serves them only to
|
||||
viewers inside an operator-chosen audience — staff unless widened, fleet-wide with a per-server
|
||||
override. Below it the public feed carries only what names nobody (a wipe, a start, a shutdown).
|
||||
Nothing on the wire changed: the class is still the module's to enforce, which is why the rule could
|
||||
be added without a protocol bump.
|
||||
|
||||
`player.login.attempt`, `player.approved` and `player.banned` carry **IP addresses**, and
|
||||
`player.reported` carries the text of one player's complaint about another. They are stored because
|
||||
an operator chasing ban evasion needs them and because the sidecar persists what it is told; they
|
||||
|
||||
Reference in New Issue
Block a user