Repository navigation
Phase 3 Execution
Status: formal Phase 3 APPROVED at remote commit 2aff9506515dbe021d37b3b1671e8acb08461239, with 99% accuracy and 99% completeness from independent GPT-6 Astra/high review. Phase 4 entry is authorized; Phases 4–6 remain required and deployment remains Phase 7.
3A covers AC-24–28/30/51 and TR-09/10/18/31: ordered membership, observer promotion into the final slot only after a departure from a full waiting room, stable arrival ties, compaction, two-minute reconnect retention and 30-minute empty-room expiry. Tests use deterministic clocks and interleaved commands, followed by actual Postgres persistence/race checks.
3B covers AC-30–33: player-only readiness, the unchanged-lobby 30-second prompt, five-second holdout warning, exactly-two retention, larger-room removal, atomic 10-second countdown/roster lock, and close below two original members at expiry. Every mutation reschedules outstanding deadlines against its committed version without extending unrelated intervals. Stale jobs have no effect. Durable leased jobs and canonical command IDs make dispatcher retries safe; production cron wiring remains Phase 7.
Validation will include domain/application fake-clock boundary and race tests, API authorization, browser controls and actual database deadline claims/commits. Existing mock-oracle assertions remain unchanged. Gameplay after countdown belongs to Phase 4; no game-completion or deployment claim is made here.
domain/lobby.ts contains pure transitions and absolute-time catch-up. Deadlines are ordered by due time, with reconnect expiry preceding readiness/countdown decisions at equal times. A delayed worker uses each deadline's original timestamp. All elapsed consequences collapse into one canonical aggregate version/event; state, event, new deadlines and command result commit together. Simultaneous player expiries remove their entire batch before readiness reconciliation. An earlier countdown followed by a later disconnect remains distinct from an equal-time abort.
LobbyService.act catches up under the room lock before deciding the requested action. If a late holdout was removed, catch-up remains durable even though their readiness request is rejected; the same command replays that failure. Admission rejects overdue consequential deadlines inside its own serialized decision, so a join cannot cancel expired removal or empty-room closure. Departure compacts surviving order and appends the earliest observer only when the waiting room was full. Equal arrival times use stable profile ID; arrival timestamps are normalized against existing observers when a server clock regresses. A followed player leaving never silently changes the observer's perspective.
Presence is a separate renewal intent: the server selects its current room version under the same lock, rechecks the verified actor's membership, and retains canonical command IDs. Concurrent heartbeats cannot starve another player through unrelated version changes. Browsers renew every 20 seconds independently of pending readiness retries. Missing heartbeats are detected after 45 seconds; this is detection latency. The disconnected player then retains the same membership/position for a full 120-second grace interval. An explicit disconnect starts that grace immediately. Late detection records lastSeenAt + 45s, and expiry uses that timestamp plus 120s, so worker delay does not extend retention. Neither presence nor idle prompts reset the membership/readiness activity timer.
Migration 006_lobby_deadlines.sql persists creation deadlines atomically and adds exclusive bounded job claims with 30-second leases and owner-scoped completion. A crash after commit is recovered through canonical job replay; stale versions are terminal no-ops. The private scheduler endpoint requires WORDPAIRS_SCHEDULER_SECRET (at least 32 characters); production scheduling is not provisioned. Cookie-authorized room reads also attempt bounded deadline/outbox progress, while every consequential player action enforces its own transactional boundary.
The room screen provides ready/unready, leave, idle prompt, holdout warning, countdown status, separate observer view and explicit retry for uncertain mutations. UI clocks are display-only and calibrated from server time. No browser timer mutates authoritative game state. The three-minute simulated browser retry journey keeps presence active while retaining the identical original readiness request.
Verified on 26 October 2026:
-
npm test: 428 tests in 22 files passed, with no failures/skips; includes 21 actual lobby policy/use-case tests and four lobby/scheduler API cases. -
npm run typecheckandnpm run lint: passed. -
npm run build: passed; local production compilation only. -
pwsh -File tests/integration/run-phase1.ps1 -Realtime: 18 actual Postgres tests in five files, two actual Realtime tests, and the SQL/RLS/retention/rollback/final-seat checks passed. Seven new persisted lobby cases cover promotion order, readiness/departure concurrency, leased-overdue holdout enforcement, claim ownership/recovery, role denial, creation retry, closed-code expiry and 12 repeated pairs of concurrent same-version heartbeat renewals. -
WORDPAIRS_BROWSER_PATH=/usr/bin/chromium npm exec playwright -- test --config playwright.phase3.config.ts: all eight journeys passed. The two Phase 3 journeys cover real multi-client readiness/lock/leave/abort and an uncertain readiness retry with three simulated minutes of continuing heartbeats.
The independent reviewer verified the exact GitHub commit and tree 06310ba41e116adb72b874b59153fd5330e9b579, matching all 151 leaf paths, modes, types and blob hashes to the local candidate. The reviewer independently passed all 428 tests, typecheck, lint, local production build, 18 actual PostgreSQL tests plus SQL checks, two actual Realtime tests and eight Chromium journeys. No unresolved material findings remain. The full request, rubric, output, resolved findings, scores and remote evidence are preserved in phase3_review_receipt.jsonl. The real Postgres/Realtime runner and browser fixtures represent separate evidence tiers. Browser HTTP boundaries are intercepted; the Phase 3 journeys run the actual lobby application/domain behind that test seam. They are not described as a deployed or live-provider full-stack acceptance run. The existing global AC oracle remains mock evidence, not proof that future gameplay has been implemented.
The MCP hook still reports missing marker, no-session, health-failed and empty failsafe path. No recovery success is claimed. No deployment, branch movement, live-account setup, GitHub Actions or release work occurred.
Generated from MCP requirements wiki export.
- Home
- Guest Game and GitHub Admin PWA
- Functional Requirements
- Technical Requirements
- Testing Requirements
- TR per FR Mapping
- Requirements Matrix
- Wordpairs
- Local Development
- Testing and Evidence
- Administration and Access Control
- Requirements Baseline v2.8
- Architecture Decision Record
- Architecture Design
- Architecture Patterns
- Content Moderation
- Deployment and Release Plan
- Acceptance Criteria Gap Analysis
- Acceptance Criteria Test Inventory
- Implementation Plan
- Phase 0 Execution
- Phase 0 Interface and Data Contracts
- Phase 1A Execution
- Phase 1 Execution
- Phase 2 Execution
- Phase 3 Execution
- Phase 4 Execution
- Phase 5 Execution
- Phase 6 Execution
- Optional Phase 6 Human Feedback
- Historical Chromium Crash Diagnosis
- Completed Coding Goal and Review Agreement
- Third Party Attributions
- Software Bill of Materials Contract
- Phone Installation and PWA
- Live Multiplayer Runtime and UI Integration
- UI Test Case Index
- UI Design Coverage
- UI Criterion Gaps
- UI Design Questions
- UI Test Persistence
- TEST-ACCESSIBLEGAMECONTROLS-044 UI Case
- TEST-ACLAUTHORIZATION-132 UI Case
- TEST-ADMINUI-136 UI Case
- TEST-AUTHORITATIVEANSWERHANDLING-045 UI Case
- TEST-BROWSEOPENLOBBIES-022 UI Case
- TEST-CATALOGVERSIONING-133 UI Case
- TEST-CATEGORYART-005 UI Case
- TEST-CATEGORYCHOICE-011 UI Case
- TEST-CATEGORYSUGGESTIONUNLOCK-019 UI Case
- TEST-CONFIGUREDCAPACITY-024 UI Case
- TEST-CONNECTIONRECOVERY-109 UI Case
- TEST-CONTENTVALIDATION-016 UI Case
- TEST-DEEPLINKJOINANDFULLROOM-026 UI Case
- TEST-FINALSTANDINGS-013 UI Case
- TEST-FIRSTCATEGORY-004 UI Case
- TEST-FREETIERQUOTAHANDLING-037 UI Case
- TEST-FULLROOMOBSERVER-027 UI Case
- TEST-GUESTPLAY-021 UI Case
- TEST-HINTPROGRESSION-009 UI Case
- TEST-HINTSCORING-007 UI Case
- TEST-HOLDOUTWARNINGANDREMOVAL-032 UI Case
- TEST-IDLELOBBYREADINESSPROMPT-033 UI Case
- TEST-INROUNDEMOJIREACTION-029 UI Case
- TEST-LANDINGPAGEPUBLICDATA-050 UI Case
- TEST-LIVESCORECARD-010 UI Case
- TEST-MODERATIONANDCATALOGBOUNDARY-047 UI Case
- TEST-NOHINTSOLVE-006 UI Case
- TEST-NOMINATIONELIGIBILITY-017 UI Case
- TEST-NOMINATIONMODERATION-114 UI Case
- TEST-NOMINATIONTHRESHOLDANDMODERATION-018 UI Case
- TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028 UI Case
- TEST-OIDCTOKENVALIDATION-046 UI Case
- TEST-OPENAIOIDCPROFILE-020 UI Case
- TEST-ORIENTATION-015 UI Case
- TEST-PLAYERLIMIT-002 UI Case
- TEST-PRECOUNTDOWNOBSERVERPROMOTION-030 UI Case
- TEST-PROFILEICON-003 UI Case
- TEST-PUBLICGAMELANDINGPAGE-043 UI Case
- TEST-PWAINSTALL-137 UI Case
- TEST-PWAPRIVACY-138 UI Case
- TEST-QUICKMATCH-023 UI Case
- TEST-READYCOUNTDOWNANDROSTERLOCK-031 UI Case
- TEST-ROOMINVITATIONS-025 UI Case
- TEST-ROOMJOINING-001 UI Case
- TEST-ROOMSYNC-139 UI Case
- TEST-ROUNDSUMMARY-012 UI Case
- TEST-SUGGESTIONREVIEW-115 UI Case
- TEST-TIMETIEBREAK-014 UI Case
- TEST-UNSOLVEDRESULT-008 UI Case
- UI Gap Decisions and Synchronization
- TEST-ACCESSIBILITYDETAILS-144 UI Case
- TEST-CANDIDATEHOLD-141 UI Case
- TEST-LOBBYMATCHING-117 UI Case
- TEST-NAVIGATIONDRAFTS-142 UI Case
- TEST-NOSOLVERFALLBACK-146 UI Case
- TEST-REQUESTFEEDBACK-143 UI Case
- TEST-RESPONSIVEMATRIX-145 UI Case
- TEST-REVIEWCHANGES-140 UI Case
- TEST-ROOMCODES-110 UI Case
- UI Gap Implementation Plan
- UI Gap Implementation and Evidence
- Contest Readiness
- Hostile Validation Evidence
- Category Artwork
- 10-Player Release Completion Plan
- Deadline Report and Token Accounting
- Deadline Report Supporting Evidence
- Deadline Timeline and Review Finding Analysis
- Stopped Wordpairs Release Handoff