docs(modules): phase 7 as built — the permission mirror, and the set arithmetic behind it
Protocol 4 (`PROTOCOL.md` §10), phase 7 as built (`PLAN.md` §20), what an operator needs to know about it (`INTEGRATION.md`), and the in-game leg as a walk to run (`PLAYER_WALK.md`). **The spec.** One verb carrying the whole desired set, diffed by the plugin against the live store; a report whose two interesting fields are the ways a push looks like it worked and did not (`unresolved`, `pending`); drift as a report rather than an action; and the permission hooks as a live SIGNAL rather than the record — a hook that stops firing costs latency, not correctness. **The finding the design turns on, written where it belongs.** A name in the store that is not in the desired set is either something the site retired or something a human granted, and those have opposite correct answers. The store records who granted a permission nowhere, so only the website can tell them apart — which is why it keeps a ledger of what it pushed, and why revoking a hand edit needed a table of its own. **§10.5 is a rule generalising.** "A wedged sidecar must never stall the game" becomes "nothing the far side sends may cost the main thread unbounded work", because `perm.sync` is the first command whose work is not bounded by its own shape. Three bounds, each on the side that can say something useful when it is hit. **§20.7 says plainly what is not proven**: the acceptance line needs a second, non-admin Steam account on the rig, and nothing in the plugin has been compiled. The walk doc carries the seven steps, including the two things to confirm on Carbon rather than assume. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM
This commit is contained in:
@@ -235,6 +235,31 @@ Two things an operator should know about it:
|
||||
refuses to move it — the player runs `/unlink` in game, or staff release it from the user's page in
|
||||
the admin panel.
|
||||
|
||||
**From protocol 4 the website owns your permissions.** Groups and grants are written in
|
||||
Admin → Rust permissions and pushed into this server's own Oxide/Carbon permission store, so every
|
||||
plugin you already run honours them — Kits, ZoneManager, anything that calls `UserHasPermission`.
|
||||
Nothing is required of those plugins and nothing is configured twice.
|
||||
|
||||
Four things an operator should know about it, because each looks like something else from the game
|
||||
side:
|
||||
|
||||
- **A wipe does not lose them.** The site re-pushes the whole set when the server comes back. If your
|
||||
wipe script clears `oxide/data/`, the permissions the site authored are back within a minute of the
|
||||
server being up; ones granted at the console are not, because nothing remembers those.
|
||||
- **Granting at the console still works, and the website notices.** A hand edit is reported as
|
||||
drift on that screen and is **never** undone on its own — an operator is offered two answers to
|
||||
it: adopt it, so the site maintains it from then on, or revoke it. That is deliberate: a console
|
||||
grant during an incident must survive the next sync.
|
||||
- **A permission no loaded plugin has registered cannot be granted.** Oxide's own API silently does
|
||||
nothing for an unknown name, so the site checks first and reports the name as unresolved instead
|
||||
of claiming a privilege nobody has. Load the plugin and the grant lands by itself.
|
||||
- **A player who has never connected to that server can hold a grant but cannot be in a group.**
|
||||
The store has no record of them to put in a group yet; the site says which memberships are waiting
|
||||
and they land on that player's first connection.
|
||||
|
||||
`rg.perms` at the server console prints what the last sync did, which is the fastest way to tell
|
||||
"that permission does not exist here" from "that player has never been seen here".
|
||||
|
||||
**Every row carries its wipe.** The plugin derives a `wipeId` from the save's creation time and
|
||||
stamps it on every frame, so a wipe splits the history rather than ending it. That is also why
|
||||
**the sidecar's database must never be in a wipe script's delete list** — see the Pterodactyl egg's
|
||||
|
||||
Reference in New Issue
Block a user