26 Commits

Author SHA1 Message Date
clement b80744d231 feat(game): warning scene auto-calls Zacus
Repo State / repo-state (pull_request) Failing after 46s
Validate Zacus refactor / validate (pull_request) Failing after 6m6s
Validate Zacus refactor / validate (push) Failing after 6m4s
Repo State / repo-state (push) Failing after 12m16s
Enable call_on_scene SCENE_WARNING -> 0142738200: Professeur Zacus
rings the PLIP when the scenario reaches the warning scene.
2026-06-18 15:02:51 +02:00
clement 37eab47f63 feat(voice): scenario-driven incoming calls
Repo State / repo-state (pull_request) Failing after 1m5s
Repo State / repo-state (push) Failing after 55s
Validate Zacus refactor / validate (pull_request) Failing after 6m20s
Validate Zacus refactor / validate (push) Failing after 13m3s
The phone now rings on cue from the game with NO firmware change. A
call_on_scene map (phone_directory.yaml: {SCENE_X: number}) tells the
gateway which scenes are scripted incoming calls; since the runtime
already pushes the scene to /game/step, the gateway auto-rings the PLIP
with that NPC on scene entry (deduped, once per entry). Factored a
_ring_board helper (shared by /game/call + auto-ring). Map ships empty
(no surprise rings) with commented examples for the designer.
2026-06-18 14:57:08 +02:00
clemsail 3066e63b24 feat(gateway): phone directory loader (numéro → persona/voix) 2026-06-14 22:21:27 +02:00
clemsail 56c44eaf4f feat(atelier): board field on morse/nfc/coffre/led/radio puzzles + tests + complete blocks scenario
Repo State / repo-state (pull_request) Failing after 37s
Repo State / repo-state (push) Failing after 27s
Validate Zacus refactor / validate (pull_request) Failing after 5m49s
2026-06-14 17:08:22 +02:00
clement b76f2d3c98 fix(scenario): zacus_v3 valide — act/objective/firmware_step sur les 3 puzzles
Repo State / repo-state (push) Failing after 12m35s
Validate Zacus refactor / validate (push) Successful in 17m26s
Les puzzles de zacus_v3.yaml n'avaient ni `act`, ni `objective`, ni
`firmware_step` (requis par le validateur schema V2). Ajout calqué sur
zacus_v2 : Diapason→acte 1, Piano LEFOU→acte 2, QR Archives→acte 2 ;
valeurs déduites du contenu existant (scène, runtime_steps, solution).
Le scénario valide, compile et simule désormais le playthrough complet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 13:07:45 +02:00
Claude Worker claude2 a481f130d6 fix(scenario): straight quotes in zacus_v3
Les guillemets typographiques servaient de pseudo-délimiteurs YAML :
les valeurs chargées contenaient littéralement “…” (endpoints LLM/TTS,
names des puzzles) et la séquence du piano valait [“L”,“E”,…] au lieu
de [L,E,F,O,U]. Conversion “”→", ‘’→', …→... ; tirets et « » français
conservés. Parse vérifié avant/après (yaml.safe_load).
2026-06-11 03:37:08 +02:00
L'électron rare 966ff731bd feat(voice-bridge): STT post-correction aliases
Server-side fuzzy alias table applied to the final STT transcript
before forwarding to /voice/intent. Closes the metier-vocabulary
gap of generic STT models (U-SON, LA 440 Hz, Zacus, ...) without
needing per-request prompt biasing — which moshi-server's Rust
runtime does not expose anyway.

Loader is soft on pyyaml (degrades to no-op if missing) and on
the yaml file itself (logs + skips on parse error). Patterns are
case-insensitive with auto word-boundaries, with a (?...) escape
hatch for advanced regex.

Per-puzzle entries layer on top of globals — firmware passes
puzzle_id in the hello frame; legacy clients omit it and get
just the global polish. Loaded once at module import; restart
voice-bridge to reload.

Unit tested on 5 representative transcripts (eu son nez -> U-SON,
diapazon -> diapason, le rasus -> Zacus, le la 440 hertz -> LA 440 Hz).
2026-05-24 01:27:47 +02:00
L'électron rare 61ca35670f feat(hints): adaptive level (group + stuck-timer)
Adds slice D_P4 of the hints engine: an adaptive level *floor* derived
from the group profile (TECH / NON_TECH / MIXED / BOTH), the elapsed
stuck-time, and the per-puzzle failed-attempt counter. The floor is
combined at the call site as
  level_served = max(level_requested, count + 1, level_floor_adaptive)
and clamped to NPC_MAX_HINT_LEVEL.

