{"event":"phase4_formal_hostile_review","timestamp":"2026-10-26T20:44:31Z","request":"FORMAL PHASE 4 EXIT requested. Exact local+GitHub candidate 4bc242c05d63dd84798940e4afd7da62a4ecd219, tree da0f52c8320ca0627edd455846cca75d395264ba, URL https://github.com/sharpninja/wordpairs/commit/4bc242c05d63dd84798940e4afd7da62a4ecd219. Parent 6bcc5e273dbdb47869920358ad9468c402b78cb1 (Phase3 receipt) also uploaded immutable. Working tree clean. Independently verify exact remote tree versus local all leaves and review Phase4A/B against approved v2.6. Root final checks:449 tests/26files, typecheck, lint61files, localproduction build,25 actualPostgres tests/6files+SQLchecks,3 actualRealtime tests,10Chromium journeys. Run independent checks as appropriate; no root Next process active. Browser env WORDPAIRS_BROWSER_PATH=/usr/bin/chromium config playwright.phase4.config.ts; DB+Realtime tests/integration/run-phase1.ps1 -Realtime. Documentation docs/phase4_execution.md records scope/evidence/limitations including no chooser reassignment. Prior three incremental material findings resolved and browser exposed refresh overlap fixed via queue, original lobby assertions unchanged. Official Unicode18full C/F map+license and original6SVG/60paircatalog included. At>=98 accuracy ANDcompleteness with no unresolvedmaterial, save full request/rubric/rawreport/scores/exactremote evidence to docs/phase4_review_receipt.jsonl and update only docs/phase4_execution.md and docs/goal_hv_agreement_through_phase_6.md. Explicitly authorizePhase5 entry ifapproved. Restore generated-only next-env.d.ts changes. No implementation edits; root will wait forphaseapproval beforephase5code. Phase5moderation/reactions andPhase6finalacceptance remainrequired; no overallgoalcomplete claim. Authorized localDocker/browser/network immutablecheckpoint verifications don't require human approval; no refs moved/deploy/Phase7work.","reviewerOutput":"{\n \"review\": \"Wordpairs formal Phase 4 exit\",\n \"reviewer\": {\n \"role\": \"Independent hostile validator\",\n \"model\": \"gpt-6-astra\",\n \"reasoningEffort\": \"high\"\n },\n \"reviewedAt\": \"2026-10-26T20:44:31Z\",\n \"candidateSHA\": \"4bc242c05d63dd84798940e4afd7da62a4ecd219\",\n \"candidateTree\": \"da0f52c8320ca0627edd455846cca75d395264ba\",\n \"candidateURL\": \"https://github.com/sharpninja/wordpairs/commit/4bc242c05d63dd84798940e4afd7da62a4ecd219\",\n \"parentSHA\": \"6bcc5e273dbdb47869920358ad9468c402b78cb1\",\n \"scope\": {\n \"baseline\": \"Approved requirements v2.6 and implementation-plan packages 4A/4B\",\n \"included\": [\n \"Validated initial catalog, six shared backgrounds and 60 curated pairs\",\n \"Frozen start roster, inclusive uniform anchor draw and authorized category selection\",\n \"Pair selection without repetition before category pool exhaustion\",\n \"Four authoritative 20-second stages, once-per-stage submissions and early advancement\",\n \"NFKC/whitespace/full-casefold comparison with significant punctuation and explicit alternatives\",\n \"5/3/2/1 scoring, solve locking, acceptance ordering and private hint projections\",\n \"Reveal, eight-round cumulative standings, unsolved penalties and shared final ties\",\n \"Atomic final awards, profile statistics and room closure\",\n \"Authenticated match API, player/observer UI, canonical retries and metadata-only Realtime notifications\"\n ],\n \"acceptanceCriteria\": [\n \"AC-04/05/16 Phase 4 allocation\",\n \"AC-06–14\",\n \"AC-45\",\n \"Gameplay-specific AC-28 privacy\",\n \"Earlier-phase regression\"\n ],\n \"technicalRequirements\": [\n \"TR-01–09\",\n \"TR-13\",\n \"TR-18\",\n \"TR-22\",\n \"TR-25\",\n \"TR-29\",\n \"TR-31\"\n ],\n \"excluded\": [\n \"Nominations, suggestions, moderation, appeals and reactions allocated to Phase 5\",\n \"Final cross-phase acceptance and human accessibility/usability evidence allocated to Phase 6\",\n \"Live providers, provisioning, deployment, scheduler operations and release allocated to Phase 7\"\n ]\n },\n \"remoteVerification\": {\n \"method\": \"Independent GitHub connector GET of Git commit and recursive Git tree, followed by comparison with git ls-tree -r of the exact local candidate.\",\n \"commitVerified\": true,\n \"treeVerified\": true,\n \"parentVerified\": true,\n \"recursiveTreeTruncated\": false,\n \"remoteLeafEntries\": 179,\n \"localLeafEntries\": 179,\n \"allPathsModesTypesAndBlobSHAsEqual\": true,\n \"localWorkingTreeCleanBeforeChecks\": true,\n \"localWorkingTreeCleanAfterGeneratedFileRestore\": true,\n \"commitURL\": \"https://api.github.com/repos/sharpninja/wordpairs/git/commits/4bc242c05d63dd84798940e4afd7da62a4ecd219\",\n \"treeURL\": \"https://api.github.com/repos/sharpninja/wordpairs/git/trees/da0f52c8320ca0627edd455846cca75d395264ba?recursive=1\"\n },\n \"rubric\": {\n \"threshold\": {\n \"accuracyMinimumPercent\": 98,\n \"completenessMinimumPercent\": 98,\n \"noUnresolvedMaterialFindings\": true\n },\n \"accuracyDefinition\": \"Conformance of implemented Phase 4 policies, authorization, privacy, timing, transactional outcomes and evidence claims to the approved contracts.\",\n \"completenessDefinition\": \"Coverage of allocated Phase 4A/4B behavior, boundaries, retries, concurrency, persistence, transport and client interaction, excluding explicitly later-phase work.\",\n \"dimensions\": [\n {\n \"name\": \"Catalog, normalization and content provenance\",\n \"accuracy\": 99,\n \"completeness\": 99\n },\n {\n \"name\": \"Match setup, stages, scoring and standings\",\n \"accuracy\": 99,\n \"completeness\": 99\n },\n {\n \"name\": \"Authorization, privacy and canonical retries\",\n \"accuracy\": 99,\n \"completeness\": 99\n },\n {\n \"name\": \"Atomic persistence, deadlines and Realtime\",\n \"accuracy\": 99,\n \"completeness\": 99\n },\n {\n \"name\": \"Client behavior, regression and evidence separation\",\n \"accuracy\": 99,\n \"completeness\": 99\n }\n ],\n \"scoresAreReviewerAssessments\": true\n },\n \"accuracyPercent\": 99,\n \"completenessPercent\": 99,\n \"findings\": [],\n \"unresolvedMaterialFindings\": 0,\n \"resolvedPriorFindings\": [\n {\n \"finding\": \"A match command could score after reconnect grace expired if the room departure worker had not yet applied its job.\",\n \"resolution\": \"The match repository checks consequential overdue room state while holding the owning-room lock before granting new-command authority. Current private projections also reject expired players and observers whose followed player is expired. The real database regression holds the reconnect job under another lease and verifies no score/version mutation.\"\n },\n {\n \"finding\": \"Current-membership authorization ran before canonical replay, so a lost accepted answer response could not be recovered after departure.\",\n \"resolution\": \"The repository checks exact actor/command/digest replay under the room lock before authorizing new actions. Same-ID accepted-answer replay after departure succeeds; changed digest conflicts; new departed-player commands and private reads remain denied. The HTTP POST path permits only the transaction-controlled replay decision.\"\n },\n {\n \"finding\": \"SQL independently reimplemented points, unsolved penalties and winner ranking, duplicating the domain business policy contrary to TR-31.\",\n \"resolution\": \"The domain computes finalStandings and finalAwards in the canonical final transition. SQL validates award scope and applies those awards idempotently without ranking recomputation. Fault injection verifies that match finish, profile statistics, room closure, events and command result roll back together before a successful once-only retry.\"\n },\n {\n \"finding\": \"Overlapping room polling and heartbeat refresh could drop the request for the newer room projection.\",\n \"resolution\": \"RoomSession coalesces an overlapping request into one follow-up refresh, retains generation/version guards and clears queued refresh state on cleanup. The existing Phase 3 uncertain-readiness/heartbeat journey passes unchanged in the full browser regression.\"\n }\n ],\n \"policyClarifications\": [\n \"The anchor or earliest accepted solver remains the fixed chooser. No approved timeout or reassignment exists for a departed chooser. The UI explains the waiting state and offers existing leave/new-room navigation; the no-solver random-category rule is not applied to a round that had a solver.\",\n \"Silent or permanent chooser absence can leave the game waiting. This is an explicit contract-consistent liveness limitation, not a claim of automatic progress through abandoned choice states.\"\n ],\n \"verification\": [\n {\n \"command\": \"npm test\",\n \"result\": \"PASS\",\n \"files\": 26,\n \"testsPassed\": 449,\n \"testsFailed\": 0,\n \"testsSkipped\": 0,\n \"tier\": \"Repository regression including original mock oracles plus actual domain/application/API/component code\"\n },\n {\n \"command\": \"npm run typecheck\",\n \"result\": \"PASS\",\n \"tier\": \"Static TypeScript verification\"\n },\n {\n \"command\": \"npm run lint\",\n \"result\": \"PASS\",\n \"filesChecked\": 61,\n \"tier\": \"Static lint verification\"\n },\n {\n \"command\": \"npm run build\",\n \"result\": \"PASS\",\n \"tier\": \"Local production compilation only\"\n },\n {\n \"command\": \"pwsh -File tests/integration/run-phase1.ps1 -Realtime\",\n \"result\": \"PASS\",\n \"postgresFiles\": 6,\n \"postgresTestsPassed\": 25,\n \"realtimeFiles\": 1,\n \"realtimeTestsPassed\": 3,\n \"tier\": \"Actual disposable local PostgreSQL and Supabase Realtime; separate TR integration evidence\",\n \"matchChecks\": [\n \"Concurrent match bootstrap creates one frozen roster/anchor\",\n \"Concurrent scoring is serialized with deterministic accepted order and canonical replay\",\n \"Observers cannot score; hint views follow the inviter and no raw incorrect text is persisted\",\n \"Elapsed-stage claims catch up all due stages once\",\n \"Accepted commands replay after departure; changed digests and new commands are rejected\",\n \"Expired actors and followed observers are denied while the reconnect job is leased elsewhere\",\n \"Final awards and room closure roll back on failure and commit exactly once on retry\",\n \"Actual match notifications reach current players and observer without private targets or hints\"\n ],\n \"baselineChecks\": \"Migration application, direct-role denial, canonical retry/conflict, durable outbox, rollback faults, retention and capacity races also passed.\",\n \"cleanup\": \"Runner returned success and executed owned-container cleanup.\"\n },\n {\n \"command\": \"WORDPAIRS_BROWSER_PATH=/usr/bin/chromium npm exec playwright -- test --config playwright.phase4.config.ts\",\n \"result\": \"PASS\",\n \"journeysPassed\": 10,\n \"journeysFailed\": 0,\n \"journeysSkipped\": 0,\n \"tier\": \"Actual Chromium and rendered application UI; intercepted HTTP boundaries use actual match/lobby application-domain logic with transaction fakes\",\n \"phase4Journeys\": [\n \"Multiple players plus bound observer: category authority, solved hint privacy, 5/3 scoring, reveal and identical uncertain-answer retry\",\n \"Eight no-solver rounds: persisted random category continuation, reveal and shared final ranking at 390×844 without horizontal page overflow\"\n ],\n \"regression\": \"All eight earlier identity, room, privacy and lobby journeys also passed.\"\n },\n {\n \"command\": \"Independent catalog/source consistency script\",\n \"result\": \"PASS\",\n \"checks\": [\n \"Migration 007 embedded catalog equals catalog-seed.json\",\n \"Six categories and 60 pairs\",\n \"All six referenced SVG files exist\",\n \"All 60 predefined word/non-space-character count hints agree with canonical targets\",\n \"Unicode source SHA-256 equals a004797658a457bec4dc11683e39f69249ea3b595b752dbea6721c4c9f587b0d\"\n ]\n },\n {\n \"command\": \"Unicode case-fold conformance regression\",\n \"result\": \"PASS\",\n \"mappingsChecked\": 1606,\n \"tier\": \"Every C/F mapping in the preserved source checked against the runtime mapping; representative expansion, sigma, locale and accent cases checked\"\n },\n {\n \"command\": \"Original AC-oracle diff inspection\",\n \"result\": \"PASS\",\n \"note\": \"Only the reviewed attribution-content golden hash changed. Existing semantic AC assertions and Phase 3 browser assertions were not weakened.\"\n },\n {\n \"command\": \"Final HEAD/status verification\",\n \"result\": \"PASS\",\n \"note\": \"Exact candidate remained checked out. Only this review's generated next-env.d.ts development paths were restored before writing reviewer documentation.\"\n }\n ],\n \"contentAndLicensing\": {\n \"conclusion\": \"No identified licensing blocker in the preserved Unicode data/derived mapping/notice arrangement or the six project SVGs and project-authored static catalog hints.\",\n \"unicodeLicense\": \"Unicode-3.0\",\n \"notice\": \"Original source, complete Unicode License V3 and generated-map provenance are preserved; attribution includes source version and SHA-256.\",\n \"sources\": [\n {\n \"url\": \"https://www.unicode.org/license.txt\",\n \"supports\": \"Official notice permits copying, modification and distribution while preserving the copyright/permission notice with copies or associated documentation.\"\n },\n {\n \"url\": \"https://www.gnu.org/licenses/license-list.en.html#Unicodev3\",\n \"supports\": \"GNU identifies Unicode License v3 as compatible with all versions of the GPL.\"\n }\n ],\n \"scopeLimit\": \"Source hash and mapping conformance were verified locally; this report does not claim a separate byte-for-byte redownload of the upstream data during the formal gate.\"\n },\n \"verificationLimits\": [\n \"Mock AC oracles remain contract evidence, not automatic proof of product behavior; actual implemented code is exercised separately.\",\n \"Browser HTTP calls are intercepted and transaction ports faked. This is not a deployed or live-provider full-stack acceptance run; actual database and transport checks are separate evidence tiers.\",\n \"The phone journey verifies an automated representative viewport, not completion of Phase 6 human usability, orientation, keyboard and accessibility review.\",\n \"No fallback chooser policy was invented; an unavailable fixed chooser can leave a match waiting.\",\n \"Live scheduler cadence, account/provider setup, production capacity, deployment and release remain Phase 7.\",\n \"The documentation's existing MCP hook/session-health limitations were not repaired or represented as recovered by this review.\",\n \"Scores are scoped engineering assessments, not a statistical guarantee or overall-goal completion claim.\"\n ],\n \"disposition\": \"APPROVE\",\n \"formalPhase4Exit\": \"APPROVED\",\n \"phase5EntryAuthorized\": true,\n \"goalThroughPhase6Complete\": false,\n \"remainingGoalPhases\": [\n 5,\n 6\n ],\n \"deploymentAuthorized\": false,\n \"releaseAuthorized\": false,\n \"reviewerAgreement\": \"Independent reviewer agrees that the exact GitHub candidate may exit Phase 4 and enter Phase 5. Implementation-owner agreement is recorded separately by the parent workflow.\",\n \"filesWritten\": [\n \"docs/phase4_review_receipt.jsonl\",\n \"docs/phase4_execution.md\",\n \"docs/goal_hv_agreement_through_phase_6.md\"\n ]\n}","remoteVerification":{"commit":{"sha":"4bc242c05d63dd84798940e4afd7da62a4ecd219","node_id":"C_kwDOVXU2i9oAKDI0MmM2YTRkMDYyNTA3YmNmMWIxNWYxMjYyZGNmMmVmMzQwM2NhMWU","url":"https://api.github.com/repos/sharpninja/wordpairs/git/commits/4bc242c05d63dd84798940e4afd7da62a4ecd219","html_url":"https://github.com/sharpninja/wordpairs/commit/4bc242c05d63dd84798940e4afd7da62a4ecd219","author":{"name":"Sharp Ninja","email":"ninja@thesharp.ninja","date":"2026-10-26T20:41:59Z"},"committer":{"name":"Sharp Ninja","email":"ninja@thesharp.ninja","date":"2026-10-26T20:41:59Z"},"tree":{"sha":"da0f52c8320ca0627edd455846cca75d395264ba","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/da0f52c8320ca0627edd455846cca75d395264ba"},"message":"feat(match): add private eight-round gameplay\n\nFreeze started rosters and serialize room/match authority. Apply domain awards atomically with profile updates and room closure. Seed complete curated content and preserve Unicode casefold notices.","parents":[{"sha":"6bcc5e273dbdb47869920358ad9468c402b78cb1","url":"https://api.github.com/repos/sharpninja/wordpairs/git/commits/6bcc5e273dbdb47869920358ad9468c402b78cb1","html_url":"https://github.com/sharpninja/wordpairs/commit/6bcc5e273dbdb47869920358ad9468c402b78cb1"}],"verification":{"verified":false,"reason":"unsigned","signature":null,"payload":null,"verified_at":null}},"tree":{"sha":"da0f52c8320ca0627edd455846cca75d395264ba","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/da0f52c8320ca0627edd455846cca75d395264ba","tree":[{"path":".gitignore","mode":"100644","type":"blob","sha":"215b51e4ce9475e78d96d8ccc0c0a77403023f38","size":99,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/215b51e4ce9475e78d96d8ccc0c0a77403023f38"},{"path":"AGENTS.md","mode":"100644","type":"blob","sha":"af3b7c84114bafeee578bf1adff2ef74af2cc6a2","size":679,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/af3b7c84114bafeee578bf1adff2ef74af2cc6a2"},{"path":"LICENSE","mode":"100644","type":"blob","sha":"17cb286430a4d8094e473d06bd7f50f40438ddba","size":17337,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/17cb286430a4d8094e473d06bd7f50f40438ddba"},{"path":"README.md","mode":"100644","type":"blob","sha":"6219152fa2d56f25b52c732515c7a491863026df","size":2203,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/6219152fa2d56f25b52c732515c7a491863026df"},{"path":"biome.json","mode":"100644","type":"blob","sha":"994281edcf130b5a54c7b72b9bbe427dd4f1f0ec","size":347,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/994281edcf130b5a54c7b72b9bbe427dd4f1f0ec"},{"path":"docs","mode":"040000","type":"tree","sha":"711957f37c826b806fd69da6e888eaea2ba4dd62","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/711957f37c826b806fd69da6e888eaea2ba4dd62"},{"path":"docs/ATTRIBUTIONS.md","mode":"100644","type":"blob","sha":"f27a58d130d99ef264066316cb29d4d9c26adcc6","size":9417,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f27a58d130d99ef264066316cb29d4d9c26adcc6"},{"path":"docs/SWBOM.md","mode":"100644","type":"blob","sha":"3eebf97bc689d62c0b2c2c0df6f98adc76adde50","size":3018,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3eebf97bc689d62c0b2c2c0df6f98adc76adde50"},{"path":"docs/ac_gap_analysis.md","mode":"100644","type":"blob","sha":"e539a662668471a36150dbb48419d6f1440fa4eb","size":8495,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e539a662668471a36150dbb48419d6f1440fa4eb"},{"path":"docs/ac_test_inventory.md","mode":"100644","type":"blob","sha":"399aec1b29c8de55c470f2a6f3cd23be3888a400","size":34237,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/399aec1b29c8de55c470f2a6f3cd23be3888a400"},{"path":"docs/architecture_command_classes.svg","mode":"100644","type":"blob","sha":"d60d6f6725637b4eb33a5b02a7d742d05c8edd72","size":3604,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/d60d6f6725637b4eb33a5b02a7d742d05c8edd72"},{"path":"docs/architecture_ddd_components.svg","mode":"100644","type":"blob","sha":"037d985297614f42f4df0d6d0bcc6af069ba420a","size":3875,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/037d985297614f42f4df0d6d0bcc6af069ba420a"},{"path":"docs/architecture_decision_record.md","mode":"100644","type":"blob","sha":"8fb3aff1cbf01062ed16c9018cad4958986a99b6","size":3594,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8fb3aff1cbf01062ed16c9018cad4958986a99b6"},{"path":"docs/architecture_design.md","mode":"100644","type":"blob","sha":"01c121305f0264a91435ee8c106f4627f9a9396d","size":15692,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/01c121305f0264a91435ee8c106f4627f9a9396d"},{"path":"docs/architecture_domain_classes.svg","mode":"100644","type":"blob","sha":"64613c570bdcecb2048fa6095ca96b25864236d1","size":7521,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/64613c570bdcecb2048fa6095ca96b25864236d1"},{"path":"docs/architecture_patterns.md","mode":"100644","type":"blob","sha":"534fcbebf36712b54e39d5cd83bcfa0205299a81","size":13819,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/534fcbebf36712b54e39d5cd83bcfa0205299a81"},{"path":"docs/architecture_patterns.svg","mode":"100644","type":"blob","sha":"598f27284ec8fb733616bb154932d40bf03596fb","size":4716,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/598f27284ec8fb733616bb154932d40bf03596fb"},{"path":"docs/deployment_plan.md","mode":"100644","type":"blob","sha":"17fb8ba7674bf49460cf6b2f559bef7d13df54c5","size":28360,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/17fb8ba7674bf49460cf6b2f559bef7d13df54c5"},{"path":"docs/goal_hv_agreement_through_phase_6.md","mode":"100644","type":"blob","sha":"5384cad46f9407db73db783195a0f104d72b0867","size":11750,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/5384cad46f9407db73db783195a0f104d72b0867"},{"path":"docs/implementation_kickoff_receipt.jsonl","mode":"100644","type":"blob","sha":"4ee5c08d47218a37b13bd3d4420a4ea9623746ec","size":22967,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4ee5c08d47218a37b13bd3d4420a4ea9623746ec"},{"path":"docs/implementation_phase0_execution.md","mode":"100644","type":"blob","sha":"46e71aa09f0db20f7f47343a2b327bb1ac8b4e36","size":14601,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/46e71aa09f0db20f7f47343a2b327bb1ac8b4e36"},{"path":"docs/implementation_plan.md","mode":"100644","type":"blob","sha":"119a59acbc0ddcf9394a63d8138c2de8a1d518f3","size":44245,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/119a59acbc0ddcf9394a63d8138c2de8a1d518f3"},{"path":"docs/moderation_plan.md","mode":"100644","type":"blob","sha":"1039c6601b516e4f96001b94986bf1a0b849c9c3","size":31447,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/1039c6601b516e4f96001b94986bf1a0b849c9c3"},{"path":"docs/phase0_approval_receipt.jsonl","mode":"100644","type":"blob","sha":"dd12b22e2a89354f8acca39d4a05344e4992ce87","size":878,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/dd12b22e2a89354f8acca39d4a05344e4992ce87"},{"path":"docs/phase0_interface_and_data_contracts.md","mode":"100644","type":"blob","sha":"728aaf0c7a67912eff601534e018aff000edb2e8","size":24684,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/728aaf0c7a67912eff601534e018aff000edb2e8"},{"path":"docs/phase0_refresh_hostile_review_receipt.jsonl","mode":"100644","type":"blob","sha":"8a3569da5d61eef2c44050b1fd963269e56242d8","size":32052,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8a3569da5d61eef2c44050b1fd963269e56242d8"},{"path":"docs/phase1_execution.md","mode":"100644","type":"blob","sha":"2a32433030ce93335e56a36eec81ef9cfd6edb89","size":7684,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2a32433030ce93335e56a36eec81ef9cfd6edb89"},{"path":"docs/phase1_review_receipt.jsonl","mode":"100644","type":"blob","sha":"23f5d442000ea441cc9db09b310d641a79beed83","size":19578,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/23f5d442000ea441cc9db09b310d641a79beed83"},{"path":"docs/phase1a_execution.md","mode":"100644","type":"blob","sha":"90e71d17faa2f5b6ec9d90780a2e5e03dcb41c01","size":3058,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/90e71d17faa2f5b6ec9d90780a2e5e03dcb41c01"},{"path":"docs/phase2_execution.md","mode":"100644","type":"blob","sha":"f661709b7d91143cd323c11f6f1a63f9637f62a8","size":7841,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f661709b7d91143cd323c11f6f1a63f9637f62a8"},{"path":"docs/phase2_review_receipt.jsonl","mode":"100644","type":"blob","sha":"db5f551c5a33eae96f946770f7fe3eace55c78b2","size":10518,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/db5f551c5a33eae96f946770f7fe3eace55c78b2"},{"path":"docs/phase3_execution.md","mode":"100644","type":"blob","sha":"1fe4ec53bd20d2ba28cc594025c47f0d0c247e4f","size":6804,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/1fe4ec53bd20d2ba28cc594025c47f0d0c247e4f"},{"path":"docs/phase3_review_receipt.jsonl","mode":"100644","type":"blob","sha":"b6f40562ffddb6bded5ef4404d4e70adfe4689ed","size":60191,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b6f40562ffddb6bded5ef4404d4e70adfe4689ed"},{"path":"docs/phase4_execution.md","mode":"100644","type":"blob","sha":"a330b35f293910a0a51b5e5c92ceb209e44a95eb","size":5033,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a330b35f293910a0a51b5e5c92ceb209e44a95eb"},{"path":"docs/repo_review_receipt.jsonl","mode":"100644","type":"blob","sha":"44404173acef080331ca2e0be4759f349331871e","size":179009,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/44404173acef080331ca2e0be4759f349331871e"},{"path":"docs/test_execution_receipt.jsonl","mode":"100644","type":"blob","sha":"6606612ef6546b5cae484e30b5173e14970732e8","size":44136,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/6606612ef6546b5cae484e30b5173e14970732e8"},{"path":"docs/word_association_category_suggestion.svg","mode":"100644","type":"blob","sha":"dfb289b4443bdc5fb3e3d5e1eb3c87c36d141394","size":204369,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/dfb289b4443bdc5fb3e3d5e1eb3c87c36d141394"},{"path":"docs/word_association_client_message_flow.svg","mode":"100644","type":"blob","sha":"2f8e89256115bf34ce1e45911e789472376ac0c6","size":216139,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2f8e89256115bf34ce1e45911e789472376ac0c6"},{"path":"docs/word_association_game_requirements.md","mode":"100644","type":"blob","sha":"fdb95562b5b3e52721aee230781d9a9e5d310fbe","size":59113,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/fdb95562b5b3e52721aee230781d9a9e5d310fbe"},{"path":"docs/word_association_identity_profile.svg","mode":"100644","type":"blob","sha":"eaa6f3424855d6c58e9d196f65546fb94816438d","size":203192,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/eaa6f3424855d6c58e9d196f65546fb94816438d"},{"path":"docs/word_association_lobby_discovery.svg","mode":"100644","type":"blob","sha":"78fe968d515b240349a20005d69f1d3944d6c0e4","size":205124,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/78fe968d515b240349a20005d69f1d3944d6c0e4"},{"path":"docs/word_association_nomination_flow.svg","mode":"100644","type":"blob","sha":"ac00137c0903d15928d4715dc9e93befe60cfb1b","size":208238,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ac00137c0903d15928d4715dc9e93befe60cfb1b"},{"path":"docs/word_association_room_creation.svg","mode":"100644","type":"blob","sha":"3dadf48936a90efbd88bbac7a92a30e1cbbbbb09","size":210157,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3dadf48936a90efbd88bbac7a92a30e1cbbbbb09"},{"path":"docs/word_association_round_flow.svg","mode":"100644","type":"blob","sha":"40eebdbd771877a90f425fb791387305f24bc8fa","size":213203,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/40eebdbd771877a90f425fb791387305f24bc8fa"},{"path":"docs/word_association_vercel_deployment.mmd","mode":"100644","type":"blob","sha":"283aea3ba076c60767fae467601f09d5af20fb32","size":866,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/283aea3ba076c60767fae467601f09d5af20fb32"},{"path":"docs/word_association_vercel_deployment.svg","mode":"100644","type":"blob","sha":"16dc0de6efed06a070ca4b7612b89db910a1229b","size":213485,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/16dc0de6efed06a070ca4b7612b89db910a1229b"},{"path":"next-env.d.ts","mode":"100644","type":"blob","sha":"ce4e94a6b10f160ee021fe18939af160d2927dcf","size":288,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ce4e94a6b10f160ee021fe18939af160d2927dcf"},{"path":"next.config.ts","mode":"100644","type":"blob","sha":"b22af960af499f682e3f73236f8ae8a6bde38da1","size":104,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b22af960af499f682e3f73236f8ae8a6bde38da1"},{"path":"package-lock.json","mode":"100644","type":"blob","sha":"6077a04d42838cd5e13399e2cb80e813070ebfed","size":145569,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/6077a04d42838cd5e13399e2cb80e813070ebfed"},{"path":"package.json","mode":"100644","type":"blob","sha":"503808a7994160000e511a7ecdc116536b035942","size":1201,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/503808a7994160000e511a7ecdc116536b035942"},{"path":"playwright.phase2.config.ts","mode":"100644","type":"blob","sha":"cd9f759f7febcb574fa3d4123a4baf0ff4f93d9a","size":435,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cd9f759f7febcb574fa3d4123a4baf0ff4f93d9a"},{"path":"playwright.phase3.config.ts","mode":"100644","type":"blob","sha":"21cc6e5c0f612a6bd1b9f103108f567646c759ba","size":190,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/21cc6e5c0f612a6bd1b9f103108f567646c759ba"},{"path":"playwright.phase4.config.ts","mode":"100644","type":"blob","sha":"4484e0c34432133950f661e698f95b34fbeae0ed","size":209,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4484e0c34432133950f661e698f95b34fbeae0ed"},{"path":"public","mode":"040000","type":"tree","sha":"ee339b4384cfbaebd4539b0e334058545c04f42d","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/ee339b4384cfbaebd4539b0e334058545c04f42d"},{"path":"public/backgrounds","mode":"040000","type":"tree","sha":"08db8ad12c61e129f6493f3f4f87e25ffb3a4621","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/08db8ad12c61e129f6493f3f4f87e25ffb3a4621"},{"path":"public/backgrounds/colors.svg","mode":"100644","type":"blob","sha":"58d325ac732370c3d6a221c533840a442e364fcd","size":612,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/58d325ac732370c3d6a221c533840a442e364fcd"},{"path":"public/backgrounds/directors.svg","mode":"100644","type":"blob","sha":"f35a1ee16817317b32c549c2d5202c4df0332687","size":618,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f35a1ee16817317b32c549c2d5202c4df0332687"},{"path":"public/backgrounds/heroes.svg","mode":"100644","type":"blob","sha":"abd3ab3d3a8450b14c97387c430dd8c16be46ade","size":612,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/abd3ab3d3a8450b14c97387c430dd8c16be46ade"},{"path":"public/backgrounds/opposites.svg","mode":"100644","type":"blob","sha":"503536fef06e640112cd2a0f51d93512fc623076","size":618,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/503536fef06e640112cd2a0f51d93512fc623076"},{"path":"public/backgrounds/singers.svg","mode":"100644","type":"blob","sha":"4c8d6109704088c9b1e91061d86719a268e2c64e","size":618,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4c8d6109704088c9b1e91061d86719a268e2c64e"},{"path":"public/backgrounds/years.svg","mode":"100644","type":"blob","sha":"28741bba79967a84456e7c4855439d6c9b744179","size":618,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/28741bba79967a84456e7c4855439d6c9b744179"},{"path":"scripts","mode":"040000","type":"tree","sha":"cc3ccdc92ce6beb4a74d3f9ca8475aeed6330911","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/cc3ccdc92ce6beb4a74d3f9ca8475aeed6330911"},{"path":"scripts/generate-casefold.ps1","mode":"100644","type":"blob","sha":"a559929c80144eae62c17cde4cea11121226e578","size":1150,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a559929c80144eae62c17cde4cea11121226e578"},{"path":"src","mode":"040000","type":"tree","sha":"f9d3f948fb85a9d9a2f14eff70ddee38b083f8fc","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/f9d3f948fb85a9d9a2f14eff70ddee38b083f8fc"},{"path":"src/app","mode":"040000","type":"tree","sha":"5563608670f678ebaf27835d5e5c375089d1d966","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/5563608670f678ebaf27835d5e5c375089d1d966"},{"path":"src/app/api","mode":"040000","type":"tree","sha":"b96d1d613b6430d8a4ada33c8cc49c3e7301b07a","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/b96d1d613b6430d8a4ada33c8cc49c3e7301b07a"},{"path":"src/app/api/auth","mode":"040000","type":"tree","sha":"8ecc6d41b9bc38dd5fad9cf5db3ebeb769a7844b","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/8ecc6d41b9bc38dd5fad9cf5db3ebeb769a7844b"},{"path":"src/app/api/auth/callback","mode":"040000","type":"tree","sha":"a9ab7b520bbd97c0fad65fc560d811ada3821e1d","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/a9ab7b520bbd97c0fad65fc560d811ada3821e1d"},{"path":"src/app/api/auth/callback/route.ts","mode":"100644","type":"blob","sha":"f6c4cb1892ea26a5e54c2bcc64f4e8de2ff564e3","size":1176,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f6c4cb1892ea26a5e54c2bcc64f4e8de2ff564e3"},{"path":"src/app/api/auth/login","mode":"040000","type":"tree","sha":"060e2a889a144e3d8bf24593ac13d6974bfa0579","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/060e2a889a144e3d8bf24593ac13d6974bfa0579"},{"path":"src/app/api/auth/login/route.ts","mode":"100644","type":"blob","sha":"c93b0fa7d3bf528d084d8041d7309ba131a574ee","size":820,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/c93b0fa7d3bf528d084d8041d7309ba131a574ee"},{"path":"src/app/api/internal","mode":"040000","type":"tree","sha":"dc5aa39c4752692248035e5724383f3b7df96baf","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/dc5aa39c4752692248035e5724383f3b7df96baf"},{"path":"src/app/api/internal/deadlines","mode":"040000","type":"tree","sha":"1cd8cfb00e9a18be08bb779aec65ec3e7bd686aa","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/1cd8cfb00e9a18be08bb779aec65ec3e7bd686aa"},{"path":"src/app/api/internal/deadlines/route.ts","mode":"100644","type":"blob","sha":"0bd0d52e3bda29508e3c62800656d96fb35a72f4","size":1168,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/0bd0d52e3bda29508e3c62800656d96fb35a72f4"},{"path":"src/app/api/landing","mode":"040000","type":"tree","sha":"dd7bf20eaa6cc37e9b2556808e01624a25541018","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/dd7bf20eaa6cc37e9b2556808e01624a25541018"},{"path":"src/app/api/landing/route.ts","mode":"100644","type":"blob","sha":"e5f63e4d6fb424f7313fd4351b407c57fcb4c593","size":1517,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e5f63e4d6fb424f7313fd4351b407c57fcb4c593"},{"path":"src/app/api/profile","mode":"040000","type":"tree","sha":"3f54077873651fd9332103646a460f739b494a23","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/3f54077873651fd9332103646a460f739b494a23"},{"path":"src/app/api/profile/route.ts","mode":"100644","type":"blob","sha":"b6d846229bb050945f0b6596bf29821202d7a11a","size":2320,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b6d846229bb050945f0b6596bf29821202d7a11a"},{"path":"src/app/api/realtime","mode":"040000","type":"tree","sha":"3ca48762f40cd8d9c450e9c3d81efd70c75dd999","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/3ca48762f40cd8d9c450e9c3d81efd70c75dd999"},{"path":"src/app/api/realtime/route.ts","mode":"100644","type":"blob","sha":"e861986e519a19cbae5fce0c7a52ae7824ef653b","size":858,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e861986e519a19cbae5fce0c7a52ae7824ef653b"},{"path":"src/app/api/rooms","mode":"040000","type":"tree","sha":"a9267c56e81c35bdabd981fc2aad837bb20a059c","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/a9267c56e81c35bdabd981fc2aad837bb20a059c"},{"path":"src/app/api/rooms/[reference]","mode":"040000","type":"tree","sha":"a96907eddfc2ee131731adaa80ee92e4b3071308","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/a96907eddfc2ee131731adaa80ee92e4b3071308"},{"path":"src/app/api/rooms/[reference]/lobby","mode":"040000","type":"tree","sha":"5d3ec56576b5f2e91ad40b67c639c4c13584acac","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/5d3ec56576b5f2e91ad40b67c639c4c13584acac"},{"path":"src/app/api/rooms/[reference]/lobby/route.ts","mode":"100644","type":"blob","sha":"68f3f41853ba89a05adfb4ebb1125d877048eb8a","size":2886,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/68f3f41853ba89a05adfb4ebb1125d877048eb8a"},{"path":"src/app/api/rooms/[reference]/match","mode":"040000","type":"tree","sha":"77280463365add7f0d26436a4c252aabcf346e86","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/77280463365add7f0d26436a4c252aabcf346e86"},{"path":"src/app/api/rooms/[reference]/match/route.ts","mode":"100644","type":"blob","sha":"c71a9600e0a27c740b82ee71204f3ca6b53e6063","size":5045,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/c71a9600e0a27c740b82ee71204f3ca6b53e6063"},{"path":"src/app/api/rooms/[reference]/route.ts","mode":"100644","type":"blob","sha":"7d53288fd2c2b845e788df61148a20b48f5001be","size":4546,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/7d53288fd2c2b845e788df61148a20b48f5001be"},{"path":"src/app/api/rooms/route.ts","mode":"100644","type":"blob","sha":"441087b57bbd6ad2fd6a5a8670f1b9488c43588e","size":2491,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/441087b57bbd6ad2fd6a5a8670f1b9488c43588e"},{"path":"src/app/api/session","mode":"040000","type":"tree","sha":"9f13be31e5000533c7278f587883fee712ff7ac9","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/9f13be31e5000533c7278f587883fee712ff7ac9"},{"path":"src/app/api/session/route.ts","mode":"100644","type":"blob","sha":"54fa45c3fc09a73d1e8e0d82e98a98457dd7e408","size":2199,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/54fa45c3fc09a73d1e8e0d82e98a98457dd7e408"},{"path":"src/app/globals.css","mode":"100644","type":"blob","sha":"d37d0e386029d213471924000458b70ed0b0f12c","size":11937,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/d37d0e386029d213471924000458b70ed0b0f12c"},{"path":"src/app/layout.tsx","mode":"100644","type":"blob","sha":"cc2c4366f306987f655fc8c5fe0b9110d1774cd6","size":388,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cc2c4366f306987f655fc8c5fe0b9110d1774cd6"},{"path":"src/app/page.tsx","mode":"100644","type":"blob","sha":"052573134b2a430e640a6242c36265f013c869b5","size":2251,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/052573134b2a430e640a6242c36265f013c869b5"},{"path":"src/app/play","mode":"040000","type":"tree","sha":"fc7d4ae9a6545ac5e550d29233076168aebdd283","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/fc7d4ae9a6545ac5e550d29233076168aebdd283"},{"path":"src/app/play/page.tsx","mode":"100644","type":"blob","sha":"35aa6db781f4952b5a275d01a9dd8ba43ca1121e","size":519,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/35aa6db781f4952b5a275d01a9dd8ba43ca1121e"},{"path":"src/app/rooms","mode":"040000","type":"tree","sha":"dd6bb8947467b4f6e0de46ebc62fe9ed82c6c429","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/dd6bb8947467b4f6e0de46ebc62fe9ed82c6c429"},{"path":"src/app/rooms/[reference]","mode":"040000","type":"tree","sha":"4baad71da6bbefb013ebf6ad95077758a64172ec","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/4baad71da6bbefb013ebf6ad95077758a64172ec"},{"path":"src/app/rooms/[reference]/page.tsx","mode":"100644","type":"blob","sha":"e9e4d8ebf8b0ac1bc2e551ad25732e8844b53836","size":849,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e9e4d8ebf8b0ac1bc2e551ad25732e8844b53836"},{"path":"src/application","mode":"040000","type":"tree","sha":"1e3eed976848e4c16c6e7293f17da293b7c533d9","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/1e3eed976848e4c16c6e7293f17da293b7c533d9"},{"path":"src/application/command.ts","mode":"100644","type":"blob","sha":"fec8d61ba5cb550bd06ef713ab64175efa94e516","size":2057,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/fec8d61ba5cb550bd06ef713ab64175efa94e516"},{"path":"src/application/identity.ts","mode":"100644","type":"blob","sha":"da0ca8416714b01514beecae055e31de06972c87","size":7824,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/da0ca8416714b01514beecae055e31de06972c87"},{"path":"src/application/index.ts","mode":"100644","type":"blob","sha":"cb0ff5c3b541f646105198ee23ac0fc3d805023e","size":11,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cb0ff5c3b541f646105198ee23ac0fc3d805023e"},{"path":"src/application/lobby.ts","mode":"100644","type":"blob","sha":"51ddca1fd0d81ce3a276c4e0aefdef619fa20453","size":5999,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/51ddca1fd0d81ce3a276c4e0aefdef619fa20453"},{"path":"src/application/matches.ts","mode":"100644","type":"blob","sha":"3e148ee30b97a99214f36a52cd5d6be039b0d118","size":7860,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3e148ee30b97a99214f36a52cd5d6be039b0d118"},{"path":"src/application/outbox.ts","mode":"100644","type":"blob","sha":"e9d1326d80094753a32213cfdcb123410e9d4df3","size":831,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e9d1326d80094753a32213cfdcb123410e9d4df3"},{"path":"src/application/ports.ts","mode":"100644","type":"blob","sha":"8e2cf53114428ed84c98b3096f1557e541532388","size":3706,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8e2cf53114428ed84c98b3096f1557e541532388"},{"path":"src/application/public-pages.ts","mode":"100644","type":"blob","sha":"cac5b1a5c24eae6e16e3fc16487727c767980681","size":1657,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cac5b1a5c24eae6e16e3fc16487727c767980681"},{"path":"src/application/public-projections.ts","mode":"100644","type":"blob","sha":"cec73c3e10188acd4092e470ffa496530443ec18","size":2534,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cec73c3e10188acd4092e470ffa496530443ec18"},{"path":"src/application/public-service.ts","mode":"100644","type":"blob","sha":"6105c59de62aef5c2d9d8c26f7060f0af5b9c0cd","size":3680,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/6105c59de62aef5c2d9d8c26f7060f0af5b9c0cd"},{"path":"src/application/rooms.ts","mode":"100644","type":"blob","sha":"2f0cd401b956b93bec44c4fd4d606928194dde3a","size":8100,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2f0cd401b956b93bec44c4fd4d606928194dde3a"},{"path":"src/domain","mode":"040000","type":"tree","sha":"982b9fe568cd20a8cfc96f8e4af0950499cad043","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/982b9fe568cd20a8cfc96f8e4af0950499cad043"},{"path":"src/domain/catalog.ts","mode":"100644","type":"blob","sha":"26baad974e64ab4b4acd883a4822803df031459e","size":3018,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/26baad974e64ab4b4acd883a4822803df031459e"},{"path":"src/domain/index.ts","mode":"100644","type":"blob","sha":"cb0ff5c3b541f646105198ee23ac0fc3d805023e","size":11,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cb0ff5c3b541f646105198ee23ac0fc3d805023e"},{"path":"src/domain/lobby.ts","mode":"100644","type":"blob","sha":"d0a001fb2fe9ced50959db65df45679753063870","size":10745,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/d0a001fb2fe9ced50959db65df45679753063870"},{"path":"src/domain/match.ts","mode":"100644","type":"blob","sha":"ee03c15aa41f4cd5daf86baf04c3bb314ccc2733","size":11458,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ee03c15aa41f4cd5daf86baf04c3bb314ccc2733"},{"path":"src/domain/model.ts","mode":"100644","type":"blob","sha":"3a74830e44227b0c32a0bfe870922a9782bafe1f","size":3640,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3a74830e44227b0c32a0bfe870922a9782bafe1f"},{"path":"src/domain/result.ts","mode":"100644","type":"blob","sha":"b235829c17598133d5e16b16139218bf1cd45645","size":745,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b235829c17598133d5e16b16139218bf1cd45645"},{"path":"src/domain/rooms.ts","mode":"100644","type":"blob","sha":"63c56a73b8f16072012c4a7fdc9b0c5de448a93f","size":3782,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/63c56a73b8f16072012c4a7fdc9b0c5de448a93f"},{"path":"src/domain/unicode-casefold.json","mode":"100644","type":"blob","sha":"708c4cb3b8abb11aeb2152e3d1f82aba8f1b7c0b","size":39523,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/708c4cb3b8abb11aeb2152e3d1f82aba8f1b7c0b"},{"path":"src/infrastructure","mode":"040000","type":"tree","sha":"fe21a67aa0901e1a9f386bc431864ea7fa94d0e2","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/fe21a67aa0901e1a9f386bc431864ea7fa94d0e2"},{"path":"src/infrastructure/catalog-repository.ts","mode":"100644","type":"blob","sha":"a0f0d32bfa790957a14693e98facd3787ee79427","size":2545,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a0f0d32bfa790957a14693e98facd3787ee79427"},{"path":"src/infrastructure/catalog-seed.json","mode":"100644","type":"blob","sha":"f244236515d3912eb918f519bec7b5c98083a879","size":26725,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f244236515d3912eb918f519bec7b5c98083a879"},{"path":"src/infrastructure/deadlines.ts","mode":"100644","type":"blob","sha":"b321f588331128ad3bf4febcd7e3d7b9afc9fa55","size":1411,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b321f588331128ad3bf4febcd7e3d7b9afc9fa55"},{"path":"src/infrastructure/identity-repository.ts","mode":"100644","type":"blob","sha":"534d3b9386813773d47e78c29ff0107949ece8cd","size":2687,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/534d3b9386813773d47e78c29ff0107949ece8cd"},{"path":"src/infrastructure/index.ts","mode":"100644","type":"blob","sha":"cb0ff5c3b541f646105198ee23ac0fc3d805023e","size":11,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cb0ff5c3b541f646105198ee23ac0fc3d805023e"},{"path":"src/infrastructure/invitations.ts","mode":"100644","type":"blob","sha":"c80f601d711c477637eaa9093b0f3c6a514dcd12","size":963,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/c80f601d711c477637eaa9093b0f3c6a514dcd12"},{"path":"src/infrastructure/match-repository.ts","mode":"100644","type":"blob","sha":"82e898ae4b7982ec3e89664713bf56cadf6aeaba","size":5905,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/82e898ae4b7982ec3e89664713bf56cadf6aeaba"},{"path":"src/infrastructure/migrations","mode":"040000","type":"tree","sha":"728ae0c32fec9f8033cf20278903fdb740568b0f","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/728ae0c32fec9f8033cf20278903fdb740568b0f"},{"path":"src/infrastructure/migrations/001_foundation.sql","mode":"100644","type":"blob","sha":"4d82984c59ec23a08422ef7e37a3e57486e6d1d2","size":18385,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4d82984c59ec23a08422ef7e37a3e57486e6d1d2"},{"path":"src/infrastructure/migrations/002_public_reads.sql","mode":"100644","type":"blob","sha":"2b6a801976429330ee07c4ab7a69e04d41d4f005","size":4825,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2b6a801976429330ee07c4ab7a69e04d41d4f005"},{"path":"src/infrastructure/migrations/003_identity.sql","mode":"100644","type":"blob","sha":"5fc3f67bd09a64c006438534955fecb5ef9708f2","size":6677,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/5fc3f67bd09a64c006438534955fecb5ef9708f2"},{"path":"src/infrastructure/migrations/004_rooms.sql","mode":"100644","type":"blob","sha":"80b0d18321d1328d9af2f2a9128ddabc3905daf7","size":10306,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/80b0d18321d1328d9af2f2a9128ddabc3905daf7"},{"path":"src/infrastructure/migrations/005_outbox.sql","mode":"100644","type":"blob","sha":"b426bb0958fc042e86fe6ae6225019fe258735af","size":1420,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b426bb0958fc042e86fe6ae6225019fe258735af"},{"path":"src/infrastructure/migrations/006_lobby_deadlines.sql","mode":"100644","type":"blob","sha":"3ad750f7489eda798d5974109b169e4b6831fe3b","size":4140,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3ad750f7489eda798d5974109b169e4b6831fe3b"},{"path":"src/infrastructure/migrations/007_matches.sql","mode":"100644","type":"blob","sha":"ad81483c5126184f913490cba359155d0d2f8f7b","size":33704,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ad81483c5126184f913490cba359155d0d2f8f7b"},{"path":"src/infrastructure/oidc.ts","mode":"100644","type":"blob","sha":"401476b52daefc520088cc6ead4d5a526b3a2ec9","size":3866,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/401476b52daefc520088cc6ead4d5a526b3a2ec9"},{"path":"src/infrastructure/outbox.ts","mode":"100644","type":"blob","sha":"f64f20ab7b706b0d1c306695f8d502ab418e100f","size":1218,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f64f20ab7b706b0d1c306695f8d502ab418e100f"},{"path":"src/infrastructure/postgres-pool.ts","mode":"100644","type":"blob","sha":"9202601cbe9d6d644f3ea9696dd1cf6278478760","size":1276,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9202601cbe9d6d644f3ea9696dd1cf6278478760"},{"path":"src/infrastructure/public-read.ts","mode":"100644","type":"blob","sha":"4528e91bb065e07dee1239f46ba76bd40e0057c7","size":2100,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4528e91bb065e07dee1239f46ba76bd40e0057c7"},{"path":"src/infrastructure/realtime-policy.sql","mode":"100644","type":"blob","sha":"ec6f25faa970ddc8a78354d6ba06a372bee26526","size":525,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ec6f25faa970ddc8a78354d6ba06a372bee26526"},{"path":"src/infrastructure/realtime.ts","mode":"100644","type":"blob","sha":"318390000ef49d6115e08f189a601e75c90d9ba5","size":3654,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/318390000ef49d6115e08f189a601e75c90d9ba5"},{"path":"src/infrastructure/room-repository.ts","mode":"100644","type":"blob","sha":"d8f8bcf3bd19e64f0f27d6ec31c0651c8f5c6f5c","size":4956,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/d8f8bcf3bd19e64f0f27d6ec31c0651c8f5c6f5c"},{"path":"src/infrastructure/runtime.ts","mode":"100644","type":"blob","sha":"8650c429d352f6dd45d8524081b321ad68dce18e","size":6570,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8650c429d352f6dd45d8524081b321ad68dce18e"},{"path":"src/infrastructure/secrets.ts","mode":"100644","type":"blob","sha":"654d69c233baaaf6fa84ecfd74c4c2d4c66906bd","size":399,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/654d69c233baaaf6fa84ecfd74c4c2d4c66906bd"},{"path":"src/infrastructure/supabase-postgres.ts","mode":"100644","type":"blob","sha":"e20d91b25c4ae7441c947ddb56b48d670c3804a8","size":4741,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e20d91b25c4ae7441c947ddb56b48d670c3804a8"},{"path":"src/web","mode":"040000","type":"tree","sha":"00827db72cafe6cedde106eadc1aba3ba56ba516","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/00827db72cafe6cedde106eadc1aba3ba56ba516"},{"path":"src/web/game-panel.tsx","mode":"100644","type":"blob","sha":"2653f61d428f2a01a7541341e40e208f2c4191e9","size":15299,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2653f61d428f2a01a7541341e40e208f2c4191e9"},{"path":"src/web/guest-credential.ts","mode":"100644","type":"blob","sha":"676929c7938783fee00202a1fff3b932e90d530c","size":1510,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/676929c7938783fee00202a1fff3b932e90d530c"},{"path":"src/web/identity-panel.tsx","mode":"100644","type":"blob","sha":"cc290a2a80c3e3ddaac28f4aaf2c68a55897c179","size":8710,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cc290a2a80c3e3ddaac28f4aaf2c68a55897c179"},{"path":"src/web/landing-board.tsx","mode":"100644","type":"blob","sha":"55553dc9e15e0fe354057af456e6560a75b6dc5a","size":11823,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/55553dc9e15e0fe354057af456e6560a75b6dc5a"},{"path":"src/web/play-hub.tsx","mode":"100644","type":"blob","sha":"547ff287ac77d453d9b379446b5c2a73938b7c6f","size":5228,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/547ff287ac77d453d9b379446b5c2a73938b7c6f"},{"path":"src/web/room-screen.tsx","mode":"100644","type":"blob","sha":"7ede7338f5b589c8ccaf01b21b42208130df7bc6","size":17568,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/7ede7338f5b589c8ccaf01b21b42208130df7bc6"},{"path":"src/web/server-http.ts","mode":"100644","type":"blob","sha":"07b91df82d3ff056fc001b782b42e5087d731ba8","size":2919,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/07b91df82d3ff056fc001b782b42e5087d731ba8"},{"path":"src/web/use-room-updates.ts","mode":"100644","type":"blob","sha":"1343ff3427743d5621fc076a02526a23d7c9f782","size":2543,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/1343ff3427743d5621fc076a02526a23d7c9f782"},{"path":"tests","mode":"040000","type":"tree","sha":"3dd8c446c173921769e4ffa898e246dd7733e213","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/3dd8c446c173921769e4ffa898e246dd7733e213"},{"path":"tests/ac-contracts","mode":"040000","type":"tree","sha":"51c0a8938edb508bbe6cc30e1ab9e41a20748794","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/51c0a8938edb508bbe6cc30e1ab9e41a20748794"},{"path":"tests/ac-contracts/archive-fixture-validator.ts","mode":"100644","type":"blob","sha":"6b6edad1fb08e0c14f06e9a3bd7d0fd0ca77d5ab","size":4447,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/6b6edad1fb08e0c14f06e9a3bd7d0fd0ca77d5ab"},{"path":"tests/ac-contracts/oracle-contract-expectations.ts","mode":"100644","type":"blob","sha":"afcb887487f620ae6cfc154440554fd823905ffc","size":19422,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/afcb887487f620ae6cfc154440554fd823905ffc"},{"path":"tests/ac-contracts/oracle-scenarios.ts","mode":"100644","type":"blob","sha":"02fe0ce4362ff75a72a171fd355f0c3861851906","size":45693,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/02fe0ce4362ff75a72a171fd355f0c3861851906"},{"path":"tests/ac-contracts/oracle-supplemental-contracts.ts","mode":"100644","type":"blob","sha":"ff817832c7cded8fbdd4521c740fff63f69368bc","size":8240,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ff817832c7cded8fbdd4521c740fff63f69368bc"},{"path":"tests/ac-contracts/oracle-supplemental-scenarios.ts","mode":"100644","type":"blob","sha":"9ff9cf9af863f8154e7208b40707ac4602588007","size":23173,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9ff9cf9af863f8154e7208b40707ac4602588007"},{"path":"tests/ac-contracts/oracle-supplemental-validation.test.ts","mode":"100644","type":"blob","sha":"40b825e8f26a74fc0d470f1b9dca82d33476feb3","size":8909,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/40b825e8f26a74fc0d470f1b9dca82d33476feb3"},{"path":"tests/ac-contracts/oracle-validation.test.ts","mode":"100644","type":"blob","sha":"d8204253bd959960e52a69914926356a7ec31e0c","size":6196,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/d8204253bd959960e52a69914926356a7ec31e0c"},{"path":"tests/application","mode":"040000","type":"tree","sha":"ef3c7a4f8e67abda7e2d6bef1cc93628bcd1dc4e","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/ef3c7a4f8e67abda7e2d6bef1cc93628bcd1dc4e"},{"path":"tests/application/catalog-seed.test.ts","mode":"100644","type":"blob","sha":"2dc9371710baa34d6df064465f6e7adad85384ac","size":2100,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2dc9371710baa34d6df064465f6e7adad85384ac"},{"path":"tests/application/command.test.ts","mode":"100644","type":"blob","sha":"f76ec9fb793e81db56d544d8409d2f2e58b1d8f8","size":12341,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f76ec9fb793e81db56d544d8409d2f2e58b1d8f8"},{"path":"tests/application/identity.test.ts","mode":"100644","type":"blob","sha":"10e3375dafa6f919583d51840dbe38b8f085886c","size":2942,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/10e3375dafa6f919583d51840dbe38b8f085886c"},{"path":"tests/application/lobby.test.ts","mode":"100644","type":"blob","sha":"15ebc2d6e027687cf0a8c2ffeb1c0120662388a6","size":14304,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/15ebc2d6e027687cf0a8c2ffeb1c0120662388a6"},{"path":"tests/application/match.test.ts","mode":"100644","type":"blob","sha":"a5316537051ffdd862a96aec7295fc1466500d14","size":8152,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a5316537051ffdd862a96aec7295fc1466500d14"},{"path":"tests/application/matches.test.ts","mode":"100644","type":"blob","sha":"e4b4a7fc12f5d92409afb0362939c21244da1138","size":3781,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e4b4a7fc12f5d92409afb0362939c21244da1138"},{"path":"tests/application/public-projections.test.ts","mode":"100644","type":"blob","sha":"a2a8df140c878931b213c3516e8a2c157b8f8494","size":3681,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a2a8df140c878931b213c3516e8a2c157b8f8494"},{"path":"tests/application/public-service.test.ts","mode":"100644","type":"blob","sha":"84259729aed3ebe44fdfc8d16e2af702b4405d30","size":4546,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/84259729aed3ebe44fdfc8d16e2af702b4405d30"},{"path":"tests/application/rooms.test.ts","mode":"100644","type":"blob","sha":"bc53e143497c22cdb4b57317a0ae6c98d53056f2","size":3365,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/bc53e143497c22cdb4b57317a0ae6c98d53056f2"},{"path":"tests/architecture","mode":"040000","type":"tree","sha":"d53c810227e91a5eaa72c560334059edfa288d93","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/d53c810227e91a5eaa72c560334059edfa288d93"},{"path":"tests/architecture/import-boundary.ts","mode":"100644","type":"blob","sha":"81ee8da2a542795c6b030ce970f0f0eceeaf01e6","size":1750,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/81ee8da2a542795c6b030ce970f0f0eceeaf01e6"},{"path":"tests/architecture/phase1a-bootstrap.test.ts","mode":"100644","type":"blob","sha":"e6d171c075a8f9d64c3dff352a2bdaec029d25d4","size":3800,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e6d171c075a8f9d64c3dff352a2bdaec029d25d4"},{"path":"tests/browser","mode":"040000","type":"tree","sha":"84bb5781ebf282fc836c16da0dc83a26786d94b4","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/84bb5781ebf282fc836c16da0dc83a26786d94b4"},{"path":"tests/browser/identity.phase2.spec.ts","mode":"100644","type":"blob","sha":"e6b4d98b16a5ebef31314c856eedb5e7e2659caf","size":1945,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e6b4d98b16a5ebef31314c856eedb5e7e2659caf"},{"path":"tests/browser/lobby.phase3.spec.ts","mode":"100644","type":"blob","sha":"3642182c8b4e92a195197d621c476c1b10923ae6","size":6200,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3642182c8b4e92a195197d621c476c1b10923ae6"},{"path":"tests/browser/matches.phase4.spec.ts","mode":"100644","type":"blob","sha":"fa6e4ae7276340326e38090dd3bc2c0bcf03f7ce","size":8058,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/fa6e4ae7276340326e38090dd3bc2c0bcf03f7ce"},{"path":"tests/browser/privacy.phase2.spec.ts","mode":"100644","type":"blob","sha":"02eee1f903841696e428df6fc56559260d16a72f","size":3279,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/02eee1f903841696e428df6fc56559260d16a72f"},{"path":"tests/browser/rooms.phase2.spec.ts","mode":"100644","type":"blob","sha":"c190990f1d21d963b5bfdbc40a0375e70c03d4f4","size":4325,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/c190990f1d21d963b5bfdbc40a0375e70c03d4f4"},{"path":"tests/integration","mode":"040000","type":"tree","sha":"cb149862619737e58e1dbc4af0e8df6b3b2abfbd","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/cb149862619737e58e1dbc4af0e8df6b3b2abfbd"},{"path":"tests/integration/identity.integration.ts","mode":"100644","type":"blob","sha":"66845ce663dfff00ce4c62772a7b5a06825a6438","size":7230,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/66845ce663dfff00ce4c62772a7b5a06825a6438"},{"path":"tests/integration/invitations.test.ts","mode":"100644","type":"blob","sha":"da7b8aa4a4c8f098e1c5c04a5bc0344d7dc683b3","size":980,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/da7b8aa4a4c8f098e1c5c04a5bc0344d7dc683b3"},{"path":"tests/integration/live-postgres.integration.ts","mode":"100644","type":"blob","sha":"b1bfa366b52ab704ac6b8e559a16c16c308b062a","size":5624,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b1bfa366b52ab704ac6b8e559a16c16c308b062a"},{"path":"tests/integration/lobby.integration.ts","mode":"100644","type":"blob","sha":"ae3423cd5c2f6c121f9fb459121245845b09f6f0","size":9251,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ae3423cd5c2f6c121f9fb459121245845b09f6f0"},{"path":"tests/integration/matches.integration.ts","mode":"100644","type":"blob","sha":"8830c11e895b9648a5da395055df5ea44f9b0c4a","size":14669,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8830c11e895b9648a5da395055df5ea44f9b0c4a"},{"path":"tests/integration/oidc.test.ts","mode":"100644","type":"blob","sha":"236f6f1a997a4f4efebba98e2cbf50c3c6a8cc9d","size":5081,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/236f6f1a997a4f4efebba98e2cbf50c3c6a8cc9d"},{"path":"tests/integration/phase1-contract.sql","mode":"100644","type":"blob","sha":"e70d9aa0432213baa3272b473d9d99790db6bd29","size":7141,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e70d9aa0432213baa3272b473d9d99790db6bd29"},{"path":"tests/integration/postgres-pool.test.ts","mode":"100644","type":"blob","sha":"ff3cb04f2c0822d51b4b43440340ac8195104c25","size":1185,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ff3cb04f2c0822d51b4b43440340ac8195104c25"},{"path":"tests/integration/postgres-store.test.ts","mode":"100644","type":"blob","sha":"fd7b5677f6677dc0f31a58cad2022ac8469f8061","size":5677,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/fd7b5677f6677dc0f31a58cad2022ac8469f8061"},{"path":"tests/integration/public-read.integration.ts","mode":"100644","type":"blob","sha":"706062eb9a53ba298954903e9262cc81112368ac","size":4987,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/706062eb9a53ba298954903e9262cc81112368ac"},{"path":"tests/integration/public-read.test.ts","mode":"100644","type":"blob","sha":"1355fb210265f7d2522b2fb5a21bb52143bbd0c9","size":1895,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/1355fb210265f7d2522b2fb5a21bb52143bbd0c9"},{"path":"tests/integration/realtime.test.ts","mode":"100644","type":"blob","sha":"0b60872f00edbae6616bd53d16a38075cf3884dc","size":3466,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/0b60872f00edbae6616bd53d16a38075cf3884dc"},{"path":"tests/integration/rooms.integration.ts","mode":"100644","type":"blob","sha":"79190fd67772f859761dc0fceab8d3f6ece807f7","size":7242,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/79190fd67772f859761dc0fceab8d3f6ece807f7"},{"path":"tests/integration/run-phase1.ps1","mode":"100644","type":"blob","sha":"891ed7c057feb1503b8cf1c36abf1d5aa97db0c3","size":9876,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/891ed7c057feb1503b8cf1c36abf1d5aa97db0c3"},{"path":"tests/integration/transport.realtime.integration.ts","mode":"100644","type":"blob","sha":"20ab17dac65efb23ec6620896f9d9c9cef9159ea","size":11214,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/20ab17dac65efb23ec6620896f9d9c9cef9159ea"},{"path":"tests/tr-contracts","mode":"040000","type":"tree","sha":"44de0144ee5b64a8a95f3895c868dc0fdc2e9619","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/44de0144ee5b64a8a95f3895c868dc0fdc2e9619"},{"path":"tests/tr-contracts/reaction-contracts.test.ts","mode":"100644","type":"blob","sha":"8e286960be2bbc2e3f1069c798e4be11e4d3ebf8","size":3405,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8e286960be2bbc2e3f1069c798e4be11e4d3ebf8"},{"path":"tests/traceability","mode":"040000","type":"tree","sha":"e7b0371f02b51839fd104b15d93d254d81c53719","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/e7b0371f02b51839fd104b15d93d254d81c53719"},{"path":"tests/traceability/ac-inventory.test.ts","mode":"100644","type":"blob","sha":"9498a991c39203c2c5371eff61ac07d49344d697","size":6006,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9498a991c39203c2c5371eff61ac07d49344d697"},{"path":"tests/traceability/inventory-validator.ts","mode":"100644","type":"blob","sha":"600c04aeeef6e1bbf75f8e027f6a704273d180c4","size":3035,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/600c04aeeef6e1bbf75f8e027f6a704273d180c4"},{"path":"tests/web","mode":"040000","type":"tree","sha":"e16dcc722230a9e9e19c0bc2c61774a3258cd8a2","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/e16dcc722230a9e9e19c0bc2c61774a3258cd8a2"},{"path":"tests/web/identity-api.test.ts","mode":"100644","type":"blob","sha":"74a080b927c8ece80a0fb026812ca6c0f42a67b0","size":4986,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/74a080b927c8ece80a0fb026812ca6c0f42a67b0"},{"path":"tests/web/landing-api.test.ts","mode":"100644","type":"blob","sha":"82a09aa6bb8031a713c4c47edd68d9769f5301c7","size":1080,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/82a09aa6bb8031a713c4c47edd68d9769f5301c7"},{"path":"tests/web/landing.test.ts","mode":"100644","type":"blob","sha":"5f4282489cb972746e21a1d7878314359f0d76b0","size":7447,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/5f4282489cb972746e21a1d7878314359f0d76b0"},{"path":"tests/web/lobby-api.test.ts","mode":"100644","type":"blob","sha":"53e2d2ac8dd14a94cd062b3783b0a38555c53444","size":3261,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/53e2d2ac8dd14a94cd062b3783b0a38555c53444"},{"path":"tests/web/matches-api.test.ts","mode":"100644","type":"blob","sha":"a4d6ef6f2fa7318e81bcfbd842391731bb4ef43d","size":4589,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a4d6ef6f2fa7318e81bcfbd842391731bb4ef43d"},{"path":"tests/web/rooms-api.test.ts","mode":"100644","type":"blob","sha":"05dc70b9cbae8a558138424c456b34bdd8d3df77","size":4418,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/05dc70b9cbae8a558138424c456b34bdd8d3df77"},{"path":"third_party","mode":"040000","type":"tree","sha":"03523b739000b4bd42aa611109d0a583890391a5","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/03523b739000b4bd42aa611109d0a583890391a5"},{"path":"third_party/unicode","mode":"040000","type":"tree","sha":"c3efe15610f853bd85eaf8f98961376a1efaab0e","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/c3efe15610f853bd85eaf8f98961376a1efaab0e"},{"path":"third_party/unicode/CaseFolding-18.0.0.txt","mode":"100644","type":"blob","sha":"9ee0a2dd654f6fa520cd932be19ac5c00ffacded","size":88776,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9ee0a2dd654f6fa520cd932be19ac5c00ffacded"},{"path":"third_party/unicode/LICENSE.txt","mode":"100644","type":"blob","sha":"56da58912807030b451a4700687d5bd02c72d6ed","size":1995,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/56da58912807030b451a4700687d5bd02c72d6ed"},{"path":"tsconfig.json","mode":"100644","type":"blob","sha":"4524c04d8219a01747b7e921a9a61a1fc3dbab4c","size":836,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4524c04d8219a01747b7e921a9a61a1fc3dbab4c"},{"path":"vitest.config.ts","mode":"100644","type":"blob","sha":"9e31dc5919ce2777c7bb014d498d745970305062","size":275,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9e31dc5919ce2777c7bb014d498d745970305062"},{"path":"vitest.postgres.config.ts","mode":"100644","type":"blob","sha":"13328f042231b1f0fc2c9dfa5a35e9c8d4c64928","size":312,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/13328f042231b1f0fc2c9dfa5a35e9c8d4c64928"},{"path":"vitest.realtime.config.ts","mode":"100644","type":"blob","sha":"0e0169d8e7bce633feef8d79b4a70b57acd382cf","size":197,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/0e0169d8e7bce633feef8d79b4a70b57acd382cf"}],"truncated":false},"comparison":{"sha":"4bc242c05d63dd84798940e4afd7da62a4ecd219","tree":"da0f52c8320ca0627edd455846cca75d395264ba","parent":["6bcc5e273dbdb47869920358ad9468c402b78cb1"],"truncated":false,"localCount":179,"remoteCount":179,"equal":true}}}