feat(rust): what the site has given a player, as the player reads it #10
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/phase-8-player-permissions"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 8's website half (
docs/modules/rust/PLAN.md§22, D39). Phase 7 made the site the author of in-game privilege and gave an operator every view of it; this is the other side, and it is the first time a player can see what they hold without asking one.One new route,
GET /player/rust/permissions— self-scoped in SQL, read-only by construction (a grant a player could change would not be a grant), and rendered on this module's own/player/rustpage as well as by the app's leg (Android-app#48), so the app never has a surface the website lacks.It is a different shape from the admin read rather than a filtered one:
scope: "*"would have to know what the fleet is to say anything, and theninScopeexists twice. Each entry carries the servers it reaches, already resolved and already marked.liveis the pushed ledger, never the authored row. A grant is not a privilege in a game until a sync confirmed it, and phase 7 is careful never to record a push that silently did nothing — so waiting is honest, and the alternative is the site claiming to have given something it has not.An entitlement that reaches nobody still lists, and the page says so — authored against the website account, it exists before a Steam id does, and hiding it until one turns up is the defect the admin user page shipped in phase 7 (§20.5).
Verified
169 server tests (7 new), 39 client tests,
check:imports,check:bundle,check:externals, the regenerated OpenAPI fragment and the frozen route manifest (generated against core at the pinned sha, as CI does).Walked in a browser against a core with this module installed and a live Oxide rig behind it — the first Rust phase whose backend talked to a real plugin rather than a stand-in.
perm.synccreated the group in Oxide's own store, applied the membership, and reportedunresolvedfor a name nothing had registered; the page showed exactly that, one entry has it and one waiting.The acceptance line needs a person in game — a
/linkcode reaches a player and nobody else. The three minutes that close it are indocs/rust-link/PLAYER_WALK.md.AI disclosure
Written with Claude Code (Opus 5).
🤖 Generated with Claude Code
https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM
Phase 8's website half. Phase 7 made the site the author of in-game privilege and gave an operator every view of it; this is the other side, and it is the first time a player can see what they hold without asking one. `GET /player/rust/permissions` is self-scoped in SQL and read-only by construction — a grant a player could change would not be a grant. Three things make it a different shape from the admin read rather than a filtered one: * the scope arithmetic is answered on the server. A client handed `*` would have to know what the fleet is to say anything, and then `inScope` exists twice. Each entry carries the servers it reaches, already resolved and already marked. * `live` is the pushed ledger, never the authored row. A grant is not a privilege in a game until a sync confirmed it, and phase 7 is careful never to record a push that silently did nothing — so "waiting" is honest, and the alternative is the site claiming to have given something it has not. * nothing says WHY it is waiting. An offline server, a permission no loaded plugin registered and a store that has never seen the account all look the same from here; telling them apart is an operator's diagnosis and an inventory of what is installed. An entitlement that reaches nobody still lists, and the page says so — authored against the website account, it exists before a Steam id does, and hiding it until one turns up is the defect the admin user page shipped in phase 7 (PLAN.md §20.5). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM