# 120 — Lessons, constraints, and risk record

## Lessons from the design discussion

| Lesson | Consequence for implementation |
|---|---|
| Standa wants the existing work selection | Reuse current callers and Subject; do not design a new film/season/episode picker |
| This is canonical plot recall, not a creative adventure | Wrong answers cost lives but never branch the story |
| Narrator, not presenter | Reuse surfaces/voice infrastructure, not Millionaire persona/feedback prompts |
| Every game is newly generated; no content memory | Fresh one-shot request per attempt; no pack cache/history or anti-repeat storage |
| Story and Millionaire share a launch card | Central mode selection; no duplicate buttons/popups at every source |
| Demo is fixed and text-only | Production engine with authored Matrix packs and silent voice; no hidden API fallback |
| Code quality is a primary requirement | Explicit ownership, small composition seams, no controller/generator/client cloning |
| Standa sees questions reliably in final chat | Ask there and wait for an actual reply; a tool response is not consent |

## Known baseline traps and mitigations

1. **Architecture documents can be ahead of implementation.** Classic/legacy classes and the large controller still exist. Recheck code before each shared change; do not implement against a fictional completed refactor.
2. **Shared shell reaches into Millionaire internals.** Introduce the small adapter-owned screen/retirement boundary; do not scatter Story branches across money/lifeline methods.
3. **Episode type is often `series`/`tv`.** Preserve episode fields and selected scope through every entry; test routing and prompts explicitly.
4. **Subject URLs lose some fields today.** Fix necessary round-trip fields narrowly; avoid a second metadata enrichment/cache layer.
5. **Player lives and used lifelines are different.** Use dedicated Story properties and counters. Never reinterpret Millionaire's `LivesUsed`.
6. **Wrong answers still reveal and traverse a scene.** Progress derives from answered count; correct count is a separate statistic.
7. **Third error on the last scene is still defeat.** Terminal precedence must be tested directly.
8. **Whole-pack generation changes latency location.** One visible preparation wait, then local play; no fake progress estimate, partial pack, automatic repair loop, or per-scene paid feedback.
9. **Demos need source identity, not title matching.** Preserve explicit offline context; missing Story fixtures never fall back to AI.
10. **Generated XML has one authoring source.** Reuse/extract existing components; no Story generator copy or hand edits of output.
11. **Option wrapping can change meaning.** Use bounded content and measured fit; never trim away the decisive action to make a tile fit.
12. **Late background workers can update a new attempt.** Retire/invalidate generation and voice work, and test close/retry/switch races with delayed stubs.
13. **Global TTS helpers can outlive the scene.** Stop/invalidate outdated game speech without making Continue wait and without stopping the video beneath the modal.
14. **The dev probe persists content by default.** Do not accidentally introduce an AI pack archive under the label “harness”; use authored traces and bounded metadata unless diagnostic capture is explicitly requested.
15. **Live checkout is already dirty.** Review only this task's diff and never reset unrelated work; coordinate overlapping shared files.

## Risks and honest limits

| Risk | Planned handling | What remains unproven |
|---|---|---|
| AI invents or confuses canonical facts | Exact scope, reliable event instructions, unavailable form, no outside trivia, manual review of requested AI tests | Knowledge-only generation cannot guarantee factual truth |
| Whole series does not fit 10–20 questions | Summarize its principal arc/endpoints; keep fixed counts and selected scope | Exhaustive episode detail is not promised |
| Ongoing/new/obscure work | Use known endpoint or unavailable; never invent future closure | Knowledge cutoff and actual model knowledge remain limits |
| Five equal chapter groups distort pacing | Choose events across the whole work; validate authored coverage; test narrative continuity | Structural chapter counts cannot prove good storytelling |
| Correct answer leaks semantically | Prompt discipline, exact leak checks where safe, fixture/content review | Semantic leakage is not fully decided by regex |
| Provider truncation/malformed JSON | Validate complete pack; explicit Retry/Back; no lost life | One successful demo does not validate every provider |
| New selector changes title-card geometry | Minimal shared-grid change, long-title/focus captures | Pixel correctness requires authorized Kodi evidence |
| Shared extraction breaks Millionaire | Preserve defaults, selected regressions, unchanged gameplay comparisons | Old plan/test labels are not current pass evidence |
| In-flight cancelled request still charged | Invalidate results and prevent overlapping retries without intent | Existing transport may not support physical cancellation |

