feat(admin): staff write plane + help-page queue #1
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/admin-controls"
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?
Adds a staff write plane to the bridge (the site can now moderate the live shard) plus the in-game help-page (support) queue. Design and decisions are in
docs/ADMIN_CONTROLS.md; the shipped scope is Phase 1 + Phase 2 (Phase 3 is not planned).What's included
Phase 1 — account & session moderation (
BridgeAdmin.cs+ config)admin.kick/admin.ban(timed + indefinite) /admin.unban/admin.broadcastAdminWriteEnabled, default off); requiredactor; hard Owner-protection floor (AdminAccessFloor, defaultCoOwner) so a compromised sidecar can never touch the Owneradmin.ok/admin.errorreplies; every applied action emits anadmin.audit(origin:"web") event; attribution isweb:<actor>POST /admin/{kick,ban,unban,broadcast}with a status mapping (200 / 403 floor / 404 unknown / 400 missing-actor / 401 no-token)Bidirectional audit (§5.5 —
patches/commandlogging-event.patch+patches/BridgeModerationAudit.cs)admin.audit(origin:"in-game"), so the moderation log is complete regardless of originCommandLogging.OnWrite; the subscriber lives inpatches/(references a post-patch symbol), applied like the Phase-7 vendor-sale patchPhase 2 — help-page queue (
BridgePages.cs)page.new/page.updated/page.closedpages.snapshot,page.respond(delivers a staff reply to the player; shows as "Staff"; optional close),page.closeGET /pages,POST /pages/{id}/respond,POST /pages/{id}/closeVerification
Every slice was verified live against a booted ServUO + the real sidecar, then the server was shut down and test artifacts reverted:
[bcastand resolved ban/kick log lines produced the rightadmin.auditframes with the target parsed; non-moderation lines ignoredpage.new×2, respond, close (page removed),page.closed, and 404 on an unknown pageDeploy notes
overlay/(deployed bydeploy.ps1).patches/commandlogging-event.patchapplied andpatches/BridgeModerationAudit.cscopied in — seepatches/README.md.AdminWriteEnabled=trueinBridge.cfgto enable it. Authorization is enforced on the website (admin/moderator roles).Downstream/remaining is website-side only: the admin UI (moderation log consuming
admin.audit, support-queue view overpage.*+/pages).🤖 Generated with Claude Code
Phase 1 (sidecar side): POST /admin/{kick,ban,unban,broadcast} forward to the shard, correlated on a fresh reqId, with an admin-specific status mapping — unknown target -> 404, protected target / plane-disabled -> 403, missing actor / bad body -> 400. actor is required and checked up front. Documents the endpoints and the admin.audit event in INTEGRATION.md. Verified end-to-end (real sidecar + booted shard): 200 on success, 403 on the Owner floor, 404 unknown target, 400 missing actor, 401 no token. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114TpmrNW4wNXsHq5CR72jQPhase 2 of docs/ADMIN_CONTROLS.md: surface the in-game help-page queue to the website. - BridgePages.cs: the queue has no EventSink, so it is polled (PageSweepSeconds, default 5s) and diffed, keyed by sender serial (one page per player) -> page.new / page.updated / page.closed. Inbound pages.snapshot -> pages.list; page.respond delivers a staff reply to the player (online: a gump now; offline: queued for next login; shows as "Staff") and can close; page.close removes it. - BridgeConfig/Bridge.cfg: PageSweepSeconds. BridgeBoot: reload re-arms the poll, status reports it. - sidecar/src/web.rs: GET /pages, POST /pages/{id}/respond, POST /pages/{id}/close. - INTEGRATION.md: page events (§4) and endpoints (§6). - tools/scaffolding/BridgePageProbe.cs: gated headless verification. Verified live (probe-seeded tickets): snapshot returns the queue, the poll emits page.new for both and page.closed on removal, respond -> 200, close removes the page, unknown page -> 404. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114TpmrNW4wNXsHq5CR72jQ