Configuration lives in game/scenarios/hints_adaptive.yaml (override
via HINTS_ADAPTIVE_PATH). When the file is absent, adaptive mode is
silently disabled (warning logged) so the engine keeps running with
the existing P3 logic.

Adds two firmware-driven endpoints:
- POST /hints/puzzle_start    seeds puzzle_started_at_ms (idempotent,
                              with optional force=true to restart)
- POST /hints/attempt_failed  bumps failed_attempts_for_puzzle, 404s
                              on unknown puzzle_id

/hints/ask gains an optional group_profile field and now reports
level_floor_adaptive, stuck_minutes, failed_attempts and
group_profile_used in every response (refusal envelope included).
Auto-trigger on stuck-timer remains firmware-side (slice D_P6) — this
slice does not poll, only serves higher levels when asked.

Tests: 35 / 35 green (26 P1+P2+P3 unchanged + 9 new). Backward
compatible by construction: when group_profile is omitted MIXED is
used and at t=0 the floor is 0, so the existing P3 decision stands.
2026-05-03 21:25:00 +02:00
L'électron rare 1ed230ebd0 feat(hints): add LLM rewrite via LiteLLM hints-deep 2026-05-03 19:02:37 +02:00
L'électron rare 7a6e2d0e89 feat(playtest): scaffold harness + 1st playtest
Phase P1 of the playtest harness design spec:
* tools/playtest/run_playtest.py — replays a playtest YAML
  against the Runtime 3 IR and compares to (or updates) a
  snapshot JSON
* game/scenarios/playtests/zacus_v3_60min_tech.playtest.yaml
  — first canonical playtest, resolves PUZZLE_LA_440 via the
  UNLOCK_LA_440 unlock event
* game/scenarios/playtests/snapshots/
  zacus_v3_60min_tech.snapshot.json — committed reference
* Makefile: new "playtest" target wiring the runner via uv

Critical-asserts evaluator and TS runner are out of P1 scope.
2026-05-03 17:17:52 +02:00
L'électron rare 9f4501b9b9 feat: Zacus V3 complete
Phase 1: zacus_v3_complete.yaml, constants, phrases
Phase 3: ESP-NOW framework, 4 puzzle firmwares, master
Phase 4: NPC V3 profiling + game coordinator
Phase 5: XTTS-v2 Docker + voice clone generator
Phase 6: AudioCraft + BLE audio control
Phase 9: One-pager, video script, pricing, guide
2026-04-03 00:42:34 +02:00
L'électron rare d838a34e73 feat: scenario v3 with NPC/phone/fallback
Add zacus_v3.yaml extending v2 with new top-level sections:
- npc_config: LLM/STT/TTS endpoints, scene timeboxes
- telephone: Audio Kit ESP32 integration config
- fallback: SD card offline mode with manifest
- puzzles: enriched with typed solutions, 3-level hints, NPC hooks

Runtime 3 compiler validates successfully (ignores new keys).
2026-04-02 09:34:23 +02:00
L'électron rare db54b8fb12 feat: NPC conversation + puzzle + endings
Add three new phrase categories to npc_phrases:
- conversation: greeting, off_topic, encouragement
- puzzle_specific: la_detector, lefou_piano, qr
- endings: fast, normal, slow, no/many hints
2026-04-02 09:30:35 +02:00
L'électron rare f4634f1dbe feat: NPC phrases, TTS generator, tests
- npc_phrases.yaml: full phrase bank (hints, personality,
  adaptation, bridges, false leads, ambiance) in French
- generate_npc_pool.py: batch TTS generator (Piper API)
- test_npc_engine.py: 21 unit tests for trigger logic
- test_npc_phrases_schema.py: YAML schema validation (12 tests)
- Fix FAST_PROGRESS guard: use absolute time limit to prevent
  false positives after several minutes on a scene

