{ "product": "PROD-WORDPAIRS", "workspace": "\u003Crepo\u003E", "layer": "layer-1", "readBackAtUtc": "2026-10-28T01:28:18.632921+00:00", "authority": "QBrain.AI", "records": { "currentLayer": { "key": "layer-1", "order": 1, "name": "Layer 1", "workspaceId": "\u003Crepo\u003E", "createdAtUtc": { "dateTime": "2026-10-27 10:10:25.440499", "utcDateTime": "2026-10-27 10:10:25.440499+00:00", "localDateTime": "2026-10-27 05:10:25.440499-05:00", "date": "2026-10-27 00:00:00", "day": 27, "dayOfWeek": "Tuesday", "dayOfYear": 300, "hour": 10, "millisecond": 440, "microsecond": 499, "nanosecond": 300, "minute": 10, "month": 10, "offset": "00:00:00", "totalOffsetMinutes": 0, "second": 25, "ticks": 639286926254404993, "utcTicks": 639286926254404993, "timeOfDay": 36625.4404993, "year": 2026 }, "updatedAtUtc": { "dateTime": "2026-10-27 10:10:25.440499", "utcDateTime": "2026-10-27 10:10:25.440499+00:00", "localDateTime": "2026-10-27 05:10:25.440499-05:00", "date": "2026-10-27 00:00:00", "day": 27, "dayOfWeek": "Tuesday", "dayOfYear": 300, "hour": 10, "millisecond": 440, "microsecond": 499, "nanosecond": 300, "minute": 10, "month": 10, "offset": "00:00:00", "totalOffsetMinutes": 0, "second": 25, "ticks": 639286926254404993, "utcTicks": 639286926254404993, "timeOfDay": 36625.4404993, "year": 2026 } }, "functional": [ { "id": "FR-ACCESSCONTROL-024", "title": "Moderator and administrator access control", "body": "Allow authorized administrators to grant and revoke moderator, senior-moderator and administrator rights; bootstrap explicit existing profile IDs from server configuration.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: FR-24; canonical MCP ID: FR-ACCESSCONTROL-024. Confirmed user requests 27October2026; server env bootstrap was explicitly selected. No default administrator or human release gate was requested. Former provisional MCP ID: FR-WP-024. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "FR-24-C01", "text": "WORDPAIRS_ADMIN_PROFILE_IDS is a private server-only comma-separated allowlist of stable existing profile IDs. Empty configuration grants no bootstrap authority and aliases/browser input cannot grant access.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-24-C02", "text": "Moderators moderate and curate; senior moderators additionally resolve independent appeals; administrators additionally manage users. Proposer/original-reviewer independence remains enforced.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-24-C03", "text": "Roles are read from trusted current server/database evidence; configured administrator authority cannot be revoked in the UI and the final effective administrator cannot be removed, including concurrent cross-revocation.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-24-C04", "text": "Role changes atomically persist revision, canonical retry result and reasoned audit. Revoked administrators cannot replay old grants to regain authority; directories omit credentials, emails and OIDC subjects.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-ADMINPAGES-023", "title": "Administration pages", "body": "Provide dedicated pages for moderation, word-pair/hint management and user-role administration.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: FR-23; canonical MCP ID: FR-ADMINPAGES-023. Confirmed user requests 27October2026; server env bootstrap was explicitly selected. No default administrator or human release gate was requested. Former provisional MCP ID: FR-WP-023. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "FR-23-C01", "text": "Authorized staff can search/filter the moderation queue at /admin, approve/reject with reasons, review history and independently resolve permitted appeals.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-23-C02", "text": "/admin/words exposes search/category filters, authoring and immutable revision editing; /admin/users exposes bounded profile search, reasoned grants/revocations and role audit history.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-23-C03", "text": "Ordinary players cannot fetch privileged records or perform administrative writes; stale authorized GET responses cannot restore private data after an authorization denial.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-23-C04", "text": "Phone-sized forms and controls remain readable and operable; uncertain-write retries preserve command identity and clear successful drafts without duplicates.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-ANCHORSELECTION-007", "title": "Category selection", "body": "At game start, the service snapshots the active roster in roster order and indexes players from 1 through N. It draws a random integer from 1 through N, inclusive; the player with the matching index becomes the anchor and chooses the first round\u2019s category. The index remains stable for the match. After each round, the first correct solver chooses the next category. The game uses the earliest accepted correct submission to identify that player.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-07; canonical MCP ID: FR-ANCHORSELECTION-007. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-007. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-04", "text": "Given a new game with 2-25 players, when the game indexes the start roster from 1 through N and draws a random integer from 1 through N inclusive, then the player with that index becomes anchor; when that player chooses a category, the first round uses the chosen category and its background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-11", "text": "Given at least one player solves a round, when the round ends, then the earliest accepted correct solver can select the next category.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-02", "text": "No response and no solver: A missing answer counts as unsolved and advances to the next hint. After Hint 3 deadline the round reveals and awards zero to remaining players. If nobody solves, choose the next category uniformly from the six configured categories.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-ANSWERREVEAL-012", "title": "Round reveal", "body": "When a round ends, the game reveals the correct paired answer. Players who remain unsolved after Hint 3 receive zero points for that round.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-12; canonical MCP ID: FR-ANSWERREVEAL-012. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-012. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-08", "text": "Given a player remains unsolved after Hint 3, when the round ends, then the player earns 0 points and the game reveals the correct answer.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-45", "text": "Given an unsolved player submits an answer for the current stage, when the server checks it against the target and approved accepted-answer list, then only a correct answer is accepted and scored once for that stage; an incorrect answer does not change score or expose guess text to other players; and the target answer remains unavailable to clients until round reveal.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-02", "text": "No response and no solver: A missing answer counts as unsolved and advances to the next hint. After Hint 3 deadline the round reveals and awards zero to remaining players. If nobody solves, choose the next category uniformly from the six configured categories.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-ANSWERSTAGES-008", "title": "Answer stages", "body": "The first answer stage has no hint. Each unsolved player gets one submission per stage. Once all unsolved players submit, the game confirms stage results and reveals the next predefined hint only to those who remain unsolved. This repeats for up to three hints.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-08; canonical MCP ID: FR-ANSWERSTAGES-008. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-008. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-06", "text": "Given a player submits the correct answer during the no-hint stage, when the game accepts it, then the player earns 5 points and their round score locks.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-07", "text": "Given a player solves after Hint 1, Hint 2, or Hint 3, when the game accepts the answer, then the player earns 3, 2, or 1 point respectively.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-08", "text": "Given a player remains unsolved after Hint 3, when the round ends, then the player earns 0 points and the game reveals the correct answer.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-09", "text": "Given multiple unsolved players, when all unsolved players submit for the current stage, then the game confirms stage results and shows the next hint only to players still unsolved.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-45", "text": "Given an unsolved player submits an answer for the current stage, when the server checks it against the target and approved accepted-answer list, then only a correct answer is accepted and scored once for that stage; an incorrect answer does not change score or expose guess text to other players; and the target answer remains unavailable to clients until round reveal.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-01", "text": "Match length and stage timer: Eight rounds. Each of the four answer stages has a 20-second deadline; a stage closes early when all unsolved players submit.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-02", "text": "No response and no solver: A missing answer counts as unsolved and advances to the next hint. After Hint 3 deadline the round reveals and awards zero to remaining players. If nobody solves, choose the next category uniformly from the six configured categories.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-CANDIDATEHOLD-028", "title": "Hold and resume nomination review", "body": "Allow independent moderators to pause pending nomination review without losing counts or implying approval.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \"Fill gaps\", 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-IMPLEMENTATION FR-CANDIDATEHOLD-028\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION FR-CANDIDATEHOLD-028", "acceptanceCriteria": [ { "id": "UI-HOLD-01", "text": "An independent moderator with a nonempty reason can move a pending candidate to on_hold; unauthorized actors and the proposer cannot do so.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-HOLD-02", "text": "on_hold retains nominations and history but prevents approval/publication/playability and never changes current scores or progression.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-HOLD-03", "text": "An independent moderator resumes with a reason to pending_review after rechecking unique-count threshold; hold/resume actor and reasons are audited.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-CATEGORIES-005", "title": "Relationship categories", "body": "The initial category set supports Heroes and Villains, Colors, Year and Event, Director and Movie, Singer and Song, and Opposites. Each pair belongs to one category.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-05; canonical MCP ID: FR-CATEGORIES-005. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-005. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-04", "text": "Given a new game with 2-25 players, when the game indexes the start roster from 1 through N and draws a random integer from 1 through N inclusive, then the player with that index becomes anchor; when that player chooses a category, the first round uses the chosen category and its background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-05", "text": "Given two word pairs in the same category, when each is played, then both rounds use that category\u2019s predefined background. A pair in another category uses that category\u2019s background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-16", "text": "Given a category is enabled, when the content catalog is checked, then every playable pair has a prompt, target answer, three ordered hints, accepted-answer policy, and category background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-06", "text": "Colors category: Each Colors pair contains complementary colors.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-CATEGORYART-006", "title": "Category backgrounds", "body": "Each category maps to one predefined background asset. All word pairs in the same category use that background. The background must remain legible behind the prompt, hints, answer field, and scorecard.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-06; canonical MCP ID: FR-CATEGORYART-006. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-006. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-05", "text": "Given two word pairs in the same category, when each is played, then both rounds use that category\u2019s predefined background. A pair in another category uses that category\u2019s background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-44", "text": "Given a player uses a phone-sized viewport in portrait or landscape, when they operate primary game actions with touch or keyboard and view text over category backgrounds, then the actions remain operable, text and controls retain clear contrast, focus is visible, and selected icon, solved status, and score changes are indicated by labels or shapes as well as color.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-CATEGORYSUGGESTIONS-017", "title": "Category and pair suggestions", "body": "After a player profile has won 10 games over its lifetime, the player can have one open suggestion at a time: one new relationship category with exactly three word pairs. Suggestions enter review and moderation; approval does not bypass the existing curated-content requirements. Approved pairs become eligible for future games only after their complete content records and category background are ready.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-17; canonical MCP ID: FR-CATEGORYSUGGESTIONS-017. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-017. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-19", "text": "Given a player has fewer than 10 game wins, when they open the content suggestion flow, then category-and-pair submission is unavailable. Given they have won 10 games, then they can submit one proposed relationship category with three word pairs for review. The submission is not playable until approved and complete.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-47", "text": "Given an actor is not authorized to perform moderation or catalog activation, when they attempt to change moderation status or publish content, then the service rejects the action; every change to nomination count, moderation status, and eligibility is auditable; and content cannot be selected for play until it has passed moderation and is complete in the curated catalog.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-08", "text": "Moderation workflow: Roles are Content Moderator and Senior Moderator. At threshold, content enters Pending Review. A moderator other than the proposer approves or rejects with a reason. The proposer may appeal once to a Senior Moderator. Approval alone does not make content playable; the complete curated record must pass validation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-09", "text": "Suggestion eligibility: Wins are lifetime wins on one stable profile. A profile may have one open category suggestion at a time; each contains one category and exactly three pairs.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-CURATEDPAIRS-004", "title": "Predefined content", "body": "Every playable word pair has a predefined category, prompt word, target answer, and three ordered hints. The game uses this content at runtime and does not generate prompts or hints dynamically.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-04; canonical MCP ID: FR-CURATEDPAIRS-004. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work.\n\nInitial content/identity/nomination/suggestion record contract preserved verbatim:\nEach content record keeps the prompt, answer, hints, accepted alternatives, and category reference together so each round is deterministic.\n\n| Field | Requirement |\n|---|---|\n| `pair_id` | Unique stable identifier for the word pair. |\n| `category_id` | Relationship category identifier. |\n| `prompt_word` | Word displayed to players at round start. |\n| `target_answer` | Canonical paired answer, held by the server until reveal. |\n| `accepted_answers` | Explicit alternative spellings or forms accepted as correct. |\n| `hints` | Exactly three ordered, predefined hint strings. |\n| `background_id` | Reference to the category\u2019s predefined background asset. |\n\nA player identity record stores the selected entry mode (OpenAI OIDC or guest), the profile reference, generated public alias, leaderboard opt-out, and selected icon. Authenticated profiles are associated with the validated OIDC subject; guest identity persists in the same browser/device until site data is cleared.\n\nNomination records include the normalized candidate word, nominating player, submission timestamp, moderation status, nomination count, and future-pool eligibility state. A nominated word does not replace the required fields in a playable word-pair record.\n\nCategory suggestion records include the submitting player, proposed relationship category, exactly three proposed word pairs, submission timestamp, win-unlock evidence, and review status. Each proposed pair must be completed with the fields above before it can be played. Former provisional MCP ID: FR-WP-004. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-16", "text": "Given a category is enabled, when the content catalog is checked, then every playable pair has a prompt, target answer, three ordered hints, accepted-answer policy, and category background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-05", "text": "Content volume and reuse: Seed 10 complete pairs per category. Do not repeat a pair within a match until every playable pair in the selected category has been used; then reshuffle that category\u2019s eligible pool.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-FINALSTANDINGS-014", "title": "Game end and tiebreak", "body": "A match contains eight rounds. When the eighth round ends, the game displays final standings. If the highest score is tied, sum each player\u2019s accepted solve durations and add 80 seconds for each unsolved round; the lowest total ranks first. Players still tied share the same rank.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-14; canonical MCP ID: FR-FINALSTANDINGS-014. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-014. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-13", "text": "Given the configured final round ends, when players have different total scores, then final standings rank them by total score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-14", "text": "Given two or more players tie for the highest score, when final standings are calculated, then total answer time is the sum of each round\u2019s accepted solve duration, with 80 seconds charged for an unsolved round; the lower total ranks first, and an exact tie shares the same rank.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-01", "text": "Match length and stage timer: Eight rounds. Each of the four answer stages has a 20-second deadline; a stage closes early when all unsolved players submit.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-04", "text": "Total answer time and final tie: Sum server-measured solve durations; an unsolved round adds the 80-second maximum round duration. Sort tied scores by this total; exact remaining ties share rank.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-IDENTITY-018", "title": "Identity modes", "body": "Before creating or joining a room, a player can authenticate with OpenAI OIDC to establish or load a game profile, or continue as a guest. Both modes provide the player identity needed for room membership and allow icon selection. A guest profile persists in the same browser/device until site data is cleared; it does not sync across devices or link to an OIDC profile.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: FR-18; canonical MCP ID: FR-IDENTITY-018. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-018. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-20", "text": "Given a player chooses account sign-in, when OpenAI OIDC authentication succeeds, then the game establishes or loads the game profile associated with that authenticated identity and allows the player to select an icon.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-21", "text": "Given a player chooses guest mode, when they continue without OIDC authentication, then the game creates a guest player identity, allows icon selection, and lets them create or join a room by code.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-46", "text": "Given an OIDC identity provider is configured, when a sign-in callback presents a token with an invalid signature, issuer, audience, state, nonce, or expiry, then the service rejects the sign-in and does not create or associate an authenticated profile from the unverified identity.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-10", "text": "OIDC provider: Keep OpenAI OIDC as specified in FR-02/FR-18/AC-20/46, using Authorization Code with PKCE and verified OIDC claims. Provider registration/entitlement is an external integration prerequisite, not an AC test oracle or deployed-artifact AC.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." }, { "id": "DEC-11", "text": "Guest profile and labels: A guest profile persists in the same browser/device until site data is cleared; it does not sync or link to an OIDC profile. Every profile gets a generated public alias; users can change it or opt out of leaderboard display. Real identity claims are never public.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-LIVESCORECARD-011", "title": "Live round scorecard", "body": "The active round page shows every player and updates a player\u2019s row when they solve. A solved row shows the player icon, points earned in the current round, and elapsed answer time. Incorrect guess text is not exposed to other players.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-11; canonical MCP ID: FR-LIVESCORECARD-011. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-011. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-10", "text": "Given a player solves, when the game accepts the answer, then the active scorecard shows that player\u2019s icon, points earned, and elapsed time from round start.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-LOBBYDISCOVERY-019", "title": "Lobby discovery and matching", "body": "Players can browse discoverable open lobbies or use quick match to join an available lobby for this game. Any player in a room can share its room code or deep link to invite others; a deep link bypasses lobby browsing. Joining as a player requires an available slot under the configured capacity. An invited player who reaches a full room can choose observer mode. Before the game start countdown begins, if a player leaves a full room, the oldest observer is promoted into the final player position and the remaining players move up to close the vacancy. If player/observer membership or readiness has not changed for 30 seconds before countdown, all players are prompted once for that room version to mark ready; any such change resets the interval. When all but one player have marked ready, the holdout receives a five-second warning. If they mark ready before it expires, the countdown begins immediately. If the warning expires while the holdout remains unready in a room with more than two players, they are removed and the countdown begins. In an exactly two-player lobby, the holdout remains and the lobby waits without starting the countdown until both players are ready. The roster locks when the countdown begins, and a player who leaves afterward is not replaced. Rooms are private by default; the creator may enable discoverability. Quick match selects the oldest eligible room, breaking equal creation times by stable room ID. These joins use the same atomic capacity check.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-19; canonical MCP ID: FR-LOBBYDISCOVERY-019. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-019. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-22", "text": "Given a discoverable lobby is waiting and has fewer players than its configured capacity, when a player browses lobbies, then the lobby appears as joinable; hidden, full, or started lobbies do not appear as joinable.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-23", "text": "Given at least one discoverable lobby has an available player slot, when a player uses quick match, then the service assigns them to the oldest eligible lobby, breaking equal creation times by stable room ID, without exceeding configured capacity. Given none is available, then the player is offered browsing or room creation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-25", "text": "Given a player is in a room, when they share its room code or deep link, then another player can use either invitation to reach the intended room, subject to an open slot.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-26", "text": "Given a valid room deep link, when a player opens it, then the game bypasses lobby browsing and checks the room directly. If a slot is open, the player joins; if the room has no open player slot, the invitee is offered observer mode.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-30", "text": "Given a room is full and the start countdown has not begun, when a player leaves and at least one observer is waiting, then the observer who entered observer mode earliest becomes the final player in the roster, existing players move up to close the vacancy while preserving their relative order, and any remaining observers stay observers.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-31", "text": "Given every player in the room has marked ready, when the final ready state is received, then the game start countdown begins immediately and the player roster locks. If a player leaves after the countdown begins, then no observer or other player is promoted or substituted into that player\u2019s place.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-32", "text": "Given all but one player have marked ready, when the room enters the holdout state, then the unready player sees a five-second warning to mark ready. If they mark ready before it expires, the start countdown begins immediately. If the warning expires while they remain unready in a room with more than two players, they are removed and the start countdown begins with the remaining roster locked. If the room has exactly two players, the holdout is not removed and the lobby continues waiting; the countdown does not begin until both are ready.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-33", "text": "Given the game start countdown has not begun, when no player/observer membership or ready-state change occurs for 30 seconds, then the game prompts all players once for that room version to mark themselves ready; any membership or ready-state change resets the interval.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-12", "text": "Lobby discovery and quick match: Rooms are undiscoverable by default; creator may opt in. Quick match selects the oldest discoverable waiting room with a free seat, then stable room ID. The same atomic capacity-checked join command handles the selection.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-LOBBYLIFECYCLE-003", "title": "Lobby", "body": "The room view displays the room code, configured maximum capacity, available player slots, current players, and observers separately. A game cannot start with fewer than 2 players. Any player in the room can invite others by sharing its code or deep link. The room identifies the anchor player. Before the game start countdown begins, when a player leaves a full room, the oldest observer is promoted into the final player position and the remaining players move up to close the vacancy. If the lobby aggregate has no membership or readiness change for 30 seconds before the start countdown, all players are prompted once for that unchanged state version to mark themselves ready; any membership or readiness change resets the idle interval. When all but one player have marked ready, the holdout receives a five-second warning to mark ready. If they mark ready before it expires, the countdown begins immediately. If the warning expires in a lobby of more than two players and the holdout remains unready, they are removed and the countdown begins with the remaining roster locked. In an exactly two-player lobby, the holdout remains and the lobby waits without starting the countdown until both players are ready. The roster locks when the countdown begins; a player who leaves afterward is not replaced. The room creator has no special readiness or start authority; every player has the same lobby controls. Rooms are private by default; the creator may enable discovery. Quick match selects the oldest eligible room with a free seat and uses stable room ID to break ties. A 10-second countdown begins when all active players are ready. If a player leaves after countdown begins, nobody replaces them. If fewer than two original players remain when the countdown expires, the game is aborted and the room closes.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-03; canonical MCP ID: FR-LOBBYLIFECYCLE-003. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-003. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-01", "text": "Given a valid room code and 2-25 players on separate devices, when each joins, then every joined player appears in the same room with their selected icon.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-02", "text": "Given a room has reached its configured player capacity from 2 through 25, when another player attempts to join, then the game rejects the additional player without changing existing room state. This is true for any configured capacity, including 2, 8, and 25.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-24", "text": "Given a player creates a room, when they set a maximum capacity from 2 through 25, then the room stores and displays that limit. Values below 2 or above 25 are rejected.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-25", "text": "Given a player is in a room, when they share its room code or deep link, then another player can use either invitation to reach the intended room, subject to an open slot.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-26", "text": "Given a valid room deep link, when a player opens it, then the game bypasses lobby browsing and checks the room directly. If a slot is open, the player joins; if the room has no open player slot, the invitee is offered observer mode.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-27", "text": "Given an invited player follows an invitation to a full room, when they choose to observe, then they enter without consuming a player slot and are bound to the player who invited them.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-30", "text": "Given a room is full and the start countdown has not begun, when a player leaves and at least one observer is waiting, then the observer who entered observer mode earliest becomes the final player in the roster, existing players move up to close the vacancy while preserving their relative order, and any remaining observers stay observers.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-31", "text": "Given every player in the room has marked ready, when the final ready state is received, then the game start countdown begins immediately and the player roster locks. If a player leaves after the countdown begins, then no observer or other player is promoted or substituted into that player\u2019s place.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-32", "text": "Given all but one player have marked ready, when the room enters the holdout state, then the unready player sees a five-second warning to mark ready. If they mark ready before it expires, the start countdown begins immediately. If the warning expires while they remain unready in a room with more than two players, they are removed and the start countdown begins with the remaining roster locked. If the room has exactly two players, the holdout is not removed and the lobby continues waiting; the countdown does not begin until both are ready.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-33", "text": "Given the game start countdown has not begun, when no player/observer membership or ready-state change occurs for 30 seconds, then the game prompts all players once for that room version to mark themselves ready; any membership or ready-state change resets the interval.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-14", "text": "Host authority and countdown: Creator has no special start/readiness privilege. All players have equivalent controls. All-ready starts a 10-second countdown and locks the roster.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-15", "text": "Countdown departure below minimum: Never replace a player who leaves after lock. If fewer than two original players remain at countdown expiry, abort start and close the room.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-16", "text": "Idle prompt and readiness races: The 30-second interval resets on player/observer membership or ready-state changes. Prompt once per unchanged aggregate version. Deadlines carry the expected version; stale jobs are no-ops.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-NAVIGATIONDRAFTS-029", "title": "Predictable navigation and private drafts", "body": "Make Back, Cancel, draft retention and explicit room departure predictable without implicit mutations.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \"Fill gaps\", 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-IMPLEMENTATION FR-NAVIGATIONDRAFTS-029\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION FR-NAVIGATIONDRAFTS-029", "acceptanceCriteria": [ { "id": "UI-NAV-01", "text": "Back returns to the previous authorized screen and dialog dismissal restores focus to its opener without submitting, changing readiness or leaving room membership.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-02", "text": "Unsaved content/editor drafts survive ordinary same-profile in-tab navigation in memory only; reload, tab close, session/profile change and permission loss clear them.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-03", "text": "Explicit Cancel/Discard abandons the draft and returns to the originating screen without changing the saved record; a canceled profile edit restores saved alias/icon.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-04", "text": "Leaving a room requires an explicit Leave action and applies the existing authoritative membership/departure rules.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-05", "text": "Returning to a privileged screen revalidates authorization; back navigation cannot restore cleared private data or another profile's draft.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-NOMINATIONS-016", "title": "Future answer nominations", "body": "A player who correctly solves during the no-hint stage may nominate a word as a candidate answer for future games. The game records nominations by candidate word. A candidate becomes eligible for the future answer pool only after it has at least 10 nominations and passes moderation. Before it is playable, content editors must create a complete curated pair record with the required prompt, category, hints, accepted answers, and category background. Nominations do not affect current-round scoring or progression.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-16; canonical MCP ID: FR-NOMINATIONS-016. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-016. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-17", "text": "Given a player solves during the no-hint stage, when the round results are shown, then that player can submit a candidate answer nomination; players who solve after any hint cannot nominate from that round.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-18", "text": "Given a candidate has fewer than 10 nominations or has not passed moderation, when the answer pool is checked, then it is not eligible for future games. Given it has at least 10 nominations and passes moderation, then it enters the future-eligible answer pool but is not playable until its full curated pair record exists.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-47", "text": "Given an actor is not authorized to perform moderation or catalog activation, when they attempt to change moderation status or publish content, then the service rejects the action; every change to nomination count, moderation status, and eligibility is auditable; and content cannot be selected for play until it has passed moderation and is complete in the curated catalog.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-07", "text": "Nomination counting: Count unique player profiles per normalized candidate. A profile may nominate a candidate once and submit at most one candidate per eligible no-hint solve. Moderation begins at 10 unique nominations.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-08", "text": "Moderation workflow: Roles are Content Moderator and Senior Moderator. At threshold, content enters Pending Review. A moderator other than the proposer approves or rejects with a reason. The proposer may appeal once to a Senior Moderator. Approval alone does not make content playable; the complete curated record must pass validation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-OBSERVERS-020", "title": "Full-room observer mode", "body": "If an invited player attempts to join a room with no open player slot, the invitee may choose to observe the game in real time from the perspective of the player who invited them. Observer mode does not take a player slot, submit answers, make category choices, or earn points. The observer sees only the game information available to the followed player. Before the game start countdown begins, if a player leaves a full room, the observer who entered earliest is promoted to the final player position; the other players move up to close the vacancy. Remaining observers keep their observer status. When all but one player have marked ready, the holdout receives a five-second warning to mark ready. If all players mark ready before expiry, the countdown begins immediately. If the warning expires in a room with more than two players while the holdout remains unready, they are removed and the countdown begins. In an exactly two-player lobby, the holdout remains and the lobby waits without starting the countdown until both players are ready. The roster locks when the countdown begins. If a player leaves after countdown begins, no observer or other player replaces them; if fewer than two original players remain at expiry, the game start is aborted and the room closes.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-20; canonical MCP ID: FR-OBSERVERS-020. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-020. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-27", "text": "Given an invited player follows an invitation to a full room, when they choose to observe, then they enter without consuming a player slot and are bound to the player who invited them.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-28", "text": "Given an observer is following an inviter, when the inviter\u2019s player-authorized view changes, then the observer sees the corresponding update in real time. Observer attempts to submit guesses, choose categories, or change game state are rejected; the observer earns no score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-30", "text": "Given a room is full and the start countdown has not begun, when a player leaves and at least one observer is waiting, then the observer who entered observer mode earliest becomes the final player in the roster, existing players move up to close the vacancy while preserving their relative order, and any remaining observers stay observers.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-13", "text": "Observer behavior: Maximum 25 observers per room. Signed links bind the inviter. Manual room-code observers select an active player as inviter. Observer arrival order is assigned transactionally; ties use stable profile ID.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-PHONEINSTALL-026", "title": "Phone home-screen installation", "body": "Wordpairs must be installable from supported phone browsers, launch standalone into /play with project branding, offer native install action when available and manual platform guidance otherwise, and show a safe reconnect screen offline without retaining private game data.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Source: user request2026-10-27: The game needs to be installable as a PWA on phones. Design and criteria: docs/pwa_design.md. Browser/worker evidence does not establish installation on physical Android/iPhone hardware. HostedHTTPS deployment remains future operational work.", "acceptanceCriteria": [ { "id": "PWA-01", "text": "Manifest has stable identity, standalone launch at /play, root scope, names, colors, same-origin192/512 icons and a separate maskable icon.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-02", "text": "Referenced PNGs have declared dimensions, opaque brand background and safe-zone maskable artwork; Apple metadata and touch icon exist.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-03", "text": "Secure-context registration succeeds at root scope, handles failure gracefully and uses fresh worker script headers.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-04", "text": "A captured install event prompts once after a click; dismissal/rejection preserves guidance; installed/standalone state hides install UI and listeners clean up.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-05", "text": "Phone install guidance covers iPhone Share and Android menus, explains HTTPS on insecure origins, and fits narrow screens accessibly; physical home-screen installation is not claimed by emulation.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-06", "text": "Offline controlled navigation returns a static reconnect screen; returning online restores the live website.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-07", "text": "API/auth/realtime/private navigation and mutations are never stored in worker caches; offline API/mutation requests fail without receiving offline HTML.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-08", "text": "Only old versioned Wordpairs static caches are cleaned up; service-worker updates do not force activation or reload during a match.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-PLAYERPROFILE-002", "title": "Player profile", "body": "Each player can select an icon in their game profile before or while joining a room. The selected icon appears consistently in the room, live scorecard, round summary, and final standings. Players receive a generated public alias; a player may change the alias or opt out of public leaderboard display. Real identity-provider names are never public. Players may establish a profile by authenticating with OpenAI OIDC or enter as a guest.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-02; canonical MCP ID: FR-PLAYERPROFILE-002. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-002. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-03", "text": "Given a player selects an icon, when that player enters the lobby and plays a round, then the same icon appears in the lobby, live scorecard, and standings.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-20", "text": "Given a player chooses account sign-in, when OpenAI OIDC authentication succeeds, then the game establishes or loads the game profile associated with that authenticated identity and allows the player to select an icon.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-21", "text": "Given a player chooses guest mode, when they continue without OIDC authentication, then the game creates a guest player identity, allows icon selection, and lets them create or join a room by code.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-11", "text": "Guest profile and labels: A guest profile persists in the same browser/device until site data is cleared; it does not sync or link to an OIDC profile. Every profile gets a generated public alias; users can change it or opt out of leaderboard display. Real identity claims are never public.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-PUBLICLANDING-022", "title": "Public landing page", "body": "An unauthenticated visitor can open the game landing page and view an approved leaderboard, public lobby information, and the gameplay rules. Lobby information is limited to approved public metadata for discoverable, joinable rooms and cannot expose private room codes, hidden answers, guesses, observer-only views, or credentials. The leaderboard uses lifetime wins, total points, earliest win, then stable profile ID; it displays generated aliases and honors opt-out. Public lobby cards expose exact player count/capacity, waiting state, and room age, with a 15-second refresh. The rules summary is concise and versioned.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-22; canonical MCP ID: FR-PUBLICLANDING-022. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-022. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-43", "text": "Given an unauthenticated visitor opens the game landing page, when the page loads, then it presents an all-time leaderboard ranked by lifetime wins, total points, earliest win, and stable profile ID; discoverable lobby cards with exact player count/capacity, waiting state, and room age; and a concise versioned rules summary. It uses generated public aliases, honors opt-outs, excludes room codes and private room/game data, and provides usable empty/unavailable states.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-50", "text": "Given an unauthenticated visitor requests landing-page data, when the service responds, then it returns only lifetime-win ranking fields, opted-in generated aliases, exact counts/capacity, waiting state, room age, and rules version for public content; it does not expose room codes, real identity, guesses, target answers, observer-only views, moderation records, or secrets.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-19", "text": "Public landing contract: Leaderboard is lifetime wins, then total points, earliest win, and stable profile ID. Show public alias only, include opt-in guests, honor profile opt-out. Lobby card shows exact player count/capacity, waiting state and room age, never room code/player names. Refresh lobby data every 15 seconds and leaderboard every five minutes. Rules are a concise versioned summary with an updated date.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-REACTIONS-021", "title": "Emoji reactions", "body": "During any active round, a player can open an emoji menu and display a selected emoji reaction to the room in real time. Reactions do not submit an answer, change round state, or affect scoring. Observers see reactions displayed by the player they are following and reactions broadcast to the room.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-21; canonical MCP ID: FR-REACTIONS-021. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-021. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-29", "text": "Given a round is active, when a player selects an emoji from the menu, then the reaction appears in real time to room players and observers and does not change scores, answer stage, or round state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-18", "text": "Reactions: Menu: \ud83d\udc4d, \u2764\ufe0f, \ud83d\ude02, \ud83c\udf89, \ud83d\udc40. A reaction is visible for five seconds; one reaction per player per two seconds. It cannot change game state or score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-REQUESTFEEDBACK-030", "title": "Accessible request feedback and safe retry", "body": "Specify loading, empty, failed, uncertain-write, conflict and denied UI outcomes without losing safe user input or duplicating commands.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \"Fill gaps\", 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-IMPLEMENTATION FR-REQUESTFEEDBACK-030\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION FR-REQUESTFEEDBACK-030", "acceptanceCriteria": [ { "id": "UI-FEEDBACK-01", "text": "Pending reads expose accessible loading feedback; empty results are distinct from unavailable results and offer an allowed next action.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-02", "text": "Pending mutations show busy feedback and prevent duplicate submission while preserving entered data.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-03", "text": "Failures show a user-safe explanation and valid Retry action while retaining safe drafts; raw errors, credentials and private data are not exposed.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-04", "text": "An uncertain-write retry uses identical command identity/payload; conflicts refresh authoritative state without silently replaying a changed command or claiming success.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-05", "text": "Authorization denial clears privileged data/drafts and rejects stale response restoration; connection recovery retains accepted state without duplicate writes.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-RESPONSIVEUI-015", "title": "Responsive screens", "body": "Profile, lobby, active round, hint stage, scorecard, round summary, category picker, and final standings remain usable on phone-sized screens in portrait and landscape orientation.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-15; canonical MCP ID: FR-RESPONSIVEUI-015. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-015. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-15", "text": "Given a phone-sized viewport in portrait or landscape, when a player enters an answer or views a hint and scorecard, then text and controls remain visible without horizontal overflow.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-44", "text": "Given a player uses a phone-sized viewport in portrait or landscape, when they operate primary game actions with touch or keyboard and view text over category backgrounds, then the actions remain operable, text and controls retain clear contrast, focus is visible, and selected icon, solved status, and score changes are indicated by labels or shapes as well as color.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-REVIEWCHANGES-027", "title": "Request and resubmit category changes", "body": "Provide a reasoned independent change-request workflow for category suggestions without bypassing curation.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \"Fill gaps\", 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-IMPLEMENTATION FR-REVIEWCHANGES-027\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION FR-REVIEWCHANGES-027", "acceptanceCriteria": [ { "id": "UI-CHANGES-01", "text": "An independent moderator requests changes with a nonempty reason; the suggestion enters changes_requested and remains unplayable.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-CHANGES-02", "text": "changes_requested consumes the proposer's one-open-suggestion slot; another open suggestion is rejected.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-CHANGES-03", "text": "Only the proposer can edit and resubmit exactly three pair suggestions; valid resubmission enters pending_review and still requires independent review and complete curation.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-CHANGES-04", "text": "Revision, reason, actor and status transitions are auditable; a change request does not consume the rejection appeal allowance.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-ROOMACCESS-001", "title": "Room access", "body": "Players can create a room and set its maximum player capacity from 2 through 25, inclusive. Players can join from their own device by room code, discoverable-lobby browsing, quick match, or a deep link containing the room code. Joining as a player requires an available slot under the room\u2019s configured capacity. If the room is full, an invited player can choose observer mode.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-01; canonical MCP ID: FR-ROOMACCESS-001. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-001. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-01", "text": "Given a valid room code and 2-25 players on separate devices, when each joins, then every joined player appears in the same room with their selected icon.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-02", "text": "Given a room has reached its configured player capacity from 2 through 25, when another player attempts to join, then the game rejects the additional player without changing existing room state. This is true for any configured capacity, including 2, 8, and 25.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-24", "text": "Given a player creates a room, when they set a maximum capacity from 2 through 25, then the room stores and displays that limit. Values below 2 or above 25 are rejected.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-25", "text": "Given a player is in a room, when they share its room code or deep link, then another player can use either invitation to reach the intended room, subject to an open slot.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-26", "text": "Given a valid room deep link, when a player opens it, then the game bypasses lobby browsing and checks the room directly. If a slot is open, the player joins; if the room has no open player slot, the invitee is offered observer mode.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-ROUNDSUMMARY-013", "title": "Round summary", "body": "After every round, the game displays a ranking of all players by cumulative score. It also shows the points and elapsed time earned in the completed round.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-13; canonical MCP ID: FR-ROUNDSUMMARY-013. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-013. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-12", "text": "Given a round ends, when the summary appears, then it ranks all players by current cumulative score and shows the completed round\u2019s points and solve times.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-SCORELOCK-010", "title": "Score lock and elapsed time", "body": "When a player submits a correct answer, the game locks that player\u2019s score for the round and records elapsed time from round start to the accepted correct submission.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-10; canonical MCP ID: FR-SCORELOCK-010. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-010. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-06", "text": "Given a player submits the correct answer during the no-hint stage, when the game accepts it, then the player earns 5 points and their round score locks.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-07", "text": "Given a player solves after Hint 1, Hint 2, or Hint 3, when the game accepts the answer, then the player earns 3, 2, or 1 point respectively.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-10", "text": "Given a player solves, when the game accepts the answer, then the active scorecard shows that player\u2019s icon, points earned, and elapsed time from round start.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-14", "text": "Given two or more players tie for the highest score, when final standings are calculated, then total answer time is the sum of each round\u2019s accepted solve duration, with 80 seconds charged for an unsolved round; the lower total ranks first, and an exact tie shares the same rank.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-45", "text": "Given an unsolved player submits an answer for the current stage, when the server checks it against the target and approved accepted-answer list, then only a correct answer is accepted and scored once for that stage; an incorrect answer does not change score or expose guess text to other players; and the target answer remains unavailable to clients until round reveal.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-SCORING-009", "title": "Scoring", "body": "The game awards 5 points for a correct answer before hints, 3 after Hint 1, 2 after Hint 2, and 1 after Hint 3. A player who remains unsolved after Hint 3 earns 0 points.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: FR-09; canonical MCP ID: FR-SCORING-009. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: FR-WP-009. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-06", "text": "Given a player submits the correct answer during the no-hint stage, when the game accepts it, then the player earns 5 points and their round score locks.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-07", "text": "Given a player solves after Hint 1, Hint 2, or Hint 3, when the game accepts the answer, then the player earns 3, 2, or 1 point respectively.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-08", "text": "Given a player remains unsolved after Hint 3, when the round ends, then the player earns 0 points and the game reveals the correct answer.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "AC-14", "text": "Given two or more players tie for the highest score, when final standings are calculated, then total answer time is the sum of each round\u2019s accepted solve duration, with 80 seconds charged for an unsolved round; the lower total ranks first, and an exact tie shares the same rank.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "FR-WORDHINTEDITOR-025", "title": "Manage word pairs and ordered hints", "body": "Authorized content staff can create and edit complete word pairs and hints while preserving playable catalog integrity and active/historical rounds.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: FR-25; canonical MCP ID: FR-WORDHINTEDITOR-025. Confirmed user requests 27October2026; server env bootstrap was explicitly selected. No default administrator or human release gate was requested. Former provisional MCP ID: FR-WP-025. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "FR-25-C01", "text": "Each pair has a prompt, canonical target, accepted alternatives, approved category/background and exactly three ordered bounded hints; invalid input is rejected without mutation.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-25-C02", "text": "Creation uses an unused ID at version0; edits append exactly the next version without moving an existing ID to another category. Community activation cannot reuse IDs or skip versions.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-25-C03", "text": "Current and historical rounds retain their recorded versions. Future selection chooses the highest version per ID and then selectability, with no fallback to older excluded versions.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-25-C04", "text": "Reasoned exclusion preserves history and cannot empty an initial category. Both editorial and community publication reject a projected total above4096 historical approved versions atomically.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" } ], "scopeStartLayerKey": "layer-1" } ], "technical": [ { "id": "TR-ACL-AUTHORIZATION-032", "title": "Server-authoritative ACL transactions", "body": "Enforce permissions in authenticated HTTP/application code and privileged SQL functions, with shared ACL locking for content writes and exclusive locking for role mutations. Validate identity/origin, strict allowlists, expected revision, digest/retry semantics and bounded private projections.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TR-32; canonical MCP ID: TR-ACL-AUTHORIZATION-032. Confirmed extension requirement; source docs/admin_acl_design.md, docs/admin_acl_review_receipt.json, tests/integration/multiplayer.integration.ts and user conversation. Former provisional MCP ID: TR-WP-GAME-032. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-32-C01", "text": "Forged actor IDs, browser roles, missing sessions and cross-origin writes are rejected; browser database roles have no direct ACL table/function privilege.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-32-C02", "text": "Serialize concurrent role changes and final-admin checks. A content writer blocked behind revocation must reload roles after the lock and deny a new revoked write.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-32-C03", "text": "Audit insertion failure rolls back role/revision/idempotency mutations; stale revisions and changed command digests fail without side effects; permitted exact replays do not reapply grants.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ANCHOR-RANDOMNESS-013", "title": "Anchor assignment", "body": "At game start, the service snapshots and indexes the active roster from 1 through N, where N is 2-25. It draws a random integer uniformly from 1 through N, inclusive, and assigns the matching player as anchor for the match. The index remains stable for the match. The service accepts the first category selection only from the anchor and synchronizes the assignment and selected category to all room clients.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-13; canonical MCP ID: TR-ANCHOR-RANDOMNESS-013. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-013. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-13-C01", "text": "At game start, the service snapshots and indexes the active roster from 1 through N, where N is 2-25. It draws a random integer uniformly from 1 through N, inclusive, and assigns the matching player as anchor for the match. The index remains stable for the match. The service accepts the first category selection only from the anchor and synchronizes the assignment and selected category to all room clients.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ANSWER-CONFIDENTIALITY-005", "title": "Answer confidentiality", "body": "The target answer remains unavailable to clients until round reveal. A hint is sent only to clients that remain unsolved. Solved players receive no later hints or answer controls for that round.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-05; canonical MCP ID: TR-ANSWER-CONFIDENTIALITY-005. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-005. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-05-C01", "text": "The target answer remains unavailable to clients until round reveal. A hint is sent only to clients that remain unsolved. Solved players receive no later hints or answer controls for that round.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ANSWER-ORDER-003", "title": "Submission ordering", "body": "The service records an authoritative acceptance time for each submission. The first correct accepted answer determines the next-category chooser. If submissions arrive at effectively the same time, the service applies a deterministic ordering rule.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-03; canonical MCP ID: TR-ANSWER-ORDER-003. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-003. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-03-C01", "text": "The service records an authoritative acceptance time for each submission. The first correct accepted answer determines the next-category chooser. If submissions arrive at effectively the same time, the service applies a deterministic ordering rule.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ANSWER-VALIDATION-004", "title": "Answer validation", "body": "The service validates each submission against the pair\u2019s target and its approved accepted-answer list. Capitalization, whitespace, punctuation, and synonym handling follow an approved answer-matching policy.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-04; canonical MCP ID: TR-ANSWER-VALIDATION-004. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-004. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-04-C01", "text": "The service validates each submission against the pair\u2019s target and its approved accepted-answer list. Capitalization, whitespace, punctuation, and synonym handling follow an approved answer-matching policy.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-03", "text": "Answer normalization: Apply Unicode NFKC, trim outer whitespace, collapse internal whitespace, and compare case-insensitively. Preserve punctuation. Only the canonical answer or an explicitly listed accepted alternative matches; no fuzzy matching.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ARCHIVE-SWBOM-028", "title": "SWBOM in release archive", "body": "Every release must include a downloadable archive containing the release contents and the SWBOM generated for the exact release commit and published build. Place the report at `sbom/.cdx.json` inside the archive. The release packaging step must verify that the SWBOM exists and that its commit SHA matches the release before publication. Do not depend on GitHub Actions for packaging or publication.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: TR-28; canonical MCP ID: TR-ARCHIVE-SWBOM-028. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-028. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-28-C01", "text": "Every release must include a downloadable archive containing the release contents and the SWBOM generated for the exact release commit and published build. Place the report at `sbom/.cdx.json` inside the archive. The release packaging step must verify that the SWBOM exists and that its commit SHA matches the release before publication. Do not depend on GitHub Actions for packaging or publication.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-24", "text": "Source archive: Use `.tar.gz` containing the complete tracked source at the release commit, root GPL-2.0-only `LICENSE`, attribution/notices, and `sbom/.cdx.json`; exclude secrets and generated dependencies. Include a SHA-256 sidecar. AC-41/42 validate temporary fixtures; live deployment inventory remains TR-only.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ART-RENDER-007", "title": "Background rendering", "body": "Category backgrounds load on supported phone screens. An overlay or equivalent treatment preserves text contrast. A missing asset must not make round controls unreadable.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-07; canonical MCP ID: TR-ART-RENDER-007. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-007. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-07-C01", "text": "Category backgrounds load on supported phone screens. An overlay or equivalent treatment preserves text contrast. A missing asset must not make round controls unreadable.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-CATALOG-INTEGRITY-006", "title": "Curated content integrity", "body": "Every playable pair has a category identifier, prompt, target answer, three ordered hints, accepted answers, and a category-background reference. A category cannot be enabled unless its required content and background are present.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-06; canonical MCP ID: TR-CATALOG-INTEGRITY-006. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-006. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-06-C01", "text": "Every playable pair has a category identifier, prompt, target answer, three ordered hints, accepted answers, and a category-background reference. A category cannot be enabled unless its required content and background are present.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-CATALOG-VERSIONING-033", "title": "Immutable and bounded catalog publication", "body": "Route editorial and community publication through the serialized moderation transaction and catalog projection, preserving exact version lookup, audit/outbox atomicity and the historical version ceiling.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TR-33; canonical MCP ID: TR-CATALOG-VERSIONING-033. Confirmed extension requirement; source docs/admin_acl_design.md, docs/admin_acl_review_receipt.json, tests/integration/multiplayer.integration.ts and user conversation. Former provisional MCP ID: TR-WP-GAME-033. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-33-C01", "text": "Save v0 then v1, exclude latest, then save v2: old lookups remain exact and future pools use the current selectable highest version.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-33-C02", "text": "Reject reused/cross-category IDs and nonzero community activation versions, invalid hints and category/background mismatches.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-33-C03", "text": "At4096 approved historical versions, another save or activation returns SERVICE_LIMIT without catalog, state, audit, revision or idempotency writes.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-CLOCK-CONSISTENCY-008", "title": "Clock consistency", "body": "Elapsed answer time uses a consistent server-controlled round start time and accepted submission time. Client clocks may animate locally, but scorecard and tiebreak values use authoritative times.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-08; canonical MCP ID: TR-CLOCK-CONSISTENCY-008. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-008. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-08-C01", "text": "Elapsed answer time uses a consistent server-controlled round start time and accepted submission time. Client clocks may animate locally, but scorecard and tiebreak values use authoritative times.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-CONNECTION-RECOVERY-009", "title": "Connection handling", "body": "A disconnect must not corrupt accepted scores or duplicate a submission. Reconnecting players retain membership for a two-minute grace interval; after it expires the room applies the normal departure rules. Client retries reuse the original command ID.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-09; canonical MCP ID: TR-CONNECTION-RECOVERY-009. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-009. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-09-C01", "text": "A disconnect must not corrupt accepted scores or duplicate a submission. Reconnecting players retain membership for a two-minute grace interval; after it expires the room applies the normal departure rules. Client retries reuse the original command ID.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-17", "text": "Room code, reconnect, creator departure: Use an eight-character Crockford Base32 code. Codes remain valid while the room is active and expire on close; empty rooms close after 30 minutes. Reconnect retains membership for a two-minute grace interval. Creator departure grants no special authority; remaining players retain control. Invalid/expired codes return the same generic not-found response; limit code attempts to 10 per minute per session.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-CONTEST-READINESS-041", "title": "Contest submission and evidence readiness", "body": "Release Word Pairs as a verified guest multiplayer contest project with accurate provenance, retained review evidence and an entrant-controlled submission.", "workspaceId": "\u003Crepo\u003E", "priority": "critical", "status": "in_progress", "notes": "Operator contest/compliance/HV retention instructions, 27October2026. Source and scope: docs/submission/README.md; official rules PDF and hash: docs/submission/rules-receipt.json; HV originals: docs/submission/hv-index.json. Exact criterion references use TR-CONTEST-READINESS-041#CONTEST-01..05. Pending authenticated mission/conduct text, entrant facts, final URL/real live matrix, Work provenance and manual entry. No agreement or entry performed. Existing FR/TR/TEST obligations remain in force.\n28October2026UTC: Operator attested all eligibility conditions. Handshake Terms https://joinhandshake.com/legal/tos/ inspected; source/hash and policy effective dates in docs/submission/rules-receipt.json. Operator states no other Code of Conduct link is available. Known conduct clauses retained; separately named text and authenticated mission not inspected. All contest criteria remain unsatisfied pending their complete combined obligations; no automated entry or agreement acceptance performed.", "acceptanceCriteria": [ { "id": "CONTEST-01", "text": "Before release, retain exact official-rule source/hash, resolve mission/conduct requirements and entrant eligibility, and use the earlier documented cutoff; do not assert unknown compliance.", "isSatisfied": false }, { "id": "CONTEST-02", "text": "At the final stable public HTTPS URL, clean guests on phone/laptop can join by code without required sign-in or install, complete synchronized games and replay; fulfill existing TEST-ROOMSYNC-139 rather than substituting fixture evidence.", "isSatisfied": false }, { "id": "CONTEST-03", "text": "Retain accurate ChatGPT Work design/build provenance and authenticated mission completion evidence; Codex-only activity does not establish the named workflow.", "isSatisfied": false }, { "id": "CONTEST-04", "text": "Prepare title, licensed cover, accurate description and playable URL; the eligible entrant manually submits through the actual Handshake mission before the cutoff, with no automated entry or unapproved agreement acceptance.", "isSatisfied": false }, { "id": "CONTEST-05", "text": "Retain every available hostile-validation receipt including rejected/superseded rounds, labeled reconstructions, corrections, candidate hashes and evidence limits; bind final approval and release/source/SWBOM evidence to the submitted candidate without exposing secrets.", "isSatisfied": false } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-DDD-TRANSACTIONS-031", "title": "Testable domain and concurrency boundaries", "body": "Organize application behavior as a modular monolith with explicit domain boundaries and application use cases. Keep game policies independent of Next.js and Supabase frameworks; route persistence, identity, time, randomness, and realtime effects through injected ports/adapters. Keep each business rule in one canonical domain policy, with database constraints as invariant backstops rather than competing rule implementations. As a TR integration requirement, the persistence adapter serializes conflicting room mutations in one database transaction, enforces durable idempotency for retried commands, and commits the event/outbox record atomically before realtime delivery. These database guarantees are verified as TR integration evidence and do not count toward AC coverage.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-31; canonical MCP ID: TR-DDD-TRANSACTIONS-031. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-031. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-31-C01", "text": "Organize application behavior as a modular monolith with explicit domain boundaries and application use cases. Keep game policies independent of Next.js and Supabase frameworks; route persistence, identity, time, randomness, and realtime effects through injected ports/adapters. Keep each business rule in one canonical domain policy, with database constraints as invariant backstops rather than competing rule implementations. As a TR integration requirement, the persistence adapter serializes conflicting room mutations in one database transaction, enforces durable idempotency for retried commands, and commits the event/outbox record atomically before realtime delivery. These database guarantees are verified as TR integration evidence and do not count toward AC coverage.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-DEPENDENCY-ATTRIBUTION-025", "title": "Direct dependencies and attribution", "body": "Declare the approved runtime and test packages as direct dependencies in `package.json`; pin compatible resolved versions through the package manager lockfile. Maintain `docs/ATTRIBUTIONS.md` with each direct package\u2019s purpose, license, and upstream source, plus attribution for any externally sourced visual, audio, or content assets. Update it when dependencies or assets change.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-25; canonical MCP ID: TR-DEPENDENCY-ATTRIBUTION-025. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-025. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-25-C01", "text": "Declare the approved runtime and test packages as direct dependencies in `package.json`; pin compatible resolved versions through the package manager lockfile. Maintain `docs/ATTRIBUTIONS.md` with each direct package\u2019s purpose, license, and upstream source, plus attribution for any externally sourced visual, audio, or content assets. Update it when dependencies or assets change.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-23", "text": "Toolchain and test stack: Next.js with TypeScript, npm with committed lockfile, Vitest for domain/use-case tests, MSW/fakes for ports, Testing Library for UI, and Playwright for browser acceptance. Pin compatible versions after the Phase 0 license/version review and before setup.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-DEPLOYMENT-NOACTIONS-024", "title": "GitHub Actions availability", "body": "Build and deployment automation must not depend on GitHub Actions. Use Vercel\u2019s Git integration for automatic branch Preview and `main` Production deployments. Run infrastructure provisioning scripts manually from an authenticated developer workstation.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "pending", "notes": "Original v2.6 document ID: TR-24; canonical MCP ID: TR-DEPLOYMENT-NOACTIONS-024. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-024. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-24-C01", "text": "Build and deployment automation must not depend on GitHub Actions. Use Vercel\u2019s Git integration for automatic branch Preview and `main` Production deployments. Run infrastructure provisioning scripts manually from an authenticated developer workstation.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-DESIGN-HOSTILEREVIEW-035", "title": "Design documentation and independent hostile validation", "body": "Update design documentation for requested behavior and obtain independent hostile validation with exact source identity, evidence boundaries, findings/corrections and final disposition.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TR-35; canonical MCP ID: TR-DESIGN-HOSTILEREVIEW-035. Confirmed extension requirement; source docs/admin_acl_design.md, docs/admin_acl_review_receipt.json, tests/integration/multiplayer.integration.ts and user conversation. Former provisional MCP ID: TR-WP-GAME-035. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-35-C01", "text": "Architecture, moderation, deployment and administration design agree with the implemented role matrix, bootstrap, transaction ordering, retry semantics and immutable content behavior.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-35-C02", "text": "An independent GPT-6 Astra/high reviewer reaches at least98/100 accuracy and completeness, with no unresolved material findings; retain its complete report and reviewed source manifest.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-35-C03", "text": "Distinguish agent visual inspection, automated fixtures, real database evidence and hosted operations. Human feedback is optional; do not invent personal sign-off gates or claim unperformed human testing.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-DOCS-WIKIPUBLISH-042", "title": "Publish synchronized requirements wiki", "body": "Each repository refresh-docs run publishes the validated authoritative GitHub wiki export with preserved review evidence and verified remote identity.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Operator instruction27October2026: When using refresh-docs, publish exported wiki to https://github.com/sharpninja/wordpairs.wiki.git. Repository contract: AGENTS.md Documentation publication. Source/evidence: docs/submission/wiki-publication.json, docs/submission/hv-index.json, docs/testing/ui/persistence.md. This authorizes wiki commits/pushes, not application-repository commits or automated contest entry. Acceptance references TR-DOCS-WIKIPUBLISH-042#WIKI-01..03.\nVerified first publication at wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc with all270remote files byte-matched. Subsequent export includes this completion evidence; application repository untouched. Each future refresh must perform new readback/export/push verification and refresh evidence rather than inheriting this result.", "acceptanceCriteria": [ { "id": "WIKI-01", "text": "Each refresh-docs reconciles authoritative QBrain records and mappings, verifies readback, exports the supported wiki and validates every configured page and scoped requirement ID before publication.", "isSatisfied": true, "evidence": "Verified wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc; complete remote Git tree readback 270files. Canonical export b6a44c6cc43dddcb473af18d504c64026ef75599f78c04863e4913afe1d0505c; docs/submission/wiki-publication.json; hostile publication approval99/99 and all retained prior rounds in docs/evidence/ui-gaps/hostile-validation.jsonl." }, { "id": "WIKI-02", "text": "Publish the GitHub export to https://github.com/sharpninja/wordpairs.wiki.git, preserve unrelated pages, disclose publication-only link/asset transforms, and verify pushed commit and file hashes by remote Git readback.", "isSatisfied": true, "evidence": "Verified wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc; complete remote Git tree readback 270files. Canonical export b6a44c6cc43dddcb473af18d504c64026ef75599f78c04863e4913afe1d0505c; docs/submission/wiki-publication.json; hostile publication approval99/99 and all retained prior rounds in docs/evidence/ui-gaps/hostile-validation.jsonl." }, { "id": "WIKI-03", "text": "Preserve all available hostile-validation receipts including rejected/superseded rounds and labeled reconstructions, bind approvals to source/evidence inventories, and exclude private runtime credentials/session files from the published evidence.", "isSatisfied": true, "evidence": "Verified wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc; complete remote Git tree readback 270files. Canonical export b6a44c6cc43dddcb473af18d504c64026ef75599f78c04863e4913afe1d0505c; docs/submission/wiki-publication.json; hostile publication approval99/99 and all retained prior rounds in docs/evidence/ui-gaps/hostile-validation.jsonl." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-FREETIER-OPERATION-021", "title": "Free-tier operation", "body": "The deployment must remain on free tiers: Vercel Hobby and Supabase Free. Do not enable paid add-ons, metered upgrades, or paid external services. The product is personal and non-commercial while using Vercel Hobby. Current Supabase Free constraints include a 500 MB database, 200 concurrent Realtime connections, 100 Realtime messages per second, 2 million Realtime messages per month, and automatic pause after one week of inactivity. Treat these as capacity limits and provide graceful handling when service quotas are reached.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: TR-21; canonical MCP ID: TR-FREETIER-OPERATION-021. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-021. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-21-C01", "text": "The deployment must remain on free tiers: Vercel Hobby and Supabase Free. Do not enable paid add-ons, metered upgrades, or paid external services. The product is personal and non-commercial while using Vercel Hobby. Current Supabase Free constraints include a 500 MB database, 200 concurrent Realtime connections, 100 Realtime messages per second, 2 million Realtime messages per month, and automatic pause after one week of inactivity. Treat these as capacity limits and provide graceful handling when service quotas are reached.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-20", "text": "Quota behavior and initial load target: Initial supported target is one full 25-player room plus up to 25 observers. Quota rejection returns a recoverable `SERVICE_LIMIT`, preserves the last committed state, and allows retry with the same command ID; no paid fallback or non-idempotent automatic retry.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-IDENTITY-AUTHENTICATION-016", "title": "Identity and authentication", "body": "The service supports OpenAI OIDC for account-backed profiles and guest identities without OIDC. It validates OIDC tokens before associating a profile with the subject and never trusts client-supplied identity claims. Guest identity persists in the same browser/device until site data is cleared; it does not sync or link to OIDC. Store generated public aliases and leaderboard opt-out separately from real identity claims. Guest identity persists only in the same browser/device until site data is cleared; guest profiles do not sync or link to OIDC accounts.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: TR-16; canonical MCP ID: TR-IDENTITY-AUTHENTICATION-016. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-016. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-16-C01", "text": "The service supports OpenAI OIDC for account-backed profiles and guest identities without OIDC. It validates OIDC tokens before associating a profile with the subject and never trusts client-supplied identity claims. Guest identity persists in the same browser/device until site data is cleared; it does not sync or link to OIDC. Store generated public aliases and leaderboard opt-out separately from real identity claims. Guest identity persists only in the same browser/device until site data is cleared; guest profiles do not sync or link to OIDC accounts.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-10", "text": "OIDC provider: Keep OpenAI OIDC as specified in FR-02/FR-18/AC-20/46, using Authorization Code with PKCE and verified OIDC claims. Provider registration/entitlement is an external integration prerequisite, not an AC test oracle or deployed-artifact AC.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-LANDING-PRIVACY-030", "title": "Public landing data boundary", "body": "Serve the landing page and its gameplay rules without requiring authentication. Retrieve leaderboard and lobby display data through a read-only, server-controlled public projection that returns only approved fields. Restrict lobby results to discoverable, joinable rooms; exclude room codes, non-public profile fields and identifiers, observer perspective data, guesses, targets, moderation records, and secrets. Use bounded pagination, a documented refresh/cache policy, and recoverable empty/unavailable states. Do not expose service-role credentials or allow the public query to mutate game state.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-30; canonical MCP ID: TR-LANDING-PRIVACY-030. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-030. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-30-C01", "text": "Serve the landing page and its gameplay rules without requiring authentication. Retrieve leaderboard and lobby display data through a read-only, server-controlled public projection that returns only approved fields. Restrict lobby results to discoverable, joinable rooms; exclude room codes, non-public profile fields and identifiers, observer perspective data, guesses, targets, moderation records, and secrets. Use bounded pagination, a documented refresh/cache policy, and recoverable empty/unavailable states. Do not expose service-role credentials or allow the public query to mutate game state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-19", "text": "Public landing contract: Leaderboard is lifetime wins, then total points, earliest win, and stable profile ID. Show public alias only, include opt-in guests, honor profile opt-out. Lobby card shows exact player count/capacity, waiting state and room age, never room code/player names. Refresh lobby data every 15 seconds and leaderboard every five minutes. Rules are a concise versioned summary with an updated date.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-LICENSE-GPL-029", "title": "Project license", "body": "License Wordpairs source and the game under GNU GPL version 2 only (`GPL-2.0-only`). Include the complete license text in the root `LICENSE` file and include that file in each source release archive. Preserve independent third-party license notices and check compatibility before redistributing any third-party code or asset as part of the game.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-29; canonical MCP ID: TR-LICENSE-GPL-029. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-029. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-29-C01", "text": "License Wordpairs source and the game under GNU GPL version 2 only (`GPL-2.0-only`). Include the complete license text in the root `LICENSE` file and include that file in each source release archive. Preserve independent third-party license notices and check compatibility before redistributing any third-party code or asset as part of the game.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-LOBBY-MATCHING-017", "title": "Lobby discovery and matching", "body": "The service lists only discoverable lobbies with available player slots under their configured capacity. Rooms are private by default. Quick match selects the oldest eligible room, then stable room ID; all player-seat assignments use the same atomic capacity check. Deep links containing a valid room code route directly to that room without lobby browsing, then use the same authoritative open-slot check. A valid invite to a full room may establish an observer session without reserving a player slot. Lobby discovery responses expose only approved lobby metadata, not private room state.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-17; canonical MCP ID: TR-LOBBY-MATCHING-017. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-017. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-17-C01", "text": "The service lists only discoverable lobbies with available player slots under their configured capacity. Rooms are private by default. Quick match selects the oldest eligible room, then stable room ID; all player-seat assignments use the same atomic capacity check. Deep links containing a valid room code route directly to that room without lobby browsing, then use the same authoritative open-slot check. A valid invite to a full room may establish an observer session without reserving a player slot. Lobby discovery responses expose only approved lobby metadata, not private room state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-MOBILE-INPUT-011", "title": "Mobile input", "body": "Primary actions work with touch and keyboard input. Category art does not obstruct text entry, hints, score status, or buttons in either phone orientation.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-11; canonical MCP ID: TR-MOBILE-INPUT-011. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-011. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-11-C01", "text": "Primary actions work with touch and keyboard input. Category art does not obstruct text entry, hints, score status, or buttons in either phone orientation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-MULTIPLAYER-INTEGRATION-034", "title": "Integration games for every supported player count", "body": "Exercise the real identity/room/lobby/match/PostgreSQL services in complete eight-round games for every integer player count2..25, using disposable infrastructure.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TR-34; canonical MCP ID: TR-MULTIPLAYER-INTEGRATION-034. Confirmed extension requirement; source docs/admin_acl_design.md, docs/admin_acl_review_receipt.json, tests/integration/multiplayer.integration.ts and user conversation. Former provisional MCP ID: TR-WP-GAME-034. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-34-C01", "text": "Run24 complete games with324 player participations and2592 accepted round solves; every game reaches shared final standings.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-34-C02", "text": "Exercise all hint/scoring stages, simultaneous conflicts/retries, roster/anchor transitions and exactly-once profile awards. Keep deterministic clocks/randomness; preserve all assertions under bounded fixture wall-clock timeouts.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-34-C03", "text": "Use a disposable loopback-only database, apply every migration and remove owned containers/fixtures in finally without touching the running game database.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-NOMINATION-MODERATION-014", "title": "Candidate nomination and moderation", "body": "The service permits nomination submission only for a player who solved the current round before any hint. It stores each nomination against a normalized candidate word and records its nominating player and timestamp. Candidate eligibility requires both at least 10 nominations and an approved moderation status. Moderation status, nomination count, and eligibility state must be auditable. An eligible candidate cannot be played until a complete curated word-pair record exists.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-14; canonical MCP ID: TR-NOMINATION-MODERATION-014. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-014. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-14-C01", "text": "The service permits nomination submission only for a player who solved the current round before any hint. It stores each nomination against a normalized candidate word and records its nominating player and timestamp. Candidate eligibility requires both at least 10 nominations and an approved moderation status. Moderation status, nomination count, and eligibility state must be auditable. An eligible candidate cannot be played until a complete curated word-pair record exists.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-07", "text": "Nomination counting: Count unique player profiles per normalized candidate. A profile may nominate a candidate once and submit at most one candidate per eligible no-hint solve. Moderation begins at 10 unique nominations.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-08", "text": "Moderation workflow: Roles are Content Moderator and Senior Moderator. At threshold, content enters Pending Review. A moderator other than the proposer approves or rejects with a reason. The proposer may appeal once to a Senior Moderator. Approval alone does not make content playable; the complete curated record must pass validation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-OBSERVER-PERMISSIONS-018", "title": "Observer perspective and permissions", "body": "An observer session is read-only, limited to 25 observers per room, and is bound to the player who invited the observer. Signed links carry inviter context; a manual room-code observer selects an active inviter from the roster. Observer queue order is transactional, with stable profile ID as tie-break. The service streams the same player-authorized game view that the inviter\u2019s client receives, including updates as the inviter\u2019s view changes, while rejecting guesses, category choices, and other game-affecting commands from the observer. Observers do not count toward player capacity or scoring.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-18; canonical MCP ID: TR-OBSERVER-PERMISSIONS-018. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-018. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-18-C01", "text": "An observer session is read-only, limited to 25 observers per room, and is bound to the player who invited the observer. Signed links carry inviter context; a manual room-code observer selects an active inviter from the roster. Observer queue order is transactional, with stable profile ID as tie-break. The service streams the same player-authorized game view that the inviter\u2019s client receives, including updates as the inviter\u2019s view changes, while rejecting guesses, category choices, and other game-affecting commands from the observer. Observers do not count toward player capacity or scoring.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-POSTGRES-PERSISTENCE-022", "title": "Persistence and real-time room state", "body": "Use Supabase Postgres as the durable source of truth for profiles, curated pairs, nominations, moderation records, completed matches, and scores. Use Supabase Realtime for active-room presence and event delivery within its free-tier limits. Do not rely on a Vercel Function\u2019s process memory as shared or durable room state. Keep category background assets in the repository unless a future requirement needs uploaded files.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: TR-22; canonical MCP ID: TR-POSTGRES-PERSISTENCE-022. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-022. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-22-C01", "text": "Use Supabase Postgres as the durable source of truth for profiles, curated pairs, nominations, moderation records, completed matches, and scores. Use Supabase Realtime for active-room presence and event delivery within its free-tier limits. Do not rely on a Vercel Function\u2019s process memory as shared or durable room state. Keep category background assets in the repository unless a future requirement needs uploaded files.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-21", "text": "Persistence/security model: All writes and private reads go through server application commands; browser receives no service-role credential and no direct table grants. RLS remains enabled, with narrow public and actor-authorized views/functions. Moderator roles are server-managed. Raw incorrect guesses are not persisted. Audit events retain one year; published outbox rows seven days; idempotency results until 30 days after room close.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-PWA-CACHEPRIVACY-037", "title": "Private-data-safe PWA offline and updates", "body": "Cache only static offline HTML and explicit public icon assets. Keep API/auth/realtime/private HTML/RSC/mutations network-only; navigation network failures may return static offline guidance. Clean only owned versioned caches, never force an active game to reload; worker is freshly validated on update.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Source: user request2026-10-27: The game needs to be installable as a PWA on phones. Design and criteria: docs/pwa_design.md. Browser/worker evidence does not establish installation on physical Android/iPhone hardware. HostedHTTPS deployment remains future operational work.", "acceptanceCriteria": [ { "id": "PWA-06", "text": "Offline controlled navigation returns a static reconnect screen; returning online restores the live website.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-07", "text": "API/auth/realtime/private navigation and mutations are never stored in worker caches; offline API/mutation requests fail without receiving offline HTML.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-08", "text": "Only old versioned Wordpairs static caches are cleaned up; service-worker updates do not force activation or reload during a match.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-PWA-INSTALLATION-036", "title": "Phone manifest and install lifecycle", "body": "Use built-in Next manifest/metadata, valid public PNG icons and root service-worker registration on secure origins. Browser prompts require user gestures, are consumed once and cannot be emulated on iPhone; provide manual guidance and handle lifecycle/errors without disrupting gameplay.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Source: user request2026-10-27: The game needs to be installable as a PWA on phones. Design and criteria: docs/pwa_design.md. Browser/worker evidence does not establish installation on physical Android/iPhone hardware. HostedHTTPS deployment remains future operational work.", "acceptanceCriteria": [ { "id": "PWA-01", "text": "Manifest has stable identity, standalone launch at /play, root scope, names, colors, same-origin192/512 icons and a separate maskable icon.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-02", "text": "Referenced PNGs have declared dimensions, opaque brand background and safe-zone maskable artwork; Apple metadata and touch icon exist.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-03", "text": "Secure-context registration succeeds at root scope, handles failure gracefully and uses fresh worker script headers.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-04", "text": "A captured install event prompts once after a click; dismissal/rejection preserves guidance; installed/standalone state hides install UI and listeners clean up.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-05", "text": "Phone install guidance covers iPhone Share and Android menus, explains HTTPS on insecure origins, and fits narrow screens accessibly; physical home-screen installation is not claimed by emulation.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-REACTION-DELIVERY-019", "title": "Emoji reaction delivery", "body": "The service accepts only \ud83d\udc4d, \u2764\ufe0f, \ud83d\ude02, \ud83c\udf89, and \ud83d\udc40; each player may send one reaction every two seconds. It broadcasts reactions to connected players and observers in real time; reactions disappear after five seconds. Reactions are informational events and cannot mutate scores, answer submissions, hint state, category selection, or match state.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-19; canonical MCP ID: TR-REACTION-DELIVERY-019. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-019. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-19-C01", "text": "The service accepts only \ud83d\udc4d, \u2764\ufe0f, \ud83d\ude02, \ud83c\udf89, and \ud83d\udc40; each player may send one reaction every two seconds. It broadcasts reactions to connected players and observers in real time; reactions disappear after five seconds. Reactions are informational events and cannot mutate scores, answer submissions, hint state, category selection, or match state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-18", "text": "Reactions: Menu: \ud83d\udc4d, \u2764\ufe0f, \ud83d\ude02, \ud83c\udf89, \ud83d\udc40. A reaction is visible for five seconds; one reaction per player per two seconds. It cannot change game state or score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-REALTIME-SYNC-002", "title": "Real-time synchronization", "body": "The service synchronizes room membership and round updates to all connected players. A confirmed correct answer updates the live scorecard, and all clients progress through the same hint stage.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-02; canonical MCP ID: TR-REALTIME-SYNC-002. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-002. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-02-C01", "text": "The service synchronizes room membership and round updates to all connected players. A confirmed correct answer updates the live scorecard, and all clients progress through the same hint stage.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ROOM-CODES-010", "title": "Room code handling", "body": "Room codes identify the intended active room and reject invalid or expired codes. Each room stores a configured capacity from 2 through 25. Room-code joins and deep-link joins use the same authoritative slot check as lobby browsing and quick match. When full, a valid invite permits the player to request observer mode instead of a player slot. Before countdown, promote the oldest observer into the last player position when a player leaves a full room; break equal observer-arrival times by stable profile ID. Use an eight-character Crockford Base32 code, valid while the room is active and expired on close; close empty rooms after 30 minutes and limit invalid-code attempts to 10 per minute per session.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-10; canonical MCP ID: TR-ROOM-CODES-010. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-010. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-10-C01", "text": "Room codes identify the intended active room and reject invalid or expired codes. Each room stores a configured capacity from 2 through 25. Room-code joins and deep-link joins use the same authoritative slot check as lobby browsing and quick match. When full, a valid invite permits the player to request observer mode instead of a player slot. Before countdown, promote the oldest observer into the last player position when a player leaves a full room; break equal observer-arrival times by stable profile ID. Use an eight-character Crockford Base32 code, valid while the room is active and expired on close; close empty rooms after 30 minutes and limit invalid-code attempts to 10 per minute per session.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-17", "text": "Room code, reconnect, creator departure: Use an eight-character Crockford Base32 code. Codes remain valid while the room is active and expire on close; empty rooms close after 30 minutes. Reconnect retains membership for a two-minute grace interval. Creator departure grants no special authority; remaining players retain control. Invalid/expired codes return the same generic not-found response; limit code attempts to 10 per minute per session.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-ROOM-SYNCRECOVERY-038", "title": "Private live multiplayer delivery and autonomous progression", "body": "Configure authenticated Realtime and an independent durable deadline/outbox worker. Game state must propagate end to end to players and bound observers without relying on periodic browser reads. Preserve authority, privacy, idempotency and owned temporary-runtime cleanup.", "workspaceId": "\u003Crepo\u003E", "priority": "critical", "status": "in_progress", "notes": "Confirmed user requirements: actual live gameplay, repeatable UI integration at2..25, design updates and independent hostile validation. Source: phone stale-roster report and corrections,27October2026. SDK token callback, coalescing, lifecycle, independent worker and owned cleanup are implemented. New presence-body defect independently reproduced in Chromium;2red React tests now pass, real heartbeat browser regression passes with unread negative control and production-only body drain.532unit/acceptance tests, lint and production build pass. Updated strict game is rerunning; full2..25 remains pending. Prior25-player round1 failure and measured shared-cluster WAL stalls are retained. Volatile TLS harness preserves fsync/synchronous_commit but proves neither power-loss durability nor public capacity. Faster waiting-room fallback and hosted Phase7 remain outside this extension.", "acceptanceCriteria": [ { "id": "LIVE-01", "text": "Actual private WebSocket subscriptions deliver only event/aggregate/version metadata to authenticated per-profile audiences; anonymous, cross-profile subscriptions and client publication are denied.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-02", "text": "Repeatable browser integration creates real guests and room membership, enters a code, readies players, plays eight UI rounds, and verifies remote category, solve, hints, scores, reveal, reactions and final standings through actual private notifications and authorized reads while periodic UI polling is suppressed.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-03", "text": "An authenticated server worker advances countdown and hint deadlines with all browsers offline, drains bounded durable outbox batches, reports deadline and publication failures separately, and preserves failed events for retry. Foreground requests never wait for an active worker batch.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-04", "text": "The temporary HTTPS gateway serves app and Realtime paths while rejecting tenant management paths; private credentials and internal ports remain private. Cleanup acts only on its captured lease generation and owned resource identities. A separate-broker harness must own a separate strict-TLS game database/outbox; partial startup or unconfirmed cleanup preserves recovery identities and blocks replacement.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-05", "text": "Focus, visibility and online recovery trigger authorized reads; concurrent reads coalesce one follow-up, older responses cannot lose newer notifications, and unmount/account changes prevent obsolete subscriptions after deferred authentication. Connected game/social safety reads use15seconds and disconnected recovery uses1second; cadence changes preserve in-flight/coalesced reads and independent display clocks. Presence responses are fully consumed before clearing canonical retries and refreshing; a body-read failure retains the exact retry command.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-06", "text": "Real UI integration proves token renewal beyond the original120-second expiry and actual WebSocket close/reconnect followed by another push-driven game transition.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-07", "text": "Repeatable browser integration plays real eight-round games at every player count2 through25, with UI readiness/categories/every answer and identical final rankings, using a separately owned TLS game database and private Realtime outbox. At most two UI answers are submitted simultaneously; local results do not establish public-tunnel capacity. Cleanup is truthful and bounded.", "isSatisfied": false, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-SCHEMA-PROVISIONING-023", "title": "Provisioning and schema changes", "body": "Provide a manually invoked, repeatable provisioning script using the Supabase and Vercel CLIs. It must create or link the projects, apply version-controlled database migrations, and set required Vercel environment variables for Preview and Production. The script must accept authenticated credentials from the operator\u2019s environment, never commit or print secret values, and avoid configuring paid resources.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: TR-23; canonical MCP ID: TR-SCHEMA-PROVISIONING-023. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-023. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-23-C01", "text": "Provide a manually invoked, repeatable provisioning script using the Supabase and Vercel CLIs. It must create or link the projects, apply version-controlled database migrations, and set required Vercel environment variables for Preview and Production. The script must accept authenticated credentials from the operator\u2019s environment, never commit or print secret values, and avoid configuring paid resources.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-22", "text": "Deadline scheduler: Store versioned deadline jobs in Postgres and process due jobs using Supabase Cron/`pg_cron` at one-second cadence; each job calls a transactional database function, with stale-version and duplicate delivery as no-ops. This is a TR technical choice; verify current Free-plan capability at Phase 7 deployment entry after coding.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-STATE-AUTHORITY-001", "title": "Authoritative room state", "body": "A server-side game service owns room membership, round state, accepted answers, hint stage, scoring, solve timestamps, category choice, and match completion. Clients cannot award points or change a target answer.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-01; canonical MCP ID: TR-STATE-AUTHORITY-001. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-001. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-01-C01", "text": "A server-side game service owns room membership, round state, accepted answers, hint stage, scoring, solve timestamps, category choice, and match completion. Clients cannot award points or change a target answer.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-SUGGESTION-REVIEW-015", "title": "Category suggestion eligibility and review", "body": "The service tracks game wins for each player and unlocks category-and-pair suggestions when the player reaches 10 wins. It stores the proposed category and its three proposed word pairs as one submission, tracks its review status, and prevents unapproved or incomplete content from entering the playable catalog. Win counts use a stable player profile and are cumulative for that profile\u2019s lifetime.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-15; canonical MCP ID: TR-SUGGESTION-REVIEW-015. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-015. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-15-C01", "text": "The service tracks game wins for each player and unlocks category-and-pair suggestions when the player reaches 10 wins. It stores the proposed category and its three proposed word pairs as one submission, tracks its review status, and prevents unapproved or incomplete content from entering the playable catalog. Win counts use a stable player profile and are cumulative for that profile\u2019s lifetime.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-08", "text": "Moderation workflow: Roles are Content Moderator and Senior Moderator. At threshold, content enters Pending Review. A moderator other than the proposer approves or rejects with a reason. The proposer may appeal once to a Senior Moderator. Approval alone does not make content playable; the complete curated record must pass validation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-SWBOM-GENERATION-027", "title": "Per-build software bill of materials", "body": "Generate one CycloneDX JSON 1.6 software bill of materials (SWBOM) from the exact npm lockfile for every Vercel Preview or Production deployment. Include direct and transitive runtime and development components, declared licenses, package URLs, dependency relationships, build timestamp, Git commit SHA, deployment environment, and Vercel deployment URL. Generate it after the mock-first test gate and before the application build, then bundle it into that same immutable deployment at `public/sbom/.cdx.json`. Never include secrets or environment-variable values. Document the artifact contract in `docs/SWBOM.md`.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "pending", "notes": "Original v2.6 document ID: TR-27; canonical MCP ID: TR-SWBOM-GENERATION-027. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-027. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-27-C01", "text": "Generate one CycloneDX JSON 1.6 software bill of materials (SWBOM) from the exact npm lockfile for every Vercel Preview or Production deployment. Include direct and transitive runtime and development components, declared licenses, package URLs, dependency relationships, build timestamp, Git commit SHA, deployment environment, and Vercel deployment URL. Generate it after the mock-first test gate and before the application build, then bundle it into that same immutable deployment at `public/sbom/.cdx.json`. Never include secrets or environment-variable values. Document the artifact contract in `docs/SWBOM.md`.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-TDD-ACCEPTANCE-026", "title": "Mock-first test gate", "body": "Before writing implementation code for an increment, define tests for every applicable acceptance criterion, validate the tests against mocks, and then implement the smallest behavior that makes them pass. The Vercel build must run the test suite before the production build. No GitHub Actions workflow is assumed or required.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "Original v2.6 document ID: TR-26; canonical MCP ID: TR-TDD-ACCEPTANCE-026. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-026. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-26-C01", "text": "Before writing implementation code for an increment, define tests for every applicable acceptance criterion, validate the tests against mocks, and then implement the smallest behavior that makes them pass. The Vercel build must run the test suite before the production build. No GitHub Actions workflow is assumed or required.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-UI-ACCESSIBILITY-012", "title": "Accessibility and readability", "body": "Text and controls maintain clear contrast over every category background. Focus, selected icons, solved status, and score changes use labels or shapes as well as color.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original v2.6 document ID: TR-12; canonical MCP ID: TR-UI-ACCESSIBILITY-012. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-012. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-12-C01", "text": "Text and controls maintain clear contrast over every category background. Focus, selected icons, solved status, and score changes use labels or shapes as well as color.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-UI-ACCESSIBILITYDETAILS-039", "title": "Measurable accessible game controls", "body": "Apply explicit contrast, focus, announcement and touch-target requirements to UI controls and feedback.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \"Fill gaps\", 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-IMPLEMENTATION TR-UI-ACCESSIBILITYDETAILS-039\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TR-UI-ACCESSIBILITYDETAILS-039", "acceptanceCriteria": [ { "id": "UI-A11Y-01", "text": "Normal text contrast is at least4.5:1, large text3:1 and essential control/state indicators3:1 against adjacent colors under the W3C definitions and applicable exceptions.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." }, { "id": "UI-A11Y-02", "text": "All primary actions support keyboard navigation with visible ordered focus, meaningful accessible names and labels/shapes for non-color state.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." }, { "id": "UI-A11Y-03", "text": "Accepted score/stage changes and errors are announced to assistive technology without unexpectedly moving focus.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." }, { "id": "UI-A11Y-04", "text": "Primary touch actions have at least44x44CSS-pixel targets as the project usability requirement; this is not a formal WCAG conformance claim.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-UI-RESPONSIVEMATRIX-040", "title": "Responsive viewport and zoom matrix", "body": "Define repeatable minimum-width, orientation and enlargement configurations for all game and staff UI.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \"Fill gaps\", 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-IMPLEMENTATION TR-UI-RESPONSIVEMATRIX-040\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TR-UI-RESPONSIVEMATRIX-040", "acceptanceCriteria": [ { "id": "UI-RESP-01", "text": "At320x568,390x844 and844x390CSS-pixel layouts, game/form text, hints, score fields and controls remain reachable without horizontal page scrolling or clipping.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. 320CSS-pixel zoom equivalent and200%text fixture." }, { "id": "UI-RESP-02", "text": "At1280px width with400%zoom (320CSS-pixel equivalent) and with200%text enlargement, content reflows without losing required information/actions; browser zoom remains enabled.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. 320CSS-pixel zoom equivalent and200%text fixture." }, { "id": "UI-RESP-03", "text": "Orientation changes preserve the authorized room and safe draft state; stacked score layouts retain all fields and touch/keyboard actions remain operable.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. 320CSS-pixel zoom equivalent and200%text fixture." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TR-VERCEL-DEPLOYMENT-020", "title": "Vercel deployment target", "body": "Deploy the web application from the `sharpninja/wordpairs` GitHub repository to Vercel. Use Vercel\u2019s Git integration: pushes to non-production branches create Preview deployments, and changes merged to `main` create Production deployments. Select the framework preset, project root, build command, and output directory to match the implementation once its framework is approved.", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "pending", "notes": "Original v2.6 document ID: TR-20; canonical MCP ID: TR-VERCEL-DEPLOYMENT-020. Imported from docs/word_association_game_requirements.md v2.6, SHA256 e356a7bdce8fae59d3f9a9d48dd471c5c05ec724b5734ba9ed14bec1a754ebc2. Original document IDs are retained as source aliases; MCP requires canonical area-qualified IDs. Baseline Phase6 evidence is historical; subsequent administration regression and source identity are recorded separately. Hosted deployment/provider entitlement remains Phase7 work. Former provisional MCP ID: TR-WP-GAME-020. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-20-C01", "text": "Deploy the web application from the `sharpninja/wordpairs` GitHub repository to Vercel. Use Vercel\u2019s Git integration: pushes to non-production branches create Preview deployments, and changes merged to `main` create Production deployments. Select the framework preset, project root, build command, and output directory to match the implementation once its framework is approved.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" } ], "testing": [ { "id": "TEST-ACCESSIBILITYDETAILS-144", "condition": "Verify the documented UI behavior: Contrast, focus, announcements and touch geometry.", "title": "Contrast, focus, announcements and touch geometry", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-ACCESSIBILITYDETAILS-144\n# TEST-ACCESSIBILITYDETAILS-144 - Contrast, focus, announcements and touch geometry\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Contrast, focus, announcements and touch geometry. |\n| QBrain reference/scope | \u0060TEST-ACCESSIBILITYDETAILS-144\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | GAP-FLOW-ACCESSIBILITYDETAILS, GAP-TRANS-ACCESSIBILITYDETAILS-01, GAP-TRANS-ACCESSIBILITYDETAILS-02, GAP-TRANS-ACCESSIBILITYDETAILS-03, GAP-TRANS-ACCESSIBILITYDETAILS-04; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060TR-UI-ACCESSIBILITYDETAILS-039#UI-A11Y-01\u0060; \u0060TR-UI-ACCESSIBILITYDETAILS-039#UI-A11Y-02\u0060; \u0060TR-UI-ACCESSIBILITYDETAILS-039#UI-A11Y-03\u0060; \u0060TR-UI-ACCESSIBILITYDETAILS-039#UI-A11Y-04\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Every game/form/staff state can be seeded with all category backgrounds and accepted/error updates. |\n| Test data | Normal text, large text and essential indicators; keyboard focus order; screen reader; target rectangles44x44CSSpx. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Measure text/indicator contrast against the actual adjacent rendered colors. | Normal text meets4.5:1, large text3:1 and essential indicators3:1 under the specified definitions/exceptions. |\n| 2 | Traverse primary actions using keyboard and inspect accessible names/non-color state. | Focus is visible and ordered; names and labels/shapes identify every primary action and relevant state. |\n| 3 | Trigger accepted score/stage changes and an error while reading the page. | Assistive announcements convey the changes without unexpectedly stealing focus. |\n| 4 | Measure the primary touch target geometry. | Each is at least44x44CSSpx under the project rule; no formal compliance result is inferred. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Contrast, focus, announcements and touch geometry\n Scenario: TEST-ACCESSIBILITYDETAILS-144 design verification\n Given Every game/form/staff state can be seeded with all category backgrounds and accepted/error updates.\n And the fixture data is Normal text, large text and essential indicators; keyboard focus order; screen reader; target rectangles44x44CSSpx.\n When Measure text/indicator contrast against the actual adjacent rendered colors.\n Then Normal text meets4.5:1, large text3:1 and essential indicators3:1 under the specified definitions/exceptions.\n When Traverse primary actions using keyboard and inspect accessible names/non-color state.\n Then Focus is visible and ordered; names and labels/shapes identify every primary action and relevant state.\n When Trigger accepted score/stage changes and an error while reading the page.\n Then Assistive announcements convey the changes without unexpectedly stealing focus.\n When Measure the primary touch target geometry.\n Then Each is at least44x44CSSpx under the project rule; no formal compliance result is inferred.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-ACCESSIBILITYDETAILS-144\n\nBEGIN UI-IMPLEMENTATION TEST-ACCESSIBILITYDETAILS-144\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-ACCESSIBILITYDETAILS-144", "acceptanceCriteria": [ { "id": "UI-A11Y-01", "text": "Normal text contrast is at least4.5:1, large text3:1 and essential control/state indicators3:1 against adjacent colors under the W3C definitions and applicable exceptions.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." }, { "id": "UI-A11Y-02", "text": "All primary actions support keyboard navigation with visible ordered focus, meaningful accessible names and labels/shapes for non-color state.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." }, { "id": "UI-A11Y-03", "text": "Accepted score/stage changes and errors are announced to assistive technology without unexpectedly moving focus.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." }, { "id": "UI-A11Y-04", "text": "Primary touch actions have at least44x44CSS-pixel targets as the project usability requirement; this is not a formal WCAG conformance claim.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. DOM/Chromium evidence; no physical assistive technology certification." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ACCESSIBLEGAMECONTROLS-044", "condition": "Given a player uses a phone-sized viewport in portrait or landscape, when they operate primary game actions with touch or keyboard and view text over category backgrounds, then the actions remain operable, text and controls retain clear contrast, focus is visible, and selected icon, solved status, and score changes are indicated by labels or shapes as well as color.", "title": "AC-44: Accessible game controls", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-44; canonical MCP ID: TEST-ACCESSIBLEGAMECONTROLS-044. Original criterion AC-44; cases AC-44-T01, AC-44-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-044. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ACCESSIBLEGAMECONTROLS-044\n# TEST-ACCESSIBLEGAMECONTROLS-044 - AC-44: Accessible game controls\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-44: Accessible game controls. |\n| QBrain reference/scope | \u0060TEST-ACCESSIBLEGAMECONTROLS-044\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | ; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORYART-006#AC-44\u0060; \u0060FR-RESPONSIVEUI-015#AC-44\u0060; \u0060TR-UI-ACCESSIBILITY-012#TR-12-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Phone-sized active game has category background, selectable icon and score updates. |\n| Test data | Portrait 390x844, landscape 844x390 (test configurations); keyboard and touch; fox selected, Alice solved. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Use keyboard focus and touch for primary actions in both orientations. | Actions are operable, focus is visible and text/control contrast remains clear over category art. |\n| 2 | Inspect selected icon, Alice\u0027s solved state and score change without relying on color. | Labels or shapes distinguish selection, solved status and changed score. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-44: Accessible game controls\n Scenario: TEST-ACCESSIBLEGAMECONTROLS-044 design verification\n Given Phone-sized active game has category background, selectable icon and score updates.\n And the fixture data is Portrait 390x844, landscape 844x390 (test configurations); keyboard and touch; fox selected, Alice solved.\n When Use keyboard focus and touch for primary actions in both orientations.\n Then Actions are operable, focus is visible and text/control contrast remains clear over category art.\n When Inspect selected icon, Alice\u0027s solved state and score change without relying on color.\n Then Labels or shapes distinguish selection, solved status and changed score.\n\u0060\u0060\u0060\n\n## Boundaries\n\nNo numeric contrast ratio or WCAG level is invented; quantitative compliance targets remain Q-A11Y-01.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ACCESSIBLEGAMECONTROLS-044", "acceptanceCriteria": [ { "id": "AC-44", "text": "Given a player uses a phone-sized viewport in portrait or landscape, when they operate primary game actions with touch or keyboard and view text over category backgrounds, then the actions remain operable, text and controls retain clear contrast, focus is visible, and selected icon, solved status, and score changes are indicated by labels or shapes as well as color.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ACLAUTHORIZATION-132", "condition": "Enforce permissions in authenticated HTTP/application code and privileged SQL functions, with shared ACL locking for content writes and exclusive locking for role mutations. Validate identity/origin, strict allowlists, expected revision, digest/retry semantics and bounded private projections.", "title": "Verify Server-authoritative ACL transactions", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-132; canonical MCP ID: TEST-ACLAUTHORIZATION-132. Actual test sources: tests/application/access.test.ts, tests/application/catalog-admin.test.ts, tests/web/admin-api.test.ts, tests/integration/admin.integration.ts, tests/integration/multiplayer.integration.ts, tests/browser/admin.phase6.spec.ts. Match the applicable suite to this requirement; do not claim all suites prove every boundary. Former provisional MCP ID: TEST-WP-132. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ACLAUTHORIZATION-132\n# TEST-ACLAUTHORIZATION-132 - Verify Server-authoritative ACL transactions\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Verify Server-authoritative ACL transactions. |\n| QBrain reference/scope | \u0060TEST-ACLAUTHORIZATION-132\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [admin_acl_design.md](../../../admin_acl_design.md) |\n| Frame/element identifiers | SCREEN-USERS, STATE-USERS-01, STATE-USERS-02, STATE-USERS-03, STATE-USERS-04, STATE-USERS-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ACCESSCONTROL-024#FR-24-C01\u0060; \u0060FR-ACCESSCONTROL-024#FR-24-C02\u0060; \u0060FR-ACCESSCONTROL-024#FR-24-C03\u0060; \u0060FR-ACCESSCONTROL-024#FR-24-C04\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Synthetic existing profiles have player/moderator/senior/admin roles; configured admin IDs are server-only. |\n| Test data | Admin Ada; moderator Mo; senior Sam; player Pat; server-configured Ada; reason Fixture role grant. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Ada grant moderator to Pat with a reason; open staff pages as Pat; revoke that role and retry. | Grant enables only moderation/word editing; revocation denies new privileged actions and history retains reason. |\n| 2 | Try user management as Mo/Sam and removal of configured/final administrator through the UI. | Only administrators manage roles; configured admin and final effective admin cannot be revoked. |\n| 3 | Inspect bounded user directory/history. | Only permitted profile metadata/effective roles appear; emails, OIDC subjects and credentials are absent. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Verify Server-authoritative ACL transactions\n Scenario: TEST-ACLAUTHORIZATION-132 design verification\n Given Synthetic existing profiles have player/moderator/senior/admin roles; configured admin IDs are server-only.\n And the fixture data is Admin Ada; moderator Mo; senior Sam; player Pat; server-configured Ada; reason Fixture role grant.\n When As Ada grant moderator to Pat with a reason; open staff pages as Pat; revoke that role and retry.\n Then Grant enables only moderation/word editing; revocation denies new privileged actions and history retains reason.\n When Try user management as Mo/Sam and removal of configured/final administrator through the UI.\n Then Only administrators manage roles; configured admin and final effective admin cannot be revoked.\n When Inspect bounded user directory/history.\n Then Only permitted profile metadata/effective roles appear; emails, OIDC subjects and credentials are absent.\n\u0060\u0060\u0060\n\n## Boundaries\n\nUI consequences do not prove concurrent cross-revocation serialization, atomic audit or private environment handling; retain separate technical evidence.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ACLAUTHORIZATION-132", "acceptanceCriteria": [ { "id": "TR-32-C01", "text": "Forged actor IDs, browser roles, missing sessions and cross-origin writes are rejected; browser database roles have no direct ACL table/function privilege.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-32-C02", "text": "Serialize concurrent role changes and final-admin checks. A content writer blocked behind revocation must reload roles after the lock and deny a new revoked write.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-32-C03", "text": "Audit insertion failure rolls back role/revision/idempotency mutations; stale revisions and changed command digests fail without side effects; permitted exact replays do not reapply grants.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "FR-24-C01", "text": "WORDPAIRS_ADMIN_PROFILE_IDS is a private server-only comma-separated allowlist of stable existing profile IDs. Empty configuration grants no bootstrap authority and aliases/browser input cannot grant access.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-24-C02", "text": "Moderators moderate and curate; senior moderators additionally resolve independent appeals; administrators additionally manage users. Proposer/original-reviewer independence remains enforced.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-24-C03", "text": "Roles are read from trusted current server/database evidence; configured administrator authority cannot be revoked in the UI and the final effective administrator cannot be removed, including concurrent cross-revocation.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-24-C04", "text": "Role changes atomically persist revision, canonical retry result and reasoned audit. Revoked administrators cannot replay old grants to regain authority; directories omit credentials, emails and OIDC subjects.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ADMINUI-136", "condition": "Provide dedicated pages for moderation, word-pair/hint management and user-role administration.", "title": "Administration browser flows and private-state invalidation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-136; canonical MCP ID: TEST-ADMINUI-136. Browser HTTP seams are disclosed; real PostgreSQL authority is separately verified by TEST-WP-132/133. Former provisional MCP ID: TEST-WP-136. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ADMINUI-136\n# TEST-ADMINUI-136 - Administration browser flows and private-state invalidation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Administration browser flows and private-state invalidation. |\n| QBrain reference/scope | \u0060TEST-ADMINUI-136\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [admin_acl_design.md](../../../admin_acl_design.md) |\n| Frame/element identifiers | SCREEN-ADMIN, STATE-ADMIN-01, STATE-ADMIN-02, STATE-ADMIN-03, STATE-ADMIN-04, STATE-ADMIN-05, SCREEN-WORDS, STATE-WORDS-01, STATE-WORDS-02, STATE-WORDS-03, STATE-WORDS-04, STATE-WORDS-05, SCREEN-USERS, STATE-USERS-01, STATE-USERS-02, STATE-USERS-03, STATE-USERS-04, STATE-USERS-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ADMINPAGES-023#FR-23-C01\u0060; \u0060FR-ADMINPAGES-023#FR-23-C02\u0060; \u0060FR-ADMINPAGES-023#FR-23-C03\u0060; \u0060FR-ADMINPAGES-023#FR-23-C04\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Independent player, moderator, senior and administrator profiles exist with pending/appealed/approved/completed content. |\n| Test data | Routes /admin, /admin/words, /admin/users; searchable synthetic aliases; reason Fixture review. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Visit all three routes as player and then each authorized staff role; search/filter queue, words and user directory. | Player sees denied state; role-appropriate bounded records/controls appear; no private records leak. |\n| 2 | Make a reasoned permitted decision; inspect history; simulate authorization loss while an older GET remains pending. | History retains the decision; a late old response cannot restore private data after denial. |\n| 3 | Simulate an uncertain write, retry the pending operation, and use forms at 390x844. | Retry preserves command identity, successful draft clears once, no duplicate write is shown, and phone forms remain operable. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Administration browser flows and private-state invalidation\n Scenario: TEST-ADMINUI-136 design verification\n Given Independent player, moderator, senior and administrator profiles exist with pending/appealed/approved/completed content.\n And the fixture data is Routes /admin, /admin/words, /admin/users; searchable synthetic aliases; reason Fixture review.\n When Visit all three routes as player and then each authorized staff role; search/filter queue, words and user directory.\n Then Player sees denied state; role-appropriate bounded records/controls appear; no private records leak.\n When Make a reasoned permitted decision; inspect history; simulate authorization loss while an older GET remains pending.\n Then History retains the decision; a late old response cannot restore private data after denial.\n When Simulate an uncertain write, retry the pending operation, and use forms at 390x844.\n Then Retry preserves command identity, successful draft clears once, no duplicate write is shown, and phone forms remain operable.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ADMINUI-136", "acceptanceCriteria": [ { "id": "FR-23-C01", "text": "Authorized staff can search/filter the moderation queue at /admin, approve/reject with reasons, review history and independently resolve permitted appeals.", "isSatisfied": true, "evidence": "tests/browser/admin.phase6.spec.ts; tests/browser/content.phase5.spec.ts; docs/admin_acl_review_receipt.json" }, { "id": "FR-23-C02", "text": "/admin/words exposes search/category filters, authoring and immutable revision editing; /admin/users exposes bounded profile search, reasoned grants/revocations and role audit history.", "isSatisfied": true, "evidence": "tests/browser/admin.phase6.spec.ts; tests/browser/content.phase5.spec.ts; docs/admin_acl_review_receipt.json" }, { "id": "FR-23-C03", "text": "Ordinary players cannot fetch privileged records or perform administrative writes; stale authorized GET responses cannot restore private data after an authorization denial.", "isSatisfied": true, "evidence": "tests/browser/admin.phase6.spec.ts; tests/browser/content.phase5.spec.ts; docs/admin_acl_review_receipt.json" }, { "id": "FR-23-C04", "text": "Phone-sized forms and controls remain readable and operable; uncertain-write retries preserve command identity and clear successful drafts without duplicates.", "isSatisfied": true, "evidence": "tests/browser/admin.phase6.spec.ts; tests/browser/content.phase5.spec.ts; docs/admin_acl_review_receipt.json" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ANCHORRANDOMNESS-113", "condition": "Inject every random boundary/index for2,8,25-player rosters; assert uniform-source bounds and only the selected anchor may choose the first category.", "title": "Verify TR-13: Anchor assignment", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-113; canonical MCP ID: TEST-ANCHORRANDOMNESS-113. Technical/integration or operational evidence only. Source TR-13. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-113. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-13", "text": "Inject every random boundary/index for2,8,25-player rosters; assert uniform-source bounds and only the selected anchor may choose the first category.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-13-C01", "text": "At game start, the service snapshots and indexes the active roster from 1 through N, where N is 2-25. It draws a random integer uniformly from 1 through N, inclusive, and assigns the matching player as anchor for the match. The index remains stable for the match. The service accepts the first category selection only from the anchor and synchronizes the assignment and selected category to all room clients.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ANSWERCONFIDENTIALITY-105", "condition": "Compare player, solved-player, observer and public DTOs before/after reveal; assert hidden targets, other private views and raw guesses never leak.", "title": "Verify TR-05: Answer confidentiality", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-105; canonical MCP ID: TEST-ANSWERCONFIDENTIALITY-105. Technical/integration or operational evidence only. Source TR-05. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-105. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-05", "text": "Compare player, solved-player, observer and public DTOs before/after reveal; assert hidden targets, other private views and raw guesses never leak.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-05-C01", "text": "The target answer remains unavailable to clients until round reveal. A hint is sent only to clients that remain unsolved. Solved players receive no later hints or answer controls for that round.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ANSWERORDER-103", "condition": "Submit simultaneous correct answers with fixed server timestamps; assert one acceptance sequence and earliest accepted solver authority without client-clock influence.", "title": "Verify TR-03: Submission ordering", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-103; canonical MCP ID: TEST-ANSWERORDER-103. Technical/integration or operational evidence only. Source TR-03. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-103. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-03", "text": "Submit simultaneous correct answers with fixed server timestamps; assert one acceptance sequence and earliest accepted solver authority without client-clock influence.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-03-C01", "text": "The service records an authoritative acceptance time for each submission. The first correct accepted answer determines the next-category chooser. If submissions arrive at effectively the same time, the service applies a deterministic ordering rule.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ANSWERVALIDATION-104", "condition": "Verify NFKC, trimmed/collapsed whitespace, case folding, punctuation preservation and explicit alternatives; reject fuzzy/unlisted matches.", "title": "Verify TR-04: Answer validation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-104; canonical MCP ID: TEST-ANSWERVALIDATION-104. Technical/integration or operational evidence only. Source TR-04. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-104. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-04", "text": "Verify NFKC, trimmed/collapsed whitespace, case folding, punctuation preservation and explicit alternatives; reject fuzzy/unlisted matches.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-04-C01", "text": "The service validates each submission against the pair\u2019s target and its approved accepted-answer list. Capitalization, whitespace, punctuation, and synonym handling follow an approved answer-matching policy.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-03", "text": "Answer normalization: Apply Unicode NFKC, trim outer whitespace, collapse internal whitespace, and compare case-insensitively. Preserve punctuation. Only the canonical answer or an explicitly listed accepted alternative matches; no fuzzy matching.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ARCHIVESWBOM-128", "condition": "Inspect exact tracked-source tar.gz, full license/notices, matching SWBOM and SHA256 sidecar; reject missing/malformed/mismatched reports before actual release publication.", "title": "Verify TR-28: SWBOM in release archive", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "New verification/extension import key: TEST-WP-128; canonical MCP ID: TEST-ARCHIVESWBOM-128. Technical/integration or operational evidence only. Source TR-28. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-128. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-28", "text": "Inspect exact tracked-source tar.gz, full license/notices, matching SWBOM and SHA256 sidecar; reject missing/malformed/mismatched reports before actual release publication.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-28-C01", "text": "Every release must include a downloadable archive containing the release contents and the SWBOM generated for the exact release commit and published build. Place the report at `sbom/.cdx.json` inside the archive. The release packaging step must verify that the SWBOM exists and that its commit SHA matches the release before publication. Do not depend on GitHub Actions for packaging or publication.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-24", "text": "Source archive: Use `.tar.gz` containing the complete tracked source at the release commit, root GPL-2.0-only `LICENSE`, attribution/notices, and `sbom/.cdx.json`; exclude secrets and generated dependencies. Include a SHA-256 sidecar. AC-41/42 validate temporary fixtures; live deployment inventory remains TR-only.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ARTRENDER-107", "condition": "Render pairs from the same/different categories with exact assets; fail an asset request then retry, asserting readable fallback and actual recovered computed background.", "title": "Verify TR-07: Background rendering", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-107; canonical MCP ID: TEST-ARTRENDER-107. Technical/integration or operational evidence only. Source TR-07. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-107. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-07", "text": "Render pairs from the same/different categories with exact assets; fail an asset request then retry, asserting readable fallback and actual recovered computed background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-07-C01", "text": "Category backgrounds load on supported phone screens. An overlay or equivalent treatment preserves text contrast. A missing asset must not make round controls unreadable.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-AUTHORITATIVEANSWERHANDLING-045", "condition": "Given an unsolved player submits an answer for the current stage, when the server checks it against the target and approved accepted-answer list, then only a correct answer is accepted and scored once for that stage; an incorrect answer does not change score or expose guess text to other players; and the target answer remains unavailable to clients until round reveal.", "title": "AC-45: Authoritative answer handling", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-45; canonical MCP ID: TEST-AUTHORITATIVEANSWERHANDLING-045. Original criterion AC-45; cases AC-45-T01, AC-45-T02, AC-45-T03, AC-45-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-045. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-AUTHORITATIVEANSWERHANDLING-045\n# TEST-AUTHORITATIVEANSWERHANDLING-045 - AC-45: Authoritative answer handling\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-45: Authoritative answer handling. |\n| QBrain reference/scope | \u0060TEST-AUTHORITATIVEANSWERHANDLING-045\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg); [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-E, ROUND-NODE-F, ROUND-TRANS-D-E, ROUND-TRANS-E-F, ROUND-TRANS-F-G, ROUND-TRANS-I-F, MSG-M14, MSG-M15, MSG-M16, MSG-M17, MSG-M18, MSG-M23, MSG-M24, MSG-M25, MSG-FLOW, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANSWERREVEAL-012#AC-45\u0060; \u0060FR-ANSWERSTAGES-008#AC-45\u0060; \u0060FR-SCORELOCK-010#AC-45\u0060; \u0060TR-ANSWER-CONFIDENTIALITY-005#TR-05-C01\u0060; \u0060TR-ANSWER-VALIDATION-004#DEC-03\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice is unsolved with one permitted answer per stage and Bob watches another client. |\n| Test data | Target Cold; accepted alternative chilly; inputs \u0022 COLD \u0022, \u0022chilly\u0022, \u0022Cold!\u0022, \u0022warm\u0022 in independent stages. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Submit each input in independent fixtures. | Normalized canonical and listed alternative score once; punctuation-modified Cold! and warm do not score. |\n| 2 | Inspect Bob\u0027s view before reveal and attempt a second same-stage submission. | Bob sees no guess text or unrevealed target; a second submission cannot award additional points. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-45: Authoritative answer handling\n Scenario: TEST-AUTHORITATIVEANSWERHANDLING-045 design verification\n Given Alice is unsolved with one permitted answer per stage and Bob watches another client.\n And the fixture data is Target Cold; accepted alternative chilly; inputs \u0022 COLD \u0022, \u0022chilly\u0022, \u0022Cold!\u0022, \u0022warm\u0022 in independent stages.\n When Submit each input in independent fixtures.\n Then Normalized canonical and listed alternative score once; punctuation-modified Cold! and warm do not score.\n When Inspect Bob\u0027s view before reveal and attempt a second same-stage submission.\n Then Bob sees no guess text or unrevealed target; a second submission cannot award additional points.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-AUTHORITATIVEANSWERHANDLING-045", "acceptanceCriteria": [ { "id": "AC-45", "text": "Given an unsolved player submits an answer for the current stage, when the server checks it against the target and approved accepted-answer list, then only a correct answer is accepted and scored once for that stage; an incorrect answer does not change score or expose guess text to other players; and the target answer remains unavailable to clients until round reveal.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-BROWSEOPENLOBBIES-022", "condition": "Given a discoverable lobby is waiting and has fewer players than its configured capacity, when a player browses lobbies, then the lobby appears as joinable; hidden, full, or started lobbies do not appear as joinable.", "title": "AC-22: Browse open lobbies", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-22; canonical MCP ID: TEST-BROWSEOPENLOBBIES-022. Original criterion AC-22; cases AC-22-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-022. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-BROWSEOPENLOBBIES-022\n# TEST-BROWSEOPENLOBBIES-022 - AC-22: Browse open lobbies\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-22: Browse open lobbies. |\n| QBrain reference/scope | \u0060TEST-BROWSEOPENLOBBIES-022\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_lobby_discovery.svg](../../../word_association_lobby_discovery.svg) |\n| Frame/element identifiers | DISC-FLOW, DISC-NODE-A, DISC-NODE-B, DISC-NODE-D, DISC-NODE-E, DISC-NODE-F, DISC-TRANS-A-B, DISC-TRANS-B-C, DISC-TRANS-C-D, DISC-TRANS-D-E, DISC-TRANS-E-F, DISC-TRANS-E-B, ROOM-FLOW, ROOM-NODE-C, ROOM-TRANS-C-D, SCREEN-DISCOVERY, STATE-DISCOVERY-01, STATE-DISCOVERY-02, STATE-DISCOVERY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-22\u0060; \u0060TR-LOBBY-MATCHING-017#TR-17-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Fixture contains four rooms with distinguishable capacity/waiting/discovery flags. |\n| Test data | Public waiting 1/2; private waiting 1/2; public full 2/2; public started 2/2. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open lobby browsing. | Only the discoverable waiting room with an open seat appears as joinable. |\n| 2 | Select that room and join. | The player reaches its room; hidden/full/started rooms remain unavailable as joinable entries. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-22: Browse open lobbies\n Scenario: TEST-BROWSEOPENLOBBIES-022 design verification\n Given Fixture contains four rooms with distinguishable capacity/waiting/discovery flags.\n And the fixture data is Public waiting 1/2; private waiting 1/2; public full 2/2; public started 2/2.\n When Open lobby browsing.\n Then Only the discoverable waiting room with an open seat appears as joinable.\n When Select that room and join.\n Then The player reaches its room; hidden/full/started rooms remain unavailable as joinable entries.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-BROWSEOPENLOBBIES-022", "acceptanceCriteria": [ { "id": "AC-22", "text": "Given a discoverable lobby is waiting and has fewer players than its configured capacity, when a player browses lobbies, then the lobby appears as joinable; hidden, full, or started lobbies do not appear as joinable.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CANDIDATEHOLD-141", "condition": "Verify the documented UI behavior: Hold and resume a nominated candidate.", "title": "Hold and resume a nominated candidate", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-CANDIDATEHOLD-141\n# TEST-CANDIDATEHOLD-141 - Hold and resume a nominated candidate\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Hold and resume a nominated candidate. |\n| QBrain reference/scope | \u0060TEST-CANDIDATEHOLD-141\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | NOM-NODE-H, NOM-TRANS-G-H, GAP-FLOW-CANDIDATEHOLD, GAP-TRANS-CANDIDATEHOLD-01, GAP-TRANS-CANDIDATEHOLD-02, GAP-TRANS-CANDIDATEHOLD-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CANDIDATEHOLD-028#UI-HOLD-01\u0060; \u0060FR-CANDIDATEHOLD-028#UI-HOLD-02\u0060; \u0060FR-CANDIDATEHOLD-028#UI-HOLD-03\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Moon has ten unique nominations and pending_review status; Alice is proposer and Bob an independent moderator. |\n| Test data | Hold reason Check wording; resume reason Review can continue; current game score Alice5. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Attempt hold as Alice, then as Bob without a reason and with Check wording. | Proposer and empty-reason attempts fail; valid hold enters on_hold with actor/reason in history. |\n| 2 | Inspect counts, score and approval/publish controls while held. | Ten nominations and Alice5 persist; held content cannot be approved, published or played. |\n| 3 | Resume as independent Bob with Review can continue. | Threshold is rechecked, status returns to pending_review and both audited decisions remain; resume is not approval. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Hold and resume a nominated candidate\n Scenario: TEST-CANDIDATEHOLD-141 design verification\n Given Moon has ten unique nominations and pending_review status; Alice is proposer and Bob an independent moderator.\n And the fixture data is Hold reason Check wording; resume reason Review can continue; current game score Alice5.\n When Attempt hold as Alice, then as Bob without a reason and with Check wording.\n Then Proposer and empty-reason attempts fail; valid hold enters on_hold with actor/reason in history.\n When Inspect counts, score and approval/publish controls while held.\n Then Ten nominations and Alice5 persist; held content cannot be approved, published or played.\n When Resume as independent Bob with Review can continue.\n Then Threshold is rechecked, status returns to pending_review and both audited decisions remain; resume is not approval.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-CANDIDATEHOLD-141\n\nBEGIN UI-IMPLEMENTATION TEST-CANDIDATEHOLD-141\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-CANDIDATEHOLD-141", "acceptanceCriteria": [ { "id": "UI-HOLD-01", "text": "An independent moderator with a nonempty reason can move a pending candidate to on_hold; unauthorized actors and the proposer cannot do so.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-HOLD-02", "text": "on_hold retains nominations and history but prevents approval/publication/playability and never changes current scores or progression.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-HOLD-03", "text": "An independent moderator resumes with a reason to pending_review after rechecking unique-count threshold; hold/resume actor and reasons are audited.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CATALOGINTEGRITY-106", "condition": "Reject incomplete pairs, wrong hint counts, wrong category/background, reused IDs and invalid catalog transitions; valid complete records become playable atomically.", "title": "Verify TR-06: Curated content integrity", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-106; canonical MCP ID: TEST-CATALOGINTEGRITY-106. Technical/integration or operational evidence only. Source TR-06. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-106. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-06", "text": "Reject incomplete pairs, wrong hint counts, wrong category/background, reused IDs and invalid catalog transitions; valid complete records become playable atomically.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-06-C01", "text": "Every playable pair has a category identifier, prompt, target answer, three ordered hints, accepted answers, and a category-background reference. A category cannot be enabled unless its required content and background are present.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-05", "text": "Content volume and reuse: Seed 10 complete pairs per category. Do not repeat a pair within a match until every playable pair in the selected category has been used; then reshuffle that category\u2019s eligible pool.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-06", "text": "Colors category: Each Colors pair contains complementary colors.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CATALOGVERSIONING-133", "condition": "Route editorial and community publication through the serialized moderation transaction and catalog projection, preserving exact version lookup, audit/outbox atomicity and the historical version ceiling.", "title": "Verify Immutable and bounded catalog publication", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-133; canonical MCP ID: TEST-CATALOGVERSIONING-133. Actual test sources: tests/application/access.test.ts, tests/application/catalog-admin.test.ts, tests/web/admin-api.test.ts, tests/integration/admin.integration.ts, tests/integration/multiplayer.integration.ts, tests/browser/admin.phase6.spec.ts. Match the applicable suite to this requirement; do not claim all suites prove every boundary. Former provisional MCP ID: TEST-WP-133. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CATALOGVERSIONING-133\n# TEST-CATALOGVERSIONING-133 - Verify Immutable and bounded catalog publication\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Verify Immutable and bounded catalog publication. |\n| QBrain reference/scope | \u0060TEST-CATALOGVERSIONING-133\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [admin_acl_design.md](../../../admin_acl_design.md) |\n| Frame/element identifiers | SCREEN-WORDS, STATE-WORDS-01, STATE-WORDS-02, STATE-WORDS-03, STATE-WORDS-04, STATE-WORDS-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-WORDHINTEDITOR-025#FR-25-C01\u0060; \u0060FR-WORDHINTEDITOR-025#FR-25-C02\u0060; \u0060FR-WORDHINTEDITOR-025#FR-25-C03\u0060; \u0060FR-WORDHINTEDITOR-025#FR-25-C04\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Mo may edit words; an active round holds pair Hot/Cold version 0; future games can select published versions. |\n| Test data | Exactly 3 ordered hints; replacement target Chilly; invalid 2/4 hints; reason Fixture edit. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Save invalid 2-hint and 4-hint versions, then a complete 3-hint next revision. | Invalid saves do not mutate content; valid edit appends the next version without moving categories. |\n| 2 | Observe the active round, start a future round, and exclude latest pair with a reason. | Active round retains version 0; future pool uses highest selectable version and never falls back to an older excluded version. |\n| 3 | Try excluding the last playable initial-category pair and publishing at the 4096-version ceiling. | Both are rejected without deleting history or emptying the category. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Verify Immutable and bounded catalog publication\n Scenario: TEST-CATALOGVERSIONING-133 design verification\n Given Mo may edit words; an active round holds pair Hot/Cold version 0; future games can select published versions.\n And the fixture data is Exactly 3 ordered hints; replacement target Chilly; invalid 2/4 hints; reason Fixture edit.\n When Save invalid 2-hint and 4-hint versions, then a complete 3-hint next revision.\n Then Invalid saves do not mutate content; valid edit appends the next version without moving categories.\n When Observe the active round, start a future round, and exclude latest pair with a reason.\n Then Active round retains version 0; future pool uses highest selectable version and never falls back to an older excluded version.\n When Try excluding the last playable initial-category pair and publishing at the 4096-version ceiling.\n Then Both are rejected without deleting history or emptying the category.\n\u0060\u0060\u0060\n\n## Boundaries\n\nActual immutable persistence and atomic ceiling checks need separate database evidence, not just the form outcome.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CATALOGVERSIONING-133", "acceptanceCriteria": [ { "id": "TR-33-C01", "text": "Save v0 then v1, exclude latest, then save v2: old lookups remain exact and future pools use the current selectable highest version.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-33-C02", "text": "Reject reused/cross-category IDs and nonzero community activation versions, invalid hints and category/background mismatches.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-33-C03", "text": "At4096 approved historical versions, another save or activation returns SERVICE_LIMIT without catalog, state, audit, revision or idempotency writes.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "FR-25-C01", "text": "Each pair has a prompt, canonical target, accepted alternatives, approved category/background and exactly three ordered bounded hints; invalid input is rejected without mutation.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-25-C02", "text": "Creation uses an unused ID at version0; edits append exactly the next version without moving an existing ID to another category. Community activation cannot reuse IDs or skip versions.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-25-C03", "text": "Current and historical rounds retain their recorded versions. Future selection chooses the highest version per ID and then selectability, with no fallback to older excluded versions.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" }, { "id": "FR-25-C04", "text": "Reasoned exclusion preserves history and cannot empty an initial category. Both editorial and community publication reject a projected total above4096 historical approved versions atomically.", "isSatisfied": true, "evidence": "docs/admin_acl_design.md; docs/admin_acl_review_receipt.json; tests/browser/admin.phase6.spec.ts; tests/integration/admin.integration.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CATEGORYART-005", "condition": "Given two word pairs in the same category, when each is played, then both rounds use that category\u2019s predefined background. A pair in another category uses that category\u2019s background.", "title": "AC-05: Category art", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-05; canonical MCP ID: TEST-CATEGORYART-005. Original criterion AC-05; cases AC-05-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-005. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CATEGORYART-005\n# TEST-CATEGORYART-005 - AC-05: Category art\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-05: Category art. |\n| QBrain reference/scope | \u0060TEST-CATEGORYART-005\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-D, ROUND-TRANS-C-D, ROUND-TRANS-D-E, ROUND-TRANS-L-D, MSG-M16, MSG-M17, MSG-M18, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORIES-005#AC-05\u0060; \u0060FR-CATEGORYART-006#AC-05\u0060; \u0060TR-ART-RENDER-007#TR-07-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Controlled catalog provides two Opposites pairs and one Colors pair with approved backgrounds. |\n| Test data | Hot/Cold and Up/Down in Opposites; Red/Green in Colors. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Play Hot/Cold and then Up/Down. | Both rounds use the same Opposites background. |\n| 2 | Play the Colors pair and simulate a missing background asset in a separate fixture. | Colors uses its own background; missing art does not obscure prompt, hints, input or scorecard. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-05: Category art\n Scenario: TEST-CATEGORYART-005 design verification\n Given Controlled catalog provides two Opposites pairs and one Colors pair with approved backgrounds.\n And the fixture data is Hot/Cold and Up/Down in Opposites; Red/Green in Colors.\n When Play Hot/Cold and then Up/Down.\n Then Both rounds use the same Opposites background.\n When Play the Colors pair and simulate a missing background asset in a separate fixture.\n Then Colors uses its own background; missing art does not obscure prompt, hints, input or scorecard.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CATEGORYART-005", "acceptanceCriteria": [ { "id": "AC-05", "text": "Given two word pairs in the same category, when each is played, then both rounds use that category\u2019s predefined background. A pair in another category uses that category\u2019s background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CATEGORYCHOICE-011", "condition": "Given at least one player solves a round, when the round ends, then the earliest accepted correct solver can select the next category.", "title": "AC-11: Category choice", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-11; canonical MCP ID: TEST-CATEGORYCHOICE-011. Original criterion AC-11; cases AC-11-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-011. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CATEGORYCHOICE-011\n# TEST-CATEGORYCHOICE-011 - AC-11: Category choice\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-11: Category choice. |\n| QBrain reference/scope | \u0060TEST-CATEGORYCHOICE-011\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-L, ROUND-TRANS-K-L, ROUND-TRANS-L-D, MSG-M36, MSG-M37, MSG-M38, MSG-M39, MSG-FLOW, SCREEN-CHOOSER, STATE-CHOOSER-01, STATE-CHOOSER-02, STATE-CHOOSER-03, SCREEN-SUMMARY, STATE-SUMMARY-01, STATE-SUMMARY-02, STATE-SUMMARY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANCHORSELECTION-007#AC-11\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice and Bob solve one round; accepted order is Bob first, then Alice. |\n| Test data | Authoritative accepted solve times Bob 4 seconds, Alice 5 seconds. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | End the round and attempt next-category choice as Alice, then as Bob. | Only first accepted solver Bob can select the next category. |\n| 2 | Choose Colors as Bob. | All room clients progress to the Colors round and background. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-11: Category choice\n Scenario: TEST-CATEGORYCHOICE-011 design verification\n Given Alice and Bob solve one round; accepted order is Bob first, then Alice.\n And the fixture data is Authoritative accepted solve times Bob 4 seconds, Alice 5 seconds.\n When End the round and attempt next-category choice as Alice, then as Bob.\n Then Only first accepted solver Bob can select the next category.\n When Choose Colors as Bob.\n Then All room clients progress to the Colors round and background.\n\u0060\u0060\u0060\n\n## Boundaries\n\nAn effectively simultaneous acceptance needs deterministic server ordering evidence; visual arrival order is not an oracle. The no-solver fallback is listed as a separate uncovered decision obligation.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CATEGORYCHOICE-011", "acceptanceCriteria": [ { "id": "AC-11", "text": "Given at least one player solves a round, when the round ends, then the earliest accepted correct solver can select the next category.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CATEGORYSUGGESTIONUNLOCK-019", "condition": "Given a player has fewer than 10 game wins, when they open the content suggestion flow, then category-and-pair submission is unavailable. Given they have won 10 games, then they can submit one proposed relationship category with three word pairs for review. The submission is not playable until approved and complete.", "title": "AC-19: Category suggestion unlock", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-19; canonical MCP ID: TEST-CATEGORYSUGGESTIONUNLOCK-019. Original criterion AC-19; cases AC-19-T01, AC-19-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-019. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CATEGORYSUGGESTIONUNLOCK-019\n# TEST-CATEGORYSUGGESTIONUNLOCK-019 - AC-19: Category suggestion unlock\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-19: Category suggestion unlock. |\n| QBrain reference/scope | \u0060TEST-CATEGORYSUGGESTIONUNLOCK-019\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_category_suggestion.svg](../../../word_association_category_suggestion.svg) |\n| Frame/element identifiers | SUG-FLOW, SUG-NODE-A, SUG-NODE-B, SUG-NODE-C, SUG-NODE-D, SUG-TRANS-A-B, SUG-TRANS-B-C, SUG-TRANS-C-D, SUG-TRANS-D-E, SCREEN-SUGGESTION, STATE-SUGGESTION-01, STATE-SUGGESTION-02, STATE-SUGGESTION-03, STATE-SUGGESTION-04, STATE-SUGGESTION-05, STATE-SUGGESTION-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORYSUGGESTIONS-017#AC-19\u0060; \u0060FR-CATEGORYSUGGESTIONS-017#DEC-09\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Profiles have controlled lifetime win totals; no open suggestion initially. |\n| Test data | Alice 9 wins; Bob 10; Bob proposes Space with exactly three complete pair suggestions. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open category suggestions as Alice and Bob. | Alice cannot submit; Bob can submit one category with exactly three pairs. |\n| 2 | As Bob try two and four pairs, then exactly three; try opening a second suggestion. | Only exactly three is accepted and a second open suggestion is rejected. |\n| 3 | Observe submitted content before approval and complete curation. | The submission is in review and not playable. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-19: Category suggestion unlock\n Scenario: TEST-CATEGORYSUGGESTIONUNLOCK-019 design verification\n Given Profiles have controlled lifetime win totals; no open suggestion initially.\n And the fixture data is Alice 9 wins; Bob 10; Bob proposes Space with exactly three complete pair suggestions.\n When Open category suggestions as Alice and Bob.\n Then Alice cannot submit; Bob can submit one category with exactly three pairs.\n When As Bob try two and four pairs, then exactly three; try opening a second suggestion.\n Then Only exactly three is accepted and a second open suggestion is rejected.\n When Observe submitted content before approval and complete curation.\n Then The submission is in review and not playable.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CATEGORYSUGGESTIONUNLOCK-019", "acceptanceCriteria": [ { "id": "AC-19", "text": "Given a player has fewer than 10 game wins, when they open the content suggestion flow, then category-and-pair submission is unavailable. Given they have won 10 games, then they can submit one proposed relationship category with three word pairs for review. The submission is not playable until approved and complete.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CLOCKCONSISTENCY-108", "condition": "Control server clock across all stages, accepted solves and deadlines; assert elapsed-time/scoring/tiebreak use server measurements and80seconds per unsolved round.", "title": "Verify TR-08: Clock consistency", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-108; canonical MCP ID: TEST-CLOCKCONSISTENCY-108. Technical/integration or operational evidence only. Source TR-08. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-108. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-08", "text": "Control server clock across all stages, accepted solves and deadlines; assert elapsed-time/scoring/tiebreak use server measurements and80seconds per unsolved round.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-08-C01", "text": "Elapsed answer time uses a consistent server-controlled round start time and accepted submission time. Client clocks may animate locally, but scorecard and tiebreak values use authoritative times.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-04", "text": "Total answer time and final tie: Sum server-measured solve durations; an unsolved round adds the 80-second maximum round duration. Sort tied scores by this total; exact remaining ties share rank.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CONFIGUREDCAPACITY-024", "condition": "Given a player creates a room, when they set a maximum capacity from 2 through 25, then the room stores and displays that limit. Values below 2 or above 25 are rejected.", "title": "AC-24: Configured capacity", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-24; canonical MCP ID: TEST-CONFIGUREDCAPACITY-024. Original criterion AC-24; cases AC-24-T01, AC-24-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-024. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CONFIGUREDCAPACITY-024\n# TEST-CONFIGUREDCAPACITY-024 - AC-24: Configured capacity\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-24: Configured capacity. |\n| QBrain reference/scope | \u0060TEST-CONFIGUREDCAPACITY-024\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg) |\n| Frame/element identifiers | ROOM-FLOW, ROOM-NODE-A, ROOM-NODE-B, ROOM-TRANS-A-B, ROOM-TRANS-B-G, MSG-M01, MSG-M02, SCREEN-CREATE, STATE-CREATE-01; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYLIFECYCLE-003#AC-24\u0060; \u0060FR-ROOMACCESS-001#AC-24\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | An identified player can create a room. |\n| Test data | Capacity inputs 1, 2, 8, 25, 26. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Try creating rooms with capacities 1 and 26. | Both invalid capacities are rejected; no invalid room is created. |\n| 2 | Create separate rooms with 2, 8 and 25. | Each room stores and displays exactly its selected limit and correct open slots. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-24: Configured capacity\n Scenario: TEST-CONFIGUREDCAPACITY-024 design verification\n Given An identified player can create a room.\n And the fixture data is Capacity inputs 1, 2, 8, 25, 26.\n When Try creating rooms with capacities 1 and 26.\n Then Both invalid capacities are rejected; no invalid room is created.\n When Create separate rooms with 2, 8 and 25.\n Then Each room stores and displays exactly its selected limit and correct open slots.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CONFIGUREDCAPACITY-024", "acceptanceCriteria": [ { "id": "AC-24", "text": "Given a player creates a room, when they set a maximum capacity from 2 through 25, then the room stores and displays that limit. Values below 2 or above 25 are rejected.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CONNECTIONRECOVERY-109", "condition": "Simulate lost response, reconnect, expiry and stale commands; assert same-command canonical retry, unchanged committed state and authoritative recovery.", "title": "Verify TR-09: Connection handling", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-109; canonical MCP ID: TEST-CONNECTIONRECOVERY-109. Technical/integration or operational evidence only. Source TR-09. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-109. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CONNECTIONRECOVERY-109\n# TEST-CONNECTIONRECOVERY-109 - Verify TR-09: Connection handling\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Verify TR-09: Connection handling. |\n| QBrain reference/scope | \u0060TEST-CONNECTIONRECOVERY-109\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg); [room_sync_fix.md](../../../room_sync_fix.md) |\n| Frame/element identifiers | SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06, SCREEN-SERVICE, STATE-SERVICE-01, STATE-SERVICE-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060TR-CONNECTION-RECOVERY-009#DEC-17\u0060; \u0060TR-CONNECTION-RECOVERY-009#TR-09-C01\u0060; \u0060TR-ROOM-CODES-010#DEC-17\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice has an accepted score and a room membership; a separate client Bob remains connected. |\n| Test data | Accepted score 5; disconnected durations below and above 120-second grace; uncertain submission fixture. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Disconnect Alice, reconnect within grace and reopen the room. | Membership and accepted score persist; no duplicate submission is recorded. |\n| 2 | Repeat beyond grace and observe the normal departure rule for the current room phase. | Expired membership departs without corrupting scores; retry of an uncertain command retains its original command ID. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Verify TR-09: Connection handling\n Scenario: TEST-CONNECTIONRECOVERY-109 design verification\n Given Alice has an accepted score and a room membership; a separate client Bob remains connected.\n And the fixture data is Accepted score 5; disconnected durations below and above 120-second grace; uncertain submission fixture.\n When Disconnect Alice, reconnect within grace and reopen the room.\n Then Membership and accepted score persist; no duplicate submission is recorded.\n When Repeat beyond grace and observe the normal departure rule for the current room phase.\n Then Expired membership departs without corrupting scores; retry of an uncertain command retains its original command ID.\n\u0060\u0060\u0060\n\n## Boundaries\n\nNetwork readiness and authoritative grace expiry are conditions; do not substitute a fixed sleep. Generic recovery copy is not specified.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CONNECTIONRECOVERY-109", "acceptanceCriteria": [ { "id": "VERIFY-TR-09", "text": "Simulate lost response, reconnect, expiry and stale commands; assert same-command canonical retry, unchanged committed state and authoritative recovery.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-09-C01", "text": "A disconnect must not corrupt accepted scores or duplicate a submission. Reconnecting players retain membership for a two-minute grace interval; after it expires the room applies the normal departure rules. Client retries reuse the original command ID.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-17", "text": "Room code, reconnect, creator departure: Use an eight-character Crockford Base32 code. Codes remain valid while the room is active and expire on close; empty rooms close after 30 minutes. Reconnect retains membership for a two-minute grace interval. Creator departure grants no special authority; remaining players retain control. Invalid/expired codes return the same generic not-found response; limit code attempts to 10 per minute per session.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CONTENTVALIDATION-016", "condition": "Given a category is enabled, when the content catalog is checked, then every playable pair has a prompt, target answer, three ordered hints, accepted-answer policy, and category background.", "title": "AC-16: Content validation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-16; canonical MCP ID: TEST-CONTENTVALIDATION-016. Original criterion AC-16; cases AC-16-T01, AC-16-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-016. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-CONTENTVALIDATION-016\n# TEST-CONTENTVALIDATION-016 - AC-16: Content validation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-16: Content validation. |\n| QBrain reference/scope | \u0060TEST-CONTENTVALIDATION-016\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_category_suggestion.svg](../../../word_association_category_suggestion.svg); [word_association_nomination_flow.svg](../../../word_association_nomination_flow.svg) |\n| Frame/element identifiers | SUG-FLOW, SUG-NODE-H, SUG-NODE-I, SUG-TRANS-F-H, SUG-TRANS-H-I, NOM-FLOW, NOM-NODE-J, NOM-TRANS-I-J, ROUND-FLOW, ROUND-NODE-D, ROUND-TRANS-C-D, ROUND-TRANS-D-E, ROUND-TRANS-L-D, MSG-M14, MSG-M15, SCREEN-SUGGESTION, STATE-SUGGESTION-01, STATE-SUGGESTION-02, STATE-SUGGESTION-03, STATE-SUGGESTION-04, STATE-SUGGESTION-05, STATE-SUGGESTION-06, SCREEN-WORDS, STATE-WORDS-01, STATE-WORDS-02, STATE-WORDS-03, STATE-WORDS-04, STATE-WORDS-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORIES-005#AC-16\u0060; \u0060FR-CATEGORIES-005#DEC-06\u0060; \u0060FR-CURATEDPAIRS-004#AC-16\u0060; \u0060FR-CURATEDPAIRS-004#DEC-05\u0060; \u0060TR-CATALOG-INTEGRITY-006#TR-06-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Authorized content editor has a complete draft pair in an approved category. |\n| Test data | Prompt Hot; target Cold; hints H1/H2/H3; accepted alternative chilly; approved category/background. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Remove each required field in turn and try publishing the pair. | Incomplete pairs do not become playable; validation identifies the missing field. |\n| 2 | Restore all required fields and complete the approved publishing path. | The catalog includes a complete pair with the three hints in order and its category background. |\n| 3 | Inspect the initial approved catalog and use a controlled two-eligible-pair category pool in an eight-round match. | Each initial category has ten complete seeded pairs; a pair is not repeated until all currently eligible pairs in that category have appeared, then that pool can reshuffle. |\n| 4 | Inspect Colors pair relationships using approved complementary-color fixtures. | Every Colors pair follows its approved complementary-color relationship; arbitrary unapproved color targets are not generated. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-16: Content validation\n Scenario: TEST-CONTENTVALIDATION-016 design verification\n Given Authorized content editor has a complete draft pair in an approved category.\n And the fixture data is Prompt Hot; target Cold; hints H1/H2/H3; accepted alternative chilly; approved category/background.\n When Remove each required field in turn and try publishing the pair.\n Then Incomplete pairs do not become playable; validation identifies the missing field.\n When Restore all required fields and complete the approved publishing path.\n Then The catalog includes a complete pair with the three hints in order and its category background.\n When Inspect the initial approved catalog and use a controlled two-eligible-pair category pool in an eight-round match.\n Then Each initial category has ten complete seeded pairs; a pair is not repeated until all currently eligible pairs in that category have appeared, then that pool can reshuffle.\n When Inspect Colors pair relationships using approved complementary-color fixtures.\n Then Every Colors pair follows its approved complementary-color relationship; arbitrary unapproved color targets are not generated.\n\u0060\u0060\u0060\n\n## Boundaries\n\nExact validation copy is not specified; assert identified field and unchanged playability, not invented wording.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-CONTENTVALIDATION-016", "acceptanceCriteria": [ { "id": "AC-16", "text": "Given a category is enabled, when the content catalog is checked, then every playable pair has a prompt, target answer, three ordered hints, accepted-answer policy, and category background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-CONTESTREADINESS-147", "condition": "Audit the final release, incorporated rules, entrant prerequisites and evidence package against each TR-CONTEST-READINESS-041 criterion; report every unresolved dependency before manual entry.", "title": "Contest readiness and retained hostile validation audit", "workspaceId": "\u003Crepo\u003E", "priority": "critical", "status": "in_progress", "notes": "Operator contest/compliance/HV retention instructions, 27October2026. Source and scope: docs/submission/README.md; official rules PDF and hash: docs/submission/rules-receipt.json; HV originals: docs/submission/hv-index.json. Exact criterion references use TR-CONTEST-READINESS-041#CONTEST-01..05. Pending authenticated mission/conduct text, entrant facts, final URL/real live matrix, Work provenance and manual entry. No agreement or entry performed. Existing FR/TR/TEST obligations remain in force. Ordered verification: (1) compare current official sources and deadline; (2) confirm eligibility/mission/Work provenance; (3) run final public two-clean-client/full live matrix with explicit observations and replay; (4) inspect cover/title/description/URL and rights; (5) verify all HV archive hashes and final release snapshot; (6) eligible entrant submits manually and retains timestamp/confirmation. Platform: final public phone/laptop browsers. Data: isolated guest rooms, no shared profile mutation. Cleanup: close test rooms/contexts. Blocked until listed dependencies resolved. No selector/driver dependency, no fixed sleeps.\n28October2026UTC: Operator attested all eligibility conditions. Handshake Terms https://joinhandshake.com/legal/tos/ inspected; source/hash and policy effective dates in docs/submission/rules-receipt.json. Operator states no other Code of Conduct link is available. Known conduct clauses retained; separately named text and authenticated mission not inspected. All contest criteria remain unsatisfied pending their complete combined obligations; no automated entry or agreement acceptance performed.", "acceptanceCriteria": [ { "id": "CONTEST-01", "text": "Before release, retain exact official-rule source/hash, resolve mission/conduct requirements and entrant eligibility, and use the earlier documented cutoff; do not assert unknown compliance.", "isSatisfied": false }, { "id": "CONTEST-02", "text": "At the final stable public HTTPS URL, clean guests on phone/laptop can join by code without required sign-in or install, complete synchronized games and replay; fulfill existing TEST-ROOMSYNC-139 rather than substituting fixture evidence.", "isSatisfied": false }, { "id": "CONTEST-03", "text": "Retain accurate ChatGPT Work design/build provenance and authenticated mission completion evidence; Codex-only activity does not establish the named workflow.", "isSatisfied": false }, { "id": "CONTEST-04", "text": "Prepare title, licensed cover, accurate description and playable URL; the eligible entrant manually submits through the actual Handshake mission before the cutoff, with no automated entry or unapproved agreement acceptance.", "isSatisfied": false }, { "id": "CONTEST-05", "text": "Retain every available hostile-validation receipt including rejected/superseded rounds, labeled reconstructions, corrections, candidate hashes and evidence limits; bind final approval and release/source/SWBOM evidence to the submitted candidate without exposing secrets.", "isSatisfied": false } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-DDDTRANSACTIONS-131", "condition": "Run architecture import guards plus actual parallel final-seat, stale/idempotent command, audit/outbox fault rollback and deterministic port tests; domain imports no framework/network adapters.", "title": "Verify TR-31: Testable domain and concurrency boundaries", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-131; canonical MCP ID: TEST-DDDTRANSACTIONS-131. Technical/integration or operational evidence only. Source TR-31. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-131. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-31", "text": "Run architecture import guards plus actual parallel final-seat, stale/idempotent command, audit/outbox fault rollback and deterministic port tests; domain imports no framework/network adapters.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-31-C01", "text": "Organize application behavior as a modular monolith with explicit domain boundaries and application use cases. Keep game policies independent of Next.js and Supabase frameworks; route persistence, identity, time, randomness, and realtime effects through injected ports/adapters. Keep each business rule in one canonical domain policy, with database constraints as invariant backstops rather than competing rule implementations. As a TR integration requirement, the persistence adapter serializes conflicting room mutations in one database transaction, enforces durable idempotency for retried commands, and commits the event/outbox record atomically before realtime delivery. These database guarantees are verified as TR integration evidence and do not count toward AC coverage.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-DEEPLINKJOINANDFULLROOM-026", "condition": "Given a valid room deep link, when a player opens it, then the game bypasses lobby browsing and checks the room directly. If a slot is open, the player joins; if the room has no open player slot, the invitee is offered observer mode.", "title": "AC-26: Deep-link join and full room", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-26; canonical MCP ID: TEST-DEEPLINKJOINANDFULLROOM-026. Original criterion AC-26; cases AC-26-T01, AC-26-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-026. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-DEEPLINKJOINANDFULLROOM-026\n# TEST-DEEPLINKJOINANDFULLROOM-026 - AC-26: Deep-link join and full room\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-26: Deep-link join and full room. |\n| QBrain reference/scope | \u0060TEST-DEEPLINKJOINANDFULLROOM-026\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg) |\n| Frame/element identifiers | ROOM-FLOW, ROOM-NODE-C, ROOM-NODE-H, ROOM-TRANS-C-D, ROOM-TRANS-D-H, ROOM-TRANS-H-I, ROOM-TRANS-H-F, SCREEN-JOIN, STATE-JOIN-01, STATE-JOIN-02, STATE-JOIN-03, STATE-JOIN-04, STATE-JOIN-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-26\u0060; \u0060FR-LOBBYLIFECYCLE-003#AC-26\u0060; \u0060FR-ROOMACCESS-001#AC-26\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice has a valid signed room invitation; one fixture has a seat, another is full. |\n| Test data | Invited guest Bob; same room deep-link destination. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open the invitation in each fixture. | It bypasses discovery and checks the intended room directly. |\n| 2 | Join the open fixture and inspect the full fixture. | Open fixture admits Bob as a player; full fixture offers observer mode without silently adding a player. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-26: Deep-link join and full room\n Scenario: TEST-DEEPLINKJOINANDFULLROOM-026 design verification\n Given Alice has a valid signed room invitation; one fixture has a seat, another is full.\n And the fixture data is Invited guest Bob; same room deep-link destination.\n When Open the invitation in each fixture.\n Then It bypasses discovery and checks the intended room directly.\n When Join the open fixture and inspect the full fixture.\n Then Open fixture admits Bob as a player; full fixture offers observer mode without silently adding a player.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-DEEPLINKJOINANDFULLROOM-026", "acceptanceCriteria": [ { "id": "AC-26", "text": "Given a valid room deep link, when a player opens it, then the game bypasses lobby browsing and checks the room directly. If a slot is open, the player joins; if the room has no open player slot, the invitee is offered observer mode.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-DEPENDENCYATTRIBUTION-039", "condition": "Given a direct dependency or externally sourced asset is added or changed, when the change is prepared, then `docs/ATTRIBUTIONS.md` records its purpose, license, and upstream source, and dependency versions are locked in the package manager lockfile.", "title": "AC-39: Dependency attribution", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-39; canonical MCP ID: TEST-DEPENDENCYATTRIBUTION-039. Original criterion AC-39; cases AC-39-T01, AC-39-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-039. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-39", "text": "Given a direct dependency or externally sourced asset is added or changed, when the change is prepared, then `docs/ATTRIBUTIONS.md` records its purpose, license, and upstream source, and dependency versions are locked in the package manager lockfile.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-DEPENDENCYATTRIBUTION-125", "condition": "Compare every installed direct package and bundled asset against attribution/license/upstream records and exact lockfile pins; reject missing notices or unreviewed distribution inputs.", "title": "Verify TR-25: Direct dependencies and attribution", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-125; canonical MCP ID: TEST-DEPENDENCYATTRIBUTION-125. Technical/integration or operational evidence only. Source TR-25. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-125. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-25", "text": "Compare every installed direct package and bundled asset against attribution/license/upstream records and exact lockfile pins; reject missing notices or unreviewed distribution inputs.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-25-C01", "text": "Declare the approved runtime and test packages as direct dependencies in `package.json`; pin compatible resolved versions through the package manager lockfile. Maintain `docs/ATTRIBUTIONS.md` with each direct package\u2019s purpose, license, and upstream source, plus attribution for any externally sourced visual, audio, or content assets. Update it when dependencies or assets change.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-23", "text": "Toolchain and test stack: Next.js with TypeScript, npm with committed lockfile, Vitest for domain/use-case tests, MSW/fakes for ports, Testing Library for UI, and Playwright for browser acceptance. Pin compatible versions after the Phase 0 license/version review and before setup.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-DEPLOYMENTNOACTIONS-124", "condition": "Verify deployment/provisioning succeeds through Vercel Git integration and manual authenticated tooling without GitHub Actions; live topology checks remain Phase7.", "title": "Verify TR-24: GitHub Actions availability", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "pending", "notes": "New verification/extension import key: TEST-WP-124; canonical MCP ID: TEST-DEPLOYMENTNOACTIONS-124. Technical/integration or operational evidence only. Source TR-24. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-124. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-24", "text": "Verify deployment/provisioning succeeds through Vercel Git integration and manual authenticated tooling without GitHub Actions; live topology checks remain Phase7.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-24-C01", "text": "Build and deployment automation must not depend on GitHub Actions. Use Vercel\u2019s Git integration for automatic branch Preview and `main` Production deployments. Run infrastructure provisioning scripts manually from an authenticated developer workstation.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-DESIGNHOSTILEREVIEW-135", "condition": "Update design documentation for requested behavior and obtain independent hostile validation with exact source identity, evidence boundaries, findings/corrections and final disposition.", "title": "Verify Design documentation and independent hostile validation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-135; canonical MCP ID: TEST-DESIGNHOSTILEREVIEW-135. Actual test sources: tests/application/access.test.ts, tests/application/catalog-admin.test.ts, tests/web/admin-api.test.ts, tests/integration/admin.integration.ts, tests/integration/multiplayer.integration.ts, tests/browser/admin.phase6.spec.ts. Match the applicable suite to this requirement; do not claim all suites prove every boundary. Former provisional MCP ID: TEST-WP-135. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-35-C01", "text": "Architecture, moderation, deployment and administration design agree with the implemented role matrix, bootstrap, transaction ordering, retry semantics and immutable content behavior.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-35-C02", "text": "An independent GPT-6 Astra/high reviewer reaches at least98/100 accuracy and completeness, with no unresolved material findings; retain its complete report and reviewed source manifest.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-35-C03", "text": "Distinguish agent visual inspection, automated fixtures, real database evidence and hosted operations. Human feedback is optional; do not invent personal sign-off gates or claim unperformed human testing.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-FINALSTANDINGS-013", "condition": "Given the configured final round ends, when players have different total scores, then final standings rank them by total score.", "title": "AC-13: Final standings", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-13; canonical MCP ID: TEST-FINALSTANDINGS-013. Original criterion AC-13; cases AC-13-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-013. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-FINALSTANDINGS-013\n# TEST-FINALSTANDINGS-013 - AC-13: Final standings\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-13: Final standings. |\n| QBrain reference/scope | \u0060TEST-FINALSTANDINGS-013\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-K, ROUND-NODE-M, ROUND-TRANS-J-K, ROUND-TRANS-K-L, ROUND-TRANS-K-M, SCREEN-FINAL, STATE-FINAL-01, STATE-FINAL-02, STATE-FINAL-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANSWERSTAGES-008#DEC-01\u0060; \u0060FR-FINALSTANDINGS-014#AC-13\u0060; \u0060FR-FINALSTANDINGS-014#DEC-01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Eight-round fixture has known totals and round eight is active. |\n| Test data | Final totals Alice 24, Bob 20, Cara 12. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Finish round eight. | Final standings appear rather than a ninth round. |\n| 2 | Read the ranking. | Alice ranks first with 24, Bob second with 20, Cara third with 12. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-13: Final standings\n Scenario: TEST-FINALSTANDINGS-013 design verification\n Given Eight-round fixture has known totals and round eight is active.\n And the fixture data is Final totals Alice 24, Bob 20, Cara 12.\n When Finish round eight.\n Then Final standings appear rather than a ninth round.\n When Read the ranking.\n Then Alice ranks first with 24, Bob second with 20, Cara third with 12.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-FINALSTANDINGS-013", "acceptanceCriteria": [ { "id": "AC-13", "text": "Given the configured final round ends, when players have different total scores, then final standings rank them by total score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-FIRSTCATEGORY-004", "condition": "Given a new game with 2-25 players, when the game indexes the start roster from 1 through N and draws a random integer from 1 through N inclusive, then the player with that index becomes anchor; when that player chooses a category, the first round uses the chosen category and its background.", "title": "AC-04: First category", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-04; canonical MCP ID: TEST-FIRSTCATEGORY-004. Original criterion AC-04; cases AC-04-T01, AC-04-T02, AC-04-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-004. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-FIRSTCATEGORY-004\n# TEST-FIRSTCATEGORY-004 - AC-04: First category\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-04: First category. |\n| QBrain reference/scope | \u0060TEST-FIRSTCATEGORY-004\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg); [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-B, ROUND-NODE-C, ROUND-TRANS-A-B, ROUND-TRANS-B-C, ROUND-TRANS-C-D, MSG-M07, MSG-M08, MSG-M09, MSG-M10, MSG-M11, MSG-M12, MSG-M13, MSG-FLOW, SCREEN-CHOOSER, STATE-CHOOSER-01, STATE-CHOOSER-02, STATE-CHOOSER-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANCHORSELECTION-007#AC-04\u0060; \u0060FR-CATEGORIES-005#AC-04\u0060; \u0060TR-ANCHOR-RANDOMNESS-013#TR-13-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | The start roster is Alice, Bob, Cara; all are ready; fixture controls which roster index the service selects. |\n| Test data | Controlled selected-index examples 1, 2, 3; opening category Opposites. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Let the countdown finish and inspect the announced anchor on all clients. | The player at the selected roster index is identified as anchor consistently. |\n| 2 | As a non-anchor attempt category selection, then select Opposites as the anchor. | Only the anchor\u0027s choice starts the first round; every client shows Opposites and its background. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-04: First category\n Scenario: TEST-FIRSTCATEGORY-004 design verification\n Given The start roster is Alice, Bob, Cara; all are ready; fixture controls which roster index the service selects.\n And the fixture data is Controlled selected-index examples 1, 2, 3; opening category Opposites.\n When Let the countdown finish and inspect the announced anchor on all clients.\n Then The player at the selected roster index is identified as anchor consistently.\n When As a non-anchor attempt category selection, then select Opposites as the anchor.\n Then Only the anchor\u0027s choice starts the first round; every client shows Opposites and its background.\n\u0060\u0060\u0060\n\n## Boundaries\n\nRepeat each selected index, including other-player branch; UI verifies consequences, not statistical uniformity. Stable-index distribution proof remains separate technical coverage.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-FIRSTCATEGORY-004", "acceptanceCriteria": [ { "id": "AC-04", "text": "Given a new game with 2-25 players, when the game indexes the start roster from 1 through N and draws a random integer from 1 through N inclusive, then the player with that index becomes anchor; when that player chooses a category, the first round uses the chosen category and its background.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-FREETIEROPERATION-121", "condition": "Assert recoverable quota rejection with canonical retry and no paid fallback; verify one25-player/25-observer target against actual approved Free-tier resources in Phase7.", "title": "Verify TR-21: Free-tier operation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "New verification/extension import key: TEST-WP-121; canonical MCP ID: TEST-FREETIEROPERATION-121. Technical/integration or operational evidence only. Source TR-21. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-121. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-21", "text": "Assert recoverable quota rejection with canonical retry and no paid fallback; verify one25-player/25-observer target against actual approved Free-tier resources in Phase7.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-21-C01", "text": "The deployment must remain on free tiers: Vercel Hobby and Supabase Free. Do not enable paid add-ons, metered upgrades, or paid external services. The product is personal and non-commercial while using Vercel Hobby. Current Supabase Free constraints include a 500 MB database, 200 concurrent Realtime connections, 100 Realtime messages per second, 2 million Realtime messages per month, and automatic pause after one week of inactivity. Treat these as capacity limits and provide graceful handling when service quotas are reached.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-20", "text": "Quota behavior and initial load target: Initial supported target is one full 25-player room plus up to 25 observers. Quota rejection returns a recoverable `SERVICE_LIMIT`, preserves the last committed state, and allows retry with the same command ID; no paid fallback or non-idempotent automatic retry.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-FREETIERQUOTAHANDLING-037", "condition": "Given a Supabase Free quota is reached, when a room or database operation cannot be served, then the game reports a recoverable service-limit state and does not silently switch to a paid resource.", "title": "AC-37: Free-tier quota handling", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-37; canonical MCP ID: TEST-FREETIERQUOTAHANDLING-037. Original criterion AC-37; cases AC-37-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-037. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-FREETIERQUOTAHANDLING-037\n# TEST-FREETIERQUOTAHANDLING-037 - AC-37: Free-tier quota handling\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-37: Free-tier quota handling. |\n| QBrain reference/scope | \u0060TEST-FREETIERQUOTAHANDLING-037\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | SCREEN-SERVICE, STATE-SERVICE-01, STATE-SERVICE-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060TR-FREETIER-OPERATION-021#TR-21-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | An isolated controllable fixture can make room operations return a quota/service-limit result. |\n| Test data | Recoverable service-limit outcome; existing accepted score 5. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Partial: controlled quota response and safe recovery fixture required; UI cannot establish infrastructure billing behavior. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Attempt a room operation while the fixture reports quota exhaustion. | The UI reports a recoverable service-limit state; existing score remains 5. |\n| 2 | Restore service and retry using the documented canonical retry behavior. | The operation can recover without duplicated state or silent paid-resource substitution. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-37: Free-tier quota handling\n Scenario: TEST-FREETIERQUOTAHANDLING-037 design verification\n Given An isolated controllable fixture can make room operations return a quota/service-limit result.\n And the fixture data is Recoverable service-limit outcome; existing accepted score 5.\n When Attempt a room operation while the fixture reports quota exhaustion.\n Then The UI reports a recoverable service-limit state; existing score remains 5.\n When Restore service and retry using the documented canonical retry behavior.\n Then The operation can recover without duplicated state or silent paid-resource substitution.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-FREETIERQUOTAHANDLING-037", "acceptanceCriteria": [ { "id": "AC-37", "text": "Given a Supabase Free quota is reached, when a room or database operation cannot be served, then the game reports a recoverable service-limit state and does not silently switch to a paid resource.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-FULLROOMOBSERVER-027", "condition": "Given an invited player follows an invitation to a full room, when they choose to observe, then they enter without consuming a player slot and are bound to the player who invited them.", "title": "AC-27: Full-room observer", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-27; canonical MCP ID: TEST-FULLROOMOBSERVER-027. Original criterion AC-27; cases AC-27-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-027. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-FULLROOMOBSERVER-027\n# TEST-FULLROOMOBSERVER-027 - AC-27: Full-room observer\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-27: Full-room observer. |\n| QBrain reference/scope | \u0060TEST-FULLROOMOBSERVER-027\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg) |\n| Frame/element identifiers | ROOM-FLOW, ROOM-NODE-H, ROOM-NODE-I, ROOM-NODE-J, ROOM-TRANS-D-H, ROOM-TRANS-H-I, ROOM-TRANS-I-J, ROOM-TRANS-I-F, ROOM-TRANS-H-F, SCREEN-JOIN, STATE-JOIN-01, STATE-JOIN-02, STATE-JOIN-03, STATE-JOIN-04, STATE-JOIN-05, SCREEN-OBSERVER, STATE-OBSERVER-01, STATE-OBSERVER-02, STATE-OBSERVER-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYLIFECYCLE-003#AC-27\u0060; \u0060FR-OBSERVERS-020#AC-27\u0060; \u0060FR-OBSERVERS-020#DEC-13\u0060; \u0060TR-OBSERVER-PERMISSIONS-018#TR-18-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice\u0027s room has reached capacity; invited Eve is not a member. |\n| Test data | Signed invitation bound to Alice; second run uses manual room code and roster inviter selection. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Choose Observe as Eve. | Eve appears only in observers; player count/capacity is unchanged and her perspective follows Alice. |\n| 2 | Repeat code invitation and select Alice from current roster. | The observer is bound to the explicitly chosen inviter, not an arbitrary player. |\n| 3 | Fill observer capacity with25 independent invited profiles, then attempt a26th observer. | Twenty-five observers are permitted; the26th is rejected without consuming a player seat or displacing an observer. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-27: Full-room observer\n Scenario: TEST-FULLROOMOBSERVER-027 design verification\n Given Alice\u0027s room has reached capacity; invited Eve is not a member.\n And the fixture data is Signed invitation bound to Alice; second run uses manual room code and roster inviter selection.\n When Choose Observe as Eve.\n Then Eve appears only in observers; player count/capacity is unchanged and her perspective follows Alice.\n When Repeat code invitation and select Alice from current roster.\n Then The observer is bound to the explicitly chosen inviter, not an arbitrary player.\n When Fill observer capacity with25 independent invited profiles, then attempt a26th observer.\n Then Twenty-five observers are permitted; the26th is rejected without consuming a player seat or displacing an observer.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-FULLROOMOBSERVER-027", "acceptanceCriteria": [ { "id": "AC-27", "text": "Given an invited player follows an invitation to a full room, when they choose to observe, then they enter without consuming a player slot and are bound to the player who invited them.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-GPL20ONLYRELEASE-042", "condition": "Given a candidate source archive is prepared, when its contents are inspected, then it contains the root `LICENSE` file with the complete GPL-2.0-only text, and every bundled third-party component retains its required attribution and license notice. This is validated against a temporary archive fixture and does not depend on a published or deployed artifact.", "title": "AC-42: GPL-2.0-only release", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-42; canonical MCP ID: TEST-GPL20ONLYRELEASE-042. Original criterion AC-42; cases AC-42-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-042. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-42", "text": "Given a candidate source archive is prepared, when its contents are inspected, then it contains the root `LICENSE` file with the complete GPL-2.0-only text, and every bundled third-party component retains its required attribution and license notice. This is validated against a temporary archive fixture and does not depend on a published or deployed artifact.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-GUESTPLAY-021", "condition": "Given a player chooses guest mode, when they continue without OIDC authentication, then the game creates a guest player identity, allows icon selection, and lets them create or join a room by code.", "title": "AC-21: Guest play", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-21; canonical MCP ID: TEST-GUESTPLAY-021. Original criterion AC-21; cases AC-21-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-021. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-GUESTPLAY-021\n# TEST-GUESTPLAY-021 - AC-21: Guest play\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-21: Guest play. |\n| QBrain reference/scope | \u0060TEST-GUESTPLAY-021\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_identity_profile.svg](../../../word_association_identity_profile.svg) |\n| Frame/element identifiers | ID-FLOW, ID-NODE-A, ID-NODE-B, ID-NODE-E, ID-TRANS-A-B, ID-TRANS-B-C, ID-TRANS-B-E, ID-TRANS-E-F, SCREEN-ENTRY, STATE-ENTRY-01, STATE-ENTRY-02, STATE-ENTRY-03, SCREEN-PROFILE, STATE-PROFILE-01, STATE-PROFILE-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-IDENTITY-018#AC-21\u0060; \u0060FR-IDENTITY-018#DEC-11\u0060; \u0060FR-PLAYERPROFILE-002#AC-21\u0060; \u0060FR-PLAYERPROFILE-002#DEC-11\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | A clean browser has no profile; OIDC sign-in is not used. |\n| Test data | Guest browser A; separate clean browser B; selected owl icon. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Choose Continue as guest, select owl and create/join a room. | A guest identity with owl can participate without OIDC. |\n| 2 | Reload browser A, then open browser B; clear A\u0027s site data and reenter. | A retains its identity until site data is cleared; B does not inherit it; cleared A receives a different guest identity. |\n| 3 | Change the generated guest alias and opt out of public leaderboard display. | The profile uses the saved generated/public alias policy, honors opt-out and never exposes real provider identity; guest is not silently linked to an OIDC subject. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-21: Guest play\n Scenario: TEST-GUESTPLAY-021 design verification\n Given A clean browser has no profile; OIDC sign-in is not used.\n And the fixture data is Guest browser A; separate clean browser B; selected owl icon.\n When Choose Continue as guest, select owl and create/join a room.\n Then A guest identity with owl can participate without OIDC.\n When Reload browser A, then open browser B; clear A\u0027s site data and reenter.\n Then A retains its identity until site data is cleared; B does not inherit it; cleared A receives a different guest identity.\n When Change the generated guest alias and opt out of public leaderboard display.\n Then The profile uses the saved generated/public alias policy, honors opt-out and never exposes real provider identity; guest is not silently linked to an OIDC subject.\n\u0060\u0060\u0060\n\n## Boundaries\n\nGuest-to-OIDC linking is not specified and must not be assumed.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-GUESTPLAY-021", "acceptanceCriteria": [ { "id": "AC-21", "text": "Given a player chooses guest mode, when they continue without OIDC authentication, then the game creates a guest player identity, allows icon selection, and lets them create or join a room by code.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-HINTPROGRESSION-009", "condition": "Given multiple unsolved players, when all unsolved players submit for the current stage, then the game confirms stage results and shows the next hint only to players still unsolved.", "title": "AC-09: Hint progression", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-09; canonical MCP ID: TEST-HINTPROGRESSION-009. Original criterion AC-09; cases AC-09-T01, AC-09-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-009. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-HINTPROGRESSION-009\n# TEST-HINTPROGRESSION-009 - AC-09: Hint progression\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-09: Hint progression. |\n| QBrain reference/scope | \u0060TEST-HINTPROGRESSION-009\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg); [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-H, ROUND-NODE-I, ROUND-TRANS-G-H, ROUND-TRANS-H-I, ROUND-TRANS-I-F, ROUND-TRANS-H-J, MSG-M30, MSG-M31, MSG-M32, MSG-FLOW, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANSWERSTAGES-008#AC-09\u0060; \u0060TR-ANSWER-CONFIDENTIALITY-005#TR-05-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice, Bob and Cara start unsolved; Alice then solves while Bob and Cara do not. |\n| Test data | Target Cold; Bob wrong answer Warm; Cara unanswered until stage closure. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Submit Warm as Bob while Cara has not submitted. | The current stage remains open until all unsolved players submit or its 20-second deadline. |\n| 2 | Submit an incorrect answer as Cara, then observe all three clients. | Bob and Cara receive the next ordered hint; solved Alice receives no later hint or answer control. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-09: Hint progression\n Scenario: TEST-HINTPROGRESSION-009 design verification\n Given Alice, Bob and Cara start unsolved; Alice then solves while Bob and Cara do not.\n And the fixture data is Target Cold; Bob wrong answer Warm; Cara unanswered until stage closure.\n When Submit Warm as Bob while Cara has not submitted.\n Then The current stage remains open until all unsolved players submit or its 20-second deadline.\n When Submit an incorrect answer as Cara, then observe all three clients.\n Then Bob and Cara receive the next ordered hint; solved Alice receives no later hint or answer control.\n\u0060\u0060\u0060\n\n## Boundaries\n\nRepeat through Hints 1..3, plus a no-response branch where the server deadline closes the stage.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-HINTPROGRESSION-009", "acceptanceCriteria": [ { "id": "AC-09", "text": "Given multiple unsolved players, when all unsolved players submit for the current stage, then the game confirms stage results and shows the next hint only to players still unsolved.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-HINTSCORING-007", "condition": "Given a player solves after Hint 1, Hint 2, or Hint 3, when the game accepts the answer, then the player earns 3, 2, or 1 point respectively.", "title": "AC-07: Hint scoring", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-07; canonical MCP ID: TEST-HINTSCORING-007. Original criterion AC-07; cases AC-07-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-007. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-HINTSCORING-007\n# TEST-HINTSCORING-007 - AC-07: Hint scoring\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-07: Hint scoring. |\n| QBrain reference/scope | \u0060TEST-HINTSCORING-007\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-F, ROUND-NODE-G, ROUND-NODE-I, ROUND-TRANS-E-F, ROUND-TRANS-F-G, ROUND-TRANS-G-H, ROUND-TRANS-H-I, ROUND-TRANS-I-F, MSG-M26, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANSWERSTAGES-008#AC-07\u0060; \u0060FR-SCORELOCK-010#AC-07\u0060; \u0060FR-SCORING-009#AC-07\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice remains unsolved until the specified hint stage in independent round fixtures. |\n| Test data | Examples: Hint 1 \u2192 3 points; Hint 2 \u2192 2; Hint 3 \u2192 1; target Cold. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Advance the fixture to the selected visible hint stage and submit Cold as Alice. | Alice receives exactly the example\u0027s points: 3, 2 or 1. |\n| 2 | Observe Alice through later stage transitions. | Her points stay locked and later hints are not offered to her. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-07: Hint scoring\n Scenario: TEST-HINTSCORING-007 design verification\n Given Alice remains unsolved until the specified hint stage in independent round fixtures.\n And the fixture data is Examples: Hint 1 \u2192 3 points; Hint 2 \u2192 2; Hint 3 \u2192 1; target Cold.\n When Advance the fixture to the selected visible hint stage and submit Cold as Alice.\n Then Alice receives exactly the example\u0027s points: 3, 2 or 1.\n When Observe Alice through later stage transitions.\n Then Her points stay locked and later hints are not offered to her.\n\u0060\u0060\u0060\n\n## Boundaries\n\nExecute one independent scenario per hint-stage/points pair; use condition-based stage synchronization.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-HINTSCORING-007", "acceptanceCriteria": [ { "id": "AC-07", "text": "Given a player solves after Hint 1, Hint 2, or Hint 3, when the game accepts the answer, then the player earns 3, 2, or 1 point respectively.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-HOLDOUTWARNINGANDREMOVAL-032", "condition": "Given all but one player have marked ready, when the room enters the holdout state, then the unready player sees a five-second warning to mark ready. If they mark ready before it expires, the start countdown begins immediately. If the warning expires while they remain unready in a room with more than two players, they are removed and the start countdown begins with the remaining roster locked. If the room has exactly two players, the holdout is not removed and the lobby continues waiting; the countdown does not begin until both are ready.", "title": "AC-32: Holdout warning and removal", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-32; canonical MCP ID: TEST-HOLDOUTWARNINGANDREMOVAL-032. Original criterion AC-32; cases AC-32-T01, AC-32-T02, AC-32-T03, AC-32-T04, AC-32-T01, AC-32-T02. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-032. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-HOLDOUTWARNINGANDREMOVAL-032\n# TEST-HOLDOUTWARNINGANDREMOVAL-032 - AC-32: Holdout warning and removal\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-32: Holdout warning and removal. |\n| QBrain reference/scope | \u0060TEST-HOLDOUTWARNINGANDREMOVAL-032\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | SCREEN-LOBBY, STATE-LOBBY-01, STATE-LOBBY-02, STATE-LOBBY-03, STATE-LOBBY-04, STATE-LOBBY-05, STATE-LOBBY-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-32\u0060; \u0060FR-LOBBYLIFECYCLE-003#AC-32\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Independent waiting-room fixtures have either two or three players with all but Bob ready. |\n| Test data | 5-second holdout warning; Bob remains unready or becomes ready before expiry. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Observe Bob\u0027s warning and mark him ready before it expires in one run. | Countdown starts immediately when Bob becomes ready. |\n| 2 | Let warning expire without readiness in three-player and two-player runs. | Three-player run removes Bob and starts locked countdown; two-player run retains Bob and waits for both players. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-32: Holdout warning and removal\n Scenario: TEST-HOLDOUTWARNINGANDREMOVAL-032 design verification\n Given Independent waiting-room fixtures have either two or three players with all but Bob ready.\n And the fixture data is 5-second holdout warning; Bob remains unready or becomes ready before expiry.\n When Observe Bob\u0027s warning and mark him ready before it expires in one run.\n Then Countdown starts immediately when Bob becomes ready.\n When Let warning expire without readiness in three-player and two-player runs.\n Then Three-player run removes Bob and starts locked countdown; two-player run retains Bob and waits for both players.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-HOLDOUTWARNINGANDREMOVAL-032", "acceptanceCriteria": [ { "id": "AC-32", "text": "Given all but one player have marked ready, when the room enters the holdout state, then the unready player sees a five-second warning to mark ready. If they mark ready before it expires, the start countdown begins immediately. If the warning expires while they remain unready in a room with more than two players, they are removed and the start countdown begins with the remaining roster locked. If the room has exactly two players, the holdout is not removed and the lobby continues waiting; the countdown does not begin until both are ready.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-IDENTITYAUTHENTICATION-116", "condition": "Exercise PKCE/code flow, state/nonce/signature/issuer/audience/expiry rejection and stable verified profile association; retain provider entitlement as an external prerequisite.", "title": "Verify TR-16: Identity and authentication", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "New verification/extension import key: TEST-WP-116; canonical MCP ID: TEST-IDENTITYAUTHENTICATION-116. Technical/integration or operational evidence only. Source TR-16. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-116. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-16", "text": "Exercise PKCE/code flow, state/nonce/signature/issuer/audience/expiry rejection and stable verified profile association; retain provider entitlement as an external prerequisite.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-16-C01", "text": "The service supports OpenAI OIDC for account-backed profiles and guest identities without OIDC. It validates OIDC tokens before associating a profile with the subject and never trusts client-supplied identity claims. Guest identity persists in the same browser/device until site data is cleared; it does not sync or link to OIDC. Store generated public aliases and leaderboard opt-out separately from real identity claims. Guest identity persists only in the same browser/device until site data is cleared; guest profiles do not sync or link to OIDC accounts.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-10", "text": "OIDC provider: Keep OpenAI OIDC as specified in FR-02/FR-18/AC-20/46, using Authorization Code with PKCE and verified OIDC claims. Provider registration/entitlement is an external integration prerequisite, not an AC test oracle or deployed-artifact AC.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." }, { "id": "DEC-11", "text": "Guest profile and labels: A guest profile persists in the same browser/device until site data is cleared; it does not sync or link to an OIDC profile. Every profile gets a generated public alias; users can change it or opt out of leaderboard display. Real identity claims are never public.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-IDLELOBBYREADINESSPROMPT-033", "condition": "Given the game start countdown has not begun, when no player/observer membership or ready-state change occurs for 30 seconds, then the game prompts all players once for that room version to mark themselves ready; any membership or ready-state change resets the interval.", "title": "AC-33: Idle lobby readiness prompt", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-33; canonical MCP ID: TEST-IDLELOBBYREADINESSPROMPT-033. Original criterion AC-33; cases AC-33-T01, AC-33-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-033. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-IDLELOBBYREADINESSPROMPT-033\n# TEST-IDLELOBBYREADINESSPROMPT-033 - AC-33: Idle lobby readiness prompt\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-33: Idle lobby readiness prompt. |\n| QBrain reference/scope | \u0060TEST-IDLELOBBYREADINESSPROMPT-033\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | SCREEN-LOBBY, STATE-LOBBY-01, STATE-LOBBY-02, STATE-LOBBY-03, STATE-LOBBY-04, STATE-LOBBY-05, STATE-LOBBY-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-33\u0060; \u0060FR-LOBBYLIFECYCLE-003#AC-33\u0060; \u0060FR-LOBBYLIFECYCLE-003#DEC-16\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Room is waiting without countdown and its current membership/readiness version is recorded. |\n| Test data | 30-second unchanged interval; one ready-state or observer membership change. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Keep the room version unchanged through the idle deadline. | All players receive one ready prompt for that version, with no repeated prompts for the same unchanged version. |\n| 2 | Change readiness or membership, then await the next idle deadline. | The idle interval restarts from the change; a new prompt appears only for the later unchanged version. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-33: Idle lobby readiness prompt\n Scenario: TEST-IDLELOBBYREADINESSPROMPT-033 design verification\n Given Room is waiting without countdown and its current membership/readiness version is recorded.\n And the fixture data is 30-second unchanged interval; one ready-state or observer membership change.\n When Keep the room version unchanged through the idle deadline.\n Then All players receive one ready prompt for that version, with no repeated prompts for the same unchanged version.\n When Change readiness or membership, then await the next idle deadline.\n Then The idle interval restarts from the change; a new prompt appears only for the later unchanged version.\n\u0060\u0060\u0060\n\n## Boundaries\n\n Expected-version stale deadline jobs are a separate technical no-op assertion; this UI case covers their visible prompt consequences.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-IDLELOBBYREADINESSPROMPT-033", "acceptanceCriteria": [ { "id": "AC-33", "text": "Given the game start countdown has not begun, when no player/observer membership or ready-state change occurs for 30 seconds, then the game prompts all players once for that room version to mark themselves ready; any membership or ready-state change resets the interval.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-INROUNDEMOJIREACTION-029", "condition": "Given a round is active, when a player selects an emoji from the menu, then the reaction appears in real time to room players and observers and does not change scores, answer stage, or round state.", "title": "AC-29: In-round emoji reaction", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-29; canonical MCP ID: TEST-INROUNDEMOJIREACTION-029. Original criterion AC-29; cases AC-29-T01, AC-29-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-029. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-INROUNDEMOJIREACTION-029\n# TEST-INROUNDEMOJIREACTION-029 - AC-29: In-round emoji reaction\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-29: In-round emoji reaction. |\n| QBrain reference/scope | \u0060TEST-INROUNDEMOJIREACTION-029\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | MSG-M19, MSG-M20, MSG-M21, MSG-M22, MSG-FLOW; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-REACTIONS-021#AC-29\u0060; \u0060FR-REACTIONS-021#DEC-18\u0060; \u0060TR-REACTION-DELIVERY-019#DEC-18\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice, Bob and observer Eve share an active round. |\n| Test data | Approved menu \uD83D\uDC4D \u2764\uFE0F \uD83D\uDE02 \uD83C\uDF89 \uD83D\uDC40; select \uD83C\uDF89; initial scores and stage recorded. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Alice select \uD83C\uDF89 from the menu and observe Bob and Eve. | The same reaction appears to players and observers in real time. |\n| 2 | Inspect scores/stage, then observe expiry and rate boundary in separate examples. | Scores/stage do not change; reaction expires at 5 seconds; a second reaction before 2 seconds is denied and at 2 seconds is allowed. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-29: In-round emoji reaction\n Scenario: TEST-INROUNDEMOJIREACTION-029 design verification\n Given Alice, Bob and observer Eve share an active round.\n And the fixture data is Approved menu \uD83D\uDC4D \u2764\uFE0F \uD83D\uDE02 \uD83C\uDF89 \uD83D\uDC40; select \uD83C\uDF89; initial scores and stage recorded.\n When As Alice select \uD83C\uDF89 from the menu and observe Bob and Eve.\n Then The same reaction appears to players and observers in real time.\n When Inspect scores/stage, then observe expiry and rate boundary in separate examples.\n Then Scores/stage do not change; reaction expires at 5 seconds; a second reaction before 2 seconds is denied and at 2 seconds is allowed.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-INROUNDEMOJIREACTION-029", "acceptanceCriteria": [ { "id": "AC-29", "text": "Given a round is active, when a player selects an emoji from the menu, then the reaction appears in real time to room players and observers and does not change scores, answer stage, or round state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-LANDINGPAGEPUBLICDATA-050", "condition": "Given an unauthenticated visitor requests landing-page data, when the service responds, then it returns only lifetime-win ranking fields, opted-in generated aliases, exact counts/capacity, waiting state, room age, and rules version for public content; it does not expose room codes, real identity, guesses, target answers, observer-only views, moderation records, or secrets.", "title": "AC-50: Landing-page public data", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-50; canonical MCP ID: TEST-LANDINGPAGEPUBLICDATA-050. Original criterion AC-50; cases AC-50-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-050. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-LANDINGPAGEPUBLICDATA-050\n# TEST-LANDINGPAGEPUBLICDATA-050 - AC-50: Landing-page public data\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-50: Landing-page public data. |\n| QBrain reference/scope | \u0060TEST-LANDINGPAGEPUBLICDATA-050\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | SCREEN-LANDING, STATE-LANDING-01, STATE-LANDING-02, STATE-LANDING-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-PUBLICLANDING-022#AC-50\u0060; \u0060FR-PUBLICLANDING-022#DEC-19\u0060; \u0060TR-LANDING-PRIVACY-030#DEC-19\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Anonymous public fixture contains opted-in generated aliases and private room/player content. |\n| Test data | Known sentinel room code, OIDC subject, guess, target, moderation reason and secret absent from public projection. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open anonymous leaderboard/lobbies/rules and inspect the public representation. | Only allowed lifetime ranking fields, generated aliases, exact counts/capacity, waiting state, age and rules version are present. |\n| 2 | Search all rendered public content and authorized public response fields for sentinels. | No room code, real identity, private game/observer view, moderation record or secret is exposed. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-50: Landing-page public data\n Scenario: TEST-LANDINGPAGEPUBLICDATA-050 design verification\n Given Anonymous public fixture contains opted-in generated aliases and private room/player content.\n And the fixture data is Known sentinel room code, OIDC subject, guess, target, moderation reason and secret absent from public projection.\n When Open anonymous leaderboard/lobbies/rules and inspect the public representation.\n Then Only allowed lifetime ranking fields, generated aliases, exact counts/capacity, waiting state, age and rules version are present.\n When Search all rendered public content and authorized public response fields for sentinels.\n Then No room code, real identity, private game/observer view, moderation record or secret is exposed.\n\u0060\u0060\u0060\n\n## Boundaries\n\nResponse inspection is an observation seam for public confidentiality, independent of selector/driver choices.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-LANDINGPAGEPUBLICDATA-050", "acceptanceCriteria": [ { "id": "AC-50", "text": "Given an unauthenticated visitor requests landing-page data, when the service responds, then it returns only lifetime-win ranking fields, opted-in generated aliases, exact counts/capacity, waiting state, room age, and rules version for public content; it does not expose room codes, real identity, guesses, target answers, observer-only views, moderation records, or secrets.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-LANDINGPRIVACY-130", "condition": "Request anonymous landing projections with bounded pagination/cache refresh and empty/unavailable states; reject private codes, identities, guesses, answers and moderation fields.", "title": "Verify TR-30: Public landing data boundary", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-130; canonical MCP ID: TEST-LANDINGPRIVACY-130. Technical/integration or operational evidence only. Source TR-30. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-130. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-30", "text": "Request anonymous landing projections with bounded pagination/cache refresh and empty/unavailable states; reject private codes, identities, guesses, answers and moderation fields.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-30-C01", "text": "Serve the landing page and its gameplay rules without requiring authentication. Retrieve leaderboard and lobby display data through a read-only, server-controlled public projection that returns only approved fields. Restrict lobby results to discoverable, joinable rooms; exclude room codes, non-public profile fields and identifiers, observer perspective data, guesses, targets, moderation records, and secrets. Use bounded pagination, a documented refresh/cache policy, and recoverable empty/unavailable states. Do not expose service-role credentials or allow the public query to mutate game state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-19", "text": "Public landing contract: Leaderboard is lifetime wins, then total points, earliest win, and stable profile ID. Show public alias only, include opt-in guests, honor profile opt-out. Lobby card shows exact player count/capacity, waiting state and room age, never room code/player names. Refresh lobby data every 15 seconds and leaderboard every five minutes. Rules are a concise versioned summary with an updated date.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-LICENSEGPL-129", "condition": "Compare complete GPL-2.0-only root text and every bundled third-party notice in temporary source-archive fixtures; preserve metadata and notices.", "title": "Verify TR-29: Project license", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-129; canonical MCP ID: TEST-LICENSEGPL-129. Technical/integration or operational evidence only. Source TR-29. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-129. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-29", "text": "Compare complete GPL-2.0-only root text and every bundled third-party notice in temporary source-archive fixtures; preserve metadata and notices.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-29-C01", "text": "License Wordpairs source and the game under GNU GPL version 2 only (`GPL-2.0-only`). Include the complete license text in the root `LICENSE` file and include that file in each source release archive. Preserve independent third-party license notices and check compatibility before redistributing any third-party code or asset as part of the game.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-LIVESCORECARD-010", "condition": "Given a player solves, when the game accepts the answer, then the active scorecard shows that player\u2019s icon, points earned, and elapsed time from round start.", "title": "AC-10: Live scorecard", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-10; canonical MCP ID: TEST-LIVESCORECARD-010. Original criterion AC-10; cases AC-10-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-010. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-LIVESCORECARD-010\n# TEST-LIVESCORECARD-010 - AC-10: Live scorecard\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-10: Live scorecard. |\n| QBrain reference/scope | \u0060TEST-LIVESCORECARD-010\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg); [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-G, ROUND-TRANS-F-G, ROUND-TRANS-G-H, MSG-M26, MSG-M27, MSG-M28, MSG-M29, MSG-FLOW, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LIVESCORECARD-011#AC-10\u0060; \u0060FR-SCORELOCK-010#AC-10\u0060; \u0060TR-CLOCK-CONSISTENCY-008#TR-08-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice and Bob see the same active round and Alice is unsolved. |\n| Test data | Alice fox icon; controlled authoritative round start 12:00:00 and accepted correct solve 12:00:04. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Submit the target as Alice and observe Bob without manual refresh. | Bob\u0027s live scorecard shows Alice, fox icon, 5 round points and 4 seconds elapsed. |\n| 2 | Change a client clock in an independent fixture. | Displayed authoritative solve duration and points remain based on server acceptance time. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-10: Live scorecard\n Scenario: TEST-LIVESCORECARD-010 design verification\n Given Alice and Bob see the same active round and Alice is unsolved.\n And the fixture data is Alice fox icon; controlled authoritative round start 12:00:00 and accepted correct solve 12:00:04.\n When Submit the target as Alice and observe Bob without manual refresh.\n Then Bob\u0027s live scorecard shows Alice, fox icon, 5 round points and 4 seconds elapsed.\n When Change a client clock in an independent fixture.\n Then Displayed authoritative solve duration and points remain based on server acceptance time.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-LIVESCORECARD-010", "acceptanceCriteria": [ { "id": "AC-10", "text": "Given a player solves, when the game accepts the answer, then the active scorecard shows that player\u2019s icon, points earned, and elapsed time from round start.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-LOBBYMATCHING-117", "condition": "Enumerate hidden/full/started/waiting discoverable rooms and concurrent oldest-room selection; assert stable ID tie-breaking and no capacity overflow.", "title": "Verify TR-17: Lobby discovery and matching", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-117; canonical MCP ID: TEST-LOBBYMATCHING-117. Technical/integration or operational evidence only. Source TR-17. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-117. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-LOBBYMATCHING-117\n# TEST-LOBBYMATCHING-117 - Discovery seat loss returns to refreshed browsing\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Discovery seat loss returns to refreshed browsing. |\n| QBrain reference/scope | \u0060TEST-LOBBYMATCHING-117\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md); [word_association_lobby_discovery.svg](../../../word_association_lobby_discovery.svg) |\n| Frame/element identifiers | GAP-FLOW-LOBBYMATCHING, GAP-TRANS-LOBBYMATCHING-01, GAP-TRANS-LOBBYMATCHING-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-23\u0060; \u0060TR-LOBBY-MATCHING-017#TR-17-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice sees a discoverable room with one free seat; Bob can fill that seat before Alice commits. |\n| Test data | Capacity2; one initial member; Alice and Bob separate profiles. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). This is the documented recovery variant, not a claim that every historical compound obligation was rerun. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open discovery as Alice, fill the last seat as Bob, then request that seat as Alice. | Alice is not admitted or shown a false success; capacity remains2 and refreshed browsing replaces the stale listing. |\n| 2 | Repeat by opening a valid direct invitation to the now-full room. | The invitee receives the observer choice rather than a player seat. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Discovery seat loss returns to refreshed browsing\n Scenario: TEST-LOBBYMATCHING-117 design verification\n Given Alice sees a discoverable room with one free seat; Bob can fill that seat before Alice commits.\n And the fixture data is Capacity2; one initial member; Alice and Bob separate profiles.\n When Open discovery as Alice, fill the last seat as Bob, then request that seat as Alice.\n Then Alice is not admitted or shown a false success; capacity remains2 and refreshed browsing replaces the stale listing.\n When Repeat by opening a valid direct invitation to the now-full room.\n Then The invitee receives the observer choice rather than a player seat.\n\u0060\u0060\u0060\n\n## Boundaries\n\nExisting requirement, newly explicit UI scenario; no change to historical evidence or status.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-LOBBYMATCHING-117", "acceptanceCriteria": [ { "id": "VERIFY-TR-17", "text": "Enumerate hidden/full/started/waiting discoverable rooms and concurrent oldest-room selection; assert stable ID tie-breaking and no capacity overflow.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-17-C01", "text": "The service lists only discoverable lobbies with available player slots under their configured capacity. Rooms are private by default. Quick match selects the oldest eligible room, then stable room ID; all player-seat assignments use the same atomic capacity check. Deep links containing a valid room code route directly to that room without lobby browsing, then use the same authoritative open-slot check. A valid invite to a full room may establish an observer session without reserving a player slot. Lobby discovery responses expose only approved lobby metadata, not private room state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-12", "text": "Lobby discovery and quick match: Rooms are undiscoverable by default; creator may opt in. Quick match selects the oldest discoverable waiting room with a free seat, then stable room ID. The same atomic capacity-checked join command handles the selection.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-MOBILEINPUT-111", "condition": "Use phone portrait/landscape touch and keyboard input; assert reachable controls, preserved answers and no horizontal overflow.", "title": "Verify TR-11: Mobile input", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-111; canonical MCP ID: TEST-MOBILEINPUT-111. Technical/integration or operational evidence only. Source TR-11. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-111. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-11", "text": "Use phone portrait/landscape touch and keyboard input; assert reachable controls, preserved answers and no horizontal overflow.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-11-C01", "text": "Primary actions work with touch and keyboard input. Category art does not obstruct text entry, hints, score status, or buttons in either phone orientation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "condition": "Given an implementation increment is ready to begin, when its test plan is reviewed, then every active acceptance criterion maps to at least one test and those tests pass against mocks before implementation code is written.", "title": "AC-38: Mock-first acceptance coverage", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-38; canonical MCP ID: TEST-MOCKFIRSTACCEPTANCECOVERAGE-038. Original criterion AC-38; cases AC-38-T01, AC-38-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-038. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-38", "text": "Given an implementation increment is ready to begin, when its test plan is reviewed, then every active acceptance criterion maps to at least one test and those tests pass against mocks before implementation code is written.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-MODERATIONANDCATALOGBOUNDARY-047", "condition": "Given an actor is not authorized to perform moderation or catalog activation, when they attempt to change moderation status or publish content, then the service rejects the action; every change to nomination count, moderation status, and eligibility is auditable; and content cannot be selected for play until it has passed moderation and is complete in the curated catalog.", "title": "AC-47: Moderation and catalog boundary", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-47; canonical MCP ID: TEST-MODERATIONANDCATALOGBOUNDARY-047. Original criterion AC-47; cases AC-47-T01, AC-47-T02, AC-47-T03, AC-47-T01, AC-47-T02, AC-47-T03. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-047. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-MODERATIONANDCATALOGBOUNDARY-047\n# TEST-MODERATIONANDCATALOGBOUNDARY-047 - AC-47: Moderation and catalog boundary\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-47: Moderation and catalog boundary. |\n| QBrain reference/scope | \u0060TEST-MODERATIONANDCATALOGBOUNDARY-047\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_nomination_flow.svg](../../../word_association_nomination_flow.svg); [word_association_category_suggestion.svg](../../../word_association_category_suggestion.svg); [admin_acl_design.md](../../../admin_acl_design.md) |\n| Frame/element identifiers | SUG-FLOW, SUG-NODE-E, SUG-NODE-F, SUG-NODE-G, SUG-TRANS-D-E, SUG-TRANS-E-F, SUG-TRANS-F-G, SUG-TRANS-F-H, NOM-FLOW, NOM-NODE-F, NOM-NODE-G, NOM-NODE-H, NOM-TRANS-D-F, NOM-TRANS-F-G, NOM-TRANS-G-H, NOM-TRANS-G-I, SCREEN-NOMINATION, STATE-NOMINATION-01, STATE-NOMINATION-02, STATE-NOMINATION-03, STATE-NOMINATION-04, STATE-NOMINATION-05, STATE-NOMINATION-06, SCREEN-SUGGESTION, STATE-SUGGESTION-01, STATE-SUGGESTION-02, STATE-SUGGESTION-03, STATE-SUGGESTION-04, STATE-SUGGESTION-05, STATE-SUGGESTION-06, SCREEN-ADMIN, STATE-ADMIN-01, STATE-ADMIN-02, STATE-ADMIN-03, STATE-ADMIN-04, STATE-ADMIN-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORYSUGGESTIONS-017#AC-47\u0060; \u0060FR-NOMINATIONS-016#AC-47\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Player Alice proposes content; independent moderator Bob and senior moderator Cara are available. |\n| Test data | Pending nomination with 10 unique profiles; category suggestion with 3 pairs; reason Approved for fixture. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Alice attempt moderation or publication, then review as independent Bob. | Alice\u0027s changes are rejected; Bob\u0027s permitted reasoned decision is recorded in history. |\n| 2 | Inspect future playability before complete curation and after approved complete publication. | Approval alone does not make incomplete content playable; only approved complete content reaches future rounds. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-47: Moderation and catalog boundary\n Scenario: TEST-MODERATIONANDCATALOGBOUNDARY-047 design verification\n Given Player Alice proposes content; independent moderator Bob and senior moderator Cara are available.\n And the fixture data is Pending nomination with 10 unique profiles; category suggestion with 3 pairs; reason Approved for fixture.\n When As Alice attempt moderation or publication, then review as independent Bob.\n Then Alice\u0027s changes are rejected; Bob\u0027s permitted reasoned decision is recorded in history.\n When Inspect future playability before complete curation and after approved complete publication.\n Then Approval alone does not make incomplete content playable; only approved complete content reaches future rounds.\n\u0060\u0060\u0060\n\n## Boundaries\n\nEvery count/decision/eligibility change needs audit verification; UI history covers visible consequences, not transaction atomicity.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-MODERATIONANDCATALOGBOUNDARY-047", "acceptanceCriteria": [ { "id": "AC-47", "text": "Given an actor is not authorized to perform moderation or catalog activation, when they attempt to change moderation status or publish content, then the service rejects the action; every change to nomination count, moderation status, and eligibility is auditable; and content cannot be selected for play until it has passed moderation and is complete in the curated catalog.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-MULTIPLAYERINTEGRATION-134", "condition": "Exercise the real identity/room/lobby/match/PostgreSQL services in complete eight-round games for every integer player count2..25, using disposable infrastructure.", "title": "Verify Integration games for every supported player count", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-134; canonical MCP ID: TEST-MULTIPLAYERINTEGRATION-134. Actual test sources: tests/application/access.test.ts, tests/application/catalog-admin.test.ts, tests/web/admin-api.test.ts, tests/integration/admin.integration.ts, tests/integration/multiplayer.integration.ts, tests/browser/admin.phase6.spec.ts. Match the applicable suite to this requirement; do not claim all suites prove every boundary. Former provisional MCP ID: TEST-WP-134. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "TR-34-C01", "text": "Run24 complete games with324 player participations and2592 accepted round solves; every game reaches shared final standings.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-34-C02", "text": "Exercise all hint/scoring stages, simultaneous conflicts/retries, roster/anchor transitions and exactly-once profile awards. Keep deterministic clocks/randomness; preserve all assertions under bounded fixture wall-clock timeouts.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-34-C03", "text": "Use a disposable loopback-only database, apply every migration and remove owned containers/fixtures in finally without touching the running game database.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-02", "text": "No response and no solver: A missing answer counts as unsolved and advances to the next hint. After Hint 3 deadline the round reveals and awards zero to remaining players. If nobody solves, choose the next category uniformly from the six configured categories.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-01", "text": "Match length and stage timer: Eight rounds. Each of the four answer stages has a 20-second deadline; a stage closes early when all unsolved players submit.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-NAVIGATIONDRAFTS-142", "condition": "Verify the documented UI behavior: Back, Cancel and profile-isolated drafts.", "title": "Back, Cancel and profile-isolated drafts", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-NAVIGATIONDRAFTS-142\n# TEST-NAVIGATIONDRAFTS-142 - Back, Cancel and profile-isolated drafts\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Back, Cancel and profile-isolated drafts. |\n| QBrain reference/scope | \u0060TEST-NAVIGATIONDRAFTS-142\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | GAP-FLOW-NAVIGATIONDRAFTS, GAP-TRANS-NAVIGATIONDRAFTS-01, GAP-TRANS-NAVIGATIONDRAFTS-02, GAP-TRANS-NAVIGATIONDRAFTS-03, GAP-TRANS-NAVIGATIONDRAFTS-04; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-NAVIGATIONDRAFTS-029#UI-NAV-01\u0060; \u0060FR-NAVIGATIONDRAFTS-029#UI-NAV-02\u0060; \u0060FR-NAVIGATIONDRAFTS-029#UI-NAV-03\u0060; \u0060FR-NAVIGATIONDRAFTS-029#UI-NAV-04\u0060; \u0060FR-NAVIGATIONDRAFTS-029#UI-NAV-05\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice has a saved category draft form, saved profile icon owl and an active room membership; editor permissions are current. |\n| Test data | Unsaved category Space; saved profile alias Oak/icon owl; unsaved alias Ash/icon fox. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Enter unsaved edits, navigate to another authorized screen and use Back; dismiss a dialog. | The same-profile in-tab content draft returns and focus returns to the dialog opener; no submission, readiness or Leave event occurs. |\n| 2 | Choose Cancel/Discard on content and profile forms. | Unsaved edits are cleared; saved content and Oak/owl remain unchanged; originating screen is shown. |\n| 3 | Repeat with reload, tab close, profile switch and permission revocation in independent fixtures. | Private drafts do not persist or cross identities; denied privileged data cannot return through Back. |\n| 4 | Choose the explicit Leave room action. | Only this action leaves membership and the existing roster/promotion rules apply. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Back, Cancel and profile-isolated drafts\n Scenario: TEST-NAVIGATIONDRAFTS-142 design verification\n Given Alice has a saved category draft form, saved profile icon owl and an active room membership; editor permissions are current.\n And the fixture data is Unsaved category Space; saved profile alias Oak/icon owl; unsaved alias Ash/icon fox.\n When Enter unsaved edits, navigate to another authorized screen and use Back; dismiss a dialog.\n Then The same-profile in-tab content draft returns and focus returns to the dialog opener; no submission, readiness or Leave event occurs.\n When Choose Cancel/Discard on content and profile forms.\n Then Unsaved edits are cleared; saved content and Oak/owl remain unchanged; originating screen is shown.\n When Repeat with reload, tab close, profile switch and permission revocation in independent fixtures.\n Then Private drafts do not persist or cross identities; denied privileged data cannot return through Back.\n When Choose the explicit Leave room action.\n Then Only this action leaves membership and the existing roster/promotion rules apply.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-NAVIGATIONDRAFTS-142\n\nBEGIN UI-IMPLEMENTATION TEST-NAVIGATIONDRAFTS-142\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-NAVIGATIONDRAFTS-142", "acceptanceCriteria": [ { "id": "UI-NAV-01", "text": "Back returns to the previous authorized screen and dialog dismissal restores focus to its opener without submitting, changing readiness or leaving room membership.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-02", "text": "Unsaved content/editor drafts survive ordinary same-profile in-tab navigation in memory only; reload, tab close, session/profile change and permission loss clear them.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-03", "text": "Explicit Cancel/Discard abandons the draft and returns to the originating screen without changing the saved record; a canceled profile edit restores saved alias/icon.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-04", "text": "Leaving a room requires an explicit Leave action and applies the existing authoritative membership/departure rules.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-NAV-05", "text": "Returning to a privileged screen revalidates authorization; back navigation cannot restore cleared private data or another profile's draft.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-NOHINTSOLVE-006", "condition": "Given a player submits the correct answer during the no-hint stage, when the game accepts it, then the player earns 5 points and their round score locks.", "title": "AC-06: No-hint solve", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-06; canonical MCP ID: TEST-NOHINTSOLVE-006. Original criterion AC-06; cases AC-06-T01, AC-06-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-006. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-NOHINTSOLVE-006\n# TEST-NOHINTSOLVE-006 - AC-06: No-hint solve\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-06: No-hint solve. |\n| QBrain reference/scope | \u0060TEST-NOHINTSOLVE-006\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-E, ROUND-NODE-F, ROUND-NODE-G, ROUND-TRANS-D-E, ROUND-TRANS-E-F, ROUND-TRANS-F-G, ROUND-TRANS-G-H, ROUND-TRANS-I-F, MSG-M26, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANSWERSTAGES-008#AC-06\u0060; \u0060FR-SCORELOCK-010#AC-06\u0060; \u0060FR-SCORING-009#AC-06\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice is unsolved in the no-hint stage; Bob keeps the round open. |\n| Test data | Prompt Hot, target Cold, initial Alice round points 0. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Alice enter Cold and submit before any hint. | Alice receives exactly 5 round points and her score is locked. |\n| 2 | Attempt another answer during that round. | Alice has no further answer opportunity and her round points remain 5. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-06: No-hint solve\n Scenario: TEST-NOHINTSOLVE-006 design verification\n Given Alice is unsolved in the no-hint stage; Bob keeps the round open.\n And the fixture data is Prompt Hot, target Cold, initial Alice round points 0.\n When As Alice enter Cold and submit before any hint.\n Then Alice receives exactly 5 round points and her score is locked.\n When Attempt another answer during that round.\n Then Alice has no further answer opportunity and her round points remain 5.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-NOHINTSOLVE-006", "acceptanceCriteria": [ { "id": "AC-06", "text": "Given a player submits the correct answer during the no-hint stage, when the game accepts it, then the player earns 5 points and their round score locks.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-NOMINATIONELIGIBILITY-017", "condition": "Given a player solves during the no-hint stage, when the round results are shown, then that player can submit a candidate answer nomination; players who solve after any hint cannot nominate from that round.", "title": "AC-17: Nomination eligibility", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-17; canonical MCP ID: TEST-NOMINATIONELIGIBILITY-017. Original criterion AC-17; cases AC-17-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-017. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-NOMINATIONELIGIBILITY-017\n# TEST-NOMINATIONELIGIBILITY-017 - AC-17: Nomination eligibility\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-17: Nomination eligibility. |\n| QBrain reference/scope | \u0060TEST-NOMINATIONELIGIBILITY-017\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_nomination_flow.svg](../../../word_association_nomination_flow.svg) |\n| Frame/element identifiers | NOM-FLOW, NOM-NODE-A, NOM-NODE-B, NOM-TRANS-A-B, NOM-TRANS-B-C, SCREEN-NOMINATION, STATE-NOMINATION-01, STATE-NOMINATION-02, STATE-NOMINATION-03, STATE-NOMINATION-04, STATE-NOMINATION-05, STATE-NOMINATION-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-NOMINATIONS-016#AC-17\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice solves with no hint; Bob solves after Hint 1 in the same round. |\n| Test data | Candidate Moon; Alice no-hint 5 points, Bob Hint-1 3 points. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open round results as Alice and Bob. | Alice can submit a nomination from this solve; Bob cannot nominate from his hinted solve. |\n| 2 | Nominate Moon as Alice. | The candidate is recorded without altering the round score or progression. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-17: Nomination eligibility\n Scenario: TEST-NOMINATIONELIGIBILITY-017 design verification\n Given Alice solves with no hint; Bob solves after Hint 1 in the same round.\n And the fixture data is Candidate Moon; Alice no-hint 5 points, Bob Hint-1 3 points.\n When Open round results as Alice and Bob.\n Then Alice can submit a nomination from this solve; Bob cannot nominate from his hinted solve.\n When Nominate Moon as Alice.\n Then The candidate is recorded without altering the round score or progression.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-NOMINATIONELIGIBILITY-017", "acceptanceCriteria": [ { "id": "AC-17", "text": "Given a player solves during the no-hint stage, when the round results are shown, then that player can submit a candidate answer nomination; players who solve after any hint cannot nominate from that round.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-NOMINATIONMODERATION-114", "condition": "Exercise eligible no-hint nominations, one-per-round/profile, normalized distinct votes at9/10, independent review, rejection, one appeal and complete-record activation.", "title": "Verify TR-14: Candidate nomination and moderation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-114; canonical MCP ID: TEST-NOMINATIONMODERATION-114. Technical/integration or operational evidence only. Source TR-14. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-114. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-NOMINATIONMODERATION-114\n# TEST-NOMINATIONMODERATION-114 - Verify TR-14: Candidate nomination and moderation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Verify TR-14: Candidate nomination and moderation. |\n| QBrain reference/scope | \u0060TEST-NOMINATIONMODERATION-114\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_nomination_flow.svg](../../../word_association_nomination_flow.svg) |\n| Frame/element identifiers | NOM-FLOW, NOM-NODE-B, NOM-NODE-C, NOM-NODE-F, NOM-NODE-G, NOM-NODE-H, NOM-TRANS-A-B, NOM-TRANS-B-C, NOM-TRANS-C-D, NOM-TRANS-E-C, NOM-TRANS-D-F, NOM-TRANS-F-G, NOM-TRANS-G-H, NOM-TRANS-G-I, SCREEN-NOMINATION, STATE-NOMINATION-01, STATE-NOMINATION-02, STATE-NOMINATION-03, STATE-NOMINATION-04, STATE-NOMINATION-05, STATE-NOMINATION-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORYSUGGESTIONS-017#DEC-08\u0060; \u0060FR-NOMINATIONS-016#DEC-07\u0060; \u0060FR-NOMINATIONS-016#DEC-08\u0060; \u0060TR-NOMINATION-MODERATION-014#DEC-07\u0060; \u0060TR-NOMINATION-MODERATION-014#DEC-08\u0060; \u0060TR-SUGGESTION-REVIEW-015#DEC-08\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice has one eligible no-hint solve; candidate Moon is already nominated by Alice; independent moderator Bob, senior Cara. |\n| Test data | 9 then 10 unique profiles; duplicate Alice nomination; one appeal; reason Needs curation. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Attempt Alice\u0027s duplicate candidate nomination and a second candidate from the same solve. | Neither increases count or consumes an additional nomination. |\n| 2 | Reach 10 unique nominations, reject as independent Bob with reason, appeal once and resolve as independent senior Cara. | Review starts at 10; reason/history persist; only one appeal is accepted; proposer/original reviewer cannot resolve the appeal. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Verify TR-14: Candidate nomination and moderation\n Scenario: TEST-NOMINATIONMODERATION-114 design verification\n Given Alice has one eligible no-hint solve; candidate Moon is already nominated by Alice; independent moderator Bob, senior Cara.\n And the fixture data is 9 then 10 unique profiles; duplicate Alice nomination; one appeal; reason Needs curation.\n When Attempt Alice\u0027s duplicate candidate nomination and a second candidate from the same solve.\n Then Neither increases count or consumes an additional nomination.\n When Reach 10 unique nominations, reject as independent Bob with reason, appeal once and resolve as independent senior Cara.\n Then Review starts at 10; reason/history persist; only one appeal is accepted; proposer/original reviewer cannot resolve the appeal.\n\u0060\u0060\u0060\n\n## Boundaries\n\nThe diagram\u0027s separate \u0022hold\u0022 outcome has no defined status contract: Q-MOD-02 remains blocked.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-NOMINATIONMODERATION-114", "acceptanceCriteria": [ { "id": "VERIFY-TR-14", "text": "Exercise eligible no-hint nominations, one-per-round/profile, normalized distinct votes at9/10, independent review, rejection, one appeal and complete-record activation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-14-C01", "text": "The service permits nomination submission only for a player who solved the current round before any hint. It stores each nomination against a normalized candidate word and records its nominating player and timestamp. Candidate eligibility requires both at least 10 nominations and an approved moderation status. Moderation status, nomination count, and eligibility state must be auditable. An eligible candidate cannot be played until a complete curated word-pair record exists.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-07", "text": "Nomination counting: Count unique player profiles per normalized candidate. A profile may nominate a candidate once and submit at most one candidate per eligible no-hint solve. Moderation begins at 10 unique nominations.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-08", "text": "Moderation workflow: Roles are Content Moderator and Senior Moderator. At threshold, content enters Pending Review. A moderator other than the proposer approves or rejects with a reason. The proposer may appeal once to a Senior Moderator. Approval alone does not make content playable; the complete curated record must pass validation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "condition": "Given a candidate has fewer than 10 nominations or has not passed moderation, when the answer pool is checked, then it is not eligible for future games. Given it has at least 10 nominations and passes moderation, then it enters the future-eligible answer pool but is not playable until its full curated pair record exists.", "title": "AC-18: Nomination threshold and moderation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-18; canonical MCP ID: TEST-NOMINATIONTHRESHOLDANDMODERATION-018. Original criterion AC-18; cases AC-18-T01, AC-18-T02, AC-18-T02. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-018. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-NOMINATIONTHRESHOLDANDMODERATION-018\n# TEST-NOMINATIONTHRESHOLDANDMODERATION-018 - AC-18: Nomination threshold and moderation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-18: Nomination threshold and moderation. |\n| QBrain reference/scope | \u0060TEST-NOMINATIONTHRESHOLDANDMODERATION-018\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_nomination_flow.svg](../../../word_association_nomination_flow.svg) |\n| Frame/element identifiers | NOM-FLOW, NOM-NODE-C, NOM-NODE-D, NOM-NODE-E, NOM-NODE-G, NOM-NODE-I, NOM-NODE-J, NOM-TRANS-B-C, NOM-TRANS-C-D, NOM-TRANS-D-E, NOM-TRANS-E-C, NOM-TRANS-D-F, NOM-TRANS-F-G, NOM-TRANS-G-H, NOM-TRANS-G-I, NOM-TRANS-I-J, SCREEN-NOMINATION, STATE-NOMINATION-01, STATE-NOMINATION-02, STATE-NOMINATION-03, STATE-NOMINATION-04, STATE-NOMINATION-05, STATE-NOMINATION-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-NOMINATIONS-016#AC-18\u0060; \u0060FR-NOMINATIONS-016#DEC-07\u0060; \u0060TR-NOMINATION-MODERATION-014#DEC-07\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Candidate Moon has nine unique nominations; a tenth independent eligible profile is available. |\n| Test data | Profiles p01..p10; independent moderator m01; one complete curated pair fixture. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Inspect the candidate at nine nominations, then record the tenth unique eligible nomination. | At nine it is ineligible; at ten it enters moderation and remains ineligible until approval. |\n| 2 | Approve as independent m01, then inspect future eligibility before and after complete curation. | Approved candidate enters the future-eligible pool but is playable only after complete curated content exists. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-18: Nomination threshold and moderation\n Scenario: TEST-NOMINATIONTHRESHOLDANDMODERATION-018 design verification\n Given Candidate Moon has nine unique nominations; a tenth independent eligible profile is available.\n And the fixture data is Profiles p01..p10; independent moderator m01; one complete curated pair fixture.\n When Inspect the candidate at nine nominations, then record the tenth unique eligible nomination.\n Then At nine it is ineligible; at ten it enters moderation and remains ineligible until approval.\n When Approve as independent m01, then inspect future eligibility before and after complete curation.\n Then Approved candidate enters the future-eligible pool but is playable only after complete curated content exists.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "acceptanceCriteria": [ { "id": "AC-18", "text": "Given a candidate has fewer than 10 nominations or has not passed moderation, when the answer pool is checked, then it is not eligible for future games. Given it has at least 10 nominations and passes moderation, then it enters the future-eligible answer pool but is not playable until its full curated pair record exists.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-NOSOLVERFALLBACK-146", "condition": "Verify the documented UI behavior: No solver advances without a human chooser.", "title": "No solver advances without a human chooser", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-NOSOLVERFALLBACK-146\n# TEST-NOSOLVERFALLBACK-146 - No solver advances without a human chooser\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify No solver advances without a human chooser. |\n| QBrain reference/scope | \u0060TEST-NOSOLVERFALLBACK-146\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | GAP-FLOW-NOSOLVERFALLBACK, GAP-TRANS-NOSOLVERFALLBACK-01, GAP-TRANS-NOSOLVERFALLBACK-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANCHORSELECTION-007#DEC-02\u0060; \u0060FR-ANSWERREVEAL-012#DEC-02\u0060; \u0060FR-ANSWERSTAGES-008#DEC-02\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Round1 is active for Alice and Bob; both remain unsolved through all four20-second stages; seven rounds remain. |\n| Test data | Prompt Hot/target Cold; no accepted correct answer; six configured categories; initial totals0. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Let the authoritative Hint3 deadline end the no-solver round and inspect both clients. | Both see Cold reveal and zero-point summary; neither is falsely shown as first solver. |\n| 2 | Await the server-selected next category and round projection without choosing as either player. | A category from the configured six appears and round2 starts for both clients without a human-choice dependency. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: No solver advances without a human chooser\n Scenario: TEST-NOSOLVERFALLBACK-146 design verification\n Given Round1 is active for Alice and Bob; both remain unsolved through all four20-second stages; seven rounds remain.\n And the fixture data is Prompt Hot/target Cold; no accepted correct answer; six configured categories; initial totals0.\n When Let the authoritative Hint3 deadline end the no-solver round and inspect both clients.\n Then Both see Cold reveal and zero-point summary; neither is falsely shown as first solver.\n When Await the server-selected next category and round projection without choosing as either player.\n Then A category from the configured six appears and round2 starts for both clients without a human-choice dependency.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-NOSOLVERFALLBACK-146\n\nBEGIN UI-IMPLEMENTATION TEST-NOSOLVERFALLBACK-146\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-NOSOLVERFALLBACK-146", "acceptanceCriteria": [ { "id": "UI-NOSOLVER-01", "text": "Verify zero-point reveal and autonomous configured next-category progression after a no-solver round without waiting for a player chooser.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-OBSERVERPERMISSIONS-118", "condition": "Fill25 observer seats, bind inviter perspective, promote FIFO before lock and reject all observer state/scoring writes; preserve50-member audiences.", "title": "Verify TR-18: Observer perspective and permissions", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-118; canonical MCP ID: TEST-OBSERVERPERMISSIONS-118. Technical/integration or operational evidence only. Source TR-18. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-118. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-18", "text": "Fill25 observer seats, bind inviter perspective, promote FIFO before lock and reject all observer state/scoring writes; preserve50-member audiences.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-18-C01", "text": "An observer session is read-only, limited to 25 observers per room, and is bound to the player who invited the observer. Signed links carry inviter context; a manual room-code observer selects an active inviter from the roster. Observer queue order is transactional, with stable profile ID as tie-break. The service streams the same player-authorized game view that the inviter\u2019s client receives, including updates as the inviter\u2019s view changes, while rejecting guesses, category choices, and other game-affecting commands from the observer. Observers do not count toward player capacity or scoring.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-13", "text": "Observer behavior: Maximum 25 observers per room. Signed links bind the inviter. Manual room-code observers select an active player as inviter. Observer arrival order is assigned transactionally; ties use stable profile ID.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "condition": "Given an observer is following an inviter, when the inviter\u2019s player-authorized view changes, then the observer sees the corresponding update in real time. Observer attempts to submit guesses, choose categories, or change game state are rejected; the observer earns no score.", "title": "AC-28: Observer perspective and permissions", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-28; canonical MCP ID: TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028. Original criterion AC-28; cases AC-28-T01, AC-28-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-028. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028\n# TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028 - AC-28: Observer perspective and permissions\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-28: Observer perspective and permissions. |\n| QBrain reference/scope | \u0060TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg); [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | ROOM-FLOW, ROOM-NODE-J, ROOM-TRANS-I-J, SCREEN-OBSERVER, STATE-OBSERVER-01, STATE-OBSERVER-02, STATE-OBSERVER-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-OBSERVERS-020#AC-28\u0060; \u0060TR-OBSERVER-PERMISSIONS-018#TR-18-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Eve observes Alice in a full room; Bob is another player. |\n| Test data | Alice remains unsolved at Hint 1; Bob already solved. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Observe Eve as Alice receives her next hint. | Eve sees Alice\u0027s authorized perspective, without Bob\u0027s private guess text. |\n| 2 | As Eve attempt guessing, category selection or state-changing controls. | Observer cannot change game state and earns no score. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-28: Observer perspective and permissions\n Scenario: TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028 design verification\n Given Eve observes Alice in a full room; Bob is another player.\n And the fixture data is Alice remains unsolved at Hint 1; Bob already solved.\n When Observe Eve as Alice receives her next hint.\n Then Eve sees Alice\u0027s authorized perspective, without Bob\u0027s private guess text.\n When As Eve attempt guessing, category selection or state-changing controls.\n Then Observer cannot change game state and earns no score.\n\u0060\u0060\u0060\n\n## Boundaries\n\nUI control absence is insufficient proof of server rejection; retain separate authority tests and mark bypass denial as technical coverage.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "acceptanceCriteria": [ { "id": "AC-28", "text": "Given an observer is following an inviter, when the inviter\u2019s player-authorized view changes, then the observer sees the corresponding update in real time. Observer attempts to submit guesses, choose categories, or change game state are rejected; the observer earns no score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-OIDCTOKENVALIDATION-046", "condition": "Given an OIDC identity provider is configured, when a sign-in callback presents a token with an invalid signature, issuer, audience, state, nonce, or expiry, then the service rejects the sign-in and does not create or associate an authenticated profile from the unverified identity.", "title": "AC-46: OIDC token validation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-46; canonical MCP ID: TEST-OIDCTOKENVALIDATION-046. Original criterion AC-46; cases AC-46-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-046. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-OIDCTOKENVALIDATION-046\n# TEST-OIDCTOKENVALIDATION-046 - AC-46: OIDC token validation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-46: OIDC token validation. |\n| QBrain reference/scope | \u0060TEST-OIDCTOKENVALIDATION-046\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_identity_profile.svg](../../../word_association_identity_profile.svg) |\n| Frame/element identifiers | ID-FLOW, ID-NODE-C, ID-TRANS-B-C, ID-TRANS-C-D, SCREEN-ENTRY, STATE-ENTRY-01, STATE-ENTRY-02, STATE-ENTRY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-IDENTITY-018#AC-46\u0060; \u0060TR-IDENTITY-AUTHENTICATION-016#TR-16-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Controlled OIDC provider can issue invalid callback inputs without contacting real users. |\n| Test data | Separate invalid signature, issuer, audience, state, nonce and expiry examples. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Partial: safe provider/callback fixture required; UI-DEC-03/04 now define Back/Cancel and safe failure/retry behavior. Real OpenAI provider credentials remain an execution dependency. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Choose sign-in and return each invalid callback. | Sign-in is rejected and no authenticated profile is created or associated with the unverified subject. |\n| 2 | Return to public/guest entry. | The visitor can still use the documented unauthenticated path; private identity claims are not exposed. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-46: OIDC token validation\n Scenario: TEST-OIDCTOKENVALIDATION-046 design verification\n Given Controlled OIDC provider can issue invalid callback inputs without contacting real users.\n And the fixture data is Separate invalid signature, issuer, audience, state, nonce and expiry examples.\n When Choose sign-in and return each invalid callback.\n Then Sign-in is rejected and no authenticated profile is created or associated with the unverified subject.\n When Return to public/guest entry.\n Then The visitor can still use the documented unauthenticated path; private identity claims are not exposed.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-OIDCTOKENVALIDATION-046", "acceptanceCriteria": [ { "id": "AC-46", "text": "Given an OIDC identity provider is configured, when a sign-in callback presents a token with an invalid signature, issuer, audience, state, nonce, or expiry, then the service rejects the sign-in and does not create or associate an authenticated profile from the unverified identity.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-OPENAIOIDCPROFILE-020", "condition": "Given a player chooses account sign-in, when OpenAI OIDC authentication succeeds, then the game establishes or loads the game profile associated with that authenticated identity and allows the player to select an icon.", "title": "AC-20: OpenAI OIDC profile", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-20; canonical MCP ID: TEST-OPENAIOIDCPROFILE-020. Original criterion AC-20; cases AC-20-T01, AC-20-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-020. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-OPENAIOIDCPROFILE-020\n# TEST-OPENAIOIDCPROFILE-020 - AC-20: OpenAI OIDC profile\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-20: OpenAI OIDC profile. |\n| QBrain reference/scope | \u0060TEST-OPENAIOIDCPROFILE-020\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_identity_profile.svg](../../../word_association_identity_profile.svg) |\n| Frame/element identifiers | ID-FLOW, ID-NODE-B, ID-NODE-C, ID-NODE-D, ID-TRANS-A-B, ID-TRANS-B-C, ID-TRANS-C-D, ID-TRANS-B-E, ID-TRANS-D-F, SCREEN-ENTRY, STATE-ENTRY-01, STATE-ENTRY-02, STATE-ENTRY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-IDENTITY-018#AC-20\u0060; \u0060FR-IDENTITY-018#DEC-10\u0060; \u0060FR-PLAYERPROFILE-002#AC-20\u0060; \u0060TR-IDENTITY-AUTHENTICATION-016#DEC-10\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | An approved test OIDC provider registration is available with callback configuration. |\n| Test data | A synthetic returning OIDC subject and a separate new subject; fox icon. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Blocked for real-provider automation until OpenAI OIDC client registration/entitlement and safe test identities are available; use a controlled provider only with its evidence limitation disclosed. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Choose account sign-in and complete a valid Authorization Code with PKCE flow. | The returning subject loads its existing profile; the new subject receives its own profile. |\n| 2 | Select fox and continue to room entry. | The authenticated profile and selected icon are used for room membership; real identity-provider name is not public. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-20: OpenAI OIDC profile\n Scenario: TEST-OPENAIOIDCPROFILE-020 design verification\n Given An approved test OIDC provider registration is available with callback configuration.\n And the fixture data is A synthetic returning OIDC subject and a separate new subject; fox icon.\n When Choose account sign-in and complete a valid Authorization Code with PKCE flow.\n Then The returning subject loads its existing profile; the new subject receives its own profile.\n When Select fox and continue to room entry.\n Then The authenticated profile and selected icon are used for room membership; real identity-provider name is not public.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-OPENAIOIDCPROFILE-020", "acceptanceCriteria": [ { "id": "AC-20", "text": "Given a player chooses account sign-in, when OpenAI OIDC authentication succeeds, then the game establishes or loads the game profile associated with that authenticated identity and allows the player to select an icon.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ORIENTATION-015", "condition": "Given a phone-sized viewport in portrait or landscape, when a player enters an answer or views a hint and scorecard, then text and controls remain visible without horizontal overflow.", "title": "AC-15: Orientation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-15; canonical MCP ID: TEST-ORIENTATION-015. Original criterion AC-15; cases AC-15-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-015. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ORIENTATION-015\n# TEST-ORIENTATION-015 - AC-15: Orientation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-15: Orientation. |\n| QBrain reference/scope | \u0060TEST-ORIENTATION-015\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | ; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-RESPONSIVEUI-015#AC-15\u0060; \u0060TR-MOBILE-INPUT-011#TR-11-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | A player is in an active round with a hint, answer input and populated scorecard. |\n| Test data | Proposed test configurations: 390x844 portrait and 844x390 landscape; target Cold. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Rotate between both viewports and enter Cold with touch and with keyboard in independent runs. | Prompt, hint, input, scorecard and primary action remain visible and operable. |\n| 2 | Inspect the whole page width in each orientation. | No horizontal overflow hides content or controls. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-15: Orientation\n Scenario: TEST-ORIENTATION-015 design verification\n Given A player is in an active round with a hint, answer input and populated scorecard.\n And the fixture data is Proposed test configurations: 390x844 portrait and 844x390 landscape; target Cold.\n When Rotate between both viewports and enter Cold with touch and with keyboard in independent runs.\n Then Prompt, hint, input, scorecard and primary action remain visible and operable.\n When Inspect the whole page width in each orientation.\n Then No horizontal overflow hides content or controls.\n\u0060\u0060\u0060\n\n## Boundaries\n\nViewport sizes are test configurations, not invented product breakpoints.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ORIENTATION-015", "acceptanceCriteria": [ { "id": "AC-15", "text": "Given a phone-sized viewport in portrait or landscape, when a player enters an answer or views a hint and scorecard, then text and controls remain visible without horizontal overflow.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-PLAYERLIMIT-002", "condition": "Given a room has reached its configured player capacity from 2 through 25, when another player attempts to join, then the game rejects the additional player without changing existing room state. This is true for any configured capacity, including 2, 8, and 25.", "title": "AC-02: Player limit", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-02; canonical MCP ID: TEST-PLAYERLIMIT-002. Original criterion AC-02; cases AC-02-T01, AC-02-T02, AC-02-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-002. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-PLAYERLIMIT-002\n# TEST-PLAYERLIMIT-002 - AC-02: Player limit\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-02: Player limit. |\n| QBrain reference/scope | \u0060TEST-PLAYERLIMIT-002\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg) |\n| Frame/element identifiers | DISC-FLOW, DISC-NODE-E, DISC-TRANS-D-E, DISC-TRANS-E-F, DISC-TRANS-E-B, ROOM-FLOW, ROOM-NODE-D, ROOM-NODE-H, ROOM-NODE-F, ROOM-TRANS-C-D, ROOM-TRANS-D-E, ROOM-TRANS-D-H, ROOM-TRANS-H-I, ROOM-TRANS-I-F, ROOM-TRANS-H-F, ROOM-TRANS-G-D, SCREEN-DISCOVERY, STATE-DISCOVERY-01, STATE-DISCOVERY-02, STATE-DISCOVERY-03, SCREEN-JOIN, STATE-JOIN-01, STATE-JOIN-02, STATE-JOIN-03, STATE-JOIN-04, STATE-JOIN-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYLIFECYCLE-003#AC-02\u0060; \u0060FR-ROOMACCESS-001#AC-02\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | A waiting room already contains exactly its configured player count. |\n| Test data | Capacity examples 2, 8, 25; independent extra profile Eve. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Eve attempt a player join. | Player admission is rejected; existing roster and configured capacity are unchanged. |\n| 2 | Reopen the room as an existing player. | There is no Eve player row and the roster still contains exactly the configured count. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-02: Player limit\n Scenario: TEST-PLAYERLIMIT-002 design verification\n Given A waiting room already contains exactly its configured player count.\n And the fixture data is Capacity examples 2, 8, 25; independent extra profile Eve.\n When As Eve attempt a player join.\n Then Player admission is rejected; existing roster and configured capacity are unchanged.\n When Reopen the room as an existing player.\n Then There is no Eve player row and the roster still contains exactly the configured count.\n\u0060\u0060\u0060\n\n## Boundaries\n\nInvited observer entry is tested separately; rejection must not be confused with read-only observer admission.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-PLAYERLIMIT-002", "acceptanceCriteria": [ { "id": "AC-02", "text": "Given a room has reached its configured player capacity from 2 through 25, when another player attempts to join, then the game rejects the additional player without changing existing room state. This is true for any configured capacity, including 2, 8, and 25.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-POSTGRESPERSISTENCE-122", "condition": "Run SQL migrations, direct-role denial, rollback faults, durable retries/outbox and concurrent writes on disposable PostgreSQL; verify isolated hosted Supabase persistence/Realtime in Phase7.", "title": "Verify TR-22: Persistence and real-time room state", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "New verification/extension import key: TEST-WP-122; canonical MCP ID: TEST-POSTGRESPERSISTENCE-122. Technical/integration or operational evidence only. Source TR-22. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-122. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-22", "text": "Run SQL migrations, direct-role denial, rollback faults, durable retries/outbox and concurrent writes on disposable PostgreSQL; verify isolated hosted Supabase persistence/Realtime in Phase7.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-22-C01", "text": "Use Supabase Postgres as the durable source of truth for profiles, curated pairs, nominations, moderation records, completed matches, and scores. Use Supabase Realtime for active-room presence and event delivery within its free-tier limits. Do not rely on a Vercel Function\u2019s process memory as shared or durable room state. Keep category background assets in the repository unless a future requirement needs uploaded files.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-21", "text": "Persistence/security model: All writes and private reads go through server application commands; browser receives no service-role credential and no direct table grants. RLS remains enabled, with narrow public and actor-authorized views/functions. Moderator roles are server-managed. Raw incorrect guesses are not persisted. Audit events retain one year; published outbox rows seven days; idempotency results until 30 days after room close.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "condition": "Given a room is full and the start countdown has not begun, when a player leaves and at least one observer is waiting, then the observer who entered observer mode earliest becomes the final player in the roster, existing players move up to close the vacancy while preserving their relative order, and any remaining observers stay observers.", "title": "AC-30: Pre-countdown observer promotion", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-30; canonical MCP ID: TEST-PRECOUNTDOWNOBSERVERPROMOTION-030. Original criterion AC-30; cases AC-30-T01, AC-30-T02, AC-30-T03, AC-30-T04. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-030. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-PRECOUNTDOWNOBSERVERPROMOTION-030\n# TEST-PRECOUNTDOWNOBSERVERPROMOTION-030 - AC-30: Pre-countdown observer promotion\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-30: Pre-countdown observer promotion. |\n| QBrain reference/scope | \u0060TEST-PRECOUNTDOWNOBSERVERPROMOTION-030\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | SCREEN-LOBBY, STATE-LOBBY-01, STATE-LOBBY-02, STATE-LOBBY-03, STATE-LOBBY-04, STATE-LOBBY-05, STATE-LOBBY-06, SCREEN-OBSERVER, STATE-OBSERVER-01, STATE-OBSERVER-02, STATE-OBSERVER-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-30\u0060; \u0060FR-LOBBYLIFECYCLE-003#AC-30\u0060; \u0060FR-OBSERVERS-020#AC-30\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Full waiting roster Alice, Bob, Cara; observers Eve then Finn; countdown not started. |\n| Test data | Observer arrival order Eve older; equal-arrival variant resolves by stable profile ID. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Have Bob leave before countdown. | Remaining players Alice/Cara keep relative order; Eve is promoted to the last player position. |\n| 2 | Inspect observers. | Finn remains an observer; player capacity is not exceeded. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-30: Pre-countdown observer promotion\n Scenario: TEST-PRECOUNTDOWNOBSERVERPROMOTION-030 design verification\n Given Full waiting roster Alice, Bob, Cara; observers Eve then Finn; countdown not started.\n And the fixture data is Observer arrival order Eve older; equal-arrival variant resolves by stable profile ID.\n When Have Bob leave before countdown.\n Then Remaining players Alice/Cara keep relative order; Eve is promoted to the last player position.\n When Inspect observers.\n Then Finn remains an observer; player capacity is not exceeded.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "acceptanceCriteria": [ { "id": "AC-30", "text": "Given a room is full and the start countdown has not begun, when a player leaves and at least one observer is waiting, then the observer who entered observer mode earliest becomes the final player in the roster, existing players move up to close the vacancy while preserving their relative order, and any remaining observers stay observers.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-PROFILEICON-003", "condition": "Given a player selects an icon, when that player enters the lobby and plays a round, then the same icon appears in the lobby, live scorecard, and standings.", "title": "AC-03: Profile icon", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-03; canonical MCP ID: TEST-PROFILEICON-003. Original criterion AC-03; cases AC-03-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-003. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-PROFILEICON-003\n# TEST-PROFILEICON-003 - AC-03: Profile icon\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-03: Profile icon. |\n| QBrain reference/scope | \u0060TEST-PROFILEICON-003\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_identity_profile.svg](../../../word_association_identity_profile.svg); [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ID-FLOW, ID-NODE-F, ID-TRANS-D-F, ID-TRANS-E-F, ID-TRANS-F-G, SCREEN-PROFILE, STATE-PROFILE-01, STATE-PROFILE-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-PLAYERPROFILE-002#AC-03\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice can edit her profile and join a room with Bob. |\n| Test data | Select fox icon for Alice; one complete eight-round match fixture. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Select the fox icon and join the room. | Alice\u0027s lobby row shows the fox icon. |\n| 2 | Play a round and inspect the live scorecard, round summary and final standings. | All four views identify Alice with the same fox icon. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-03: Profile icon\n Scenario: TEST-PROFILEICON-003 design verification\n Given Alice can edit her profile and join a room with Bob.\n And the fixture data is Select fox icon for Alice; one complete eight-round match fixture.\n When Select the fox icon and join the room.\n Then Alice\u0027s lobby row shows the fox icon.\n When Play a round and inspect the live scorecard, round summary and final standings.\n Then All four views identify Alice with the same fox icon.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-PROFILEICON-003", "acceptanceCriteria": [ { "id": "AC-03", "text": "Given a player selects an icon, when that player enters the lobby and plays a round, then the same icon appears in the lobby, live scorecard, and standings.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-PUBLICGAMELANDINGPAGE-043", "condition": "Given an unauthenticated visitor opens the game landing page, when the page loads, then it presents an all-time leaderboard ranked by lifetime wins, total points, earliest win, and stable profile ID; discoverable lobby cards with exact player count/capacity, waiting state, and room age; and a concise versioned rules summary. It uses generated public aliases, honors opt-outs, excludes room codes and private room/game data, and provides usable empty/unavailable states.", "title": "AC-43: Public game landing page", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-43; canonical MCP ID: TEST-PUBLICGAMELANDINGPAGE-043. Original criterion AC-43; cases AC-43-T01, AC-43-T02, AC-43-T03, AC-43-T01, AC-43-T02. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-043. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-PUBLICGAMELANDINGPAGE-043\n# TEST-PUBLICGAMELANDINGPAGE-043 - AC-43: Public game landing page\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-43: Public game landing page. |\n| QBrain reference/scope | \u0060TEST-PUBLICGAMELANDINGPAGE-043\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_game_requirements.md](../../../word_association_game_requirements.md); [word_association_lobby_discovery.svg](../../../word_association_lobby_discovery.svg) |\n| Frame/element identifiers | ID-FLOW, ID-NODE-A, ID-TRANS-A-B, SCREEN-LANDING, STATE-LANDING-01, STATE-LANDING-02, STATE-LANDING-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-PUBLICLANDING-022#AC-43\u0060; \u0060FR-PUBLICLANDING-022#DEC-19\u0060; \u0060TR-LANDING-PRIVACY-030#DEC-19\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Visitor is signed out and a public-data fixture includes leaderboard/lobby results. |\n| Test data | Alias Oak wins 10 points 100; Ash wins 9 points 200; opted-out Pine; public lobby 1/2; empty and unavailable variants. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open the landing page while signed out. | Leaderboard, public lobbies and versioned rules are visible; Oak ranks above Ash by wins; Pine is omitted. |\n| 2 | Repeat with empty data and unavailable service. | Usable empty/unavailable states are shown; private room code and player-specific state never appear. |\n| 3 | Change the isolated public data source and await the documented refresh periods. | Lobby data refreshes on the15-second cadence and leaderboard on the five-minute cadence; rules include version and updated date. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-43: Public game landing page\n Scenario: TEST-PUBLICGAMELANDINGPAGE-043 design verification\n Given Visitor is signed out and a public-data fixture includes leaderboard/lobby results.\n And the fixture data is Alias Oak wins 10 points 100; Ash wins 9 points 200; opted-out Pine; public lobby 1/2; empty and unavailable variants.\n When Open the landing page while signed out.\n Then Leaderboard, public lobbies and versioned rules are visible; Oak ranks above Ash by wins; Pine is omitted.\n When Repeat with empty data and unavailable service.\n Then Usable empty/unavailable states are shown; private room code and player-specific state never appear.\n When Change the isolated public data source and await the documented refresh periods.\n Then Lobby data refreshes on the15-second cadence and leaderboard on the five-minute cadence; rules include version and updated date.\n\u0060\u0060\u0060\n\n## Boundaries\n\nAlso vary equal wins using total points, earliest win and stable profile ID; exact empty/error copy remains unspecified.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-PUBLICGAMELANDINGPAGE-043", "acceptanceCriteria": [ { "id": "AC-43", "text": "Given an unauthenticated visitor opens the game landing page, when the page loads, then it presents an all-time leaderboard ranked by lifetime wins, total points, earliest win, and stable profile ID; discoverable lobby cards with exact player count/capacity, waiting state, and room age; and a concise versioned rules summary. It uses generated public aliases, honors opt-outs, excludes room codes and private room/game data, and provides usable empty/unavailable states.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-PWAINSTALL-137", "condition": "Verify actual manifest/icon bytes and Apple/viewport metadata; test secure registration, failures, accepted/dismissed/rejected one-shot install prompts, standalone/appinstalled state and listener cleanup. Production Chromium diagnostics and phone/iPhone-UA layouts verify web install prerequisites; physical OS installation remains an unverified operational check.", "title": "Manifest, icons and phone installation contracts", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Source: user request2026-10-27: The game needs to be installable as a PWA on phones. Design and criteria: docs/pwa_design.md. Browser/worker evidence does not establish installation on physical Android/iPhone hardware. HostedHTTPS deployment remains future operational work.\n\nBEGIN UI-CASE TEST-PWAINSTALL-137\n# TEST-PWAINSTALL-137 - Manifest, icons and phone installation contracts\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Manifest, icons and phone installation contracts. |\n| QBrain reference/scope | \u0060TEST-PWAINSTALL-137\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [pwa_design.md](../../../pwa_design.md) |\n| Frame/element identifiers | SCREEN-INSTALL, STATE-INSTALL-01, STATE-INSTALL-02, STATE-INSTALL-03, STATE-INSTALL-04, STATE-INSTALL-05, STATE-INSTALL-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-PHONEINSTALL-026#PWA-01\u0060; \u0060FR-PHONEINSTALL-026#PWA-02\u0060; \u0060FR-PHONEINSTALL-026#PWA-03\u0060; \u0060FR-PHONEINSTALL-026#PWA-04\u0060; \u0060FR-PHONEINSTALL-026#PWA-05\u0060; \u0060TR-PWA-INSTALLATION-036#PWA-01\u0060; \u0060TR-PWA-INSTALLATION-036#PWA-02\u0060; \u0060TR-PWA-INSTALLATION-036#PWA-03\u0060; \u0060TR-PWA-INSTALLATION-036#PWA-04\u0060; \u0060TR-PWA-INSTALLATION-036#PWA-05\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Phone browser opens a secure Wordpairs origin; separate native-event and unsupported-browser fixtures exist. |\n| Test data | Android Chromium; iPhone Safari guidance; 390x844; dismissed/accepted/rejected native prompt fixtures. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Partial: synthetic browser prompt lifecycle is automatable; real OS installation requires an HTTPS origin and physical devices. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Open install help without a native prompt event, then on an insecure origin in a separate run. | Android menu/iPhone Share guidance is usable; insecure origin explains HTTPS instead of presenting a nonfunctional native prompt. |\n| 2 | Provide an install event, click Install once, dismiss/reject, then supply a fresh event. | One event prompts at most once; cancellation retains manual guidance; only a fresh event enables another prompt. |\n| 3 | Enter standalone/appinstalled state and simulate registration failure separately. | Install controls hide in installed mode; registration failure does not break gameplay. |\n| 4 | Inspect the browser-reported install manifest, linked icon resources and Apple metadata. | Manifest has stable root identity/scope, /play standalone launch, names/colors, same-origin192/512icons and separate maskable icon; actual opaque icon dimensions/safe zone and Apple touch metadata match their declarations. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Manifest, icons and phone installation contracts\n Scenario: TEST-PWAINSTALL-137 design verification\n Given Phone browser opens a secure Wordpairs origin; separate native-event and unsupported-browser fixtures exist.\n And the fixture data is Android Chromium; iPhone Safari guidance; 390x844; dismissed/accepted/rejected native prompt fixtures.\n When Open install help without a native prompt event, then on an insecure origin in a separate run.\n Then Android menu/iPhone Share guidance is usable; insecure origin explains HTTPS instead of presenting a nonfunctional native prompt.\n When Provide an install event, click Install once, dismiss/reject, then supply a fresh event.\n Then One event prompts at most once; cancellation retains manual guidance; only a fresh event enables another prompt.\n When Enter standalone/appinstalled state and simulate registration failure separately.\n Then Install controls hide in installed mode; registration failure does not break gameplay.\n When Inspect the browser-reported install manifest, linked icon resources and Apple metadata.\n Then Manifest has stable root identity/scope, /play standalone launch, names/colors, same-origin192/512icons and separate maskable icon; actual opaque icon dimensions/safe zone and Apple touch metadata match their declarations.\n\u0060\u0060\u0060\n\n## Boundaries\n\nPhysical Android/iPhone home-screen installation and manifest/icon metadata are separate verification obligations, not proven by emulation.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-PWAINSTALL-137", "acceptanceCriteria": [ { "id": "PWA-01", "text": "Manifest has stable identity, standalone launch at /play, root scope, names, colors, same-origin192/512 icons and a separate maskable icon.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-02", "text": "Referenced PNGs have declared dimensions, opaque brand background and safe-zone maskable artwork; Apple metadata and touch icon exist.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-03", "text": "Secure-context registration succeeds at root scope, handles failure gracefully and uses fresh worker script headers.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-04", "text": "A captured install event prompts once after a click; dismissal/rejection preserves guidance; installed/standalone state hides install UI and listeners clean up.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-05", "text": "Phone install guidance covers iPhone Share and Android menus, explains HTTPS on insecure origins, and fits narrow screens accessibly; physical home-screen installation is not claimed by emulation.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-PWAPRIVACY-138", "condition": "Run worker lifecycle negative controls and a production real-service-worker browser journey through online/offline/reconnect. Inspect CacheStorage after API/auth/private navigation, ensure offline GET/POSTAPI fails without HTML fallback, unrelated caches survive activation and no forced update reload is used.", "title": "Real worker offline, private traffic and update safety", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Source: user request2026-10-27: The game needs to be installable as a PWA on phones. Design and criteria: docs/pwa_design.md. Browser/worker evidence does not establish installation on physical Android/iPhone hardware. HostedHTTPS deployment remains future operational work.\n\nBEGIN UI-CASE TEST-PWAPRIVACY-138\n# TEST-PWAPRIVACY-138 - Real worker offline, private traffic and update safety\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Real worker offline, private traffic and update safety. |\n| QBrain reference/scope | \u0060TEST-PWAPRIVACY-138\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [pwa_design.md](../../../pwa_design.md) |\n| Frame/element identifiers | SCREEN-OFFLINE, STATE-OFFLINE-01, STATE-OFFLINE-02, STATE-OFFLINE-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-PHONEINSTALL-026#PWA-06\u0060; \u0060FR-PHONEINSTALL-026#PWA-07\u0060; \u0060FR-PHONEINSTALL-026#PWA-08\u0060; \u0060TR-PWA-CACHEPRIVACY-037#PWA-06\u0060; \u0060TR-PWA-CACHEPRIVACY-037#PWA-07\u0060; \u0060TR-PWA-CACHEPRIVACY-037#PWA-08\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | A real worker controls the page; a private room has been visited; an unrelated origin cache also exists. |\n| Test data | Offline navigation, private API GET and mutation POST; pending worker update during active round. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Disconnect and navigate, then attempt private reads/mutations. | Navigation shows static reconnect guidance; private requests fail rather than receive cached private data or offline HTML. |\n| 2 | Inspect worker caches, restore connectivity and reload through the UI. | Only static allowlisted Wordpairs resources are cached; online live site returns. |\n| 3 | Install a new worker version during an active round and later activate after clients close. | No forced in-match reload/activation occurs; unrelated cache survives cleanup. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Real worker offline, private traffic and update safety\n Scenario: TEST-PWAPRIVACY-138 design verification\n Given A real worker controls the page; a private room has been visited; an unrelated origin cache also exists.\n And the fixture data is Offline navigation, private API GET and mutation POST; pending worker update during active round.\n When Disconnect and navigate, then attempt private reads/mutations.\n Then Navigation shows static reconnect guidance; private requests fail rather than receive cached private data or offline HTML.\n When Inspect worker caches, restore connectivity and reload through the UI.\n Then Only static allowlisted Wordpairs resources are cached; online live site returns.\n When Install a new worker version during an active round and later activate after clients close.\n Then No forced in-match reload/activation occurs; unrelated cache survives cleanup.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-PWAPRIVACY-138", "acceptanceCriteria": [ { "id": "PWA-06", "text": "Offline controlled navigation returns a static reconnect screen; returning online restores the live website.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-07", "text": "API/auth/realtime/private navigation and mutations are never stored in worker caches; offline API/mutation requests fail without receiving offline HTML.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" }, { "id": "PWA-08", "text": "Only old versioned Wordpairs static caches are cleaned up; service-worker updates do not force activation or reload during a match.", "isSatisfied": true, "evidence": "docs/pwa_review_receipt.json; docs/evidence/pwa/; tests/web/pwa-support.test.ts; tests/web/pwa-worker.test.ts; tests/browser/pwa.spec.ts; tests/web/pwa-manifest.test.ts" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-QUICKMATCH-023", "condition": "Given at least one discoverable lobby has an available player slot, when a player uses quick match, then the service assigns them to the oldest eligible lobby, breaking equal creation times by stable room ID, without exceeding configured capacity. Given none is available, then the player is offered browsing or room creation.", "title": "AC-23: Quick match", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-23; canonical MCP ID: TEST-QUICKMATCH-023. Original criterion AC-23; cases AC-23-T01, AC-23-T02, AC-23-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-023. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-QUICKMATCH-023\n# TEST-QUICKMATCH-023 - AC-23: Quick match\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-23: Quick match. |\n| QBrain reference/scope | \u0060TEST-QUICKMATCH-023\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_lobby_discovery.svg](../../../word_association_lobby_discovery.svg) |\n| Frame/element identifiers | DISC-FLOW, DISC-NODE-B, DISC-NODE-C, DISC-NODE-D, DISC-NODE-E, DISC-NODE-G, DISC-TRANS-A-B, DISC-TRANS-B-C, DISC-TRANS-C-D, DISC-TRANS-D-E, DISC-TRANS-E-F, DISC-TRANS-E-B, DISC-TRANS-C-G, SCREEN-DISCOVERY, STATE-DISCOVERY-01, STATE-DISCOVERY-02, STATE-DISCOVERY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-23\u0060; \u0060FR-LOBBYDISCOVERY-019#DEC-12\u0060; \u0060TR-LOBBY-MATCHING-017#TR-17-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Two discoverable waiting rooms have open seats and known creation times. |\n| Test data | Room A older than B; equal-time second run uses stable IDs A \u003C B; third run has no eligible room. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Choose Quick match. | The player enters oldest eligible A; an equal-time run selects the lower stable room ID. |\n| 2 | Repeat with no eligible room. | The UI reports no match and offers browsing or room creation; no over-capacity join occurs. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-23: Quick match\n Scenario: TEST-QUICKMATCH-023 design verification\n Given Two discoverable waiting rooms have open seats and known creation times.\n And the fixture data is Room A older than B; equal-time second run uses stable IDs A \u003C B; third run has no eligible room.\n When Choose Quick match.\n Then The player enters oldest eligible A; an equal-time run selects the lower stable room ID.\n When Repeat with no eligible room.\n Then The UI reports no match and offers browsing or room creation; no over-capacity join occurs.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-QUICKMATCH-023", "acceptanceCriteria": [ { "id": "AC-23", "text": "Given at least one discoverable lobby has an available player slot, when a player uses quick match, then the service assigns them to the oldest eligible lobby, breaking equal creation times by stable room ID, without exceeding configured capacity. Given none is available, then the player is offered browsing or room creation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-REACTIONDELIVERY-119", "condition": "Test only the five allowed emoji, five-second expiry and two-second interval; verify real authorized delivery and unchanged game state/scores.", "title": "Verify TR-19: Emoji reaction delivery", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-119; canonical MCP ID: TEST-REACTIONDELIVERY-119. Technical/integration or operational evidence only. Source TR-19. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-119. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-19", "text": "Test only the five allowed emoji, five-second expiry and two-second interval; verify real authorized delivery and unchanged game state/scores.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-19-C01", "text": "The service accepts only \ud83d\udc4d, \u2764\ufe0f, \ud83d\ude02, \ud83c\udf89, and \ud83d\udc40; each player may send one reaction every two seconds. It broadcasts reactions to connected players and observers in real time; reactions disappear after five seconds. Reactions are informational events and cannot mutate scores, answer submissions, hint state, category selection, or match state.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-18", "text": "Reactions: Menu: \ud83d\udc4d, \u2764\ufe0f, \ud83d\ude02, \ud83c\udf89, \ud83d\udc40. A reaction is visible for five seconds; one reaction per player per two seconds. It cannot change game state or score.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "condition": "Given every player in the room has marked ready, when the final ready state is received, then the game start countdown begins immediately and the player roster locks. If a player leaves after the countdown begins, then no observer or other player is promoted or substituted into that player\u2019s place.", "title": "AC-31: Ready countdown and roster lock", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-31; canonical MCP ID: TEST-READYCOUNTDOWNANDROSTERLOCK-031. Original criterion AC-31; cases AC-31-T01, AC-31-T02, AC-31-T03, AC-31-T04. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-031. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-READYCOUNTDOWNANDROSTERLOCK-031\n# TEST-READYCOUNTDOWNANDROSTERLOCK-031 - AC-31: Ready countdown and roster lock\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-31: Ready countdown and roster lock. |\n| QBrain reference/scope | \u0060TEST-READYCOUNTDOWNANDROSTERLOCK-031\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | MSG-M06, MSG-FLOW, SCREEN-LOBBY, STATE-LOBBY-01, STATE-LOBBY-02, STATE-LOBBY-03, STATE-LOBBY-04, STATE-LOBBY-05, STATE-LOBBY-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-31\u0060; \u0060FR-LOBBYLIFECYCLE-003#AC-31\u0060; \u0060FR-LOBBYLIFECYCLE-003#DEC-14\u0060; \u0060FR-LOBBYLIFECYCLE-003#DEC-15\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Two or more players are in a waiting room; an observer is available. |\n| Test data | Alice and Bob; countdown 10 seconds; original roster recorded. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Mark every player ready. | The 10-second start countdown begins and roster locks immediately. |\n| 2 | Have one original player leave and try substituting an observer. | No substitution occurs; if fewer than two original members remain at expiry the game aborts and closes. |\n| 3 | Repeat readiness controls as creator and non-creator. | Both have equal readiness controls; creator has no special force-start authority. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-31: Ready countdown and roster lock\n Scenario: TEST-READYCOUNTDOWNANDROSTERLOCK-031 design verification\n Given Two or more players are in a waiting room; an observer is available.\n And the fixture data is Alice and Bob; countdown 10 seconds; original roster recorded.\n When Mark every player ready.\n Then The 10-second start countdown begins and roster locks immediately.\n When Have one original player leave and try substituting an observer.\n Then No substitution occurs; if fewer than two original members remain at expiry the game aborts and closes.\n When Repeat readiness controls as creator and non-creator.\n Then Both have equal readiness controls; creator has no special force-start authority.\n\u0060\u0060\u0060\n\n## Boundaries\n\nRetain the specified 10-second timing condition; do not implement synchronization with a fixed sleep.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-READYCOUNTDOWNANDROSTERLOCK-031", "acceptanceCriteria": [ { "id": "AC-31", "text": "Given every player in the room has marked ready, when the final ready state is received, then the game start countdown begins immediately and the player roster locks. If a player leaves after the countdown begins, then no observer or other player is promoted or substituted into that player\u2019s place.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-REALTIMESYNC-102", "condition": "Publish committed state to authorized players/observers; assert ordered deduplicated allowlisted delivery, no pre-commit notification and authorized refetch after gaps.", "title": "Verify TR-02: Real-time synchronization", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-102; canonical MCP ID: TEST-REALTIMESYNC-102. Technical/integration or operational evidence only. Source TR-02. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-102. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-02", "text": "Publish committed state to authorized players/observers; assert ordered deduplicated allowlisted delivery, no pre-commit notification and authorized refetch after gaps.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-02-C01", "text": "The service synchronizes room membership and round updates to all connected players. A confirmed correct answer updates the live scorecard, and all clients progress through the same hint stage.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-REQUESTFEEDBACK-143", "condition": "Verify the documented UI behavior: Loading, empty, failure and canonical retry feedback.", "title": "Loading, empty, failure and canonical retry feedback", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-REQUESTFEEDBACK-143\n# TEST-REQUESTFEEDBACK-143 - Loading, empty, failure and canonical retry feedback\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Loading, empty, failure and canonical retry feedback. |\n| QBrain reference/scope | \u0060TEST-REQUESTFEEDBACK-143\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | GAP-FLOW-REQUESTFEEDBACK, GAP-TRANS-REQUESTFEEDBACK-01, GAP-TRANS-REQUESTFEEDBACK-02, GAP-TRANS-REQUESTFEEDBACK-03, GAP-TRANS-REQUESTFEEDBACK-04; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-REQUESTFEEDBACK-030#UI-FEEDBACK-01\u0060; \u0060FR-REQUESTFEEDBACK-030#UI-FEEDBACK-02\u0060; \u0060FR-REQUESTFEEDBACK-030#UI-FEEDBACK-03\u0060; \u0060FR-REQUESTFEEDBACK-030#UI-FEEDBACK-04\u0060; \u0060FR-REQUESTFEEDBACK-030#UI-FEEDBACK-05\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | An isolated fixture controls pending reads, empty results, denied reads and mutation outcomes for Alice. |\n| Test data | Draft Space; command C-1 with fixed payload; outcomes pending, unavailable, committed-response-lost, conflict, forbidden. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Hold a read pending, then resolve empty and unavailable in separate examples. | Accessible loading feedback changes to distinct empty/allowed-action or unavailable/Retry states without a false success. |\n| 2 | Hold a form submission pending and attempt another submit; then fail it. | Busy feedback prevents duplicate submission; the safe draft remains and a user-safe error/valid Retry appears. |\n| 3 | Retry a committed-response-lost C-1, then exercise conflict in another fixture. | The uncertain retry sends identical C-1/payload and displays one committed result; conflict refreshes state without silently replaying a changed command. |\n| 4 | Deny authorization while an older read is pending, then complete that older read. | Privileged records/drafts clear and the older response cannot restore them; no raw errors or credentials are shown. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Loading, empty, failure and canonical retry feedback\n Scenario: TEST-REQUESTFEEDBACK-143 design verification\n Given An isolated fixture controls pending reads, empty results, denied reads and mutation outcomes for Alice.\n And the fixture data is Draft Space; command C-1 with fixed payload; outcomes pending, unavailable, committed-response-lost, conflict, forbidden.\n When Hold a read pending, then resolve empty and unavailable in separate examples.\n Then Accessible loading feedback changes to distinct empty/allowed-action or unavailable/Retry states without a false success.\n When Hold a form submission pending and attempt another submit; then fail it.\n Then Busy feedback prevents duplicate submission; the safe draft remains and a user-safe error/valid Retry appears.\n When Retry a committed-response-lost C-1, then exercise conflict in another fixture.\n Then The uncertain retry sends identical C-1/payload and displays one committed result; conflict refreshes state without silently replaying a changed command.\n When Deny authorization while an older read is pending, then complete that older read.\n Then Privileged records/drafts clear and the older response cannot restore them; no raw errors or credentials are shown.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nFinal hostile-review regression: malformed200room GET and POST bodies containing a private sentinel render only controlled room errors; the sentinel/parser/network text is absent and explicit Refresh restores authoritative room access. Both paths are included in the final61-browser run.\n\nEND UI-CASE TEST-REQUESTFEEDBACK-143\n\nBEGIN UI-IMPLEMENTATION TEST-REQUESTFEEDBACK-143\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-REQUESTFEEDBACK-143", "acceptanceCriteria": [ { "id": "UI-FEEDBACK-01", "text": "Pending reads expose accessible loading feedback; empty results are distinct from unavailable results and offer an allowed next action.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-02", "text": "Pending mutations show busy feedback and prevent duplicate submission while preserving entered data.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-03", "text": "Failures show a user-safe explanation and valid Retry action while retaining safe drafts; raw errors, credentials and private data are not exposed.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-04", "text": "An uncertain-write retry uses identical command identity/payload; conflicts refresh authoritative state without silently replaying a changed command or claiming success.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-FEEDBACK-05", "text": "Authorization denial clears privileged data/drafts and rejects stale response restoration; connection recovery retains accepted state without duplicate writes.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-RESPONSIVEMATRIX-145", "condition": "Verify the documented UI behavior: Minimum width, orientation and zoom preservation.", "title": "Minimum width, orientation and zoom preservation", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-RESPONSIVEMATRIX-145\n# TEST-RESPONSIVEMATRIX-145 - Minimum width, orientation and zoom preservation\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Minimum width, orientation and zoom preservation. |\n| QBrain reference/scope | \u0060TEST-RESPONSIVEMATRIX-145\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | GAP-FLOW-RESPONSIVEMATRIX, GAP-TRANS-RESPONSIVEMATRIX-01, GAP-TRANS-RESPONSIVEMATRIX-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060TR-UI-RESPONSIVEMATRIX-040#UI-RESP-01\u0060; \u0060TR-UI-RESPONSIVEMATRIX-040#UI-RESP-02\u0060; \u0060TR-UI-RESPONSIVEMATRIX-040#UI-RESP-03\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | An active round and each form/staff screen can be opened with a populated scorecard and safe in-tab draft. |\n| Test data | 320x568,390x844,844x390;1280px at400%zoom;200%text enlargement; draft Space. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Visit each screen at each specified viewport and enlargement configuration. | Required text, hint, score fields and controls remain reachable without horizontal page scrolling or clipping; zoom is enabled. |\n| 2 | Rotate portrait/landscape while editing Space and while observing the active round. | Draft and authorized room state remain; stacked score layout retains fields; keyboard/touch actions still work. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Minimum width, orientation and zoom preservation\n Scenario: TEST-RESPONSIVEMATRIX-145 design verification\n Given An active round and each form/staff screen can be opened with a populated scorecard and safe in-tab draft.\n And the fixture data is 320x568,390x844,844x390;1280px at400%zoom;200%text enlargement; draft Space.\n When Visit each screen at each specified viewport and enlargement configuration.\n Then Required text, hint, score fields and controls remain reachable without horizontal page scrolling or clipping; zoom is enabled.\n When Rotate portrait/landscape while editing Space and while observing the active round.\n Then Draft and authorized room state remain; stacked score layout retains fields; keyboard/touch actions still work.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-RESPONSIVEMATRIX-145\n\nBEGIN UI-IMPLEMENTATION TEST-RESPONSIVEMATRIX-145\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-RESPONSIVEMATRIX-145", "acceptanceCriteria": [ { "id": "UI-RESP-01", "text": "At320x568,390x844 and844x390CSS-pixel layouts, game/form text, hints, score fields and controls remain reachable without horizontal page scrolling or clipping.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. 320CSS-pixel zoom equivalent and200%text fixture." }, { "id": "UI-RESP-02", "text": "At1280px width with400%zoom (320CSS-pixel equivalent) and with200%text enlargement, content reflows without losing required information/actions; browser zoom remains enabled.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. 320CSS-pixel zoom equivalent and200%text fixture." }, { "id": "UI-RESP-03", "text": "Orientation changes preserve the authorized room and safe draft state; stacked score layouts retain all fields and touch/keyboard actions remain operable.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. 320CSS-pixel zoom equivalent and200%text fixture." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-REVIEWCHANGES-140", "condition": "Verify the documented UI behavior: Reasoned change request and resubmission.", "title": "Reasoned change request and resubmission", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Specified by operator instruction \u0022Fill gaps\u0022, 27October2026. Design: docs/testing/ui/decisions.md. Original documentation-only snapshot retained in docs/testing/ui/archive/design-20261027/; implementation now has the separately scoped evidence below.\n\nBEGIN UI-CASE TEST-REVIEWCHANGES-140\n# TEST-REVIEWCHANGES-140 - Reasoned change request and resubmission\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Reasoned change request and resubmission. |\n| QBrain reference/scope | \u0060TEST-REVIEWCHANGES-140\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md) |\n| Frame/element identifiers | SUG-NODE-G, SUG-TRANS-F-G, GAP-FLOW-REVIEWCHANGES, GAP-TRANS-REVIEWCHANGES-01, GAP-TRANS-REVIEWCHANGES-02, GAP-TRANS-REVIEWCHANGES-03, GAP-TRANS-REVIEWCHANGES-NONPROPOSER; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-REVIEWCHANGES-027#UI-CHANGES-01\u0060; \u0060FR-REVIEWCHANGES-027#UI-CHANGES-02\u0060; \u0060FR-REVIEWCHANGES-027#UI-CHANGES-03\u0060; \u0060FR-REVIEWCHANGES-027#UI-CHANGES-04\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice proposed Space with three pairs; independent moderator Bob can review it. |\n| Test data | Reason Add clearer hints; revised pair hints H1/H2/H3; second category Oceans. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Bob request changes with an empty reason, then with Add clearer hints. | Empty reason is rejected; valid request shows changes_requested, the reason and an audit entry. |\n| 2 | While Space is changes_requested, attempt to edit its pairs and resubmit as another proposer Mallory and as reviewer Bob. | Both non-proposer attempts are denied; Space content, pair count, recorded revision and changes_requested status are unchanged, and no accepted edit/resubmission appears in decision history. |\n| 3 | As Alice try a second open category, then revise Space with two pairs and with three pairs. | The second suggestion and two-pair resubmission are rejected; exactly three edited pairs can resubmit. |\n| 4 | Resubmit and inspect review/playability/history. | Status becomes pending_review; content remains unplayable pending independent approval/complete curation, revision history is retained and rejection-appeal allowance is unused. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Reasoned change request and resubmission\n Scenario: TEST-REVIEWCHANGES-140 design verification\n Given Alice proposed Space with three pairs; independent moderator Bob can review it.\n And the fixture data is Reason Add clearer hints; revised pair hints H1/H2/H3; second category Oceans.\n When As Bob request changes with an empty reason, then with Add clearer hints.\n Then Empty reason is rejected; valid request shows changes_requested, the reason and an audit entry.\n When While Space is changes_requested, attempt to edit its pairs and resubmit as another proposer Mallory and as reviewer Bob.\n Then Both non-proposer attempts are denied; Space content, pair count, recorded revision and changes_requested status are unchanged, and no accepted edit/resubmission appears in decision history.\n When As Alice try a second open category, then revise Space with two pairs and with three pairs.\n Then The second suggestion and two-pair resubmission are rejected; exactly three edited pairs can resubmit.\n When Resubmit and inspect review/playability/history.\n Then Status becomes pending_review; content remains unplayable pending independent approval/complete curation, revision history is retained and rejection-appeal allowance is unused.\n\u0060\u0060\u0060\n\n## Boundaries\n\nSpecified gap behavior is implemented and verified within the execution receipt\u0027s isolated UI/application/SQL scope. The original design-only snapshot remains historical.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-REVIEWCHANGES-140\n\nBEGIN UI-IMPLEMENTATION TEST-REVIEWCHANGES-140\nImplemented UI-DEC behavior. Exact source inventory: docs/testing/ui/implementation-manifest.json. Evidence: docs/testing/ui/implementation-receipt.json; docs/evidence/ui-gaps/unit-safe-errors-final.log (542 tests), browser-safe-errors-final.log (61 journeys including malformed room GET/POST), browser-seats-tagged.log (5 refined recovery cases), postgres.log (68 real SQL tests), build-safe-errors-final.log, lint-safe-errors.log and typecheck-safe-errors.log. Browser HTTP/persistence/time ports are isolated fixtures around actual React/application/domain services; do not treat them as real Realtime/physical-phone/OIDC/public-origin evidence. Criterion-level procedures: matching UI TEST notes/cases. Historical148baseline criteria/evidence and TEST-ROOMSYNC-139 / LIVE-07 are preserved.\nEND UI-IMPLEMENTATION TEST-REVIEWCHANGES-140", "acceptanceCriteria": [ { "id": "UI-CHANGES-01", "text": "An independent moderator requests changes with a nonempty reason; the suggestion enters changes_requested and remains unplayable.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-CHANGES-02", "text": "changes_requested consumes the proposer's one-open-suggestion slot; another open suggestion is rejected.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-CHANGES-03", "text": "Only the proposer can edit and resubmit exactly three pair suggestions; valid resubmission enters pending_review and still requires independent review and complete curation.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." }, { "id": "UI-CHANGES-04", "text": "Revision, reason, actor and status transitions are auditable; a change request does not consume the rejection appeal allowance.", "isSatisfied": true, "evidence": "docs/testing/ui/implementation-receipt.json; matching criterion procedure in docs/testing/ui/cases/; exact snapshot docs/testing/ui/implementation-manifest.json. Isolated UI + real application/domain; SQL tier separately identified." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ROOMCODES-110", "condition": "Test valid/invalid/expired eight-character codes,10-per-minute attempts, atomic final-slot admission, empty-room expiry and generic not-found privacy.", "title": "Verify TR-10: Room code handling", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-110; canonical MCP ID: TEST-ROOMCODES-110. Technical/integration or operational evidence only. Source TR-10. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-110. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ROOMCODES-110\n# TEST-ROOMCODES-110 - Invalid and expired room-code recovery\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json). Current implementation evidence is in [implementation-receipt.json](../implementation-receipt.json); the original documentation-only snapshot is retained under archive/design-20261027/.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Invalid and expired room-code recovery. |\n| QBrain reference/scope | \u0060TEST-ROOMCODES-110\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [decisions.md](../decisions.md); [word_association_game_requirements.md](../../../word_association_game_requirements.md) |\n| Frame/element identifiers | GAP-FLOW-ROOMCODES, GAP-TRANS-ROOMCODES-01, GAP-TRANS-ROOMCODES-02; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060TR-ROOM-CODES-010#TR-10-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice is at room-code entry; valid active and closed-code fixtures exist. |\n| Test data | Invalid eight-character Crockford code, closed room code,10 invalid attempts in one minute and a valid generated code. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Automated isolated browser integration and supporting application/SQL checks executed; operational boundaries remain separate. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Executed applicable UI-DEC variants in Chromium with real React and isolated HTTP/application/domain fixtures; real disposable PostgreSQL covers persistence/audit. See [execution receipt](../implementation-receipt.json). This is the documented recovery variant, not a claim that every historical compound obligation was rerun. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Submit invalid/closed codes, then correct to the valid active code. | A safe error permits correction without leaking another active code; the valid code reaches the intended room. |\n| 2 | Exceed the documented invalid-attempt window and attempt another code. | Further invalid attempts are rate-limited until the window allows retry; no unauthorized membership or false success occurs. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Invalid and expired room-code recovery\n Scenario: TEST-ROOMCODES-110 design verification\n Given Alice is at room-code entry; valid active and closed-code fixtures exist.\n And the fixture data is Invalid eight-character Crockford code, closed room code,10 invalid attempts in one minute and a valid generated code.\n When Submit invalid/closed codes, then correct to the valid active code.\n Then A safe error permits correction without leaking another active code; the valid code reaches the intended room.\n When Exceed the documented invalid-attempt window and attempt another code.\n Then Further invalid attempts are rate-limited until the window allows retry; no unauthorized membership or false success occurs.\n\u0060\u0060\u0060\n\n## Boundaries\n\nExisting requirement, newly explicit UI scenario; no change to historical evidence or status.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\n## Implementation evidence\n\n[Implementation snapshot and tiered results](../implementation.md), [hashed source inventory](../implementation-manifest.json), and [raw execution logs](../../../evidence/ui-gaps/) bind this case to the current tested implementation. Browser journeys use actual pages and real application/domain services behind isolated HTTP/persistence/time ports. They do not establish physical screen-reader behavior, native phone install, real OIDC, deployed availability or real private-push2..25UI delivery. Reflow at400% is the documented320CSS-pixel equivalent, not a physical browser-zoom certification.\n\nEND UI-CASE TEST-ROOMCODES-110", "acceptanceCriteria": [ { "id": "VERIFY-TR-10", "text": "Test valid/invalid/expired eight-character codes,10-per-minute attempts, atomic final-slot admission, empty-room expiry and generic not-found privacy.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-10-C01", "text": "Room codes identify the intended active room and reject invalid or expired codes. Each room stores a configured capacity from 2 through 25. Room-code joins and deep-link joins use the same authoritative slot check as lobby browsing and quick match. When full, a valid invite permits the player to request observer mode instead of a player slot. Before countdown, promote the oldest observer into the last player position when a player leaves a full room; break equal observer-arrival times by stable profile ID. Use an eight-character Crockford Base32 code, valid while the room is active and expired on close; close empty rooms after 30 minutes and limit invalid-code attempts to 10 per minute per session.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-17", "text": "Room code, reconnect, creator departure: Use an eight-character Crockford Base32 code. Codes remain valid while the room is active and expire on close; empty rooms close after 30 minutes. Reconnect retains membership for a two-minute grace interval. Creator departure grants no special authority; remaining players retain control. Invalid/expired codes return the same generic not-found response; limit code attempts to 10 per minute per session.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ROOMINVITATIONS-025", "condition": "Given a player is in a room, when they share its room code or deep link, then another player can use either invitation to reach the intended room, subject to an open slot.", "title": "AC-25: Room invitations", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-25; canonical MCP ID: TEST-ROOMINVITATIONS-025. Original criterion AC-25; cases AC-25-T01, AC-25-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-025. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ROOMINVITATIONS-025\n# TEST-ROOMINVITATIONS-025 - AC-25: Room invitations\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-25: Room invitations. |\n| QBrain reference/scope | \u0060TEST-ROOMINVITATIONS-025\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg) |\n| Frame/element identifiers | ROOM-FLOW, ROOM-NODE-C, ROOM-NODE-G, ROOM-TRANS-C-D, ROOM-TRANS-B-G, ROOM-TRANS-G-D, MSG-M01, MSG-M02, SCREEN-JOIN, STATE-JOIN-01, STATE-JOIN-02, STATE-JOIN-03, STATE-JOIN-04, STATE-JOIN-05; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYDISCOVERY-019#AC-25\u0060; \u0060FR-LOBBYLIFECYCLE-003#AC-25\u0060; \u0060FR-ROOMACCESS-001#AC-25\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice is already a player in an active room; Bob and Cara have independent profiles. |\n| Test data | The room\u0027s generated code and inviter-bound signed deep link. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Alice share the code to Bob and link to Cara. | Both invitation forms refer to Alice\u0027s intended room. |\n| 2 | Join as Bob by code and Cara by link when seats are open. | Both enter that same room subject to its configured capacity. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-25: Room invitations\n Scenario: TEST-ROOMINVITATIONS-025 design verification\n Given Alice is already a player in an active room; Bob and Cara have independent profiles.\n And the fixture data is The room\u0027s generated code and inviter-bound signed deep link.\n When As Alice share the code to Bob and link to Cara.\n Then Both invitation forms refer to Alice\u0027s intended room.\n When Join as Bob by code and Cara by link when seats are open.\n Then Both enter that same room subject to its configured capacity.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ROOMINVITATIONS-025", "acceptanceCriteria": [ { "id": "AC-25", "text": "Given a player is in a room, when they share its room code or deep link, then another player can use either invitation to reach the intended room, subject to an open slot.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ROOMJOINING-001", "condition": "Given a valid room code and 2-25 players on separate devices, when each joins, then every joined player appears in the same room with their selected icon.", "title": "AC-01: Room joining", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-01; canonical MCP ID: TEST-ROOMJOINING-001. Original criterion AC-01; cases AC-01-T01, AC-01-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-001. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ROOMJOINING-001\n# TEST-ROOMJOINING-001 - AC-01: Room joining\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-01: Room joining. |\n| QBrain reference/scope | \u0060TEST-ROOMJOINING-001\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_room_creation.svg](../../../word_association_room_creation.svg); [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg) |\n| Frame/element identifiers | ID-FLOW, ID-NODE-G, ID-TRANS-F-G, DISC-FLOW, DISC-NODE-F, DISC-TRANS-E-F, ROOM-FLOW, ROOM-NODE-C, ROOM-NODE-D, ROOM-NODE-E, ROOM-TRANS-C-D, ROOM-TRANS-D-E, ROOM-TRANS-D-H, ROOM-TRANS-G-D, ROUND-FLOW, ROUND-NODE-A, ROUND-TRANS-A-B, MSG-M03, MSG-M04, MSG-M05, MSG-FLOW, SCREEN-JOIN, STATE-JOIN-01, STATE-JOIN-02, STATE-JOIN-03, STATE-JOIN-04, STATE-JOIN-05, SCREEN-LOBBY, STATE-LOBBY-01, STATE-LOBBY-02, STATE-LOBBY-03, STATE-LOBBY-04, STATE-LOBBY-05, STATE-LOBBY-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-LOBBYLIFECYCLE-003#AC-01\u0060; \u0060FR-ROOMACCESS-001#AC-01\u0060; \u0060TR-REALTIME-SYNC-002#TR-02-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice has a waiting room; Bob has an independent browser profile and no room membership. |\n| Test data | Generated active room code, Alice owl icon, Bob fox icon; repeat for capacities 2, 8 and 25. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | As Bob enter the generated room code and choose player join. | Bob enters Alice\u0027s room with the fox icon. |\n| 2 | Observe Alice\u0027s room without manually refreshing. | The same room roster includes Alice and Bob, each once, with their selected icons. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-01: Room joining\n Scenario: TEST-ROOMJOINING-001 design verification\n Given Alice has a waiting room; Bob has an independent browser profile and no room membership.\n And the fixture data is Generated active room code, Alice owl icon, Bob fox icon; repeat for capacities 2, 8 and 25.\n When As Bob enter the generated room code and choose player join.\n Then Bob enters Alice\u0027s room with the fox icon.\n When Observe Alice\u0027s room without manually refreshing.\n Then The same room roster includes Alice and Bob, each once, with their selected icons.\n\u0060\u0060\u0060\n\n## Boundaries\n\nRun separate-device browser contexts; extend the fixture to all counts 2..25 under TEST-MULTIPLAYERINTEGRATION-134. This case alone does not establish every count or a live latency bound.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ROOMJOINING-001", "acceptanceCriteria": [ { "id": "AC-01", "text": "Given a valid room code and 2-25 players on separate devices, when each joins, then every joined player appears in the same room with their selected icon.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ROOMSYNC-139", "condition": "Run repeatable UI integration against an explicitly selected actual database-backed runtime with real private WebSockets and no HTTP fixtures, plus focused concurrency, lifecycle, scheduler and negative authorization regressions. Exercise2 through25 players and an observer, retain evidence and distinguish local runtime proof from hosted deployment.", "title": "Real browser multiplayer, private push and recovery integration", "workspaceId": "\u003Crepo\u003E", "priority": "critical", "status": "in_progress", "notes": "Confirmed user requirements: actual live gameplay, repeatable UI integration at2..25, design updates and independent hostile validation. Source: phone stale-roster report and corrections,27October2026. SDK token callback, coalescing, lifecycle, independent worker and owned cleanup are implemented. New presence-body defect independently reproduced in Chromium;2red React tests now pass, real heartbeat browser regression passes with unread negative control and production-only body drain.532unit/acceptance tests, lint and production build pass. Updated strict game is rerunning; full2..25 remains pending. Prior25-player round1 failure and measured shared-cluster WAL stalls are retained. Volatile TLS harness preserves fsync/synchronous_commit but proves neither power-loss durability nor public capacity. Faster waiting-room fallback and hosted Phase7 remain outside this extension.\n\nBEGIN UI-CASE TEST-ROOMSYNC-139\n# TEST-ROOMSYNC-139 - Real browser multiplayer, private push and recovery integration\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Real browser multiplayer, private push and recovery integration. |\n| QBrain reference/scope | \u0060TEST-ROOMSYNC-139\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_client_message_flow.svg](../../../word_association_client_message_flow.svg); [room_sync_fix.md](../../../room_sync_fix.md) |\n| Frame/element identifiers | MSG-M03, MSG-M04, MSG-M05, MSG-M27, MSG-M28, MSG-M29, MSG-FLOW, SCREEN-ROUND, STATE-ROUND-01, STATE-ROUND-02, STATE-ROUND-03, STATE-ROUND-04, STATE-ROUND-05, STATE-ROUND-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060TR-ROOM-SYNCRECOVERY-038#LIVE-02\u0060; \u0060TR-ROOM-SYNCRECOVERY-038#LIVE-03\u0060; \u0060TR-ROOM-SYNCRECOVERY-038#LIVE-07\u0060 |\n| Priority | critical |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Actual isolated TLS runtime has database, private notifications and autonomous deadline worker; separate UI contexts have real guest identities. |\n| Test data | Player counts every integer 2..25; one inviter-bound observer; controlled pairs Hot/Cold, Up/Down, Left/Right, In/Out, Day/Night, Open/Closed, Big/Small, Fast/Slow; all no-hint correct solves yield 5 per round and 40 per player. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Partial: full actual-runtime UI fixture, seed control and independent observer are required; current execution state remains the existing QBrain in_progress record. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Join by UI room code and ready each player without manual refresh, with periodic application refresh suppressed. | All clients see the same roster, countdown and category chooser through actual private updates. |\n| 2 | Select category and submit answers through UI for eight rounds; observe hints, scorecard, reactions and summaries from remote clients. | All clients converge on authorized state and identical final ranking; accepted UI solves correspond to expected round points. |\n| 3 | Repeat each player count and perform offline/reconnect, token-renewal and socket-recovery variants. | Autonomous progression and authorized recovery work; no polling-only pass or service-only result is accepted. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Real browser multiplayer, private push and recovery integration\n Scenario: TEST-ROOMSYNC-139 design verification\n Given Actual isolated TLS runtime has database, private notifications and autonomous deadline worker; separate UI contexts have real guest identities.\n And the fixture data is Player counts every integer 2..25; one inviter-bound observer; controlled pairs Hot/Cold, Up/Down, Left/Right, In/Out, Day/Night, Open/Closed, Big/Small, Fast/Slow; all no-hint correct solves yield 5 per round and 40 per player.\n When Join by UI room code and ready each player without manual refresh, with periodic application refresh suppressed.\n Then All clients see the same roster, countdown and category chooser through actual private updates.\n When Select category and submit answers through UI for eight rounds; observe hints, scorecard, reactions and summaries from remote clients.\n Then All clients converge on authorized state and identical final ranking; accepted UI solves correspond to expected round points.\n When Repeat each player count and perform offline/reconnect, token-renewal and socket-recovery variants.\n Then Autonomous progression and authorized recovery work; no polling-only pass or service-only result is accepted.\n\u0060\u0060\u0060\n\n## Boundaries\n\nThis documents the outstanding matrix obligation; it does not claim that all counts passed. Private-frame privacy and worker ownership/fault contracts remain separate LIVE criteria.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ROOMSYNC-139", "acceptanceCriteria": [ { "id": "LIVE-01", "text": "Actual private WebSocket subscriptions deliver only event/aggregate/version metadata to authenticated per-profile audiences; anonymous, cross-profile subscriptions and client publication are denied.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-02", "text": "Repeatable browser integration creates real guests and room membership, enters a code, readies players, plays eight UI rounds, and verifies remote category, solve, hints, scores, reveal, reactions and final standings through actual private notifications and authorized reads while periodic UI polling is suppressed.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-03", "text": "An authenticated server worker advances countdown and hint deadlines with all browsers offline, drains bounded durable outbox batches, reports deadline and publication failures separately, and preserves failed events for retry. Foreground requests never wait for an active worker batch.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-04", "text": "The temporary HTTPS gateway serves app and Realtime paths while rejecting tenant management paths; private credentials and internal ports remain private. Cleanup acts only on its captured lease generation and owned resource identities. A separate-broker harness must own a separate strict-TLS game database/outbox; partial startup or unconfirmed cleanup preserves recovery identities and blocks replacement.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-05", "text": "Focus, visibility and online recovery trigger authorized reads; concurrent reads coalesce one follow-up, older responses cannot lose newer notifications, and unmount/account changes prevent obsolete subscriptions after deferred authentication. Connected game/social safety reads use15seconds and disconnected recovery uses1second; cadence changes preserve in-flight/coalesced reads and independent display clocks. Presence responses are fully consumed before clearing canonical retries and refreshing; a body-read failure retains the exact retry command.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-06", "text": "Real UI integration proves token renewal beyond the original120-second expiry and actual WebSocket close/reconnect followed by another push-driven game transition.", "isSatisfied": true, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" }, { "id": "LIVE-07", "text": "Repeatable browser integration plays real eight-round games at every player count2 through25, with UI readiness/categories/every answer and identical final rankings, using a separately owned TLS game database and private Realtime outbox. At most two UI answers are submitted simultaneously; local results do not establish public-tunnel capacity. Cleanup is truthful and bounded.", "isSatisfied": false, "evidence": "docs/evidence/room-sync/live-ui-final.log; docs/evidence/room-sync/live-ui-observations.json; docs/evidence/room-sync/runtime-health.json; docs/evidence/room-sync/auth-callback-green.log; docs/evidence/room-sync/lease-contract.log; docs/evidence/room-sync/unit-regression-final.log; tests/browser/live-player-counts.integration.spec.ts (matrix pending)" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-ROUNDSUMMARY-012", "condition": "Given a round ends, when the summary appears, then it ranks all players by current cumulative score and shows the completed round\u2019s points and solve times.", "title": "AC-12: Round summary", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-12; canonical MCP ID: TEST-ROUNDSUMMARY-012. Original criterion AC-12; cases AC-12-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-012. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-ROUNDSUMMARY-012\n# TEST-ROUNDSUMMARY-012 - AC-12: Round summary\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-12: Round summary. |\n| QBrain reference/scope | \u0060TEST-ROUNDSUMMARY-012\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-J, ROUND-TRANS-H-J, ROUND-TRANS-J-K, MSG-M33, MSG-M34, MSG-M35, SCREEN-SUMMARY, STATE-SUMMARY-01, STATE-SUMMARY-02, STATE-SUMMARY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ROUNDSUMMARY-013#AC-12\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | A round is about to finish with controlled prior totals and current round outcomes. |\n| Test data | Before round Alice 5, Bob 0; round Alice 1 in 65 seconds, Bob 5 in 4 seconds. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Finish the round and open the round summary. | Alice ranks above Bob by cumulative totals 6 and 5. |\n| 2 | Read each completed-round row. | Alice shows 1 round point and 65 seconds; Bob shows 5 and 4 seconds. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-12: Round summary\n Scenario: TEST-ROUNDSUMMARY-012 design verification\n Given A round is about to finish with controlled prior totals and current round outcomes.\n And the fixture data is Before round Alice 5, Bob 0; round Alice 1 in 65 seconds, Bob 5 in 4 seconds.\n When Finish the round and open the round summary.\n Then Alice ranks above Bob by cumulative totals 6 and 5.\n When Read each completed-round row.\n Then Alice shows 1 round point and 65 seconds; Bob shows 5 and 4 seconds.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-ROUNDSUMMARY-012", "acceptanceCriteria": [ { "id": "AC-12", "text": "Given a round ends, when the summary appears, then it ranks all players by current cumulative score and shows the completed round\u2019s points and solve times.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-SCHEMAPROVISIONING-123", "condition": "Verify fresh/versioned migrations and repeatable credential-redacted provisioning with separated Preview/Production settings; actual provisioning entry point and hosted checks remain Phase7.", "title": "Verify TR-23: Provisioning and schema changes", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "New verification/extension import key: TEST-WP-123; canonical MCP ID: TEST-SCHEMAPROVISIONING-123. Technical/integration or operational evidence only. Source TR-23. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-123. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-23", "text": "Verify fresh/versioned migrations and repeatable credential-redacted provisioning with separated Preview/Production settings; actual provisioning entry point and hosted checks remain Phase7.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-23-C01", "text": "Provide a manually invoked, repeatable provisioning script using the Supabase and Vercel CLIs. It must create or link the projects, apply version-controlled database migrations, and set required Vercel environment variables for Preview and Production. The script must accept authenticated credentials from the operator\u2019s environment, never commit or print secret values, and avoid configuring paid resources.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." }, { "id": "DEC-22", "text": "Deadline scheduler: Store versioned deadline jobs in Postgres and process due jobs using Supabase Cron/`pg_cron` at one-second cadence; each job calls a transactional database function, with stale-version and duplicate delivery as no-ops. This is a TR technical choice; verify current Free-plan capability at Phase 7 deployment entry after coding.", "isSatisfied": false, "evidence": "Requirement imported; operational portions remain unverified until the documented Phase7 check." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-STATEAUTHORITY-101", "condition": "Submit forged, stale and competing room/game commands; assert only the authoritative transaction commits and rejected commands preserve roster, score and version.", "title": "Verify TR-01: Authoritative room state", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-101; canonical MCP ID: TEST-STATEAUTHORITY-101. Technical/integration or operational evidence only. Source TR-01. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-101. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-01", "text": "Submit forged, stale and competing room/game commands; assert only the authoritative transaction commits and rejected commands preserve roster, score and version.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-01-C01", "text": "A server-side game service owns room membership, round state, accepted answers, hint stage, scoring, solve timestamps, category choice, and match completion. Clients cannot award points or change a target answer.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-14", "text": "Host authority and countdown: Creator has no special start/readiness privilege. All players have equivalent controls. All-ready starts a 10-second countdown and locks the roster.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-15", "text": "Countdown departure below minimum: Never replace a player who leaves after lock. If fewer than two original players remain at countdown expiry, abort start and close the room.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-16", "text": "Idle prompt and readiness races: The 30-second interval resets on player/observer membership or ready-state changes. Prompt once per unchanged aggregate version. Deadlines carry the expected version; stale jobs are no-ops.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-SUGGESTIONREVIEW-115", "condition": "Exercise lifetime wins at9/10, one open suggestion and exactly three pairs; reject unauthorized/incomplete activation and require independent review.", "title": "Verify TR-15: Category suggestion eligibility and review", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-115; canonical MCP ID: TEST-SUGGESTIONREVIEW-115. Technical/integration or operational evidence only. Source TR-15. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-115. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-SUGGESTIONREVIEW-115\n# TEST-SUGGESTIONREVIEW-115 - Verify TR-15: Category suggestion eligibility and review\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify Verify TR-15: Category suggestion eligibility and review. |\n| QBrain reference/scope | \u0060TEST-SUGGESTIONREVIEW-115\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_category_suggestion.svg](../../../word_association_category_suggestion.svg) |\n| Frame/element identifiers | SUG-FLOW, SUG-NODE-E, SUG-NODE-F, SUG-NODE-G, SUG-NODE-H, SUG-NODE-I, SUG-TRANS-D-E, SUG-TRANS-E-F, SUG-TRANS-F-G, SUG-TRANS-F-H, SUG-TRANS-H-I, SCREEN-SUGGESTION, STATE-SUGGESTION-01, STATE-SUGGESTION-02, STATE-SUGGESTION-03, STATE-SUGGESTION-04, STATE-SUGGESTION-05, STATE-SUGGESTION-06; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-CATEGORYSUGGESTIONS-017#DEC-08\u0060; \u0060FR-NOMINATIONS-016#DEC-08\u0060; \u0060TR-NOMINATION-MODERATION-014#DEC-08\u0060; \u0060TR-SUGGESTION-REVIEW-015#DEC-08\u0060; \u0060TR-SUGGESTION-REVIEW-015#TR-15-C01\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Bob has 10 lifetime wins, one open three-pair suggestion and no independent review yet. |\n| Test data | Category Space with exactly 3 pairs; independent moderator Alice; one appeal to senior Cara. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Try opening another suggestion, then independently review the existing submission with a reason. | Only one suggestion remains open and the reasoned independent decision is recorded. |\n| 2 | For a rejected example appeal once; for approved example complete required curation before activation. | Only permitted independent senior resolution succeeds; approved incomplete pairs are never playable. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: Verify TR-15: Category suggestion eligibility and review\n Scenario: TEST-SUGGESTIONREVIEW-115 design verification\n Given Bob has 10 lifetime wins, one open three-pair suggestion and no independent review yet.\n And the fixture data is Category Space with exactly 3 pairs; independent moderator Alice; one appeal to senior Cara.\n When Try opening another suggestion, then independently review the existing submission with a reason.\n Then Only one suggestion remains open and the reasoned independent decision is recorded.\n When For a rejected example appeal once; for approved example complete required curation before activation.\n Then Only permitted independent senior resolution succeeds; approved incomplete pairs are never playable.\n\u0060\u0060\u0060\n\n## Boundaries\n\nThe diagram\u0027s \u0022request changes\u0022 action lacks a defined resubmission/status contract: Q-MOD-01 remains blocked.\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-SUGGESTIONREVIEW-115", "acceptanceCriteria": [ { "id": "VERIFY-TR-15", "text": "Exercise lifetime wins at9/10, one open suggestion and exactly three pairs; reject unauthorized/incomplete activation and require independent review.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-15-C01", "text": "The service tracks game wins for each player and unlocks category-and-pair suggestions when the player reaches 10 wins. It stores the proposed category and its three proposed word pairs as one submission, tracks its review status, and prevents unapproved or incomplete content from entering the playable catalog. Win counts use a stable player profile and are cumulative for that profile\u2019s lifetime.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-08", "text": "Moderation workflow: Roles are Content Moderator and Senior Moderator. At threshold, content enters Pending Review. A moderator other than the proposer approves or rejects with a reason. The proposer may appeal once to a Senior Moderator. Approval alone does not make content playable; the complete curated record must pass validation.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "DEC-09", "text": "Suggestion eligibility: Wins are lifetime wins on one stable profile. A profile may have one open category suggestion at a time; each contains one category and exactly three pairs.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-SWBOMGENERATION-127", "condition": "Generate CycloneDX1.6 from the exact lockfile with commit/environment/URL metadata and no secrets; reject invalid schema or mismatched deployment identity in Phase7.", "title": "Verify TR-27: Per-build software bill of materials", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "pending", "notes": "New verification/extension import key: TEST-WP-127; canonical MCP ID: TEST-SWBOMGENERATION-127. Technical/integration or operational evidence only. Source TR-27. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-127. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-27", "text": "Generate CycloneDX1.6 from the exact lockfile with commit/environment/URL metadata and no secrets; reject invalid schema or mismatched deployment identity in Phase7.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-27-C01", "text": "Generate one CycloneDX JSON 1.6 software bill of materials (SWBOM) from the exact npm lockfile for every Vercel Preview or Production deployment. Include direct and transitive runtime and development components, declared licenses, package URLs, dependency relationships, build timestamp, Git commit SHA, deployment environment, and Vercel deployment URL. Generate it after the mock-first test gate and before the application build, then bundle it into that same immutable deployment at `public/sbom/.cdx.json`. Never include secrets or environment-variable values. Document the artifact contract in `docs/SWBOM.md`.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-SWBOMRELEASEARCHIVE-041", "condition": "Given source files and a candidate SWBOM fixture for the same release commit are prepared, when a source archive is packaged, then the archive contains the complete source, `LICENSE`, and SWBOM at `sbom/.cdx.json`; packaging rejects a missing, invalid, or mismatched report. This criterion is verified against temporary files and does not depend on a deployed artifact.", "title": "AC-41: SWBOM release archive", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-41; canonical MCP ID: TEST-SWBOMRELEASEARCHIVE-041. Original criterion AC-41; cases AC-41-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-041. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-41", "text": "Given source files and a candidate SWBOM fixture for the same release commit are prepared, when a source archive is packaged, then the archive contains the complete source, `LICENSE`, and SWBOM at `sbom/.cdx.json`; packaging rejects a missing, invalid, or mismatched report. This criterion is verified against temporary files and does not depend on a deployed artifact.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-TDDACCEPTANCE-126", "condition": "Reject uncovered active ACs, invalid mocks and missing negative controls before implementation; verify the eventual deployment build runs tests before compilation and fails closed.", "title": "Verify TR-26: Mock-first test gate", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "in_progress", "notes": "New verification/extension import key: TEST-WP-126; canonical MCP ID: TEST-TDDACCEPTANCE-126. Technical/integration or operational evidence only. Source TR-26. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-126. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-26", "text": "Reject uncovered active ACs, invalid mocks and missing negative controls before implementation; verify the eventual deployment build runs tests before compilation and fails closed.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-26-C01", "text": "Before writing implementation code for an increment, define tests for every applicable acceptance criterion, validate the tests against mocks, and then implement the smallest behavior that makes them pass. The Vercel build must run the test suite before the production build. No GitHub Actions workflow is assumed or required.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "condition": "Given game rules are exercised without production infrastructure, when domain use cases are tested, then they run through injected ports/fakes without requiring Next.js or Supabase runtime services. Given an application command targets a full or stale room, when its repository port reports a conflict, then the use case returns the canonical conflict result without repeating a domain side effect.", "title": "AC-51: Testable, concurrency-safe domain boundary", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-51; canonical MCP ID: TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051. Original criterion AC-51; cases AC-51-T01, AC-51-T02, AC-51-T03, AC-51-T04. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-051. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "AC-51", "text": "Given game rules are exercised without production infrastructure, when domain use cases are tested, then they run through injected ports/fakes without requiring Next.js or Supabase runtime services. Given an application command targets a full or stale room, when its repository port reports a conflict, then the use case returns the canonical conflict result without repeating a domain side effect.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-TIMETIEBREAK-014", "condition": "Given two or more players tie for the highest score, when final standings are calculated, then total answer time is the sum of each round\u2019s accepted solve duration, with 80 seconds charged for an unsolved round; the lower total ranks first, and an exact tie shares the same rank.", "title": "AC-14: Time tiebreak", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-14; canonical MCP ID: TEST-TIMETIEBREAK-014. Original criterion AC-14; cases AC-14-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-014. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-TIMETIEBREAK-014\n# TEST-TIMETIEBREAK-014 - AC-14: Time tiebreak\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-14: Time tiebreak. |\n| QBrain reference/scope | \u0060TEST-TIMETIEBREAK-014\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-M, ROUND-TRANS-K-M, SCREEN-FINAL, STATE-FINAL-01, STATE-FINAL-02, STATE-FINAL-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-FINALSTANDINGS-014#AC-14\u0060; \u0060FR-FINALSTANDINGS-014#DEC-04\u0060; \u0060FR-SCORELOCK-010#AC-14\u0060; \u0060FR-SCORING-009#AC-14\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Eight-round game has tied highest scores and controlled solve durations. |\n| Test data | Alice and Bob 20 points; Alice accepted solve total 30 seconds plus one unsolved round =110; Bob accepted solve total 115 and no unsolved rounds. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Complete round eight and inspect final standings. | Alice ranks above Bob because 110 \u003C 115, including Alice\u0027s 80-second unsolved charge. |\n| 2 | Repeat with both tied score and exactly equal total answer time. | Alice and Bob share the same rank. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-14: Time tiebreak\n Scenario: TEST-TIMETIEBREAK-014 design verification\n Given Eight-round game has tied highest scores and controlled solve durations.\n And the fixture data is Alice and Bob 20 points; Alice accepted solve total 30 seconds plus one unsolved round =110; Bob accepted solve total 115 and no unsolved rounds.\n When Complete round eight and inspect final standings.\n Then Alice ranks above Bob because 110 \u003C 115, including Alice\u0027s 80-second unsolved charge.\n When Repeat with both tied score and exactly equal total answer time.\n Then Alice and Bob share the same rank.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-TIMETIEBREAK-014", "acceptanceCriteria": [ { "id": "AC-14", "text": "Given two or more players tie for the highest score, when final standings are calculated, then total answer time is the sum of each round\u2019s accepted solve duration, with 80 seconds charged for an unsolved round; the lower total ranks first, and an exact tie shares the same rank.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-UIACCESSIBILITY-112", "condition": "Measure text/button contrast, visible focus,44px primary targets, semantic state labels and keyboard/touch action across portrait/landscape.", "title": "Verify TR-12: Accessibility and readability", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "New verification/extension import key: TEST-WP-112; canonical MCP ID: TEST-UIACCESSIBILITY-112. Technical/integration or operational evidence only. Source TR-12. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-112. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-12", "text": "Measure text/button contrast, visible focus,44px primary targets, semantic state labels and keyboard/touch action across portrait/landscape.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" }, { "id": "TR-12-C01", "text": "Text and controls maintain clear contrast over every category background. Focus, selected icons, solved status, and score changes use labels or shapes as well as color.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-UNSOLVEDRESULT-008", "condition": "Given a player remains unsolved after Hint 3, when the round ends, then the player earns 0 points and the game reveals the correct answer.", "title": "AC-08: Unsolved result", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Original acceptance criterion: AC-08; canonical MCP ID: TEST-UNSOLVEDRESULT-008. Original criterion AC-08; cases AC-08-T01. Preserve all original independent expectations and semantic negative controls. Evidence docs/evidence/phase6/acceptance-mapping.json and docs/phase6_execution.md; later regression docs/admin_acl_review_receipt.json. Database/provider/deployment evidence does not substitute for AC coverage. Former provisional MCP ID: TEST-WP-008. Replaced at user request with a subject-identifying ID.\n\nBEGIN UI-CASE TEST-UNSOLVEDRESULT-008\n# TEST-UNSOLVEDRESULT-008 - AC-08: Unsolved result\n\nLinked specification for the matching authoritative QBrain TEST record. Persistence is reported by [receipt.json](../receipt.json); this documentation run executed no application tests.\n\n| Field | Specification |\n| --- | --- |\n| Objective | Verify AC-08: Unsolved result. |\n| QBrain reference/scope | \u0060TEST-UNSOLVEDRESULT-008\u0060; Word Pairs / \u0060PROD-WORDPAIRS\u0060; workspace \u0060\u003Chome\u003E/github/WordGame/.mcpServer/wordpairs\u0060; layer \u0060layer-1\u0060 |\n| Source revision | Original designs at \u00603273c121de6517aec34503d8c769b0159e9e52df\u0060; exact dirty prose/decision hashes in [sources.json](../sources.json). New UI-DEC decisions derive from the operator instruction to fill gaps. |\n| Source links | [word_association_round_flow.svg](../../../word_association_round_flow.svg) |\n| Frame/element identifiers | ROUND-FLOW, ROUND-NODE-H, ROUND-NODE-J, ROUND-TRANS-G-H, ROUND-TRANS-H-I, ROUND-TRANS-H-J, ROUND-TRANS-J-K, MSG-M33, MSG-M34, MSG-M35, SCREEN-SUMMARY, STATE-SUMMARY-01, STATE-SUMMARY-02, STATE-SUMMARY-03; exact SVG anchors are listed in [coverage.md](../coverage.md) |\n| FR/TR \u2192 specific AC references | \u0060FR-ANSWERREVEAL-012#AC-08\u0060; \u0060FR-ANSWERSTAGES-008#AC-08\u0060; \u0060FR-SCORING-009#AC-08\u0060 |\n| Priority | high |\n| Platform/viewport | Phone Chromium/Android and Safari/iPhone where applicable; project matrix320x568,390x844,844x390;1280px at400%zoom and200%text enlargement. OS-native installation is a separate physical-device dependency. |\n| Preconditions/roles | Alice remains unsolved at Hint 3 and Bob has already solved. |\n| Test data | Target Cold; Alice either submits wrong or gives no answer through the final deadline. |\n| Synchronization | Await the explicit observable conditions and source-defined deadlines below; no fixed sleeps. Harness timeouts do not create a product response-time SLA. |\n| Cleanup | Close case-owned contexts and reset only isolated fixture accounts, rooms or content, including after failure. Preserve shared catalog and real profile data. |\n| Automation readiness | Ready for automation once isolated UI fixture seeding and observations are available; documentation only. |\n| Basis | Specified by cited designs/QBrain; new gap behavior is specified by UI-DEC-01..08. Synthetic fixture identities/data are test configurations. |\n| Execution | Not run here. Existing historical status/evidence remains unchanged; new obligations remain pending/unsatisfied. |\n\n## Ordered actions and observable results\n\n| Step | Action / condition | Observable expected result |\n| --- | --- | --- |\n| 1 | Submit an incorrect final-stage answer, or await the authoritative final deadline without answering. | The round ends and reveals Cold. |\n| 2 | Inspect Alice\u0027s round summary. | Alice receives 0 points for the round. |\n\n## Scenario\n\n\u0060\u0060\u0060gherkin\nFeature: AC-08: Unsolved result\n Scenario: TEST-UNSOLVEDRESULT-008 design verification\n Given Alice remains unsolved at Hint 3 and Bob has already solved.\n And the fixture data is Target Cold; Alice either submits wrong or gives no answer through the final deadline.\n When Submit an incorrect final-stage answer, or await the authoritative final deadline without answering.\n Then The round ends and reveals Cold.\n When Inspect Alice\u0027s round summary.\n Then Alice receives 0 points for the round.\n\u0060\u0060\u0060\n\n## Boundaries\n\n\n\nCriterion references identify intended verification. Non-UI transaction, distribution, release/deployment and native OS guarantees retain separate technical/operational tests; this document is not a claim that a compound criterion passed.\n\nEND UI-CASE TEST-UNSOLVEDRESULT-008", "acceptanceCriteria": [ { "id": "AC-08", "text": "Given a player remains unsolved after Hint 3, when the round ends, then the player earns 0 points and the game reveals the correct answer.", "isSatisfied": true, "evidence": "docs/phase6_execution.md; docs/admin_acl_review_receipt.json; docs/testing.md" } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-VERCELDEPLOYMENT-120", "condition": "After Phase7 implementation, verify the authorized Vercel Git target, preview/production branch mapping and commit-bound deployment metadata; no hosted deployment is currently claimed.", "title": "Verify TR-20: Vercel deployment target", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "pending", "notes": "New verification/extension import key: TEST-WP-120; canonical MCP ID: TEST-VERCELDEPLOYMENT-120. Technical/integration or operational evidence only. Source TR-20. Existing commands and evidence limits: docs/testing.md; docs/phase6_execution.md; docs/deployment_plan.md. Former provisional MCP ID: TEST-WP-120. Replaced at user request with a subject-identifying ID.", "acceptanceCriteria": [ { "id": "VERIFY-TR-20", "text": "After Phase7 implementation, verify the authorized Vercel Git target, preview/production branch mapping and commit-bound deployment metadata; no hosted deployment is currently claimed.", "isSatisfied": false, "evidence": "Verification contract recorded; local partial evidence retained, Phase7 completion not claimed." }, { "id": "TR-20-C01", "text": "Deploy the web application from the `sharpninja/wordpairs` GitHub repository to Vercel. Use Vercel\u2019s Git integration: pushes to non-production branches create Preview deployments, and changes merged to `main` create Production deployments. Select the framework preset, project root, build command, and output directory to match the implementation once its framework is approved.", "isSatisfied": false, "evidence": "Local implementation/fixtures may cover part of this obligation; Phase7 operational completion is not claimed." } ], "scopeStartLayerKey": "layer-1" }, { "id": "TEST-WIKIPUBLISH-148", "condition": "Verify current QBrain readback/export counts, canonical ZIP integrity, all page/evidence hashes and link transforms; push the isolated wiki checkout, read back its exact commit/tree, preserve unrelated pages and reject secret-bearing evidence. Record the concrete remote result, not merely a prepared payload.", "title": "Verify requirements wiki publication", "workspaceId": "\u003Crepo\u003E", "priority": "high", "status": "completed", "notes": "Operator instruction27October2026: When using refresh-docs, publish exported wiki to https://github.com/sharpninja/wordpairs.wiki.git. Repository contract: AGENTS.md Documentation publication. Source/evidence: docs/submission/wiki-publication.json, docs/submission/hv-index.json, docs/testing/ui/persistence.md. This authorizes wiki commits/pushes, not application-repository commits or automated contest entry. Acceptance references TR-DOCS-WIKIPUBLISH-042#WIKI-01..03.\nVerified first publication at wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc with all270remote files byte-matched. Subsequent export includes this completion evidence; application repository untouched. Each future refresh must perform new readback/export/push verification and refresh evidence rather than inheriting this result.", "acceptanceCriteria": [ { "id": "WIKI-01", "text": "Each refresh-docs reconciles authoritative QBrain records and mappings, verifies readback, exports the supported wiki and validates every configured page and scoped requirement ID before publication.", "isSatisfied": true, "evidence": "Verified wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc; complete remote Git tree readback 270files. Canonical export b6a44c6cc43dddcb473af18d504c64026ef75599f78c04863e4913afe1d0505c; docs/submission/wiki-publication.json; hostile publication approval99/99 and all retained prior rounds in docs/evidence/ui-gaps/hostile-validation.jsonl." }, { "id": "WIKI-02", "text": "Publish the GitHub export to https://github.com/sharpninja/wordpairs.wiki.git, preserve unrelated pages, disclose publication-only link/asset transforms, and verify pushed commit and file hashes by remote Git readback.", "isSatisfied": true, "evidence": "Verified wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc; complete remote Git tree readback 270files. Canonical export b6a44c6cc43dddcb473af18d504c64026ef75599f78c04863e4913afe1d0505c; docs/submission/wiki-publication.json; hostile publication approval99/99 and all retained prior rounds in docs/evidence/ui-gaps/hostile-validation.jsonl." }, { "id": "WIKI-03", "text": "Preserve all available hostile-validation receipts including rejected/superseded rounds and labeled reconstructions, bind approvals to source/evidence inventories, and exclude private runtime credentials/session files from the published evidence.", "isSatisfied": true, "evidence": "Verified wiki commit 45a8e4339746871defa307b0d78e5c9301f006fc; complete remote Git tree readback 270files. Canonical export b6a44c6cc43dddcb473af18d504c64026ef75599f78c04863e4913afe1d0505c; docs/submission/wiki-publication.json; hostile publication approval99/99 and all retained prior rounds in docs/evidence/ui-gaps/hostile-validation.jsonl." } ], "scopeStartLayerKey": "layer-1" } ], "mappings": [ { "frId": "FR-ACCESSCONTROL-024", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-IDENTITY-AUTHENTICATION-016", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACLAUTHORIZATION-132", "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-GUESTPLAY-021", "TEST-IDENTITYAUTHENTICATION-116", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-OIDCTOKENVALIDATION-046", "TEST-OPENAIOIDCPROFILE-020", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PROFILEICON-003", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-ADMINPAGES-023", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-NOMINATION-MODERATION-014", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SUGGESTION-REVIEW-015", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACLAUTHORIZATION-132", "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONELIGIBILITY-017", "TEST-NOMINATIONMODERATION-114", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SUGGESTIONREVIEW-115", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-ANCHORSELECTION-007", "trIds": [ "TR-ANCHOR-RANDOMNESS-013", "TR-ANSWER-ORDER-003", "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANCHORRANDOMNESS-113", "TEST-ANSWERORDER-103", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-NOSOLVERFALLBACK-146", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-ANSWERREVEAL-012", "trIds": [ "TR-ANSWER-CONFIDENTIALITY-005", "TR-ANSWER-VALIDATION-004", "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERCONFIDENTIALITY-105", "TEST-ANSWERVALIDATION-104", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LANDINGPAGEPUBLICDATA-050", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-NOSOLVERFALLBACK-146", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-ANSWERSTAGES-008", "trIds": [ "TR-ANSWER-CONFIDENTIALITY-005", "TR-ANSWER-ORDER-003", "TR-ANSWER-VALIDATION-004", "TR-ARCHIVE-SWBOM-028", "TR-CLOCK-CONSISTENCY-008", "TR-CONNECTION-RECOVERY-009", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-ROOM-CODES-010", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERCONFIDENTIALITY-105", "TEST-ANSWERORDER-103", "TEST-ANSWERVALIDATION-104", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CLOCKCONSISTENCY-108", "TEST-CONFIGUREDCAPACITY-024", "TEST-CONNECTIONRECOVERY-109", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LANDINGPAGEPUBLICDATA-050", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-NOSOLVERFALLBACK-146", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-CANDIDATEHOLD-028", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-DOCS-WIKIPUBLISH-042", "TR-NOMINATION-MODERATION-014" ], "testIds": [ "TEST-CANDIDATEHOLD-141", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-CATEGORIES-005", "trIds": [ "TR-ANCHOR-RANDOMNESS-013", "TR-ARCHIVE-SWBOM-028", "TR-ART-RENDER-007", "TR-CATALOG-INTEGRITY-006", "TR-CATALOG-VERSIONING-033", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-CATALOGINTEGRITY-106", "TEST-CATALOGVERSIONING-133", "TEST-CATEGORYART-005", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-CONTENTVALIDATION-016", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-CATEGORYART-006", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-ART-RENDER-007", "TR-CATALOG-INTEGRITY-006", "TR-CATALOG-VERSIONING-033", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-UI-ACCESSIBILITY-012", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACCESSIBLEGAMECONTROLS-044", "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-ARTRENDER-107", "TEST-CATALOGINTEGRITY-106", "TEST-CATALOGVERSIONING-133", "TEST-CATEGORYART-005", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-CONTENTVALIDATION-016", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-ORIENTATION-015", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-UIACCESSIBILITY-112", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-CATEGORYSUGGESTIONS-017", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-ARCHIVE-SWBOM-028", "TR-CATALOG-INTEGRITY-006", "TR-CATALOG-VERSIONING-033", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-NOMINATION-MODERATION-014", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SUGGESTION-REVIEW-015", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACLAUTHORIZATION-132", "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-CATALOGINTEGRITY-106", "TEST-CATALOGVERSIONING-133", "TEST-CATEGORYART-005", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-CONTENTVALIDATION-016", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONMODERATION-114", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SUGGESTIONREVIEW-115", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-CURATEDPAIRS-004", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-CATALOG-INTEGRITY-006", "TR-CATALOG-VERSIONING-033", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-CATALOGINTEGRITY-106", "TEST-CATALOGVERSIONING-133", "TEST-CATEGORYART-005", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-CONTENTVALIDATION-016", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-FINALSTANDINGS-014", "trIds": [ "TR-ANSWER-ORDER-003", "TR-ARCHIVE-SWBOM-028", "TR-CLOCK-CONSISTENCY-008", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERORDER-103", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CLOCKCONSISTENCY-108", "TEST-CONFIGUREDCAPACITY-024", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-IDENTITY-018", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-CONNECTION-RECOVERY-009", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-IDENTITY-AUTHENTICATION-016", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-ROOM-CODES-010", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ARCHIVESWBOM-128", "TEST-CONNECTIONRECOVERY-109", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-GUESTPLAY-021", "TEST-IDENTITYAUTHENTICATION-116", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-OIDCTOKENVALIDATION-046", "TEST-OPENAIOIDCPROFILE-020", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PROFILEICON-003", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-LIVESCORECARD-011", "trIds": [ "TR-ANSWER-CONFIDENTIALITY-005", "TR-ARCHIVE-SWBOM-028", "TR-CLOCK-CONSISTENCY-008", "TR-CONNECTION-RECOVERY-009", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-REALTIME-SYNC-002", "TR-ROOM-CODES-010", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERCONFIDENTIALITY-105", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-CONNECTIONRECOVERY-109", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-FULLROOMOBSERVER-027", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-INROUNDEMOJIREACTION-029", "TEST-LANDINGPAGEPUBLICDATA-050", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-REALTIMESYNC-102", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-LOBBYDISCOVERY-019", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-CONNECTION-RECOVERY-009", "TR-CONTEST-READINESS-041", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-LOBBY-MATCHING-017", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-REALTIME-SYNC-002", "TR-ROOM-CODES-010", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ARCHIVESWBOM-128", "TEST-BROWSEOPENLOBBIES-022", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-CONNECTIONRECOVERY-109", "TEST-CONTESTREADINESS-147", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-FULLROOMOBSERVER-027", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-INROUNDEMOJIREACTION-029", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-LOBBYMATCHING-117", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-QUICKMATCH-023", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-REALTIMESYNC-102", "TEST-ROOMCODES-110", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-LOBBYLIFECYCLE-003", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-CONNECTION-RECOVERY-009", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-OBSERVER-PERMISSIONS-018", "TR-POSTGRES-PERSISTENCE-022", "TR-REALTIME-SYNC-002", "TR-ROOM-CODES-010", "TR-ROOM-SYNCRECOVERY-038", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ARCHIVESWBOM-128", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-CONNECTIONRECOVERY-109", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-FULLROOMOBSERVER-027", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-INROUNDEMOJIREACTION-029", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-REALTIMESYNC-102", "TEST-ROOMCODES-110", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-ROOMSYNC-139", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-NAVIGATIONDRAFTS-029", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-DOCS-WIKIPUBLISH-042", "TR-MOBILE-INPUT-011" ], "testIds": [ "TEST-NAVIGATIONDRAFTS-142", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-NOMINATIONS-016", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-ARCHIVE-SWBOM-028", "TR-CATALOG-INTEGRITY-006", "TR-CATALOG-VERSIONING-033", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-NOMINATION-MODERATION-014", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SUGGESTION-REVIEW-015", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACLAUTHORIZATION-132", "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-CATALOGINTEGRITY-106", "TEST-CATALOGVERSIONING-133", "TEST-CATEGORYART-005", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-CONTENTVALIDATION-016", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONELIGIBILITY-017", "TEST-NOMINATIONMODERATION-114", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SUGGESTIONREVIEW-115", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-OBSERVERS-020", "trIds": [ "TR-ANSWER-CONFIDENTIALITY-005", "TR-ARCHIVE-SWBOM-028", "TR-CONNECTION-RECOVERY-009", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-OBSERVER-PERMISSIONS-018", "TR-POSTGRES-PERSISTENCE-022", "TR-REALTIME-SYNC-002", "TR-ROOM-CODES-010", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERCONFIDENTIALITY-105", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CONFIGUREDCAPACITY-024", "TEST-CONNECTIONRECOVERY-109", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-FULLROOMOBSERVER-027", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-INROUNDEMOJIREACTION-029", "TEST-LANDINGPAGEPUBLICDATA-050", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-OBSERVERPERMISSIONS-118", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-REALTIMESYNC-102", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-PHONEINSTALL-026", "trIds": [ "TR-DOCS-WIKIPUBLISH-042", "TR-PWA-CACHEPRIVACY-037", "TR-PWA-INSTALLATION-036" ], "testIds": [ "TEST-PWAINSTALL-137", "TEST-PWAPRIVACY-138", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-PLAYERPROFILE-002", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-IDENTITY-AUTHENTICATION-016", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-UI-ACCESSIBILITY-012", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACCESSIBLEGAMECONTROLS-044", "TEST-ARCHIVESWBOM-128", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-GUESTPLAY-021", "TEST-IDENTITYAUTHENTICATION-116", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-OIDCTOKENVALIDATION-046", "TEST-OPENAIOIDCPROFILE-020", "TEST-ORIENTATION-015", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PROFILEICON-003", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-UIACCESSIBILITY-112", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-PUBLICLANDING-022", "trIds": [ "TR-ANSWER-CONFIDENTIALITY-005", "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LANDING-PRIVACY-030", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERCONFIDENTIALITY-105", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-LANDINGPAGEPUBLICDATA-050", "TEST-LANDINGPRIVACY-130", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PUBLICGAMELANDINGPAGE-043", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-REACTIONS-021", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-REACTION-DELIVERY-019", "TR-REALTIME-SYNC-002", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ARCHIVESWBOM-128", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-FULLROOMOBSERVER-027", "TEST-GPL20ONLYRELEASE-042", "TEST-INROUNDEMOJIREACTION-029", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-REACTIONDELIVERY-119", "TEST-REALTIMESYNC-102", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-REQUESTFEEDBACK-030", "trIds": [ "TR-CONNECTION-RECOVERY-009", "TR-DOCS-WIKIPUBLISH-042", "TR-ROOM-SYNCRECOVERY-038" ], "testIds": [ "TEST-REQUESTFEEDBACK-143", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-RESPONSIVEUI-015", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-ART-RENDER-007", "TR-CONTEST-READINESS-041", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MOBILE-INPUT-011", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-UI-ACCESSIBILITY-012", "TR-UI-ACCESSIBILITYDETAILS-039", "TR-UI-RESPONSIVEMATRIX-040", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACCESSIBILITYDETAILS-144", "TEST-ACCESSIBLEGAMECONTROLS-044", "TEST-ARCHIVESWBOM-128", "TEST-ARTRENDER-107", "TEST-CATEGORYART-005", "TEST-CONTESTREADINESS-147", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOBILEINPUT-111", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-ORIENTATION-015", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-RESPONSIVEMATRIX-145", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-UIACCESSIBILITY-112", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-REVIEWCHANGES-027", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-DOCS-WIKIPUBLISH-042", "TR-SUGGESTION-REVIEW-015" ], "testIds": [ "TEST-REVIEWCHANGES-140", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-ROOMACCESS-001", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-CONNECTION-RECOVERY-009", "TR-CONTEST-READINESS-041", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-LOBBY-MATCHING-017", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-REALTIME-SYNC-002", "TR-ROOM-CODES-010", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ARCHIVESWBOM-128", "TEST-BROWSEOPENLOBBIES-022", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-CONNECTIONRECOVERY-109", "TEST-CONTESTREADINESS-147", "TEST-DDDTRANSACTIONS-131", "TEST-DEEPLINKJOINANDFULLROOM-026", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-LOBBYMATCHING-117", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-QUICKMATCH-023", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMCODES-110", "TEST-ROOMINVITATIONS-025", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-ROUNDSUMMARY-013", "trIds": [ "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ARCHIVESWBOM-128", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-SCORELOCK-010", "trIds": [ "TR-ANSWER-CONFIDENTIALITY-005", "TR-ANSWER-ORDER-003", "TR-ANSWER-VALIDATION-004", "TR-ARCHIVE-SWBOM-028", "TR-CLOCK-CONSISTENCY-008", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERORDER-103", "TEST-ANSWERVALIDATION-104", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CLOCKCONSISTENCY-108", "TEST-CONFIGUREDCAPACITY-024", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-SCORING-009", "trIds": [ "TR-ANSWER-ORDER-003", "TR-ANSWER-VALIDATION-004", "TR-ARCHIVE-SWBOM-028", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-MULTIPLAYER-INTEGRATION-034", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-STATE-AUTHORITY-001", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ANSWERORDER-103", "TEST-ANSWERVALIDATION-104", "TEST-ARCHIVESWBOM-128", "TEST-AUTHORITATIVEANSWERHANDLING-045", "TEST-CATEGORYCHOICE-011", "TEST-CONFIGUREDCAPACITY-024", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FINALSTANDINGS-013", "TEST-FIRSTCATEGORY-004", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-HINTPROGRESSION-009", "TEST-HINTSCORING-007", "TEST-HOLDOUTWARNINGANDREMOVAL-032", "TEST-IDLELOBBYREADINESSPROMPT-033", "TEST-LICENSEGPL-129", "TEST-LIVESCORECARD-010", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-MULTIPLAYERINTEGRATION-134", "TEST-NOHINTSOLVE-006", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-PRECOUNTDOWNOBSERVERPROMOTION-030", "TEST-READYCOUNTDOWNANDROSTERLOCK-031", "TEST-ROOMJOINING-001", "TEST-ROUNDSUMMARY-012", "TEST-SCHEMAPROVISIONING-123", "TEST-STATEAUTHORITY-101", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-TIMETIEBREAK-014", "TEST-UNSOLVEDRESULT-008", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" }, { "frId": "FR-WORDHINTEDITOR-025", "trIds": [ "TR-ACL-AUTHORIZATION-032", "TR-ARCHIVE-SWBOM-028", "TR-CATALOG-INTEGRITY-006", "TR-CATALOG-VERSIONING-033", "TR-DDD-TRANSACTIONS-031", "TR-DEPENDENCY-ATTRIBUTION-025", "TR-DEPLOYMENT-NOACTIONS-024", "TR-DESIGN-HOSTILEREVIEW-035", "TR-DOCS-WIKIPUBLISH-042", "TR-FREETIER-OPERATION-021", "TR-LICENSE-GPL-029", "TR-POSTGRES-PERSISTENCE-022", "TR-SCHEMA-PROVISIONING-023", "TR-SWBOM-GENERATION-027", "TR-TDD-ACCEPTANCE-026", "TR-VERCEL-DEPLOYMENT-020" ], "testIds": [ "TEST-ACLAUTHORIZATION-132", "TEST-ADMINUI-136", "TEST-ARCHIVESWBOM-128", "TEST-CATALOGINTEGRITY-106", "TEST-CATALOGVERSIONING-133", "TEST-CATEGORYART-005", "TEST-CATEGORYSUGGESTIONUNLOCK-019", "TEST-CONTENTVALIDATION-016", "TEST-DDDTRANSACTIONS-131", "TEST-DEPENDENCYATTRIBUTION-039", "TEST-DEPENDENCYATTRIBUTION-125", "TEST-DEPLOYMENTNOACTIONS-124", "TEST-DESIGNHOSTILEREVIEW-135", "TEST-FREETIEROPERATION-121", "TEST-FREETIERQUOTAHANDLING-037", "TEST-GPL20ONLYRELEASE-042", "TEST-LICENSEGPL-129", "TEST-MOCKFIRSTACCEPTANCECOVERAGE-038", "TEST-MODERATIONANDCATALOGBOUNDARY-047", "TEST-NOMINATIONTHRESHOLDANDMODERATION-018", "TEST-PLAYERLIMIT-002", "TEST-POSTGRESPERSISTENCE-122", "TEST-ROOMJOINING-001", "TEST-SCHEMAPROVISIONING-123", "TEST-SWBOMGENERATION-127", "TEST-SWBOMRELEASEARCHIVE-041", "TEST-TDDACCEPTANCE-126", "TEST-TESTABLECONCURRENCYSAFEDOMAINBOUNDARY-051", "TEST-VERCELDEPLOYMENT-120", "TEST-WIKIPUBLISH-148" ], "workspaceId": "\u003Crepo\u003E" } ] } }