## What not to do when stuck

Do not solve a schema failure by accepting partial stories, guessing correct=A, inventing missing events, silently lowering difficulty, searching online, making extra paid calls, switching providers, or adding permanent response storage. Surface the existing error/retry flow.

Do not solve a UI issue by copying the dialog, shrinking all fonts, hiding decisive option text, disabling navigation, or modifying baseline frames. Fix the responsible shared/component/story layer narrowly.

## Implementation learning log

The original planning phase had no implementation incidents. Actual findings from the subsequent authorized implementation follow; retain the distinction between planning risks and observed failures.

```text
Date / phase:
Trigger and reproduction:
Expected versus observed:
Confirmed cause (or explicitly still suspected):
Minimal fix and files:
Evidence after fix:
General lesson for the next agent:
Remaining risk / follow-up:
```

### 2026-10-12/13 — Native inputs and actual difficulty

- Trigger: request Hard in the live harness, then start. Title briefly showed 20; played pack had 10.
- Cause: asynchronously closing the settings overlay raced another settings click. The original native click mapping also targeted hidden Millionaire controls for Story intents.
- Fix: resolve controls by current mode/screen, synchronously issue native Back, wait until `settings_open` is false, and assert the actual prepared count. Restore the previous difficulty in the runner's cleanup.
- Evidence: the erroneous run is explicitly INVALID; final Hard played all 20 and lost on the third error at question 20.
- Lesson: a settings chip/screenshot cannot prove which pack was played. Assert behavioral state and keep invalid evidence visible.

### 2026-10-12/13 — Text fit and animation settlement

- Trigger: a 37-character option wrapped beyond the existing answer tile; paired result cards were crowded; rules prose wrapped to a clipped fourth line. Capturing immediately after property settlement also recorded unfinished screen animations.
- Fix: one authoritative option maximum of 30, meaningful shortened authored options, existing `font27` only in the narrow result pair, compact three-line rules prose, and 0.7 s capture settlement in the existing live runner. Do not truncate answer meaning or shrink all gameplay fonts.
- Evidence: final Hard question/result 16 and terminal 20 are fully readable; compact rules are recaptured separately after the last wording edit.
- Lesson: limits and prose must follow actual fonts/card widths; state settlement and visual settlement are different.

### 2026-10-13 — Addon translation cache

- Trigger: source contained new ID 35444 and shorter 35435, but live Kodi returned an empty caption and old rules text. `ReloadSkin()` did not update addon strings.
- Cause: Kodi 21.3 caches addon translations separately. Its same-language `SetLanguage()` is a no-op. Checked the official 21.3 `Application.cpp` / `LangInfo.cpp` implementations.
- Fix during testing: close the demo, switch UI language to installed English, restore the exact original Czech locale, then verify the labels. Starting Kodi afresh also loads the current strings. No addon version hack or persistent language change.
- Lesson: distinguish stale runtime resources from incorrect source; record actual loaded strings before changing geometry again.

### 2026-10-13 — Native closure and voice ownership

- Trigger: a native `doModal()` return can bypass custom `close()`. Delayed TTS can otherwise begin after a scene/mode change or stop the video under the game.
- Fix: one modal `_dispose_adapter()` used by close, title/mode changes and `doModal()` finally; idempotent retirement releases pack before stopping owned voice. Shared voice serial/owner/path guards reject stale audio and stop only its own current media.
- Evidence: native return/cancel/replay and two mocked ownership cases pass; no real voice call needed for these lifecycle properties.
- Lesson: window closure and asynchronous ownership must be explicit, without duplicating the engine or voice transport.

### 2026-10-13 — Baseline tests and dirty checkout

- Trigger: combined test discovery contaminated fake Kodi modules; broad PO uniqueness and menu tests exposed existing unrelated failures.
- Fix: run isolated focused scripts, check new translation IDs specifically, and verify menu failures with the original launch block in memory. Preserve unrelated edits and baseline assets.
- Lesson: a red check must be attributed before changing production behavior. Do not conceal it, count it as a Story failure, or broaden scope to make every old test green.

### 2026-10-13 — Shared captions and comparable visual evidence

