Add administrator pause and joining-lock controls

Provide authenticated owner/operator room controls with live account binding, durable audit and exact saved retries. Pause gates human, bot and automatic writes while preserving recovery, discussion and taking back control. Resume keeps decisions and restores AI pacing. Add directory availability filters and player notices.

Verified types, lint, 5223 offline tests, 52 HTTP tests and build. Independent persistence/privacy review and authenticated HTTP acceptance passed. Desktop/mobile browser QA confirmed lost-response refresh/retry makes one audit row and resume restores controls. Existing games preserved. Authenticated deployed admin acceptance remains pending explicit QA access confirmation.
This commit is contained in:
Quintine committed 2026-09-22 10:41:09 +10:00
1 parent f29d05620c
commit 8c922b446b
39 files changed
+3196 -104

No files matched your search

+9 -6
View File
@@ -10,9 +10,9 @@ recovery and persistence systems where suitable.
| Area | Required behavior | Stage |
| --- | --- | --- |
| Administrator access | Personal access keys, server-enforced owner/operator/viewer roles, persistent eight-hour sessions, individual/all-session sign-out and operator provisioning/revocation. A room host is not a site administrator. Account-management UI and further operational permissions remain. | Prototyped |
| Room directory | Search room codes/public player names, filter status/rules, sort and paginate; show host, roster, modules, game change time and bounded decision ownership. Detailed setup/shared-window ownership and later lifecycle metadata remain. | Prototyped |
| Room directory | Search room codes/public player names, filter status/rules/availability, sort and paginate; show host, roster, modules, game change time, pause/join flags and bounded decision ownership. Detailed setup/shared-window ownership remains. | Prototyped |
| Create and configure | Create rooms with supported rules and human/AI seats, manage lobby settings and invitations, and assign a host through an explicit workflow. Preserve normal prerequisites and readiness rules. | Missing |
| Lifecycle and removal | Pause/resume, lock/unlock new joins, close/end, archive, restore and delete selected rooms. Offer recoverable removal and explicit permanent deletion with clear scope, consequences and safeguards for related records. | Missing |
| Lifecycle and removal | [Pause/resume and joining locks](ADMIN_ROOM_CONTROLS.md) have controls, durable audit, exact retries and player/AI enforcement. Close/end, archive, restore and recoverable/permanent removal remain missing. | Prototyped, partial |
| Participant support | Remove disruptive participants or revoke access, manage appropriate restrictions, assist saved-seat recovery and host reassignment, and use supported AI takeover/replacement without losing forces, cards or decisions. | Missing |
| Saved-game operations | Create/list/download backups, validate imports, restore a selected checkpoint safely, and diagnose or resume interrupted automatic work through authoritative game actions. | Missing |
| Operations and audit | Show server/build/storage health, room/player counts and actionable errors; provide maintenance controls and a searchable record of administrator actions. | Missing |
@@ -33,8 +33,9 @@ expiry. HTTPS uses Secure, HttpOnly, SameSite=Strict cookies scoped to the admin
API. Mutations require the exact configured origin and bounded JSON requests.
All three roles may read the current directory and sign out their own sessions.
Owner/operator mutation capabilities will be added with the room-management
slices. The role is checked from the live account, never accepted from a client.
Owners/operators may pause/resume rooms and lock/unlock new joins through
[Room controls](ADMIN_ROOM_CONTROLS.md). The role is checked from the live
account, never accepted from a client.
Disabling an account invalidates its sessions; later re-enabling it cannot restore
them. The database refuses to disable, demote or delete the final enabled owner.
No default key, public account creation or host-to-administrator promotion exists.
@@ -98,10 +99,12 @@ node tools/verify-admin.mjs --url http://localhost:3000 --key-file /private/dune
```
The HTTP verifier requires a **dedicated QA administrator account** and explicitly
checks its ID before proceeding: it creates one named QA room and signs out all
checks its ID before proceeding: it creates a named QA room and signs out all
sessions of that QA account. Never supply a human operator's normal key. It checks
authentication, cookie properties, ordinary-host denial, directory privacy,
session revocation and unchanged game/seat continuation. Private reports retain
session revocation and unchanged game/seat continuation. Operator/owner QA keys
also create one additional room for joining locks, pause/takeback/resume and
account-bound request checks. Private reports retain
room IDs and safe outcomes, never keys/cookies. The container verifier provisions
its own disposable QA account and checks admin-session continuity across restart
and replacement, followed by the HTTP flow and HTTPS-proxy cookie behavior.
+83
View File
@@ -0,0 +1,83 @@
# Administrator pause and joining locks
The directory now offers **Room controls** and an **Availability** filter. Owners
and operators can pause/resume a selected room and lock/unlock new joins; viewers
can inspect its flags. This is a reversible lifecycle prototype. Closing,
archiving, removal, participant support and backups remain unfinished in
[the panel checklist](ADMIN_PANEL.md).
Identify the room, provide a short operational reason, warn active players if
necessary, and explicitly confirm the displayed scope before applying settings.
Reasons belong to the private audit and must not contain credentials or private
game information. Players see only public availability flags.
## Paused behavior
| Operation | While paused |
| --- | --- |
| Game decisions, lobby changes and new joins | Rejected without changing the game |
| Automatic normalization and native/human-owned AI | Stop before work and are fenced again at the database write, including sleeping workers |
| Reading, refresh, discussion and component inspection | Remain available |
| Seat protection, recovery and voluntary handover | Remain available with existing ownership/revocation safeguards |
| Taking back control and revoking AI permission | Remain available |
| New AI permission or activation | Rejected; completed saved requests can still be confirmed |
A joining lock alone prevents new seats. Existing seats can reconnect, recover
or confirm an already completed join. Neither flag removes players, cards,
forces or pending choices. Resume preserves the game and gives existing AI seats
a fresh 1.5-second pacing deadline; it does not settle a player's decision.
## Persistence, authority and retries
The additive [migration](../drizzle/0009_admin_room_controls.sql) stores flags in
`room_controls`, separate from game JSON. A control change, room-version fence
and durable `admin_room_audit` receipt commit together. The audit records actor,
room, time, reason, expected revision and previous/new flags; it contains no
cards, credentials or raw game state. Audit browsing remains unfinished.
Untouched rooms retain their existing player-view shape; an absent control field
means running with joins open. After the first control change, player views keep
the public flags and revision, including after resume. Administrator reads always
return explicit defaults. Operational settings never enter saved game JSON.
The [HTTP endpoint](../app/api/admin/rooms/[code]/control/route.ts) requires the
configured origin, administrator authentication and owner/operator permissions
for writes. `X-Dune-Admin-Id` binds a write to the displayed account, preventing
an old tab from applying that account's saved intent after another account signs
in. SQL rechecks live session, role and generation within the transaction.
Each request has an operation ID, expected control revision, desired flags and
reason. Exact retries confirm the receipt and return current settings without
reapplying old flags. Conflicting revisions or reused IDs cannot overwrite a
later change. The [client](../components/admin-room-controls.tsx) saves the exact
request in account/room-scoped tab storage before sending. Uncertain responses
keep explicit retry controls across refresh. Authentication failures retain the
original account's pending request for confirmation after sign-in. There is no
automatic mutation retry. Deliberately discarding an unreadable local record
does not cancel a server change.
## Verification and remaining gates
Focused in-memory tests execute production SQL for roles, revoked sessions,
stale/conflicting requests, replay, rollback, joined-seat receipts, worker/action
races, pause during AI sleep, recovery/handover and resume pacing. UI tests cover
pause guidance, disabled AI-start controls, available takeback, account-scoped
retry storage and directory filters.
Authenticated local HTTP acceptance uses dedicated QA rooms. A temporary local
transport loses one successful control response: the browser reads the paused
state, refresh keeps the exact request, and explicit retry confirms one audit
row. Player controls disable on pause and return on resume. Mobile controls were
inspected at 390 pixels with 16-pixel labels and a 44-pixel apply button. Existing
games were not reset or used for these operations.
`tools/verify-admin.mjs` creates one room for access checks. A dedicated operator
or owner QA key also creates one room for account binding, joining locks,
pause/takeback/resume and saved-seat checks. Cleanup restores that QA room's flags
and stops its owning human's autopilot. Original failures and cleanup failures
are recorded separately. Never pass a human operator's key. The isolated container
verifier provisions its own QA operator and runs this flow.
Source checks, container checks and deployed acceptance are separate evidence.
Production administrator provisioning still needs explicit access confirmation;
local success does not close that deployed gate.
+15 -1
View File
@@ -6,6 +6,20 @@ Expansion starts and full rules/publication acceptance remain gated.**
## Current checkpoint and work
Current implementation adds [administrator pause/resume and joining locks](ADMIN_ROOM_CONTROLS.md):
usable controls, availability filters, player guidance, stopped human/AI
decisions, durable audit and account-bound exact retries. Recovery, discussion
and AI takeback remain available. Focused persistence, authenticated local HTTP
and desktop/mobile browser checks accompany the checkpoint. Remaining lifecycle
and full-admin requirements stay open; authenticated production acceptance waits
for the required QA-access confirmation.
Checkpoint `f29d056` was pushed and deployed to the NAS instance. Readable
create/join progress and Continue notices passed actual HTTPS browser acceptance,
including mobile and saved-seat refresh; existing production records survived
the update. Administrator sign-in renders closed by default. Authenticated admin
production checks remain pending provisioning approval.
The [readable-notice fix](READABLE_NOTICES.md) replaces the flashing recovery
screen during ordinary room creation/join with concise progress. Actual recovery
instructions stay until resolved, and completed-action text waits for a local
@@ -33,7 +47,7 @@ relevant real player/admin flows in dedicated QA rooms, and record deployed
results separately from local checks. See [production verification](VERIFICATION_WORKFLOW.md#verify-the-deployed-application).
This requirements update does not claim a new deployed test result.
Latest delivered checkpoint: `0f79f28`, [forced Harkonnen exchange return](HARKONNEN_EXCHANGE.md).
Earlier completed rules checkpoint: `0f79f28`, [forced Harkonnen exchange return](HARKONNEN_EXCHANGE.md).
Types, lint, **5,150 offline tests**, **49 HTTP tests** and the production build
passed. One complete Advanced sample had no rejected actions across 158 actions
and four JSON restores. Browser inspection and exact refresh were checked;
+11
View File
@@ -1,5 +1,16 @@
# Dune implementation status
## 22 September 2026 — Administrator room pause and joining locks
Added reversible pause/resume and joining-lock controls, availability filters
and public player notices. SQL fences cover joins, player actions, automatic
normalization and AI workers, including in-flight races. Saved-seat recovery,
handover, discussion and AI takeback remain available. Control changes and exact
receipts are audited atomically, with expected account binding protecting stale
administrator tabs. Local HTTP/browser evidence includes a lost successful
response, refresh, one-record replay and resume. See [scope and verification](ADMIN_ROOM_CONTROLS.md).
Full lifecycle, admin tools and authenticated deployed acceptance remain open.
## 22 September 2026 — Readable room entry and completed-action text
Normal create/join now shows concise pending text while the first request runs;