Impact: Sprint 3 NPC data layer complete. 33 tests passing.
2026-04-02 09:15:01 +02:00
L'électron rare 20aed903ba feat: AI integration — voice pipeline, hints engine, MCP server, analytics, security
- Voice pipeline: ESP32 WebSocket client → voice bridge → LLM → Piper TTS (Tower :8001)
- Hints engine: 3 puzzles (LA_440, LEFOU_PIANO, QR_FINALE), anti-cheat, 3 hint levels
- MCP hardware server: 6 tools (puzzle, audio, LED, camera, scenario, status), stdio transport
- Analytics: ESP32 module + 6 web endpoints + Dashboard UI with chat interface
- Security: auth middleware (Bearer NVS), rate limiting, input validation on 30 endpoints
- Frontend: code-split (1.1MB → 210KB initial), ErrorBoundary, API timeout, WS reconnect
- Tests: 24 Python + 38 TypeScript + 18 MCP = 80 project tests (+ 19 mascarade)
- Specs: AI_INTEGRATION_SPEC, MCP_HARDWARE_SERVER_SPEC, QA_TEST_MATRIX_SPEC
- Docs: SECURITY, DEPLOYMENT_RUNBOOK, voice pipeline guide, AI architecture map
- 6 AI agent definitions (.github/agents/ai_*.md)
- TUI orchestration script (tools/dev/zacus_tui.py)
- Docker compose TTS for Tower + KXKM-AI
- CHANGELOG, README, mkdocs.yml updated
- Cycle detection (DFS) in runtime3 validator
- Sprint plan: plans/SPRINT_AI_INTEGRATION.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 13:52:45 +01:00
Clément SAILLANT e2bdd8b66c Add SceneGyrophare effect implementation
- Introduced SceneGyrophareConfig structure for configuration parameters.
- Implemented SceneGyrophare class with methods for creating, destroying, and updating the gyrophare effect.
- Added rendering functions for background, beams, and warning triangle.
- Integrated timer for animation updates based on frame rate.
- Created a log file for ESP32 audio kit boot information.
2026-03-01 11:41:15 +01:00
Clément SAILLANT 0aee3ca834 Hotline ringback + Freenove U_SON playlist and LEFOU sequence 2026-02-28 06:31:59 +01:00
Clément SAILLANT 520f98d2b9 freenove: publish current story/ui source of truth 2026-02-27 14:48:29 +01:00
Clément SAILLANT 0e7774a062 feat: Nettoyage des écrans inutilisés et mise à jour des références dans les scénarios 2026-02-26 11:58:27 +01:00
Clément SAILLANT feed1695c6 feat: Clean up unused screens and improve storage management
- Removed 9 unused screen JSON files: SCENE_BROKEN, SCENE_CAMERA_SCAN, SCENE_FIREWORKS, SCENE_LA_DETECT, SCENE_MEDIA_ARCHIVE, SCENE_SIGNAL_SPIKE, SCENE_WIN, SCENE_WINNER, SCENE_WIN_ETAPE.
- Updated AGENT_TODO.md to reflect the cleanup actions and results.
- Enhanced StorageManager to handle SD card access failures with a failure streak mechanism, switching to LittleFS after repeated failures.
- Added support for aliasing long action IDs to short filenames in the generator.
- Improved scenario manager to handle different key names for action IDs in YAML files.
2026-02-25 20:37:51 +01:00
Clément SAILLANT 3ac0b7d997 Refactor scene JSON configurations and enhance user logging capabilities
- Updated multiple scene JSON files to improve visual themes, effects, and transitions.
- Changed effect speeds and added missing timeline objects for better scene management.
- Enhanced SCENE_LA_DETECTOR, SCENE_LEFOU_DETECTOR, SCENE_MEDIA_MANAGER, SCENE_QR_DETECTOR, SCENE_WARNING, SCENE_WIN_ETAPE1, and SCENE_WIN_ETAPE2 with refined titles, subtitles, and symbols.
- Introduced a new user live logger script to capture serial logs during real user playtests for better debugging and analysis.
- Added a workbench export/import tool to streamline scene editing and synchronization with JSON files.
- Improved FX verificator documentation to clarify usage modes and verification processes.
2026-02-25 19:41:20 +01:00
Clément SAILLANT 229c381c3e docs: importer zacus_conversation_bundle_v3 et clôturer le blocage ZIP intake (#106)
* docs: import zacus conversation bundle v3 and close ZIP intake TODO

* tools: add reproducible validator installer and document next gates

* docs: remove ZIP terminology and align intake docs to conversation bundle

* tools: add runtime bundle validator and update docs workflow

* feat: promote gameplay scenario and enforce G3 bundle checks in CI

* docs: add deep repo analysis and next-step TODOs

* Initial plan (#107)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-02-25 18:17:46 +01:00
Clément SAILLANT cdbbed3fd0 Add QR Unlock App implementation and schema
- Implemented QrUnlockApp class with methods for lifecycle management (begin, start, update, stop, handleEvent) and snapshot retrieval.
- Created header file for QrUnlockApp with necessary method declarations and private members.
- Added Yamale schema for scenario template to define prompt input and optional firmware snapshot.
2026-02-25 17:21:24 +01:00
Clément SAILLANT d4ccd49b3f freenove: scope QR media flow to espnow and fix boot action asset 2026-02-25 17:21:23 +01:00
Clément SAILLANT 8cccd8c3a9 freenove: add QR final flow and media-manager boot mode 2026-02-25 17:21:23 +01:00
Clément SAILLANT 2915984946 feat: zacus v1 (scenario, kit MJ, printables/audio pipeline, docs, licenses) 2026-02-14 00:07:29 +01:00