- Final settings capture showed the inherited “Game and moderator” heading in Story. Changed only that mode's group caption to its existing localized Story label; Millionaire retains its heading. Regenerated the single XML and passed 28 modern checks.
- A much older recorded Millionaire frame differed from the current rendering. The whole question group was unchanged against the saved pre-Story XML, so re-rendered both XML versions in the same current Kodi/runtime with the same properties/focus. The card comparison was 100% identical, with mean/max difference 0.
- Lesson: sharing components includes reviewing their captions. Compare like-for-like runtime evidence, preserve older goldens, and do not classify an unexplained old-frame mismatch as a successful pixel check.

### 2026-10-13 — Real-model validation and reasoning

- Baseline Matrix low/medium packs failed structural validation in all four cases. Explicit chapter positions, shorter option targets and canonical-answer generation followed by local shuffle improved playability; schema success still concealed serious plot/chronology errors.
- High reasoning consumed the output ceiling before final JSON: Sonnet at 16K and Luna max / Sonnet xhigh at 32K produced no usable game. Thinking and visible text share the output budget. Timeout without returned usage has unknown charge, not zero.
- An English outline followed by a separate Czech pack preserved wrong facts and overlong options. Rejected the experiment; production remains one inference with no automatic repair or saved content.
- More elaborate instructions were not monotonically better. A compact setup/reveal prompt reduced observed high-effort latency/cost, but errors such as Oracle vase/cookie order, an invented doctor and multiple true escape options remained. Repeated samples are essential; one good-looking 20-scene pack did not establish reliability.
- Keep automatic schema/local-play and manual factual verdicts separate. A larger ceiling prevents some truncation; it is neither a promise of completion nor a truth check. Do not introduce Matrix-specific facts into the generic production prompt or silently ground plots online.

### 2026-10-13 — Authored catalog and episode scope

- Expanding a demo source requires removing both its Matrix-only loader gate and modal eligibility gate. Reuse the original catalog, source and subject boundaries; one Story-only episode overlay prevents the Millionaire selector/metadata from changing.
- First strict validation found four repeated question phrasings across five packs. Fix the authored wording and regenerate the fixed fixtures once; do not weaken the shared validator or add automatic repair.
- A valid JSON pack can still reveal its own answer or use implausible/cross-work alternatives. Review setups, the actual event, false choices and ending separately. Preserve ambiguous endings (Inception/Titanic), movie-only boundaries and presentation-order flashbacks (Pulp Fiction/Chernobyl).
- Aired episodes and draft scripts can differ. The aired Big Bang Theory pilot presents boards before the couch and Sheldon eventually sits elsewhere; Stranger Things presents Benny's help before the bicycle discovery. Fix the authored event order rather than converting the entire work to fictional chronological order. Read-only editorial references are documented in `140`; they add no runtime search feature.
- Deterministic data must remain static during play. All three difficulty selections span opening to final event; fixed answer positions vary across letters but require no runtime shuffle. Missing/incomplete sources stay offline limitations, and explicit caller episode/season scope is never overwritten.
- Run the cheap all-pack modal/rules checks with socket/AI/TTS calls forbidden, then the affected original Millionaire checks. Preserve hashes of the accepted Matrix packs and original Millionaire JSON. Source-note text reuses existing geometry; no fresh GUI or visual-proof claim was made for this expansion.

### 2026-10-13 — Movie collections and narrative order

- Full-film collection expansion is fixed data work: extend the original catalog and reuse its stable ordering, assets, moderator, sources and dialog. Preserve an already accepted first movie rather than regenerating it for consistency.
- A plot summary may group simultaneous threads differently from their presentation in the film. Harry Potter's Slughorn/vow and Riddle/keeper sequences required checking actual aired order; valid JSON and a winning game cannot prove chronology.
- Adaptation differences are concrete acceptance constraints: movie Neville supplies gillyweed/finds the room, movie Goyle casts Fiendfyre, and movie Harry breaks the Elder Wand. Part 1 and Part 2 have distinct endings even though they adapt one book.
- Generic welcome plus rules can scroll for longer movie titles even when authored question/narrator fields fit. Retain the harness's text-fit warning and established autoscroll behavior; do not change shared templates, canonical title identity or geometry merely to turn the report green. No pixel-fit claim is justified without an authorized GUI check.
