{"event":"phase5_formal_exit_review","timestamp":"2026-10-26T21:21:19.206Z","request":"FORMAL PHASE5 EXIT requested. Exact local+GitHub candidate2c1daaa2b51f91969a81b304e5c586c993c2f183 tree97b9711e8cd5949ff33feab4bce3a3c279ae0f9f URL https://github.com/sharpninja/wordpairs/commit/7df395c3fb181784bb41d76f90eb481de5efa6ac. Parent754f3aa355b02eabeb00df99ae80f8b53a5beba3 Phase4receipt also immutablyuploaded. Cleanworkingtree. Independently verify allremote leaves vs exactlocalcommit and full Phase5A/B against v2.6. Rootfinal466tests/33files, typecheck, lint74files, localbuild,34actualPostgres tests/8files+SQLchecks,4actualRealtime tests,12Chromium journeys allpass. Source docs/phase5_execution.md records invariants/evidence/limits. Browserconfigplaywright.phase5.config.ts envWORDPAIRS_BROWSER_PATH=/usr/bin/chromium; DBtests/integration/run-phase1.ps1 -Realtime. No rootNextprocess active; build/browser sequentially. Three material increment findings corrected with red-green regressions: originalseedexclusions preserve startup+configuredsix availability; appealoneopen plusprojection guard; SocialPanel serialized/coalescedslow1.2sreads. Postgres regressions coveralloriginalseedexclusions/staledraw and unchangedstate/audit/commandrecords forblockedappeal; ReactDOMtest provesreactionvisible/nominationenabled/maxconcurrentfetch1. ReactionRealtime test renewspresence throughactualLobbyService thenverifiesallmembers/outsiderexclusion, privateallowlistedrefetch, noemoji innotification, exactexpiry+unchangedMatch. Source/TDD andseparateevidence tiers documented. Please independentformalreview >=98accuracyANDcompleteness, no unresolvedmaterial, save complete request/rubric/rawreport/remoteverification/resolvedfindings/scores to docs/phase5_review_receipt.jsonl and updateonly docs/phase5_execution.md +docs/goal_hv_agreement_through_phase_6.md. ExplicitlyauthorizePhase6ifapproved. Restoregeneratednext-envonly, noimplementationedits. AuthorizedDocker/browser/networkread no newhumanapproval. No branchmovement/deployment/Phase7work. Goalremainsactiveuntil6. Optional preparationnote: Phase6existingoracle AC13 fixture says configuredRounds3 despitefixed8 v2.6; advise honest adapter strategy that preserves originalassertions andprovesactual8-round behavior (not gate5scope).","reviewerOutput":"{\n \"review\": \"Formal Phase 5A/5B exact-commit hostile validation\",\n \"reviewer\": {\n \"model\": \"gpt-6-astra\",\n \"reasoningEffort\": \"high\",\n \"role\": \"Independent hostile validator\",\n \"implementationEdits\": false\n },\n \"reviewedAt\": \"2026-10-26T21:21:19.206Z\",\n \"candidateSHA\": \"7df395c3fb181784bb41d76f90eb481de5efa6ac\",\n \"candidateTree\": \"97b9711e8cd5949ff33feab4bce3a3c279ae0f9f\",\n \"candidateURL\": \"https://github.com/sharpninja/wordpairs/commit/7df395c3fb181784bb41d76f90eb481de5efa6ac\",\n \"parentSHA\": \"d956b2df2463c7c3a5ecf76e103c6ac8e96c9325\",\n \"scope\": {\n \"approvedBaseline\": \"Requirements v2.6; docs/implementation_plan.md Phase 5A and 5B; Phase 0 interface/data contracts and approved overlapping allocation\",\n \"phase5A\": \"AC-16–18/47: current revealed no-hint nomination eligibility, normalized unique votes, threshold, independent moderation, appeal, audit and complete curated publication.\",\n \"phase5B\": \"AC-19/29/47 and separate TR-19: lifetime-win suggestion unlock, one open three-pair category suggestion, review/curation handoff, allowlisted room reactions, rate and expiry.\",\n \"notClaimed\": \"Phase 6 final real-SUT acceptance matrix, full responsive/accessibility human evidence, overall goal completion, deployment or release.\"\n },\n \"remoteVerification\": {\n \"sha\": \"7df395c3fb181784bb41d76f90eb481de5efa6ac\",\n \"tree\": \"97b9711e8cd5949ff33feab4bce3a3c279ae0f9f\",\n \"parents\": [\n \"d956b2df2463c7c3a5ecf76e103c6ac8e96c9325\"\n ],\n \"truncated\": false,\n \"localCount\": 208,\n \"remoteCount\": 208,\n \"equal\": true\n },\n \"rubric\": {\n \"threshold\": {\n \"accuracyPercent\": 98,\n \"completenessPercent\": 98,\n \"noUnresolvedMaterialFindings\": true\n },\n \"scoringMethod\": \"Independent reviewer judgments of correctness against the approved phase requirements and completeness of phase implementation/evidence; these percentages are not code-coverage measurements or guarantees.\",\n \"dimensions\": [\n {\n \"area\": \"Nomination and suggestion invariants\",\n \"accuracy\": 99,\n \"completeness\": 99,\n \"evidence\": \"Actual pure domain and application source/tests enforce current revealed no-hint solve and stable roster identity, normalized Unicode candidate uniqueness, one profile/candidate and one nomination/round, 9/10 threshold, ten stored lifetime wins, exactly three proposed pairs, and one open suggestion including reopening by appeal.\"\n },\n {\n \"area\": \"Moderation, privacy and authority\",\n \"accuracy\": 99,\n \"completeness\": 99,\n \"evidence\": \"Strict same-origin private APIs derive actor from verified session and enforce expected-profile preconditions; fresh roles/wins come from private server data. Independent moderator reasons, one proposer appeal, distinct Senior Moderator resolution, filtered own/reviewer projections and durable audit transitions are implemented.\"\n },\n {\n \"area\": \"Catalog integrity and concurrency\",\n \"accuracy\": 99,\n \"completeness\": 99,\n \"evidence\": \"Approval and activation remain separate. Activation validates complete approved records and matching proposed targets. Immutable historical versions remain readable, exclusions remove future selection only, configured category availability is guarded, and stale cached catalog revisions conflict under a shared database revision lock.\"\n },\n {\n \"area\": \"Reaction behavior and isolation\",\n \"accuracy\": 99,\n \"completeness\": 99,\n \"evidence\": \"Five fixed emojis; current player/active round checks; serialized per-actor 2s boundary; absolute 5s expiry; canonical replay without duplicate delivery or renewed expiry; separate room-anchored durable aggregate leaves room/match versions, guesses, hints, scores and selections unchanged. Metadata-only notifications require authorized refetch.\"\n },\n {\n \"area\": \"Client recovery, regression and evidence discipline\",\n \"accuracy\": 99,\n \"completeness\": 99,\n \"evidence\": \"Exact uncertain write intents survive explicit retries, profile keys and server preconditions preserve account scope, slow social polling is serialized/coalesced, own nominated-round evidence recovers uncertain nominations, and independent tests/build/database/Realtime/Chromium checks pass. Original AC oracle assertions and dependency/license inputs are unchanged.\"\n }\n ]\n },\n \"accuracyPercent\": 99,\n \"completenessPercent\": 99,\n \"findings\": [],\n \"unresolvedMaterialFindings\": 0,\n \"resolvedPriorFindings\": [\n {\n \"id\": \"P5-HV-01\",\n \"priority\": \"P1\",\n \"original\": \"A successful original-pair exclusion reduced an initial category to nine selectable records and blocked all new match startup; exhausting an initial category also prevented no-solver round expiry.\",\n \"independentReproduction\": \"Actual domain/application invocation accepted the exclusion and MatchService.open returned CONFLICT. Actual expireStage succeeded with the original catalog and returned VALIDATION_ERROR after excluding an unrelated initial category.\",\n \"resolution\": \"Startup checks ten distinct immutable historical IDs plus at least one selectable record per initial category. disablePair rejects exclusion of the last selectable record in any configured initial category. Catalog revision locking prevents stale decisions.\",\n \"verification\": \"Independent full suite and actual PostgreSQL regression passed: nine original exclusions, new match startup, final-exclusion CONFLICT, stale-draw CONFLICT with unchanged match, fresh draw of the survivor and no-solver summary progression.\"\n },\n {\n \"id\": \"P5-HV-02\",\n \"priority\": \"P2\",\n \"original\": \"Reject suggestion A, submit B, then appeal A: domain accepted two open suggestions and SQL converted the uniqueness violation into TEMPORARY_UNAVAILABLE.\",\n \"independentReproduction\": \"Actual domain invocation produced A=appealed and B=pending for the same proposer.\",\n \"resolution\": \"anotherOpenSuggestion is checked when reopening by appeal and by canAppeal; rejection is typed CONFLICT before persistence.\",\n \"verification\": \"Independent domain and actual PostgreSQL regression passed, including unchanged aggregate, audit count and absence of a command record after blocked appeal.\"\n },\n {\n \"id\": \"P5-HV-03\",\n \"priority\": \"P2\",\n \"original\": \"SocialPanel's 1s polling invalidated every successful response taking 1.2s; reaction results never displayed and content-version loading never ran.\",\n \"independentReproduction\": \"Actual SocialPanel with ReactDOM/jsdom at 3.7s observed four requests, three successful responses, zero visible reactions, zero content requests and a disabled nomination fieldset.\",\n \"resolution\": \"One in-flight refresh covers reaction and required content reads; overlapping polls/notifications coalesce into a follow-up. Timeout and generation/unmount guards remain; initial content reads are cached per round and invalidated after mutations.\",\n \"verification\": \"Independent full suite passed the actual React/jsdom 1.2s latency regression: reaction visible, eligible nomination enabled and maximum concurrent fetches one. All twelve browser journeys passed.\"\n }\n ],\n \"verification\": [\n {\n \"tier\": \"Exact remote source identity\",\n \"performedBy\": \"Reviewer\",\n \"tool\": \"GitHub connector read-only fetch\",\n \"commands\": [\n \"GET /repos/sharpninja/wordpairs/git/commits/7df395c3fb181784bb41d76f90eb481de5efa6ac\",\n \"GET /repos/sharpninja/wordpairs/git/trees/97b9711e8cd5949ff33feab4bce3a3c279ae0f9f?recursive=1\",\n \"git ls-tree -r 7df395c3fb181784bb41d76f90eb481de5efa6ac\"\n ],\n \"result\": \"PASS; exact commit, tree and parent; all 208 leaf path/mode/type/blob-SHA tuples match; recursive response not truncated. Full raw commit/tree responses are saved alongside this report.\"\n },\n {\n \"tier\": \"Regression, domain/application, API and mock contracts\",\n \"performedBy\": \"Reviewer\",\n \"command\": \"npm test\",\n \"result\": \"PASS\",\n \"files\": 33,\n \"passed\": 466,\n \"failed\": 0,\n \"skipped\": 0,\n \"limits\": \"Includes both original mock-oracle/process tests and real source exercised through injected ports. The total is not a count of completed real-product ACs.\"\n },\n {\n \"tier\": \"Static checks and local production compilation\",\n \"performedBy\": \"Reviewer\",\n \"commands\": [\n \"npm run typecheck\",\n \"npm run lint\",\n \"npm run build\"\n ],\n \"result\": \"PASS; typecheck exit 0, Biome checked 74 files with no fixes, Next local production build exit 0. Build preceded Chromium. No deployment.\"\n },\n {\n \"tier\": \"Actual disposable PostgreSQL\",\n \"performedBy\": \"Reviewer\",\n \"command\": \"pwsh -File tests/integration/run-phase1.ps1 -Realtime\",\n \"result\": \"PASS\",\n \"files\": 8,\n \"passed\": 34,\n \"failed\": 0,\n \"skipped\": 0,\n \"additional\": \"SQL migration/RLS/direct-role denial, canonical retry/conflict, outbox rollback, retention and concurrent final-seat checks passed. New content cases exercise threshold race, audited moderation/appeal rollback, curated activation/exclusion/history/cache, authoritative lifetime wins, blocked reopening and stale draws. New reactions exercise concurrency/rate/canonical replay/expiry/rollback and private authority.\",\n \"log\": \"/tmp/wordpairs-phase5-hv-integration.log\"\n },\n {\n \"tier\": \"Actual disposable Supabase Realtime\",\n \"performedBy\": \"Reviewer\",\n \"command\": \"pwsh -File tests/integration/run-phase1.ps1 -Realtime\",\n \"result\": \"PASS\",\n \"files\": 1,\n \"passed\": 4,\n \"failed\": 0,\n \"skipped\": 0,\n \"additional\": \"Actual private channels and publisher/outbox relay deliver committed notifications to members and exclude outsider; reaction content is fetched through authorized service projection, emoji does not appear in notification, match state remains unchanged, and exact expiry hides the reaction. Presence fixture uses actual lobby service. Runner exits successfully and cleans its owned disposable containers.\",\n \"log\": \"/tmp/wordpairs-phase5-hv-integration.log\"\n },\n {\n \"tier\": \"Actual Chromium UI with intercepted HTTP/application fakes\",\n \"performedBy\": \"Reviewer\",\n \"command\": \"WORDPAIRS_BROWSER_PATH=/usr/bin/chromium npm exec playwright -- test --config playwright.phase5.config.ts\",\n \"result\": \"PASS\",\n \"passed\": 12,\n \"failed\": 0,\n \"skipped\": 0,\n \"durationSeconds\": 39.8,\n \"additional\": \"New three-role suggestion/rejection/appeal/curation and player/observer reaction/uncertain retry/rate/expiry journeys passed along with earlier identity, lobby, room/privacy and eight-round game journeys.\",\n \"limits\": \"HTTP seams invoke actual application/domain with transaction fakes. These are browser behavior evidence, not live end-to-end Postgres/provider conformance.\",\n \"log\": \"/tmp/wordpairs-phase5-hv-browser.log\"\n },\n {\n \"tier\": \"Source and preservation checks\",\n \"performedBy\": \"Reviewer\",\n \"result\": \"PASS\",\n \"additional\": \"Reviewed full Phase 5 source delta and relevant baseline contracts. No changes to tests/ac-contracts, package.json or package-lock.json in the candidate delta. No implementation edits during review. Only browser-generated next-env.d.ts was restored exactly from candidate; git status was clean and HEAD remained exact candidate before writing reviewer receipts.\"\n }\n ],\n \"policyClarifications\": [\n \"Exclusion requires a replacement before removing the last selectable pair of an initial category; the six-category no-solver policy remains unchanged.\",\n \"Canonical replay is checked before current membership/role authorization, while every new transition uses current server evidence; this preserves accepted result retry without authorizing new commands.\",\n \"Global content bounds (512 cases/4096 nominations) are explicit SERVICE_LIMIT behavior, not silent truncation or automatic paid service use.\",\n \"Reaction notifications are metadata-only wakeups, with authorization and expiry enforced by the private refetch.\",\n \"The shared moderation aggregate kind is partitioned by fixed content-catalog ID versus validated room IDs for reaction streams; reaction state remains separate from content, room and match state.\"\n ],\n \"phase6Preparation\": {\n \"issue\": \"The preserved AC-13-T01 mock fixture requests configuredRounds=3/completedRound=3, while approved product policy is fixed eight rounds.\",\n \"advice\": \"Keep the original oracle and its assertions intact as historical projection/mock evidence. Add a clearly mapped real-SUT eight-round counterpart that executes actual transitions, asserts not-final after rounds 3 and 7, final only after 8, and obtains standings from the actual projection. Document which test proves standings ordering and which proves termination. Do not silently reinterpret 3 as 8, manufacture observations, weaken the fixed-eight rule, or count the original three-round fixture as direct lifecycle conformance.\",\n \"disposition\": \"Phase 6 evidence work; not a Phase 5 product defect or waiver of final acceptance.\"\n },\n \"contentAndLicensing\": {\n \"newDependencies\": false,\n \"dependencyFilesUnchanged\": true,\n \"license\": \"GPL-2.0-only and existing attribution remain unchanged\",\n \"catalog\": \"New publication uses approved complete records and existing repository backgrounds; immutable seed/history retained\"\n },\n \"verificationLimits\": [\n \"This approval covers Phase 5A/5B at the named exact GitHub commit, not completion of every active AC against the real product.\",\n \"Mock-oracle tests establish their contracts; application/domain tests and browser fakes prove their stated scope only. Actual database and Realtime tests are separate TR integration evidence.\",\n \"Phase 6 still requires the complete honest real-SUT acceptance driver matrix, responsive/accessibility review and required human evidence, final privacy/security review and exact-commit hostile validation.\",\n \"Disposable local provider tests do not prove live free-tier capacity, production scheduling, external identity-provider provisioning, deployment configuration or release operations; those belong to the later authorized phase.\",\n \"Review is not an exhaustive proof against all possible concurrency, security or usability failures. Scores describe evidence-based reviewer confidence and scope completeness.\",\n \"Existing MCP hook recovery remains documented as degraded; this review neither repairs nor claims it resolved.\",\n \"No branch movement, deployment, release, GitHub Actions or paid resource provisioning occurred during reviewer work.\"\n ],\n \"disposition\": \"APPROVE\",\n \"formalPhase5Exit\": \"APPROVED\",\n \"phase6EntryAuthorized\": true,\n \"goalThroughPhase6Complete\": false,\n \"remainingGoalPhases\": [\n 6\n ],\n \"deploymentAuthorized\": false,\n \"releaseAuthorized\": false,\n \"reviewerAgreement\": \"The exact candidate meets the approved Phase 5 exit criteria at 99% accuracy and 99% completeness, with no unresolved material findings. Phase 6 entry is authorized; overall goal remains active.\",\n \"filesWritten\": [\n \"docs/phase5_review_receipt.jsonl\",\n \"docs/phase5_execution.md\",\n \"docs/goal_hv_agreement_through_phase_6.md\"\n ]\n}","remoteVerification":{"commit":{"sha":"7df395c3fb181784bb41d76f90eb481de5efa6ac","node_id":"C_kwDOVXU2i9oAKDJjMWRhYWEyYjUxZjkxOTY5YTgxYjMwNGU1YzU4NmM5OTNjMmYxODM","url":"https://api.github.com/repos/sharpninja/wordpairs/git/commits/7df395c3fb181784bb41d76f90eb481de5efa6ac","html_url":"https://github.com/sharpninja/wordpairs/commit/7df395c3fb181784bb41d76f90eb481de5efa6ac","author":{"name":"Sharp Ninja","email":"ninja@thesharp.ninja","date":"2026-10-26T21:16:55Z"},"committer":{"name":"Sharp Ninja","email":"ninja@thesharp.ninja","date":"2026-10-26T21:16:55Z"},"tree":{"sha":"97b9711e8cd5949ff33feab4bce3a3c279ae0f9f","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/97b9711e8cd5949ff33feab4bce3a3c279ae0f9f"},"message":"feat(content): add moderation and reactions\n\nSerialize nominations, suggestions, appeals and audited curation. Guard catalog revisions and preserve immutable round history. Store timed reactions separately so social actions cannot change game state.","parents":[{"sha":"d956b2df2463c7c3a5ecf76e103c6ac8e96c9325","url":"https://api.github.com/repos/sharpninja/wordpairs/git/commits/d956b2df2463c7c3a5ecf76e103c6ac8e96c9325","html_url":"https://github.com/sharpninja/wordpairs/commit/d956b2df2463c7c3a5ecf76e103c6ac8e96c9325"}],"verification":{"verified":false,"reason":"unsigned","signature":null,"payload":null,"verified_at":null}},"tree":{"sha":"97b9711e8cd5949ff33feab4bce3a3c279ae0f9f","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/97b9711e8cd5949ff33feab4bce3a3c279ae0f9f","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":"1e2f94ec4f782e22b2567f43b5b6b6c5003f2c9a","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/1e2f94ec4f782e22b2567f43b5b6b6c5003f2c9a"},{"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":"ae0bd3b8bf7350a1c6039f818a91538eb63d5412","size":12657,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ae0bd3b8bf7350a1c6039f818a91538eb63d5412"},{"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":"3ff14a49f2895a30521613467f2abcaa81a2445c","size":5987,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3ff14a49f2895a30521613467f2abcaa81a2445c"},{"path":"docs/phase4_review_receipt.jsonl","mode":"100644","type":"blob","sha":"9c1a585a8d0917152035e2176d10197a029c4468","size":70211,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9c1a585a8d0917152035e2176d10197a029c4468"},{"path":"docs/phase5_execution.md","mode":"100644","type":"blob","sha":"fddd46b0f252bf6f67a2de4b99698dd31decbeb3","size":6770,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/fddd46b0f252bf6f67a2de4b99698dd31decbeb3"},{"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":"playwright.phase5.config.ts","mode":"100644","type":"blob","sha":"2446c541d6e83c4af99fcceb0d11e1eb671d4cda","size":224,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/2446c541d6e83c4af99fcceb0d11e1eb671d4cda"},{"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":"918385e2b35442bac279267fe48e164db525d774","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/918385e2b35442bac279267fe48e164db525d774"},{"path":"src/app","mode":"040000","type":"tree","sha":"ed3bc5224bf28337f599e9ab4d8a6752f23f956b","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/ed3bc5224bf28337f599e9ab4d8a6752f23f956b"},{"path":"src/app/api","mode":"040000","type":"tree","sha":"4805b231ab64809d5942e518b5bb6eca3f367ab2","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/4805b231ab64809d5942e518b5bb6eca3f367ab2"},{"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/content","mode":"040000","type":"tree","sha":"42ccdefaee6b8f329e67b67569b0fa21a08690ae","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/42ccdefaee6b8f329e67b67569b0fa21a08690ae"},{"path":"src/app/api/content/route.ts","mode":"100644","type":"blob","sha":"12358c6405e8940734c5bae95de9d625fd8ea0a6","size":2541,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/12358c6405e8940734c5bae95de9d625fd8ea0a6"},{"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":"7b6d0e15e5214b5a65b488eff141629031f8f319","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/7b6d0e15e5214b5a65b488eff141629031f8f319"},{"path":"src/app/api/rooms/[reference]","mode":"040000","type":"tree","sha":"d994dcf71b3a884497a57f57f953b38ff0e2c5ef","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/d994dcf71b3a884497a57f57f953b38ff0e2c5ef"},{"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]/reactions","mode":"040000","type":"tree","sha":"aaf392f8a9afeebccac787ae3459d764f8994279","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/aaf392f8a9afeebccac787ae3459d764f8994279"},{"path":"src/app/api/rooms/[reference]/reactions/route.ts","mode":"100644","type":"blob","sha":"208e7dc7f38c14aeb41db4e8bdc183fec914b7a8","size":2990,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/208e7dc7f38c14aeb41db4e8bdc183fec914b7a8"},{"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/content","mode":"040000","type":"tree","sha":"5dd0a0e17f48d1556d595619a5218393c7ac0f99","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/5dd0a0e17f48d1556d595619a5218393c7ac0f99"},{"path":"src/app/content/page.tsx","mode":"100644","type":"blob","sha":"e99d0e2caabad0e7c99a59ae8099f2750cccdc8c","size":581,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e99d0e2caabad0e7c99a59ae8099f2750cccdc8c"},{"path":"src/app/globals.css","mode":"100644","type":"blob","sha":"e034bf0a81e6403b18d259f37180bbf4d423454f","size":13081,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e034bf0a81e6403b18d259f37180bbf4d423454f"},{"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":"607a68ea341af67c76f3eae5559043b43062b5e4","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/607a68ea341af67c76f3eae5559043b43062b5e4"},{"path":"src/app/play/page.tsx","mode":"100644","type":"blob","sha":"402617a9c26f7b9efd237bda71884787ac8fd93f","size":570,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/402617a9c26f7b9efd237bda71884787ac8fd93f"},{"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":"f0c6f5af39ea3e4d3549c333d902d0c8c40dc419","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/f0c6f5af39ea3e4d3549c333d902d0c8c40dc419"},{"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/content.ts","mode":"100644","type":"blob","sha":"ee4cf1eb51d79d29dd207a06fb58c5c4194f45f9","size":9089,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/ee4cf1eb51d79d29dd207a06fb58c5c4194f45f9"},{"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":"33dbfb04220c3a9adb8a298c264040b71937814a","size":8204,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/33dbfb04220c3a9adb8a298c264040b71937814a"},{"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/reactions.ts","mode":"100644","type":"blob","sha":"908a5d41ce0fdcdde7cfeea31b6229df4583edcc","size":3373,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/908a5d41ce0fdcdde7cfeea31b6229df4583edcc"},{"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":"ba0d89cdd75b0bccd379062b55bd37bf1a5eac26","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/ba0d89cdd75b0bccd379062b55bd37bf1a5eac26"},{"path":"src/domain/catalog.ts","mode":"100644","type":"blob","sha":"3608ff5adb227383cb04bc110320cccd8a794645","size":3081,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3608ff5adb227383cb04bc110320cccd8a794645"},{"path":"src/domain/content.ts","mode":"100644","type":"blob","sha":"de609d5080e9ff5e424c231ffa2ac2b018e1406f","size":14243,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/de609d5080e9ff5e424c231ffa2ac2b018e1406f"},{"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":"8d3a78f57a7f8696f45e3bc95ca4dbcfd82c9b59","size":11528,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8d3a78f57a7f8696f45e3bc95ca4dbcfd82c9b59"},{"path":"src/domain/model.ts","mode":"100644","type":"blob","sha":"97803ecc8ce2a113686f81517295824169d1f126","size":3664,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/97803ecc8ce2a113686f81517295824169d1f126"},{"path":"src/domain/reactions.ts","mode":"100644","type":"blob","sha":"76558b98dcf9b065f598a6067c81b1fb290d4f77","size":2204,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/76558b98dcf9b065f598a6067c81b1fb290d4f77"},{"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":"e787e431f4cf2c9bd15d6f045923041a31349a99","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/e787e431f4cf2c9bd15d6f045923041a31349a99"},{"path":"src/infrastructure/catalog-repository.ts","mode":"100644","type":"blob","sha":"9e5be33c5d91356b3fc1720785d3352b1706f088","size":2476,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/9e5be33c5d91356b3fc1720785d3352b1706f088"},{"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/content-repository.ts","mode":"100644","type":"blob","sha":"5b23c01a874a0775c29cf9b89409fe733a52c02f","size":4860,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/5b23c01a874a0775c29cf9b89409fe733a52c02f"},{"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":"4d85cfb872e08417d3689cd7f58b2e30b2c1e5fa","size":6287,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4d85cfb872e08417d3689cd7f58b2e30b2c1e5fa"},{"path":"src/infrastructure/migrations","mode":"040000","type":"tree","sha":"c40e1659126123b8454eacbe56fe42e75a63573f","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/c40e1659126123b8454eacbe56fe42e75a63573f"},{"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/migrations/008_content.sql","mode":"100644","type":"blob","sha":"cf4b768a06451a0fce848beab58ffe8afb3466fa","size":8122,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/cf4b768a06451a0fce848beab58ffe8afb3466fa"},{"path":"src/infrastructure/migrations/009_reactions.sql","mode":"100644","type":"blob","sha":"f88d2d624fe7472df17e45e5bc7a38092b81efa8","size":720,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/f88d2d624fe7472df17e45e5bc7a38092b81efa8"},{"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/reaction-repository.ts","mode":"100644","type":"blob","sha":"a01dcbd4fa166ef3685957647e51c865b26f27cb","size":4100,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a01dcbd4fa166ef3685957647e51c865b26f27cb"},{"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":"d55546e5b6b4703c2bbe8838c19bda53d3d6923c","size":7278,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/d55546e5b6b4703c2bbe8838c19bda53d3d6923c"},{"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":"038ae6afcd3209e3f24e1bfcfa2611b92af8e643","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/038ae6afcd3209e3f24e1bfcfa2611b92af8e643"},{"path":"src/web/content-input.ts","mode":"100644","type":"blob","sha":"b081c1ded171ec31e6b74cba421d087b974e2a15","size":4661,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/b081c1ded171ec31e6b74cba421d087b974e2a15"},{"path":"src/web/content-panel.tsx","mode":"100644","type":"blob","sha":"87b39d0d41e88fe9629a2e9cd3079e66b26e2a18","size":17127,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/87b39d0d41e88fe9629a2e9cd3079e66b26e2a18"},{"path":"src/web/game-panel.tsx","mode":"100644","type":"blob","sha":"42f1a0a7fe7ec79623cf36f70e20ee7bd3d4c342","size":15796,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/42f1a0a7fe7ec79623cf36f70e20ee7bd3d4c342"},{"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/social-panel.tsx","mode":"100644","type":"blob","sha":"62372081ccc8335defa5f72fa1f29527f371b8c9","size":7386,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/62372081ccc8335defa5f72fa1f29527f371b8c9"},{"path":"src/web/use-private-intent.ts","mode":"100644","type":"blob","sha":"e6892b1c5de4fbd90981826dcd4d2fa6956915b5","size":2490,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e6892b1c5de4fbd90981826dcd4d2fa6956915b5"},{"path":"src/web/use-room-updates.ts","mode":"100644","type":"blob","sha":"4face54f8156500715547f3b8d894c6eb3758753","size":2557,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/4face54f8156500715547f3b8d894c6eb3758753"},{"path":"tests","mode":"040000","type":"tree","sha":"8365ceeef440d6cca51debef90d46aacc4f25f6d","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/8365ceeef440d6cca51debef90d46aacc4f25f6d"},{"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":"d2e8c672dd54cd900fe38a9edba50ed74de71eb5","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/d2e8c672dd54cd900fe38a9edba50ed74de71eb5"},{"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/content-service.test.ts","mode":"100644","type":"blob","sha":"c1ef7649699ff1c989883f7dfd6c97cc3cfbe78d","size":2952,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/c1ef7649699ff1c989883f7dfd6c97cc3cfbe78d"},{"path":"tests/application/content.test.ts","mode":"100644","type":"blob","sha":"bbb90a927c929d8a13cd0e69703909e79865b3a1","size":7932,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/bbb90a927c929d8a13cd0e69703909e79865b3a1"},{"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/reaction-service.test.ts","mode":"100644","type":"blob","sha":"adb5aa51ae9df152bec52e5488041d44aed1266f","size":2435,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/adb5aa51ae9df152bec52e5488041d44aed1266f"},{"path":"tests/application/reactions.test.ts","mode":"100644","type":"blob","sha":"e8b41d9444bade38d5be22e7de60d4f373e7c90f","size":2232,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/e8b41d9444bade38d5be22e7de60d4f373e7c90f"},{"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":"9613801808c29e6f673851201057b2b1b0309b13","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/9613801808c29e6f673851201057b2b1b0309b13"},{"path":"tests/browser/content.phase5.spec.ts","mode":"100644","type":"blob","sha":"edef9325ed1c37c1c06aed76b132ecb991bbf5bc","size":4758,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/edef9325ed1c37c1c06aed76b132ecb991bbf5bc"},{"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/reactions.phase5.spec.ts","mode":"100644","type":"blob","sha":"3974ae8a8850b2db8e6ce84920598ff75c369825","size":5432,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/3974ae8a8850b2db8e6ce84920598ff75c369825"},{"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":"be504b964b8dc2412ddc3cebdf1ff6493281443c","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/be504b964b8dc2412ddc3cebdf1ff6493281443c"},{"path":"tests/integration/content.integration.ts","mode":"100644","type":"blob","sha":"8a7c6d9476f68caeb58fe6e2a617b3c015fd2029","size":14996,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8a7c6d9476f68caeb58fe6e2a617b3c015fd2029"},{"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/reactions.integration.ts","mode":"100644","type":"blob","sha":"8f6dccf8321c19473a82f78670c9774e96055335","size":7298,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/8f6dccf8321c19473a82f78670c9774e96055335"},{"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":"90e4d6cf0d4ce19928be36df7b176b3c6910e207","size":14316,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/90e4d6cf0d4ce19928be36df7b176b3c6910e207"},{"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":"79fca2cfb7731d3e63ee01bd1abce1590e03ac3f","url":"https://api.github.com/repos/sharpninja/wordpairs/git/trees/79fca2cfb7731d3e63ee01bd1abce1590e03ac3f"},{"path":"tests/web/content-api.test.ts","mode":"100644","type":"blob","sha":"7a6aefef4577878700eb10bbbb8c4efdb0c85279","size":2876,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/7a6aefef4577878700eb10bbbb8c4efdb0c85279"},{"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/reactions-api.test.ts","mode":"100644","type":"blob","sha":"a0c90736cba925e9d38539cd17985fe6923ad2b2","size":2408,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/a0c90736cba925e9d38539cd17985fe6923ad2b2"},{"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":"tests/web/social-panel.test.ts","mode":"100644","type":"blob","sha":"5bb8a25597d6971099ebb894d5538e76e9d95ad2","size":1363,"url":"https://api.github.com/repos/sharpninja/wordpairs/git/blobs/5bb8a25597d6971099ebb894d5538e76e9d95ad2"},{"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":"7df395c3fb181784bb41d76f90eb481de5efa6ac","tree":"97b9711e8cd5949ff33feab4bce3a3c279ae0f9f","parents":["d956b2df2463c7c3a5ecf76e103c6ac8e96c9325"],"truncated":false,"localCount":208,"remoteCount":208,"equal":true}}}