Målret FupOgFakta/WPP gameplay-flowet, så det følger den klassiske bluff/guess/reveal-rytme tættere, men med egen formulering, egen struktur og egen identitet.
Mål
Spillet skal i praksis føles som dette overordnede forløb:
prompt/spørgsmål vises
hver spiller indsender et falsk svar
korrekt svar + falske svar blandes
alle gætter på det rigtige svar
reveal af hvem der narrede hvem + korrekt svar
point/scoreboard opdateres
næste runde / finale / afslutning
Vigtigt
Ingen copy/paste af navne, mode-navne eller branded formuleringer fra eksterne spil.
Brug kun dette som strukturel inspiration til pacing og round loop.
Omskriv det til FupOgFakta/WPP-domænet.
Produktretning
Det vigtigste er ikke 1:1 feature-paritet, men at WPP's kerneforløb bliver tydeligt og sammenhængende:
lobby → runde start
spørgsmål vises
indsend fup-svar
gæt
reveal
score
næste runde
afslutning/finale
Konkret leverance
Afklar og dokumentér:
canonical round flow for host + player
hvilke faser der findes i API/state model
hvilke host-actions og player-actions der hører til hver fase
hvilke reveal/score steps der er obligatoriske
hvad der er MVP vs senere polish
Acceptance
Ét tydeligt issue-/design-output i Gitea beskriver det canonical WPP/FupOgFakta round loop.
Flowet kan bruges direkte af architect/dev som source-of-truth.
Det er tydeligt, hvor nuværende implementation matcher/mangler.
Ingen direkte overtagelse af brand/navne/tekst fra inspirationskilden.
Foreslået opdeling
Architect: oversæt dette til WPP canonical round-flow/spec
Dev: align state model / API / frontend flow med denne spec
Review: check at implementation følger canonical flow
Målret FupOgFakta/WPP gameplay-flowet, så det følger den klassiske bluff/guess/reveal-rytme tættere, men med egen formulering, egen struktur og egen identitet.
## Mål
Spillet skal i praksis føles som dette overordnede forløb:
1. prompt/spørgsmål vises
2. hver spiller indsender et falsk svar
3. korrekt svar + falske svar blandes
4. alle gætter på det rigtige svar
5. reveal af hvem der narrede hvem + korrekt svar
6. point/scoreboard opdateres
7. næste runde / finale / afslutning
## Vigtigt
- Ingen copy/paste af navne, mode-navne eller branded formuleringer fra eksterne spil.
- Brug kun dette som strukturel inspiration til pacing og round loop.
- Omskriv det til FupOgFakta/WPP-domænet.
## Produktretning
Det vigtigste er ikke 1:1 feature-paritet, men at WPP's kerneforløb bliver tydeligt og sammenhængende:
- lobby → runde start
- spørgsmål vises
- indsend fup-svar
- gæt
- reveal
- score
- næste runde
- afslutning/finale
## Konkret leverance
Afklar og dokumentér:
- canonical round flow for host + player
- hvilke faser der findes i API/state model
- hvilke host-actions og player-actions der hører til hver fase
- hvilke reveal/score steps der er obligatoriske
- hvad der er MVP vs senere polish
## Acceptance
- Ét tydeligt issue-/design-output i Gitea beskriver det canonical WPP/FupOgFakta round loop.
- Flowet kan bruges direkte af architect/dev som source-of-truth.
- Det er tydeligt, hvor nuværende implementation matcher/mangler.
- Ingen direkte overtagelse af brand/navne/tekst fra inspirationskilden.
## Foreslået opdeling
- Architect: oversæt dette til WPP canonical round-flow/spec
- Dev: align state model / API / frontend flow med denne spec
- Review: check at implementation følger canonical flow
Relateret:
- #16 EPIC: Fase 3 gameplay scope board
- #17 Scope Guardrail: MVP beslutninger
Behandl #287 som en epic for gameplay-målretningen.
Brug den som parent/source-of-truth for nye under-issues, der konkretiserer canonical FupOgFakta/WPP round flow.
Opret gerne flere mindre, merge-/implementerbare issues under denne epic for state model, host flow, player flow, reveal/score, finale/afslutning og evt. MVP-vs-polish-opdeling.
PO-præcisering:
- Behandl **#287 som en epic** for gameplay-målretningen.
- Brug den som parent/source-of-truth for nye under-issues, der konkretiserer canonical FupOgFakta/WPP round flow.
- Opret gerne flere mindre, merge-/implementerbare issues under denne epic for state model, host flow, player flow, reveal/score, finale/afslutning og evt. MVP-vs-polish-opdeling.
eksplicit host-transition fra reveal til scoreboard
reveal-payload med korrekt svar, løgne, guesses og fooled-relations
scoreboard som egen status/fase
host/player UI følger samme faseorden
tests bruger samme canonical model
Senere polish
auto-advance baseret på timer i stedet for host-knap
mere detaljeret host-oversigt over hvem der mangler at svare
animationer/stepvis reveal af hvert bluff
richer finale-flow med flere runder/summary
reconnect/resume UX med mere granular fasevisning
Kort gap-analyse mod nuværende implementation
Det der allerede matcher godt
backend har kerneentiteterne: RoundConfig, RoundQuestion, LieAnswer, Guess, ScoreEvent
grundflowet lobby -> lie -> guess -> reveal findes allerede
mix_answers() flytter fra lie til guess
calculate_scores() beregner både korrekte gæt og bluff-point og flytter til reveal
start_next_round() og finish_game() findes allerede
De vigtigste gaps
Ingen canonical scoreboard-status i backend
Frontend phase-machine bruger scoreboard, men GameSession.Status gør ikke.
Reveal-payload er utilstrækkelig session_detail giver prompt og evt. mixed answers, men ikke canonical reveal-data om korrekt svar, løgne og hvem der narrede hvem.
reveal_scoreboard er et sidekald, ikke en faseovergang
Scoreboard findes som GET-endpoint i reveal, men ikke som selvstændig state med egen host-gating.
Host-flowet er teknisk men ikke canonical
Handlinger er API-tekniske (show question, mix answers, calculate scores) i stedet for tydeligt knyttet til canonical faseansvar og obligatoriske output.
Frontend/backend phase drift er allerede synlig i tests frontend/src/spa/gameplay-phase-machine.ts kender scoreboard; backend session.status gør ikke. Det bør stoppes nu, ikke senere.
Det er den mindste model, der bevarer bluff/guess/reveal-rytmen tydeligt uden at gøre MVP for tung.
READY dev-opgaver oprettet
#288 — Canonical session state model: explicit scoreboard phase after reveal
#289 — Canonical reveal payload for round question incl. who-fooled-whom
ARCHI-output for #287 — canonical WPP/FupOgFakta round-flow spec
## Problem
Nuværende gameplay har de rigtige byggesten, men round loopet er stadig semantisk uklart som canonical WPP-flow:
- backend modellerer primært `lobby -> lie -> guess -> reveal -> finished`
- frontend phase-machine forventer samtidig en særskilt `scoreboard`-fase
- reveal og score ligger i praksis delvist sammenblandet via `calculate_scores` + `reveal_scoreboard`
- host-flowet er stadig knopstyret (`start round`, `show question`, `mix answers`, `calculate scores`) fremfor tydeligt fase-drevet
Det gør det sværere at bruge state/API som fælles source-of-truth for host, player og SPA-sync.
## Expected value
En canonical round-flow-spec skal give:
- én fælles faseforståelse for backend, frontend og test
- tydelig host/player-adfærd pr. fase
- obligatoriske reveal/score steps, så bluff/guess/reveal-rytmen opleves korrekt
- mindre risiko for phase drift mellem API-status, UI-routes og test-forventninger
- bedre grundlag for små dev-opgaver, hvor implementering kan ske uden at genopfinde flowet
## Why now
Issue #287 er markeret need-to-have og epic. Repoet har allerede en del gameplay-API, men mismatch er synlig nu:
- backend har **ingen** persisted `scoreboard`-status, mens frontend allerede tester for den
- `session_detail` eksponerer kun blandede svar, ikke reveal-data om hvem der narrede hvem
- scoreboard bliver i dag mere et sidekald end en tydelig obligatorisk fase
Hvis flowet ikke canonicaliseres nu, vil host/player-SPA og videre gameplay-arbejde sandsynligvis cementere forskellige sandheder.
## Canonical MVP round loop
Canonical WPP-rounden skal være:
1. **Lobby / round setup**
2. **Prompt shown / lie submission**
3. **Guessing**
4. **Reveal**
5. **Scoreboard**
6. **Next round eller finale**
Det skal opleves som én fast rytme for alle runder.
---
## Canonical state/API-faser
### 0. `lobby`
Formål:
- session eksisterer
- spillere joiner
- host vælger at starte næste runde
Tilladt host-action:
- `start_round(category_slug)`
Tilladt player-action:
- `join_session(code, nickname)`
Udgangsbetingelse:
- host starter runden
Resultat:
- round config for `current_round` oprettes
- session går til `lie`
### 1. `lie`
Formål:
- spørgsmålet vises
- hver spiller indsender ét fup-svar
Tilladt host-actions:
- `show_question()` hvis round question ikke findes endnu
- `lock_lies / mix_answers()` når host vil afslutte lie-vinduet
Tilladt player-actions:
- `submit_lie(round_question_id, text)` præcis én gang pr. spiller
Obligatorisk state-data:
- aktiv `round_question`
- prompt
- lie deadline / vindue
- submissions-status pr. spiller er ønskelig for host, men ikke påkrævet til player-MVP
Udgangsbetingelse:
- host låser løgne og systemet bygger answer-pool
Resultat:
- korrekte + falske svar deduplikeres og blandes
- session går til `guess`
### 2. `guess`
Formål:
- alle spillere gætter på det rigtige svar blandt mixed answers
Tilladt host-action:
- `lock_guesses / calculate_scores()` når guess-vinduet er slut
Tilladt player-action:
- `submit_guess(round_question_id, selected_text)` præcis én gang pr. spiller
Obligatorisk state-data:
- mixed answers
- guess deadline / vindue
Udgangsbetingelse:
- host låser gæt og systemet beregner reveal-grundlag + score-delta
Resultat:
- guess-resultater og bluff-relationer fastfryses
- score-events oprettes
- session går til `reveal`
### 3. `reveal`
Formål:
- vise rundens sandhed før scoreboard tager over
Tilladt host-action:
- `advance_to_scoreboard()` / equivalent explicit transition
Tilladt player-action:
- ingen mutation; kun se reveal
**Obligatoriske reveal-steps i MVP:**
1. korrekt svar vises
2. hvert falsk svar vises med ophavs-spiller
3. for hvert guess skal det være muligt at afgøre “hvem blev narret af hvem”
4. reveal skal være bundet til den konkrete `round_question`
Obligatorisk output-model:
- `correct_answer`
- liste over lies med `player_id/nickname + text`
- liste over guesses med mindst `player_id/nickname + selected_text + is_correct + fooled_player_id`
Udgangsbetingelse:
- host går videre efter reveal er vist
Resultat:
- session går til `scoreboard`
### 4. `scoreboard`
Formål:
- vise aggregeret stilling efter revealen
Tilladt host-actions:
- `start_next_round()`
- `finish_game()`
Tilladt player-action:
- ingen mutation; kun se scoreboard/finale-status
**Obligatoriske scoreboard-steps i MVP:**
1. leaderboard efter score-beregning vises
2. scoreboard skal være en eksplicit fase, ikke kun et GET-sidekald
3. host må først her vælge næste runde eller afslutte spillet
Udgangsbetingelse:
- host starter næste runde eller afslutter spillet
Resultat:
- enten `lobby` med `current_round + 1`
- eller `finished`
### 5. `finished`
Formål:
- spillet er afsluttet
- finale/winner kan vises
Tilladt host/player-action:
- read-only visning
---
## Host-actions pr. fase
- `lobby`: start round
- `lie`: show question, derefter lock lies / mix answers
- `guess`: lock guesses / calculate scores
- `reveal`: fortsæt til scoreboard
- `scoreboard`: start næste runde eller afslut spil
- `finished`: ingen gameplay-mutation
## Player-actions pr. fase
- `lobby`: join
- `lie`: submit lie
- `guess`: submit guess
- `reveal`: se korrekt svar + hvem der narrede hvem
- `scoreboard`: se stilling
- `finished`: se slutresultat
---
## Reveal/score: obligatorisk separation
Canonical WPP skal skelne mellem **reveal** og **scoreboard**.
### Reveal er ikke det samme som scoreboard
Reveal svarer på:
- hvad var det korrekte svar?
- hvilke fup-svar blev indsendt?
- hvem narrede hvem?
Scoreboard svarer på:
- hvad er den samlede stilling efter denne runde?
- vil host starte næste runde eller afslutte?
### MVP-beslutning
MVP må gerne beregne score **inden** reveal vises, men den samlede stilling må først præsenteres i `scoreboard`-fasen.
Det betyder:
- `calculate_scores()` må gerne skabe score-events som del af overgangen `guess -> reveal`
- men API/state skal stadig have en **eksplicit** overgang `reveal -> scoreboard`
- `session.status` skal derfor kunne bære begge faser
---
## MVP vs senere polish
### MVP (need-to-have)
- canonical persisted faser: `lobby`, `lie`, `guess`, `reveal`, `scoreboard`, `finished`
- eksplicit host-transition fra `reveal` til `scoreboard`
- reveal-payload med korrekt svar, løgne, guesses og fooled-relations
- scoreboard som egen status/fase
- host/player UI følger samme faseorden
- tests bruger samme canonical model
### Senere polish
- auto-advance baseret på timer i stedet for host-knap
- mere detaljeret host-oversigt over hvem der mangler at svare
- animationer/stepvis reveal af hvert bluff
- richer finale-flow med flere runder/summary
- reconnect/resume UX med mere granular fasevisning
---
## Kort gap-analyse mod nuværende implementation
### Det der allerede matcher godt
- backend har kerneentiteterne: `RoundConfig`, `RoundQuestion`, `LieAnswer`, `Guess`, `ScoreEvent`
- grundflowet `lobby -> lie -> guess -> reveal` findes allerede
- `mix_answers()` flytter fra lie til guess
- `calculate_scores()` beregner både korrekte gæt og bluff-point og flytter til reveal
- `start_next_round()` og `finish_game()` findes allerede
### De vigtigste gaps
1. **Ingen canonical `scoreboard`-status i backend**
Frontend phase-machine bruger `scoreboard`, men `GameSession.Status` gør ikke.
2. **Reveal-payload er utilstrækkelig**
`session_detail` giver prompt og evt. mixed answers, men ikke canonical reveal-data om korrekt svar, løgne og hvem der narrede hvem.
3. **`reveal_scoreboard` er et sidekald, ikke en faseovergang**
Scoreboard findes som GET-endpoint i `reveal`, men ikke som selvstændig state med egen host-gating.
4. **Host-flowet er teknisk men ikke canonical**
Handlinger er API-tekniske (`show question`, `mix answers`, `calculate scores`) i stedet for tydeligt knyttet til canonical faseansvar og obligatoriske output.
5. **Frontend/backend phase drift er allerede synlig i tests**
`frontend/src/spa/gameplay-phase-machine.ts` kender `scoreboard`; backend `session.status` gør ikke. Det bør stoppes nu, ikke senere.
---
## Arkitekturbeslutning / source-of-truth
Jeg anbefaler, at WPP canonicaliseres som:
- persisted session statuses: `lobby | lie | guess | reveal | scoreboard | finished`
- `guess -> reveal` = lock guesses + beregn score-events + fastfrys reveal-data
- `reveal -> scoreboard` = eksplicit host-transition
- `scoreboard -> lobby` = næste runde
- `scoreboard -> finished` = afslut spil
Det er den mindste model, der bevarer bluff/guess/reveal-rytmen tydeligt uden at gøre MVP for tung.
## READY dev-opgaver oprettet
- #288 — Canonical session state model: explicit scoreboard phase after reveal
- #289 — Canonical reveal payload for round question incl. who-fooled-whom
Bemærkning: der var ingen tidligere smoke-artifacts i staging før denne kørsel, så testen blev kørt som første smoke efter den observerede deploy.
Staging smoke-status (2026-03-15 22:17 UTC)
- Ny staging deploy observeret via app-promovering: 2026-03-15 19:16:39 UTC
- /healthz: OK
- `infra/staging/smoke_suite.sh`: PASS
- Smoke flow gennemført (`manage.py smoke_staging`), session: `5TV9CF`
Bemærkning: der var ingen tidligere smoke-artifacts i staging før denne kørsel, så testen blev kørt som første smoke efter den observerede deploy.
Det vigtige er, at "round" betyder bluff/guess/reveal/scoreboard-loopet. Lobby er kun pre-round setup. Scoreboard er post-round recap. Reveal + score er ikke valgfri host-knapper; det er en obligatorisk del af loopet.
Canonical phase model
0. LOBBY / ROUND SETUP
Formål: få spillere ind, vælge kategori/konfiguration, og starte næste spørgsmål.
Host actions
Opret session.
Se/joinede spillere.
Vælg kategori for næste spørgsmål/runde.
Tryk Start round.
Fra senere scoreboard: vælg Next round eller Finish game.
Player actions
Join session med kode + nickname.
Ellers read-only/waiting.
Server invariants
Min/max player gate håndhæves server-side.
Når host starter runden, skal systemet vælge/spærre det konkrete spørgsmål og straks gøre BLUFF-fasen aktiv.
Spørgsmålet skal være kendt i server-state, ikke kræve separat host-step for at blive “vist”.
Canonical exit condition
Host starter runden -> session går til BLUFF med aktivt spørgsmål.
1. BLUFF
Formål: alle spillere indsender præcis én løgn til det aktive spørgsmål.
Host actions
Se prompt + submit-progress.
Ingen obligatorisk “show question”- eller “mix answers”-handling i canonical flow.
Optional polish/dev-control: force lock / skip timer kan findes senere, men er ikke del af normal MVP-flow.
Player actions
Se prompt.
Indsend præcis én løgn inden deadline.
Efter submit: read-only/venter.
Server invariants
Deadline håndhæves server-side.
Én løgn pr. spiller.
Input låses når deadline udløber (eller alle har submitted, hvis vi vil tillade early close i polish).
Ved phase-exit skal svarlisten gøres klar som: correct answer + gyldige løgne, dedupet/canonicalized.
Canonical exit condition
BLUFF låses -> session går til GUESS.
2. GUESS
Formål: alle spillere vælger ét svar fra den blandede svarliste.
Host actions
Se mixed answers / guess-progress.
Ingen obligatorisk manuel “calculate scores”-handling i canonical flow.
Player actions
Vælg præcis ét svar.
Kan ikke ændre valg efter lock (MVP).
Server invariants
Deadline håndhæves server-side.
Ét gæt pr. spiller.
Ved phase-exit er alle guesses låst, og serveren har det komplette grundlag for reveal/scoring.
Canonical exit condition
GUESS låses -> session går til REVEAL.
3. REVEAL (mandatory)
Formål: vise udfaldet af runden i fast rækkefølge og gøre score-ændringer forklarlige.
Dette er en obligatorisk canonical del af loopet. Ingen runde må hoppe direkte fra GUESS til SCOREBOARD uden reveal.
Minimum mandatory reveal/score steps (MVP)
Reveal lies that fooled someone
Vis hvilke løgne der trak guesses.
Vis hvem der skrev dem / hvem der blev narret.
Tildel bluff-point til løgner(e).
Reveal truth
Vis korrekt svar.
Vis hvem der gættede rigtigt.
Tildel correct-guess points.
Freeze round result
Når reveal er færdig, er rundens score færdigberegnet og klar til scoreboard.
Host actions
Read-only præsentation af reveal.
Ingen særskilt “calculate score” som produktkrav.
Ingen særskilt “load scoreboard” som produktkrav.
Player actions
Read-only reveal.
Server invariants
Reveal er server-authoritative.
Scoring sker som del af reveal-resolution, ikke som uafhængig UI-manuel handling.
Resultatet skal være deterministisk og reproducerbart fra round data.
Canonical exit condition
Reveal færdig -> session går til SCOREBOARD.
MVP note
MVP må gerne sende reveal som ét samlet payload/UI-trin, så længe ovenstående tre semantiske steps stadig er opfyldt og ikke kan springes over.
Polish note
Senere kan reveal splittes op i REVEAL_LIE_n + REVEAL_TRUTH med timers/animationer.
4. SCOREBOARD
Formål: vise den opdaterede leaderboard efter den afsluttede round.
Host actions
Se leaderboard.
Vælg Next round eller Finish game.
Player actions
Se leaderboard.
Server invariants
Scoreboard er et obligatorisk resultat af reveal-completion.
Scoreboard må ikke kræve en separat “load scoreboard” semantics for at eksistere; det er en state, ikke en debug-fetch.
Canonical exit conditions
Next round -> nyt spørgsmål/runde starter tilbage i BLUFF (ikke tilbage til en diffus mellemtilstand i samme runde-loop).
Finish game -> FINISHED.
5. FINISHED
Formål: vise endelig leaderboard/winner og afslutte sessionen.
Host actions
Read-only slutresultat / evt. ny session.
Player actions
Se slutresultat.
Canonical action ownership by phase
Phase
Host
Player
Server-mandatory
Lobby
create/start/next/finish
join
validate player bounds + lock active question on start
Bluff
monitor only
submit one lie
lock lie window + prepare mixed answers
Guess
monitor only
submit one guess
lock guess window
Reveal
read-only
read-only
reveal lies -> reveal truth -> finalize score
Scoreboard
next/finish
read-only
expose sorted leaderboard
Finished
read-only
read-only
expose final result
Det centrale designvalg her er: host driver kun round boundaries, ikke interne bluff/guess/reveal/score transitions.
Ét host-initieret Start round for at gå fra lobby/setup til aktiv BLUFF med valgt spørgsmål.
BLUFF og GUESS er spiller-inputfaser.
REVEAL er obligatorisk og score-afsluttende.
SCOREBOARD er obligatorisk efter reveal.
Next round og Finish game er de eneste post-scoreboard host-valg.
Server-side phase gates/timers/state er source-of-truth.
Polish / senere iteration
Separate subphases REVEAL_LIE_1..n og REVEAL_TRUTH.
Auto-advance med timers mellem reveal og scoreboard.
Force-advance / pause / resume host controls.
Reactions/awards/animationer.
Early-close når alle har indsendt før deadline.
Gap analysis vs current implementation
Kort version: nuværende kode er tæt på den rigtige grovform, men den er stadig host-step/manual-control-orienteret i stedet for canonical round-loop-orienteret.
1. show_question er en ekstra host-gate som ikke bør være canonical
Nu: start_round() sætter status til lie, men spørgsmålet oprettes først i separat show_question().
Problem: round-start og question-activation er splittet i to host-handlinger.
Canonical: Start round skal aktivere BLUFF med et konkret spørgsmål i samme flow.
2. mix_answers er stadig en host-manuel overgang
Nu: host kalder mix_answers() for at gå fra lie til guess.
Problem: bluff->guess er defineret som host-knap i stedet for round-invariant.
Canonical: BLUFF lukkes server-side, derefter starter GUESS som obligatorisk næste fase.
3. calculate_scores er stadig en host-manuel overgang
Nu: host kalder calculate_scores() for at gå fra guess til reveal.
Problem: scoring/reveal er et manuelt admin-step, ikke en obligatorisk del af round resolution.
Canonical: når GUESS låses, skal reveal+score ske som server-authoritative resolution.
4. reveal_scoreboard gør scoreboard til en fetch/host-step i stedet for state
Nu: scoreboard promoveres først når host kalder GET /scoreboard.
Problem: scoreboard findes ikke som naturlig konsekvens af reveal-completion; host skal “hente” den frem.
Canonical: scoreboard er næste state efter reveal, ikke en separat operational handling.
5. Current status machine afspejler ikke hele den ønskede source-of-truth
Nu: modellerne har lobby/lie/guess/reveal/scoreboard/finished, hvilket er brugbart, men semantics er stadig manuelle.
Positivt: de eksisterende states kan genbruges til MVP.
Mangler: source-of-truth for hvem der må trigge transitions, og hvilke transitions der er obligatoriske vs optional debug/dev controls.
6. Host/player UI bærer stadig developer-control-panel spor
Nu: host shell viser show question, mix answers, calculate scores, load scoreboard som primære handlinger.
7. MVP docs og runtime implementation er ikke helt aligned om round semantics
docs/F0_MVP_FUP_OG_FAKTA.md siger i praksis “system vælger/spørgsmål -> spillere lyver -> system mixer -> spillere gætter -> scoreboard”.
docs/UI_SMOKE.md og nuværende kode beskriver derimod et mere manuelt host-koreograferet flow.
#287 bør låse den product-facing canonical version, så dev/review ikke skal gætte fremadrettet.
8. Constraint drift: spillerantal matcher ikke docs
F0-doc siger 3-12 spillere.
_build_phase_view_model() håndhæver aktuelt min=3, max=5 i UI surface.
Det er ikke selve #287’s round-flow-beslutning, men det er en tydelig drift som bør enten rettes eller eksplcitt accepteres i en follow-up.
Concrete outcome for downstream dev/review
Når nogen efterfølgende bygger/reviewer mod #287, bør de bruge denne testbare regel:
En canonical round starter når host starter næste spørgsmål fra lobby/setup, fortsætter gennem bluff -> guess -> mandatory reveal -> scoreboard, og kun hostens boundary-valg er start/next/finish. Mid-round resolution er server-authoritative og må ikke kræve manuelle host-trin som produktkrav.
Suggested dev lanes (max 2)
Lane A — Backend/server phase ownership
Scope
Flyt canonical ownership af transitions fra host-manual endpoints til server-side round lifecycle.
Acceptance
Start round aktiverer konkret spørgsmål + BLUFF uden separat show_question-krav.
BLUFF -> GUESS kræver ikke host mix_answers som canonical path.
GUESS -> REVEAL -> SCOREBOARD kræver ikke host calculate_scores / load_scoreboard som canonical path.
Session/state payload dokumenterer tydeligt current phase og scoreboard/readiness.
Regression-tests dækker canonical loop fra start til scoreboard.
Required artifact
Commit på issue-bunden branch + PR der refererer #287.
Remote head SHA i PR.
Kort artifact i PR/issue med state-transition matrix eller flow-log.
Lane B — Host/player UX alignment to canonical flow
Scope
Fjern developer-panel semantics fra host/player shells og align UI til canonical phase ownership.
Acceptance
Host primær actionsurface = Start round, Next round, Finish game.
Mid-round host-skærm er progress/read-only, ikke operatørpanel for show/mix/calculate/load.
Player UI matcher canonical BLUFF/GUESS/REVEAL/SCOREBOARD flow.
Tests opdateres så de låser canonical host/player action-surface.
Required artifact
Commit på issue-bunden branch + PR der refererer #287.
Remote head SHA i PR.
Test artifact: relevante frontend spec-navne + PASS-output i PR-beskrivelse eller issue-kommentar.
Hvis vi vil holde WIP lav, vil jeg anbefale at tage Lane A først, fordi den låser source-of-truth i server-state og gør efterfølgende UI-review langt mindre tvetydig.
Proposed canonical source-of-truth for #287 after local code review (`lobby/views.py`, `fupogfakta/models.py`, SPA host/player shells, gameplay-phase-machine, MVP docs).
## Decision
Vi bør låse **ét** canonical round flow for Fup og Fakta/WPP:
`LOBBY -> BLUFF -> GUESS -> REVEAL -> SCOREBOARD -> (NEXT_ROUND -> BLUFF) | FINISHED`
Det vigtige er, at **"round" betyder bluff/guess/reveal/scoreboard-loopet**. Lobby er kun pre-round setup. Scoreboard er post-round recap. Reveal + score er ikke valgfri host-knapper; det er en obligatorisk del af loopet.
---
## Canonical phase model
### 0. LOBBY / ROUND SETUP
**Formål:** få spillere ind, vælge kategori/konfiguration, og starte næste spørgsmål.
**Host actions**
- Opret session.
- Se/joinede spillere.
- Vælg kategori for næste spørgsmål/runde.
- Tryk **Start round**.
- Fra senere scoreboard: vælg **Next round** eller **Finish game**.
**Player actions**
- Join session med kode + nickname.
- Ellers read-only/waiting.
**Server invariants**
- Min/max player gate håndhæves server-side.
- Når host starter runden, skal systemet vælge/spærre det konkrete spørgsmål og straks gøre BLUFF-fasen aktiv.
- Spørgsmålet skal være kendt i server-state, ikke kræve separat host-step for at blive “vist”.
**Canonical exit condition**
- Host starter runden -> session går til `BLUFF` med aktivt spørgsmål.
---
### 1. BLUFF
**Formål:** alle spillere indsender præcis én løgn til det aktive spørgsmål.
**Host actions**
- Se prompt + submit-progress.
- Ingen obligatorisk “show question”- eller “mix answers”-handling i canonical flow.
- Optional polish/dev-control: force lock / skip timer kan findes senere, men er ikke del af normal MVP-flow.
**Player actions**
- Se prompt.
- Indsend præcis én løgn inden deadline.
- Efter submit: read-only/venter.
**Server invariants**
- Deadline håndhæves server-side.
- Én løgn pr. spiller.
- Input låses når deadline udløber (eller alle har submitted, hvis vi vil tillade early close i polish).
- Ved phase-exit skal svarlisten gøres klar som: `correct answer + gyldige løgne`, dedupet/canonicalized.
**Canonical exit condition**
- BLUFF låses -> session går til `GUESS`.
---
### 2. GUESS
**Formål:** alle spillere vælger ét svar fra den blandede svarliste.
**Host actions**
- Se mixed answers / guess-progress.
- Ingen obligatorisk manuel “calculate scores”-handling i canonical flow.
**Player actions**
- Vælg præcis ét svar.
- Kan ikke ændre valg efter lock (MVP).
**Server invariants**
- Deadline håndhæves server-side.
- Ét gæt pr. spiller.
- Ved phase-exit er alle guesses låst, og serveren har det komplette grundlag for reveal/scoring.
**Canonical exit condition**
- GUESS låses -> session går til `REVEAL`.
---
### 3. REVEAL (mandatory)
**Formål:** vise udfaldet af runden i fast rækkefølge og gøre score-ændringer forklarlige.
**Dette er en obligatorisk canonical del af loopet.** Ingen runde må hoppe direkte fra GUESS til SCOREBOARD uden reveal.
**Minimum mandatory reveal/score steps (MVP)**
1. **Reveal lies that fooled someone**
- Vis hvilke løgne der trak guesses.
- Vis hvem der skrev dem / hvem der blev narret.
- Tildel bluff-point til løgner(e).
2. **Reveal truth**
- Vis korrekt svar.
- Vis hvem der gættede rigtigt.
- Tildel correct-guess points.
3. **Freeze round result**
- Når reveal er færdig, er rundens score færdigberegnet og klar til scoreboard.
**Host actions**
- Read-only præsentation af reveal.
- Ingen særskilt “calculate score” som produktkrav.
- Ingen særskilt “load scoreboard” som produktkrav.
**Player actions**
- Read-only reveal.
**Server invariants**
- Reveal er server-authoritative.
- Scoring sker som del af reveal-resolution, ikke som uafhængig UI-manuel handling.
- Resultatet skal være deterministisk og reproducerbart fra round data.
**Canonical exit condition**
- Reveal færdig -> session går til `SCOREBOARD`.
**MVP note**
- MVP må gerne sende reveal som ét samlet payload/UI-trin, **så længe** ovenstående tre semantiske steps stadig er opfyldt og ikke kan springes over.
**Polish note**
- Senere kan reveal splittes op i `REVEAL_LIE_n` + `REVEAL_TRUTH` med timers/animationer.
---
### 4. SCOREBOARD
**Formål:** vise den opdaterede leaderboard efter den afsluttede round.
**Host actions**
- Se leaderboard.
- Vælg **Next round** eller **Finish game**.
**Player actions**
- Se leaderboard.
**Server invariants**
- Scoreboard er et obligatorisk resultat af reveal-completion.
- Scoreboard må ikke kræve en separat “load scoreboard” semantics for at eksistere; det er en state, ikke en debug-fetch.
**Canonical exit conditions**
- `Next round` -> nyt spørgsmål/runde starter tilbage i `BLUFF` (ikke tilbage til en diffus mellemtilstand i samme runde-loop).
- `Finish game` -> `FINISHED`.
---
### 5. FINISHED
**Formål:** vise endelig leaderboard/winner og afslutte sessionen.
**Host actions**
- Read-only slutresultat / evt. ny session.
**Player actions**
- Se slutresultat.
---
## Canonical action ownership by phase
| Phase | Host | Player | Server-mandatory |
|---|---|---|---|
| Lobby | create/start/next/finish | join | validate player bounds + lock active question on start |
| Bluff | monitor only | submit one lie | lock lie window + prepare mixed answers |
| Guess | monitor only | submit one guess | lock guess window |
| Reveal | read-only | read-only | reveal lies -> reveal truth -> finalize score |
| Scoreboard | next/finish | read-only | expose sorted leaderboard |
| Finished | read-only | read-only | expose final result |
Det centrale designvalg her er: **host driver kun round boundaries, ikke interne bluff/guess/reveal/score transitions.**
---
## MVP vs polish
### MVP (need-to-have for #287)
- Fase-modellen ovenfor er canonical.
- Ét host-initieret `Start round` for at gå fra lobby/setup til aktiv BLUFF med valgt spørgsmål.
- BLUFF og GUESS er spiller-inputfaser.
- REVEAL er obligatorisk og score-afsluttende.
- SCOREBOARD er obligatorisk efter reveal.
- `Next round` og `Finish game` er de eneste post-scoreboard host-valg.
- Server-side phase gates/timers/state er source-of-truth.
### Polish / senere iteration
- Separate subphases `REVEAL_LIE_1..n` og `REVEAL_TRUTH`.
- Auto-advance med timers mellem reveal og scoreboard.
- Force-advance / pause / resume host controls.
- Reactions/awards/animationer.
- Early-close når alle har indsendt før deadline.
---
## Gap analysis vs current implementation
Kort version: nuværende kode er tæt på den rigtige grovform, men den er stadig **host-step/manual-control-orienteret** i stedet for **canonical round-loop-orienteret**.
### 1. `show_question` er en ekstra host-gate som ikke bør være canonical
- Nu: `start_round()` sætter status til `lie`, men spørgsmålet oprettes først i separat `show_question()`.
- Problem: round-start og question-activation er splittet i to host-handlinger.
- Canonical: `Start round` skal aktivere BLUFF med et konkret spørgsmål i samme flow.
### 2. `mix_answers` er stadig en host-manuel overgang
- Nu: host kalder `mix_answers()` for at gå fra `lie` til `guess`.
- Problem: bluff->guess er defineret som host-knap i stedet for round-invariant.
- Canonical: BLUFF lukkes server-side, derefter starter GUESS som obligatorisk næste fase.
### 3. `calculate_scores` er stadig en host-manuel overgang
- Nu: host kalder `calculate_scores()` for at gå fra `guess` til `reveal`.
- Problem: scoring/reveal er et manuelt admin-step, ikke en obligatorisk del af round resolution.
- Canonical: når GUESS låses, skal reveal+score ske som server-authoritative resolution.
### 4. `reveal_scoreboard` gør scoreboard til en fetch/host-step i stedet for state
- Nu: scoreboard promoveres først når host kalder `GET /scoreboard`.
- Problem: scoreboard findes ikke som naturlig konsekvens af reveal-completion; host skal “hente” den frem.
- Canonical: scoreboard er næste state efter reveal, ikke en separat operational handling.
### 5. Current status machine afspejler ikke hele den ønskede source-of-truth
- Nu: modellerne har `lobby/lie/guess/reveal/scoreboard/finished`, hvilket er brugbart, men semantics er stadig manuelle.
- Positivt: de eksisterende states kan genbruges til MVP.
- Mangler: source-of-truth for hvem der må trigge transitions, og hvilke transitions der er obligatoriske vs optional debug/dev controls.
### 6. Host/player UI bærer stadig developer-control-panel spor
- Nu: host shell viser `show question`, `mix answers`, `calculate scores`, `load scoreboard` som primære handlinger.
- Canonical: host UI bør afspejle boundary decisions (`start`, `next`, `finish`) + read-only progress i mellem-faserne.
### 7. MVP docs og runtime implementation er ikke helt aligned om round semantics
- `docs/F0_MVP_FUP_OG_FAKTA.md` siger i praksis “system vælger/spørgsmål -> spillere lyver -> system mixer -> spillere gætter -> scoreboard”.
- `docs/UI_SMOKE.md` og nuværende kode beskriver derimod et mere manuelt host-koreograferet flow.
- #287 bør låse den product-facing canonical version, så dev/review ikke skal gætte fremadrettet.
### 8. Constraint drift: spillerantal matcher ikke docs
- F0-doc siger `3-12 spillere`.
- `_build_phase_view_model()` håndhæver aktuelt `min=3`, `max=5` i UI surface.
- Det er ikke selve #287’s round-flow-beslutning, men det er en tydelig drift som bør enten rettes eller eksplcitt accepteres i en follow-up.
---
## Concrete outcome for downstream dev/review
Når nogen efterfølgende bygger/reviewer mod #287, bør de bruge denne testbare regel:
> En canonical round starter når host starter næste spørgsmål fra lobby/setup, fortsætter gennem bluff -> guess -> mandatory reveal -> scoreboard, og kun hostens boundary-valg er start/next/finish. Mid-round resolution er server-authoritative og må ikke kræve manuelle host-trin som produktkrav.
---
## Suggested dev lanes (max 2)
### Lane A — Backend/server phase ownership
**Scope**
Flyt canonical ownership af transitions fra host-manual endpoints til server-side round lifecycle.
**Acceptance**
- `Start round` aktiverer konkret spørgsmål + BLUFF uden separat `show_question`-krav.
- BLUFF -> GUESS kræver ikke host `mix_answers` som canonical path.
- GUESS -> REVEAL -> SCOREBOARD kræver ikke host `calculate_scores` / `load_scoreboard` som canonical path.
- Session/state payload dokumenterer tydeligt current phase og scoreboard/readiness.
- Regression-tests dækker canonical loop fra start til scoreboard.
**Required artifact**
- Commit på issue-bunden branch + PR der refererer `#287`.
- Remote head SHA i PR.
- Kort artifact i PR/issue med state-transition matrix eller flow-log.
### Lane B — Host/player UX alignment to canonical flow
**Scope**
Fjern developer-panel semantics fra host/player shells og align UI til canonical phase ownership.
**Acceptance**
- Host primær actionsurface = `Start round`, `Next round`, `Finish game`.
- Mid-round host-skærm er progress/read-only, ikke operatørpanel for `show/mix/calculate/load`.
- Player UI matcher canonical BLUFF/GUESS/REVEAL/SCOREBOARD flow.
- Tests opdateres så de låser canonical host/player action-surface.
**Required artifact**
- Commit på issue-bunden branch + PR der refererer `#287`.
- Remote head SHA i PR.
- Test artifact: relevante frontend spec-navne + PASS-output i PR-beskrivelse eller issue-kommentar.
Hvis vi vil holde WIP lav, vil jeg anbefale at tage **Lane A først**, fordi den låser source-of-truth i server-state og gør efterfølgende UI-review langt mindre tvetydig.
Architect status sync: the epic is no longer blocked on missing executable decomposition. Child tasks were created as #300/#301/#302; delivery has landed via merged PRs #305, #303, and #304. Remaining work on #287 should now be tracked as new follow-up child tasks only, not by reusing stale blocker issues.
Architect status sync: the epic is no longer blocked on missing executable decomposition. Child tasks were created as #300/#301/#302; delivery has landed via merged PRs #305, #303, and #304. Remaining work on #287 should now be tracked as new follow-up child tasks only, not by reusing stale blocker issues.
Architect status sync: created a new READY follow-up wave under #287 after the previous child tasks (#300/#301/#302) were exhausted. New executable work:
#308 [READY][Gameplay] #287-D Canonical phase contract parity between session-detail and phase transition responses
#309 [READY][Gameplay] #287-E Realtime phase-event contract for client refresh and route sync
#310 [READY][Gameplay] #287-F Host transition idempotency and error catalog for scoreboard -> next round / finish
Older stale blockers/governance artifacts (#290, #292, #293, #294, #307) were closed to reduce backlog noise and make the live queue reflect actual next work.
Architect status sync: created a new READY follow-up wave under #287 after the previous child tasks (#300/#301/#302) were exhausted. New executable work:
- #308 [READY][Gameplay] #287-D Canonical phase contract parity between session-detail and phase transition responses
- #309 [READY][Gameplay] #287-E Realtime phase-event contract for client refresh and route sync
- #310 [READY][Gameplay] #287-F Host transition idempotency and error catalog for scoreboard -> next round / finish
Older stale blockers/governance artifacts (#290, #292, #293, #294, #307) were closed to reduce backlog noise and make the live queue reflect actual next work.
Architecture safeguard: #311 is now an explicit companion issue to this gameplay epic. The canonical round flow work must not further entrench FupOgFakta-specific phase logic inside lobby/. New gameplay changes under #287 should preserve or improve the cartridge boundary, not deepen the drift.
Architecture safeguard: #311 is now an explicit companion issue to this gameplay epic. The canonical round flow work must not further entrench FupOgFakta-specific phase logic inside `lobby/`. New gameplay changes under #287 should preserve or improve the cartridge boundary, not deepen the drift.
Architect fast-progress wave added for immediate pickup:
#316 [READY][Gameplay] #287-G Extract canonical phase_view_model builder out of lobby.views hot path
#317 [READY][Gameplay] #287-H Add session-detail refresh contract tests for host/player route sync after phase events
#318 [READY][Architecture] #311-D Move one concrete FupOgFakta write endpoint out of lobby as the first cartridge slice
These are intentionally small, mergeable slices aimed at reducing coupling and speeding up current gameplay/architecture progress.
Architect fast-progress wave added for immediate pickup:
- #316 [READY][Gameplay] #287-G Extract canonical phase_view_model builder out of lobby.views hot path
- #317 [READY][Gameplay] #287-H Add session-detail refresh contract tests for host/player route sync after phase events
- #318 [READY][Architecture] #311-D Move one concrete FupOgFakta write endpoint out of lobby as the first cartridge slice
These are intentionally small, mergeable slices aimed at reducing coupling and speeding up current gameplay/architecture progress.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Målret FupOgFakta/WPP gameplay-flowet, så det følger den klassiske bluff/guess/reveal-rytme tættere, men med egen formulering, egen struktur og egen identitet.
Mål
Spillet skal i praksis føles som dette overordnede forløb:
Vigtigt
Produktretning
Det vigtigste er ikke 1:1 feature-paritet, men at WPP's kerneforløb bliver tydeligt og sammenhængende:
Konkret leverance
Afklar og dokumentér:
Acceptance
Foreslået opdeling
Relateret:
PO-præcisering:
ARCHI-output for #287 — canonical WPP/FupOgFakta round-flow spec
Problem
Nuværende gameplay har de rigtige byggesten, men round loopet er stadig semantisk uklart som canonical WPP-flow:
lobby -> lie -> guess -> reveal -> finishedscoreboard-fasecalculate_scores+reveal_scoreboardstart round,show question,mix answers,calculate scores) fremfor tydeligt fase-drevetDet gør det sværere at bruge state/API som fælles source-of-truth for host, player og SPA-sync.
Expected value
En canonical round-flow-spec skal give:
Why now
Issue #287 er markeret need-to-have og epic. Repoet har allerede en del gameplay-API, men mismatch er synlig nu:
scoreboard-status, mens frontend allerede tester for densession_detaileksponerer kun blandede svar, ikke reveal-data om hvem der narrede hvemHvis flowet ikke canonicaliseres nu, vil host/player-SPA og videre gameplay-arbejde sandsynligvis cementere forskellige sandheder.
Canonical MVP round loop
Canonical WPP-rounden skal være:
Det skal opleves som én fast rytme for alle runder.
Canonical state/API-faser
0.
lobbyFormål:
Tilladt host-action:
start_round(category_slug)Tilladt player-action:
join_session(code, nickname)Udgangsbetingelse:
Resultat:
current_roundopretteslie1.
lieFormål:
Tilladt host-actions:
show_question()hvis round question ikke findes endnulock_lies / mix_answers()når host vil afslutte lie-vinduetTilladt player-actions:
submit_lie(round_question_id, text)præcis én gang pr. spillerObligatorisk state-data:
round_questionUdgangsbetingelse:
Resultat:
guess2.
guessFormål:
Tilladt host-action:
lock_guesses / calculate_scores()når guess-vinduet er slutTilladt player-action:
submit_guess(round_question_id, selected_text)præcis én gang pr. spillerObligatorisk state-data:
Udgangsbetingelse:
Resultat:
reveal3.
revealFormål:
Tilladt host-action:
advance_to_scoreboard()/ equivalent explicit transitionTilladt player-action:
Obligatoriske reveal-steps i MVP:
round_questionObligatorisk output-model:
correct_answerplayer_id/nickname + textplayer_id/nickname + selected_text + is_correct + fooled_player_idUdgangsbetingelse:
Resultat:
scoreboard4.
scoreboardFormål:
Tilladt host-actions:
start_next_round()finish_game()Tilladt player-action:
Obligatoriske scoreboard-steps i MVP:
Udgangsbetingelse:
Resultat:
lobbymedcurrent_round + 1finished5.
finishedFormål:
Tilladt host/player-action:
Host-actions pr. fase
lobby: start roundlie: show question, derefter lock lies / mix answersguess: lock guesses / calculate scoresreveal: fortsæt til scoreboardscoreboard: start næste runde eller afslut spilfinished: ingen gameplay-mutationPlayer-actions pr. fase
lobby: joinlie: submit lieguess: submit guessreveal: se korrekt svar + hvem der narrede hvemscoreboard: se stillingfinished: se slutresultatReveal/score: obligatorisk separation
Canonical WPP skal skelne mellem reveal og scoreboard.
Reveal er ikke det samme som scoreboard
Reveal svarer på:
Scoreboard svarer på:
MVP-beslutning
MVP må gerne beregne score inden reveal vises, men den samlede stilling må først præsenteres i
scoreboard-fasen.Det betyder:
calculate_scores()må gerne skabe score-events som del af overgangenguess -> revealreveal -> scoreboardsession.statusskal derfor kunne bære begge faserMVP vs senere polish
MVP (need-to-have)
lobby,lie,guess,reveal,scoreboard,finishedrevealtilscoreboardSenere polish
Kort gap-analyse mod nuværende implementation
Det der allerede matcher godt
RoundConfig,RoundQuestion,LieAnswer,Guess,ScoreEventlobby -> lie -> guess -> revealfindes alleredemix_answers()flytter fra lie til guesscalculate_scores()beregner både korrekte gæt og bluff-point og flytter til revealstart_next_round()ogfinish_game()findes alleredeDe vigtigste gaps
Ingen canonical
scoreboard-status i backendFrontend phase-machine bruger
scoreboard, menGameSession.Statusgør ikke.Reveal-payload er utilstrækkelig
session_detailgiver prompt og evt. mixed answers, men ikke canonical reveal-data om korrekt svar, løgne og hvem der narrede hvem.reveal_scoreboarder et sidekald, ikke en faseovergangScoreboard findes som GET-endpoint i
reveal, men ikke som selvstændig state med egen host-gating.Host-flowet er teknisk men ikke canonical
Handlinger er API-tekniske (
show question,mix answers,calculate scores) i stedet for tydeligt knyttet til canonical faseansvar og obligatoriske output.Frontend/backend phase drift er allerede synlig i tests
frontend/src/spa/gameplay-phase-machine.tskenderscoreboard; backendsession.statusgør ikke. Det bør stoppes nu, ikke senere.Arkitekturbeslutning / source-of-truth
Jeg anbefaler, at WPP canonicaliseres som:
lobby | lie | guess | reveal | scoreboard | finishedguess -> reveal= lock guesses + beregn score-events + fastfrys reveal-datareveal -> scoreboard= eksplicit host-transitionscoreboard -> lobby= næste rundescoreboard -> finished= afslut spilDet er den mindste model, der bevarer bluff/guess/reveal-rytmen tydeligt uden at gøre MVP for tung.
READY dev-opgaver oprettet
Staging smoke-status (2026-03-15 22:17 UTC)
infra/staging/smoke_suite.sh: PASSmanage.py smoke_staging), session:5TV9CFBemærkning: der var ingen tidligere smoke-artifacts i staging før denne kørsel, så testen blev kørt som første smoke efter den observerede deploy.
Proposed canonical source-of-truth for #287 after local code review (
lobby/views.py,fupogfakta/models.py, SPA host/player shells, gameplay-phase-machine, MVP docs).Decision
Vi bør låse ét canonical round flow for Fup og Fakta/WPP:
LOBBY -> BLUFF -> GUESS -> REVEAL -> SCOREBOARD -> (NEXT_ROUND -> BLUFF) | FINISHEDDet vigtige er, at "round" betyder bluff/guess/reveal/scoreboard-loopet. Lobby er kun pre-round setup. Scoreboard er post-round recap. Reveal + score er ikke valgfri host-knapper; det er en obligatorisk del af loopet.
Canonical phase model
0. LOBBY / ROUND SETUP
Formål: få spillere ind, vælge kategori/konfiguration, og starte næste spørgsmål.
Host actions
Player actions
Server invariants
Canonical exit condition
BLUFFmed aktivt spørgsmål.1. BLUFF
Formål: alle spillere indsender præcis én løgn til det aktive spørgsmål.
Host actions
Player actions
Server invariants
correct answer + gyldige løgne, dedupet/canonicalized.Canonical exit condition
GUESS.2. GUESS
Formål: alle spillere vælger ét svar fra den blandede svarliste.
Host actions
Player actions
Server invariants
Canonical exit condition
REVEAL.3. REVEAL (mandatory)
Formål: vise udfaldet af runden i fast rækkefølge og gøre score-ændringer forklarlige.
Dette er en obligatorisk canonical del af loopet. Ingen runde må hoppe direkte fra GUESS til SCOREBOARD uden reveal.
Minimum mandatory reveal/score steps (MVP)
Host actions
Player actions
Server invariants
Canonical exit condition
SCOREBOARD.MVP note
Polish note
REVEAL_LIE_n+REVEAL_TRUTHmed timers/animationer.4. SCOREBOARD
Formål: vise den opdaterede leaderboard efter den afsluttede round.
Host actions
Player actions
Server invariants
Canonical exit conditions
Next round-> nyt spørgsmål/runde starter tilbage iBLUFF(ikke tilbage til en diffus mellemtilstand i samme runde-loop).Finish game->FINISHED.5. FINISHED
Formål: vise endelig leaderboard/winner og afslutte sessionen.
Host actions
Player actions
Canonical action ownership by phase
Det centrale designvalg her er: host driver kun round boundaries, ikke interne bluff/guess/reveal/score transitions.
MVP vs polish
MVP (need-to-have for #287)
Start roundfor at gå fra lobby/setup til aktiv BLUFF med valgt spørgsmål.Next roundogFinish gameer de eneste post-scoreboard host-valg.Polish / senere iteration
REVEAL_LIE_1..nogREVEAL_TRUTH.Gap analysis vs current implementation
Kort version: nuværende kode er tæt på den rigtige grovform, men den er stadig host-step/manual-control-orienteret i stedet for canonical round-loop-orienteret.
1.
show_questioner en ekstra host-gate som ikke bør være canonicalstart_round()sætter status tillie, men spørgsmålet oprettes først i separatshow_question().Start roundskal aktivere BLUFF med et konkret spørgsmål i samme flow.2.
mix_answerser stadig en host-manuel overgangmix_answers()for at gå fralietilguess.3.
calculate_scoreser stadig en host-manuel overgangcalculate_scores()for at gå fraguesstilreveal.4.
reveal_scoreboardgør scoreboard til en fetch/host-step i stedet for stateGET /scoreboard.5. Current status machine afspejler ikke hele den ønskede source-of-truth
lobby/lie/guess/reveal/scoreboard/finished, hvilket er brugbart, men semantics er stadig manuelle.6. Host/player UI bærer stadig developer-control-panel spor
show question,mix answers,calculate scores,load scoreboardsom primære handlinger.start,next,finish) + read-only progress i mellem-faserne.7. MVP docs og runtime implementation er ikke helt aligned om round semantics
docs/F0_MVP_FUP_OG_FAKTA.mdsiger i praksis “system vælger/spørgsmål -> spillere lyver -> system mixer -> spillere gætter -> scoreboard”.docs/UI_SMOKE.mdog nuværende kode beskriver derimod et mere manuelt host-koreograferet flow.8. Constraint drift: spillerantal matcher ikke docs
3-12 spillere._build_phase_view_model()håndhæver aktueltmin=3,max=5i UI surface.Concrete outcome for downstream dev/review
Når nogen efterfølgende bygger/reviewer mod #287, bør de bruge denne testbare regel:
Suggested dev lanes (max 2)
Lane A — Backend/server phase ownership
Scope
Flyt canonical ownership af transitions fra host-manual endpoints til server-side round lifecycle.
Acceptance
Start roundaktiverer konkret spørgsmål + BLUFF uden separatshow_question-krav.mix_answerssom canonical path.calculate_scores/load_scoreboardsom canonical path.Required artifact
#287.Lane B — Host/player UX alignment to canonical flow
Scope
Fjern developer-panel semantics fra host/player shells og align UI til canonical phase ownership.
Acceptance
Start round,Next round,Finish game.show/mix/calculate/load.Required artifact
#287.Hvis vi vil holde WIP lav, vil jeg anbefale at tage Lane A først, fordi den låser source-of-truth i server-state og gør efterfølgende UI-review langt mindre tvetydig.
Architect status sync: the epic is no longer blocked on missing executable decomposition. Child tasks were created as #300/#301/#302; delivery has landed via merged PRs #305, #303, and #304. Remaining work on #287 should now be tracked as new follow-up child tasks only, not by reusing stale blocker issues.
Architect status sync: created a new READY follow-up wave under #287 after the previous child tasks (#300/#301/#302) were exhausted. New executable work:
Older stale blockers/governance artifacts (#290, #292, #293, #294, #307) were closed to reduce backlog noise and make the live queue reflect actual next work.
Architecture safeguard: #311 is now an explicit companion issue to this gameplay epic. The canonical round flow work must not further entrench FupOgFakta-specific phase logic inside
lobby/. New gameplay changes under #287 should preserve or improve the cartridge boundary, not deepen the drift.Architect fast-progress wave added for immediate pickup:
These are intentionally small, mergeable slices aimed at reducing coupling and speeding up current gameplay/architecture progress.