docs: importer zacus_conversation_bundle_v3 et clôturer le blocage ZIP intake #106

Merged
electron-rare merged 8 commits from codex/analyser-zip-pour-creer-une-pr into main 2026-02-25 17:17:46 +00:00
13 changed files with 1216 additions and 0 deletions
Showing only changes of commit f9289258e8 - Show all commits
+17
View File
@@ -0,0 +1,17 @@
# Architecture d'intégration ZIP — implémentation minimale (G1)
## Entrée / sortie
- **Entrée**: bundle conversationnel `scenario-ai-coherence/zacus_conversation_bundle_v3/*`.
- **Sortie**: ajout des fichiers dans ce sous-dossier + commit atomique + evidence.
## Interface d'intégration
- Source de vérité gameplay inchangée: `game/scenarios/*.yaml`.
- Bundle stocké comme matériau de travail IA/scénario, isolé dans `scenario-ai-coherence/`.
- Aucun couplage runtime ajouté dans ce lot.
## Budget / impact
- Impact code exécutable: nul (docs/data only).
- Impact CI: validateurs scénario/audio/printables exécutés pour non-régression.
## Statut Gates
- G1 Arch Freeze : **satisfait** pour ce lot d'import documentaire/data.
@@ -0,0 +1,6 @@
# Artifact PM/Spec — ZIP imported
- Date: 2026-02-25
- Source: https://github.com/electron-rare/le-mystere-professeur-zacus/tree/main/scenario-ai-coherence/zacus_conversation_bundle_v3
- Action: import du bundle local dans `scenario-ai-coherence/zacus_conversation_bundle_v3/`.
- Scope: data/docs only, sans impact firmware/runtime.
@@ -0,0 +1,5 @@
# Artifact PM/Spec — ZIP intake
- Date: 2026-02-25
- Statut: Bloqué, ZIP non fourni
- Action: TODO specs + TODO architecture ajoutés pour débloquer la prochaine itération.
+27
View File
@@ -0,0 +1,27 @@
{
"date": "2026-02-25",
"agent": "pm-spec",
"changes": [
"specs/ZIP_PR_INTAKE_TODO.md",
"architecture/ZIP_PR_ARCH_TODO.md",
"scenario-ai-coherence/zacus_conversation_bundle_v3/CODEX_PROMPT.md",
"scenario-ai-coherence/zacus_conversation_bundle_v3/CONVERSATION_SUMMARY.md",
"scenario-ai-coherence/zacus_conversation_bundle_v3/README.md",
"scenario-ai-coherence/zacus_conversation_bundle_v3/fsm_mermaid.md",
"scenario-ai-coherence/zacus_conversation_bundle_v3/scenario_canonical.yaml",
"scenario-ai-coherence/zacus_conversation_bundle_v3/scenario_promptable_template.yaml",
"scenario-ai-coherence/zacus_conversation_bundle_v3/scenario_runtime.json",
"scenario-ai-coherence/zacus_conversation_bundle_v3/zacus_v2.yaml"
],
"artifacts": [
"artifacts/pm-spec/2026-02-25/zip-intake-note.md",
"artifacts/pm-spec/2026-02-25/zip-intake-imported.md"
],
"gates": {
"G0": "satisfied",
"G1": "satisfied",
"G2": "docs_data_only",
"G3": "validated"
},
"note": "Bundle fourni et importé sans transformation; validateurs projet exécutés en non-régression."
}
@@ -0,0 +1,52 @@
# Codex Prompt — Zacus Scenario Bundle (Firmware + Narrative)
chatgpt-codex-connector[bot] commented 2026-02-25 16:26:53 +00:00 (Migrated from github.com)
Review

P1 Badge Point integration targets at actual firmware paths

These target paths omit the hardware/firmware/ prefix used by this repository layout, so following the prompt from repo root will modify/create the wrong files and leave the real firmware scenario untouched. I checked the existing targets and they live at hardware/firmware/docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml and hardware/firmware/data/story/scenarios/DEFAULT.json, which means the current instructions are not reproducible as written.

Useful? React with 👍 / 👎.

**<sub><sub>![P1 Badge](https://img.shields.io/badge/P1-orange?style=flat)</sub></sub> Point integration targets at actual firmware paths** These target paths omit the `hardware/firmware/` prefix used by this repository layout, so following the prompt from repo root will modify/create the wrong files and leave the real firmware scenario untouched. I checked the existing targets and they live at `hardware/firmware/docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml` and `hardware/firmware/data/story/scenarios/DEFAULT.json`, which means the current instructions are not reproducible as written. Useful? React with 👍 / 👎.
You are acting as an embedded firmware engineer working on the Freenove ESP32-S3 Zacus firmware.
Goal: integrate/update the scenario files so the story runtime matches the canonical scenario and remains stable.
## Bundle contents
- scenario_promptable_template.yaml (human editable input)
- scenario_canonical.yaml (canonical, to be copied into docs/protocols/... target)
- scenario_runtime.json (runtime, to be copied into data/story/scenarios/DEFAULT.json)
- fsm_mermaid.md (visual FSM)
- zacus_v2.yaml (narrative scenario aligned with runtime)
## Repo targets to update
- docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml
- data/story/scenarios/DEFAULT.json
## Narrative anchors (do not break)
- Prototype: U-SON
- Acte 1: LA 440 Hz (STEP_LA_DETECTOR)
- Acte 2: Zone 4 piano-alphabet → jouer "LEFOU" (letters placed randomly; A on LA 440 Hz)
- QR final: payload "WIN", hidden behind the portrait in the Archives
- After QR success: Media Hub + persistent boot into media_manager (persist_after_validation=true)
## Required work (must do)
1) Replace/update the target YAML file with `scenario_canonical.yaml`.
2) Replace/update `data/story/scenarios/DEFAULT.json` with `scenario_runtime.json`.
3) Ensure the runtime loader accepts:
- step_id naming convention STEP_*
- transitions encoded as {channel,event,target}
- led_policy as a sibling of transitions (not nested)
4) Ensure QR alignment:
- QR rule scene_id is `SCENE_QR_DETECTOR`
- QR success emits `UNLOCK_QR` and is wired to existing unlock pipeline.
5) Fail-safe:
- `ACTION_QR_TIMEOUT_30S` must fire `QR_TIMEOUT` event after ~30s (or closest existing timer infra).
- Transition `event:QR_TIMEOUT->STEP_RTC_ESP_ETAPE2` must work.
## Acceptance checks
- No PANIC/ASSERT/ABORT/REBOOT in serial logs.
- Each scene transition produces an ACK ok=1 (or existing equivalent).
- Ownership/locking of camera / mic / amp is consistent:
- SCENE_QR_DETECTOR uses camera
- audio packs do not deadlock mic/amp
- WS2812 behaviour matches per-step led_policy.
- After QR validated once, persist_after_validation=true causes subsequent boots to start in media_manager.
## Deliverables
- Updated repo files (2 targets)
- Any minimal loader patches required
- Short changelog entry
- Evidence: build log + short serial trace demonstrating path:
STEP_U_SON_PROTO -> ... -> STEP_QR_DETECTOR -> STEP_FINAL_WIN -> SCENE_MEDIA_MANAGER
@@ -0,0 +1,18 @@
# Zacus — Conversation Summary (bundle v3)
This bundle consolidates the key outputs from the conversation:
- Promptable scenario template (user-edited section: prompt_input)
- Canonical scenario YAML (STEP_*/SCENE_* conventions)
- Runtime JSON (DEFAULT.json)
- FSM diagram (Mermaid)
- Codex prompt to update repo targets
- Narrative zacus_v2.yaml aligned with the runtime + real-world gameplay
Key decisions captured:
- Prototype is U-SON.
- Act 1 (~45 min): LA 440 Hz stabilization (STEP_LA_DETECTOR).
- Act 2 (~60 min): Zone 4 piano-alphabet puzzle → play "LEFOU" (letters randomly placed; A anchored on LA 440 Hz).
- QR final payload is "WIN", hidden behind the portrait in the Archives.
- After QR success: Media Hub + persistent boot into media_manager.
Generated: 2026-02-25 (Europe/Paris)
@@ -0,0 +1,17 @@
# Zacus Conversation Bundle (v3)
Files:
- scenario_promptable_template.yaml : your editable template (prompt_input)
- scenario_canonical.yaml : canonical YAML (copy into docs/... target)
- scenario_runtime.json : runtime JSON (copy into data/story/scenarios/DEFAULT.json)
- fsm_mermaid.md : FSM diagram
- CODEX_PROMPT.md : ready-to-paste Codex prompt
- zacus_v2.yaml : narrative scenario aligned with runtime + gameplay reality
- CONVERSATION_SUMMARY.md : what changed / key decisions
Typical flow:
1) Update prompt_input in scenario_promptable_template.yaml if needed.
2) Use canonical/runtime files to update repo targets.
3) Use zacus_v2.yaml as the printed narrative / MJ reference for the real game.
Generated: 2026-02-25
@@ -0,0 +1,49 @@
# Zacus FSM — Mermaid diagram (runtime DEFAULT)
```mermaid
stateDiagram-v2
[*] --> STEP_U_SON_PROTO
STEP_U_SON_PROTO --> STEP_U_SON_PROTO: audio_done:loop
STEP_U_SON_PROTO --> STEP_LA_DETECTOR: BTN:ANY
STEP_U_SON_PROTO --> STEP_LA_DETECTOR: serial:FORCE_ETAPE2
STEP_LA_DETECTOR --> STEP_U_SON_PROTO: timer:ETAPE2_DUE
STEP_LA_DETECTOR --> STEP_RTC_ESP_ETAPE1: serial:BTN_NEXT
STEP_LA_DETECTOR --> STEP_RTC_ESP_ETAPE1: unlock:UNLOCK
STEP_LA_DETECTOR --> STEP_RTC_ESP_ETAPE1: action:ACTION_FORCE_ETAPE2
STEP_LA_DETECTOR --> STEP_RTC_ESP_ETAPE1: serial:FORCE_WIN_ETAPE1
STEP_RTC_ESP_ETAPE1 --> STEP_WIN_ETAPE1: esp_now:ACK_WIN1
STEP_RTC_ESP_ETAPE1 --> STEP_WIN_ETAPE1: serial:FORCE_DONE
STEP_WIN_ETAPE1 --> STEP_WARNING: serial:BTN_NEXT
STEP_WIN_ETAPE1 --> STEP_WARNING: serial:FORCE_DONE
STEP_WIN_ETAPE1 --> STEP_WARNING: esp_now:ACK_WARNING
STEP_WARNING --> STEP_WARNING: audio_done:loop
STEP_WARNING --> STEP_LEFOU_DETECTOR: BTN:ANY
STEP_WARNING --> STEP_LEFOU_DETECTOR: serial:FORCE_ETAPE2
STEP_LEFOU_DETECTOR --> STEP_WARNING: timer:ETAPE2_DUE
STEP_LEFOU_DETECTOR --> STEP_RTC_ESP_ETAPE2: serial:BTN_NEXT
STEP_LEFOU_DETECTOR --> STEP_RTC_ESP_ETAPE2: unlock:UNLOCK
STEP_LEFOU_DETECTOR --> STEP_RTC_ESP_ETAPE2: action:ACTION_FORCE_ETAPE2
STEP_LEFOU_DETECTOR --> STEP_RTC_ESP_ETAPE2: serial:FORCE_WIN_ETAPE2
STEP_RTC_ESP_ETAPE2 --> STEP_QR_DETECTOR: esp_now:ACK_WIN2
STEP_RTC_ESP_ETAPE2 --> STEP_QR_DETECTOR: serial:FORCE_DONE
STEP_QR_DETECTOR --> STEP_RTC_ESP_ETAPE2: timer:ETAPE2_DUE
STEP_QR_DETECTOR --> STEP_RTC_ESP_ETAPE2: event:QR_TIMEOUT
STEP_QR_DETECTOR --> STEP_FINAL_WIN: serial:BTN_NEXT
STEP_QR_DETECTOR --> STEP_FINAL_WIN: unlock:UNLOCK_QR
STEP_QR_DETECTOR --> STEP_FINAL_WIN: action:ACTION_FORCE_ETAPE2
STEP_QR_DETECTOR --> STEP_FINAL_WIN: serial:FORCE_WIN_ETAPE2
STEP_FINAL_WIN --> SCENE_MEDIA_MANAGER: timer:WIN_DUE
STEP_FINAL_WIN --> SCENE_MEDIA_MANAGER: serial:BTN_NEXT
STEP_FINAL_WIN --> SCENE_MEDIA_MANAGER: unlock:UNLOCK
STEP_FINAL_WIN --> SCENE_MEDIA_MANAGER: action:FORCE_WIN_ETAPE2
STEP_FINAL_WIN --> SCENE_MEDIA_MANAGER: serial:FORCE_WIN_ETAPE2
```
@@ -0,0 +1,291 @@
# Zacus Scenario — Canonical YAML (v3)
# Generated: 2026-02-25
#
# Conventions:
# - step_id = STEP_*, screen_scene_id = SCENE_*
# - led_policy is a sibling of transitions (NOT nested inside)
# - QR rule scene_id aligned to SCENE_QR_DETECTOR
# - Final transitions go to SCENE_MEDIA_MANAGER (hub scene)
#
# Narrative anchors (conversation):
# - Prototype: U-SON
# - Acte 1 (~45min): LA 440 Hz (STEP_LA_DETECTOR)
# - Acte 2 (~60min): Zone 4 piano-alphabet → jouer "LEFOU" (STEP_LEFOU_DETECTOR)
# * Lettres collées en ordre aléatoire sur touches blanches
# * A placé sur la touche correspondant au LA 440 Hz (ancre)
# - QR final: payload "WIN", caché derrière le portrait dans la Salle des Archives
prompt_input:
meta:
request_name: "DEFAULT_UNLOCK_WIN_ETAPE2"
owner: "clement"
board_target: "freenove_esp32s3"
objective: "U-SON: Acte1 LA440 (~45min) -> Acte2 piano 'LEFOU' (~60min) -> QR WIN -> Media Manager (persistant)"
boot_policy:
startup_mode: "story" # story | media_manager
persist_after_validation: true
rollback_command_required: true
qr_rule:
enabled: true
scene_id: "SCENE_QR_DETECTOR"
expected_payload: "WIN"
match_mode: "exact" # exact | prefix | contains
case_insensitive: true
success_event: "UNLOCK_QR"
failure_event: "QR_INVALID"
media_hub:
enabled: true
hub_scene_id: "SCENE_MEDIA_MANAGER"
entries:
- "SCENE_PHOTO_MANAGER"
- "SCENE_MP3_PLAYER"
- "SCENE_READY"
led_policy:
strict_rgb: true
defaults:
ws2812: 1
led_auto: 1
rgb: "18/45/95"
scene_overrides:
- scene_id: "SCENE_LA_DETECTOR"
rgb: "dynamic_tuner_or_off"
custom_steps: []
serial_test_plan:
- "SC_LOAD DEFAULT"
- "SCENE_GOTO SCENE_U_SON_PROTO"
- "QR_SIM WIN"
- "SC_EVENT UNLOCK_QR"
- "BOOT_MODE_STATUS"
- "RESET"
acceptance_criteria:
- "Pas de PANIC|ASSERT|ABORT|REBOOT|rst:"
- "Transitions scene avec ACK ... ok=1"
- "Ownership camera/mic/amp coherent"
- "LED WS2812 conformes policy + RGB"
- "Boot mode media_manager persistant apres QR valide"
notes:
- "Prototype: U-SON."
- "Etape1: LA 440 Hz stable (Acte1 ~45min)."
- "Etape2: piano-alphabet → jouer 'LEFOU' (Acte2 ~60min)."
- "QR WIN: caché derrière le portrait (Salle des Archives)."
- "SCENE_QR_DETECTOR a un timeout (QR_TIMEOUT) pour eviter le blocage."
scenario:
id: "DEFAULT"
version: 2
initial_step: "STEP_U_SON_PROTO"
app_bindings:
- "APP_AUDIO"
- "APP_SCREEN"
- "APP_GATE"
- "APP_WIFI"
- "APP_ESPNOW"
- "APP_SONAR"
- "APP_SD"
- "APP_CAMERA"
- "APP_LED"
- "APP_SERIAL"
- "APP_TIMER"
- "APP_UNLOCK"
- "APP_QR"
- "APP_INPUT"
- "APP_LOG"
- "APP_ACTION"
steps_runtime_order:
- step_id: "STEP_U_SON_PROTO"
screen_scene_id: "SCENE_U_SON_PROTO"
audio_pack_id: "PACK_BOOT_RADIO"
actions:
- "ACTION_TRACE_STEP"
- "ACTION_HW_LED_ALERT"
transitions:
- "audio_done:loop->STEP_U_SON_PROTO"
- "BTN:ANY->STEP_LA_DETECTOR"
- "serial:FORCE_ETAPE2->STEP_LA_DETECTOR"
led_policy:
ws2812_1: on
ws2812_2: on
ws2812_3: on
ws2812_4: on
animation: "random_one_blink"
brightness: "random_bright"
rgb: "random_color"
- step_id: "STEP_LA_DETECTOR"
screen_scene_id: "SCENE_LA_DETECTOR"
audio_pack_id: ""
actions:
- "ACTION_TRACE_STEP"
- "ACTION_QUEUE_SONAR"
transitions:
- "timer:ETAPE2_DUE->STEP_U_SON_PROTO"
- "serial:BTN_NEXT->STEP_RTC_ESP_ETAPE1"
- "unlock:UNLOCK->STEP_RTC_ESP_ETAPE1"
- "action:ACTION_FORCE_ETAPE2->STEP_RTC_ESP_ETAPE1"
- "serial:FORCE_WIN_ETAPE1->STEP_RTC_ESP_ETAPE1"
led_policy:
ws2812_1: on
ws2812_2: on
ws2812_3: on
ws2812_4: on
animation: "dynamic_tuner"
brightness: "100%"
rgb: "random_color"
- step_id: "STEP_RTC_ESP_ETAPE1"
screen_scene_id: "SCENE_WIN_ETAPE1"
audio_pack_id: "PACK_CONFIRM_WIN_ETAPE1"
actions:
- "ACTION_TRACE_STEP"
- "ACTION_HW_LED_ALERT"
- "ACTION_ESP_NOW_SEND_ETAPE1"
- "ACTION_QUEUE_SONAR"
transitions:
- "esp_now:ACK_WIN1->STEP_WIN_ETAPE1"
- "serial:FORCE_DONE->STEP_WIN_ETAPE1"
led_policy:
ws2812_1: on
ws2812_2: off
ws2812_3: off
ws2812_4: on
animation: "breathing"
brightness: "random_bright"
rgb: "random_color"
- step_id: "STEP_WIN_ETAPE1"
screen_scene_id: "SCENE_WIN_ETAPE1"
audio_pack_id: "PACK_WIN"
actions:
- "ACTION_TRACE_STEP"
- "ACTION_HW_LED_ALERT"
transitions:
- "serial:BTN_NEXT->STEP_WARNING"
- "serial:FORCE_DONE->STEP_WARNING"
- "esp_now:ACK_WARNING->STEP_WARNING"
led_policy:
ws2812_1: on
ws2812_2: off
ws2812_3: off
ws2812_4: on
animation: "K2000"
brightness: "K2000"
rgb: "red"
- step_id: "STEP_WARNING"
screen_scene_id: "SCENE_WARNING"
audio_pack_id: "PACK_BOOT_RADIO"
actions:
- "ACTION_TRACE_STEP"
- "ACTION_HW_LED_ALERT"
transitions:
- "audio_done:loop->STEP_WARNING"
- "BTN:ANY->STEP_LEFOU_DETECTOR"
- "serial:FORCE_ETAPE2->STEP_LEFOU_DETECTOR"
led_policy:
ws2812_1: on
ws2812_2: on
ws2812_3: on
ws2812_4: on
animation: "blink_all"
brightness: "100%"
rgb: "red"
- step_id: "STEP_LEFOU_DETECTOR"
screen_scene_id: "SCENE_LEFOU_DETECTOR"
audio_pack_id: ""
actions:
- "ACTION_TRACE_STEP"
- "ACTION_QUEUE_SONAR"
transitions:
- "timer:ETAPE2_DUE->STEP_WARNING"
- "serial:BTN_NEXT->STEP_RTC_ESP_ETAPE2"
- "unlock:UNLOCK->STEP_RTC_ESP_ETAPE2"
- "action:ACTION_FORCE_ETAPE2->STEP_RTC_ESP_ETAPE2"
- "serial:FORCE_WIN_ETAPE2->STEP_RTC_ESP_ETAPE2"
led_policy:
ws2812_1: on
ws2812_2: on
ws2812_3: on
ws2812_4: on
animation: "dynamic_tuner"
brightness: "100%"
rgb: "random_color"
- step_id: "STEP_RTC_ESP_ETAPE2"
screen_scene_id: "SCENE_WIN_ETAPE2"
audio_pack_id: "PACK_CONFIRM_WIN_ETAPE2"
actions:
- "ACTION_TRACE_STEP"
- "ACTION_HW_LED_ALERT"
- "ACTION_ESP_NOW_SEND_ETAPE2"
- "ACTION_QUEUE_SONAR"
transitions:
- "esp_now:ACK_WIN2->STEP_QR_DETECTOR"
- "serial:FORCE_DONE->STEP_QR_DETECTOR"
led_policy:
ws2812_1: on
ws2812_2: off
ws2812_3: off
ws2812_4: on
animation: "breathing"
brightness: "random_bright"
rgb: "random_color"
- step_id: "STEP_QR_DETECTOR"
screen_scene_id: "SCENE_QR_DETECTOR"
audio_pack_id: ""
actions:
- "ACTION_TRACE_STEP"
- "ACTION_QR_CODE_SCANNER_START"
- "ACTION_QR_TIMEOUT_30S"
transitions:
- "timer:ETAPE2_DUE->STEP_RTC_ESP_ETAPE2"
- "event:QR_TIMEOUT->STEP_RTC_ESP_ETAPE2"
- "serial:BTN_NEXT->STEP_FINAL_WIN"
- "unlock:UNLOCK_QR->STEP_FINAL_WIN"
- "action:ACTION_FORCE_ETAPE2->STEP_FINAL_WIN"
- "serial:FORCE_WIN_ETAPE2->STEP_FINAL_WIN"
led_policy:
ws2812_1: on
ws2812_2: on
ws2812_3: on
ws2812_4: on
animation: "bargraph_qr_trigger"
brightness: "bargraph"
rgb: "bargraph_red_to_green"
- step_id: "STEP_FINAL_WIN"
screen_scene_id: "SCENE_FINAL_WIN"
audio_pack_id: ""
actions:
- "ACTION_TRACE_STEP"
- "ACTION_WINNER"
transitions:
- "timer:WIN_DUE->SCENE_MEDIA_MANAGER"
- "serial:BTN_NEXT->SCENE_MEDIA_MANAGER"
- "unlock:UNLOCK->SCENE_MEDIA_MANAGER"
- "action:FORCE_WIN_ETAPE2->SCENE_MEDIA_MANAGER"
- "serial:FORCE_WIN_ETAPE2->SCENE_MEDIA_MANAGER"
led_policy:
ws2812_1: on
ws2812_2: on
ws2812_3: on
ws2812_4: on
animation: "blink_all_random"
brightness: "100%"
rgb: "random_color"
current_firmware_snapshot:
source_to_update_files:
- "docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml"
- "data/story/scenarios/DEFAULT.json"
@@ -0,0 +1,105 @@
# Scenario reel - template lisible + promptable.
chatgpt-codex-connector[bot] commented 2026-02-25 17:09:35 +00:00 (Migrated from github.com)
Review

P2 Badge Fix firmware target paths in promptable snapshot

current_firmware_snapshot.source_to_update_files points to docs/... and data/... at repo root, but those targets actually live under hardware/firmware/... in this repository. Any automation or manual integration that consumes this snapshot will update/create the wrong files and leave the real firmware scenario unchanged.

Useful? React with 👍 / 👎.

**<sub><sub>![P2 Badge](https://img.shields.io/badge/P2-yellow?style=flat)</sub></sub> Fix firmware target paths in promptable snapshot** `current_firmware_snapshot.source_to_update_files` points to `docs/...` and `data/...` at repo root, but those targets actually live under `hardware/firmware/...` in this repository. Any automation or manual integration that consumes this snapshot will update/create the wrong files and leave the real firmware scenario unchanged. Useful? React with 👍 / 👎.
#
# Comment l'utiliser:
# 1) Edite uniquement la section `prompt_input`.
# 2) Laisse `current_firmware_snapshot` comme reference de l'etat actuel code.
# 3) Envoie ce fichier a Codex: je convertis ensuite vers le YAML canonique + JSON runtime.
#
# NOTE (conversation):
# - Prototype: U-SON
# - Etape 1 (LA_DETECTOR): fréquence audio LA 440 Hz
# - Etape 2 (LEFOU_DETECTOR): puzzle piano-alphabet → jouer "LEFOU"
# * Lettres collées en ordre aléatoire sur les touches blanches
# * A est placé sur la touche correspondant au LA 440 Hz (ancre)
# - QR final: payload "WIN", caché derrière le portrait dans la Salle des Archives
prompt_input:
meta:
request_name: "A_COMPLETER"
owner: "A_COMPLETER"
board_target: "freenove_esp32s3"
objective: "U-SON: Acte1 LA440 (~45min) -> Acte2 Zone4 piano 'LEFOU' (~60min) -> QR WIN -> Media Manager"
boot_policy:
startup_mode: "story" # story | media_manager
persist_after_validation: true
rollback_command_required: true
qr_rule:
enabled: true
scene_id: "SCENE_QR_DETECTOR"
expected_payload: "WIN"
match_mode: "exact" # exact | prefix | contains
case_insensitive: true
success_event: "UNLOCK_QR"
failure_event: "QR_INVALID"
media_hub:
enabled: true
hub_scene_id: "SCENE_MEDIA_MANAGER"
entries:
- "SCENE_PHOTO_MANAGER"
- "SCENE_MP3_PLAYER"
- "SCENE_READY"
led_policy:
strict_rgb: true
defaults:
ws2812: 1
led_auto: 1
rgb: "18/45/95"
scene_overrides:
- scene_id: "SCENE_LA_DETECTOR"
rgb: "dynamic_tuner_or_off"
custom_steps:
# Ajoute, retire, ou reordonne des steps ici.
- "A_COMPLETER"
serial_test_plan:
- "SC_LOAD DEFAULT"
- "SCENE_GOTO"
- "QR_SIM WIN"
- "SC_EVENT UNLOCK_QR"
- "BOOT_MODE_STATUS"
- "RESET"
acceptance_criteria:
- "Pas de PANIC|ASSERT|ABORT|REBOOT|rst:"
- "Transitions scene avec ACK ... ok=1"
- "Ownership camera/mic/amp coherent"
- "LED WS2812 conformes policy + RGB"
- "Boot mode media_manager persistant apres QR valide"
notes:
- "Acte 1: LA 440 Hz (stabilité) ~45 minutes."
- "Acte 2: Zone 4 piano-alphabet (LEFOU) + Archives (QR WIN derrière portrait) ~60 minutes."
- "Prototype: U-SON."
- "Ajouter ici les exceptions ou aliases scene."
scenario:
id: "DEFAULT"
version: 2
initial_step: "STEP_U_SON_PROTO"
app_bindings:
- "APP_AUDIO"
- "APP_SCREEN"
- "APP_GATE"
- "APP_WIFI"
- "APP_ESPNOW"
- "APP_SONAR"
- "APP_SD"
- "APP_CAMERA"
- "APP_LED"
- "APP_SERIAL"
- "APP_TIMER"
- "APP_UNLOCK"
- "APP_QR"
- "APP_INPUT"
- "APP_LOG"
- "APP_ACTION"
current_firmware_snapshot:
source_to_update_files:
- "docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml"
- "data/story/scenarios/DEFAULT.json"
@@ -0,0 +1,434 @@
{
chatgpt-codex-connector[bot] commented 2026-02-25 16:26:53 +00:00 (Migrated from github.com)
Review

P2 Badge Use defined action event for final-win transition

The final step listens on channel: "action" for FORCE_WIN_ETAPE2, but the repository’s action catalog emits ACTION_FORCE_ETAPE2 (see hardware/firmware/data/story/actions/ACTION_FORCE_ETAPE2.json), and there is no producer for an action event named FORCE_WIN_ETAPE2. If this runtime is integrated, the action-based fast-forward path to SCENE_MEDIA_MANAGER will never trigger.

Useful? React with 👍 / 👎.

**<sub><sub>![P2 Badge](https://img.shields.io/badge/P2-yellow?style=flat)</sub></sub> Use defined action event for final-win transition** The final step listens on `channel: "action"` for `FORCE_WIN_ETAPE2`, but the repository’s action catalog emits `ACTION_FORCE_ETAPE2` (see `hardware/firmware/data/story/actions/ACTION_FORCE_ETAPE2.json`), and there is no producer for an action event named `FORCE_WIN_ETAPE2`. If this runtime is integrated, the action-based fast-forward path to `SCENE_MEDIA_MANAGER` will never trigger. Useful? React with 👍 / 👎.
"scenario": {
"id": "DEFAULT",
"version": 2,
"initial_step": "STEP_U_SON_PROTO",
"app_bindings": [
"APP_AUDIO",
"APP_SCREEN",
"APP_GATE",
"APP_WIFI",
"APP_ESPNOW",
"APP_SONAR",
"APP_SD",
"APP_CAMERA",
"APP_LED",
"APP_SERIAL",
"APP_TIMER",
"APP_UNLOCK",
"APP_QR",
"APP_INPUT",
"APP_LOG",
"APP_ACTION"
]
},
"boot_policy": {
"startup_mode": "story",
"persist_after_validation": true,
"rollback_command_required": true
},
"qr_rule": {
"enabled": true,
"scene_id": "SCENE_QR_DETECTOR",
"expected_payload": "WIN",
"match_mode": "exact",
"case_insensitive": true,
"success_event": "UNLOCK_QR",
"failure_event": "QR_INVALID",
"timeout_seconds": 30,
"timeout_event": "QR_TIMEOUT"
},
"media_hub": {
"enabled": true,
"hub_scene_id": "SCENE_MEDIA_MANAGER",
"entries": [
"SCENE_PHOTO_MANAGER",
"SCENE_MP3_PLAYER",
"SCENE_READY"
]
},
"led_policy": {
"strict_rgb": true,
"defaults": {
"ws2812": 1,
"led_auto": 1,
"rgb": "18/45/95"
},
"scene_overrides": [
{
"scene_id": "SCENE_LA_DETECTOR",
"rgb": "dynamic_tuner_or_off"
}
]
},
"narrative_meta": {
"prototype": "U-SON",
"act_durations_minutes": {
"act_1": 45,
"act_2": 60
},
"zone4_piano": {
"code_word": "LEFOU",
"letters_random_order": true,
"anchor": "A on LA 440 Hz"
},
"qr_location": "Derriere le portrait (Salle des Archives)"
},
"steps_runtime_order": [
{
"step_id": "STEP_U_SON_PROTO",
"screen_scene_id": "SCENE_U_SON_PROTO",
"audio_pack_id": "PACK_BOOT_RADIO",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_HW_LED_ALERT"
],
"transitions": [
{
"channel": "audio_done",
"event": "loop",
"target": "STEP_U_SON_PROTO"
},
{
"channel": "BTN",
"event": "ANY",
"target": "STEP_LA_DETECTOR"
},
{
"channel": "serial",
"event": "FORCE_ETAPE2",
"target": "STEP_LA_DETECTOR"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "on",
"ws2812_3": "on",
"ws2812_4": "on",
"animation": "random_one_blink",
"brightness": "random_bright",
"rgb": "random_color"
}
},
{
"step_id": "STEP_LA_DETECTOR",
"screen_scene_id": "SCENE_LA_DETECTOR",
"audio_pack_id": "",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_QUEUE_SONAR"
],
"transitions": [
{
"channel": "timer",
"event": "ETAPE2_DUE",
"target": "STEP_U_SON_PROTO"
},
{
"channel": "serial",
"event": "BTN_NEXT",
"target": "STEP_RTC_ESP_ETAPE1"
},
{
"channel": "unlock",
"event": "UNLOCK",
"target": "STEP_RTC_ESP_ETAPE1"
},
{
"channel": "action",
"event": "ACTION_FORCE_ETAPE2",
"target": "STEP_RTC_ESP_ETAPE1"
},
{
"channel": "serial",
"event": "FORCE_WIN_ETAPE1",
"target": "STEP_RTC_ESP_ETAPE1"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "on",
"ws2812_3": "on",
"ws2812_4": "on",
"animation": "dynamic_tuner",
"brightness": "100%",
"rgb": "random_color"
}
},
{
"step_id": "STEP_RTC_ESP_ETAPE1",
"screen_scene_id": "SCENE_WIN_ETAPE1",
"audio_pack_id": "PACK_CONFIRM_WIN_ETAPE1",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_HW_LED_ALERT",
"ACTION_ESP_NOW_SEND_ETAPE1",
"ACTION_QUEUE_SONAR"
],
"transitions": [
{
"channel": "esp_now",
"event": "ACK_WIN1",
"target": "STEP_WIN_ETAPE1"
},
{
"channel": "serial",
"event": "FORCE_DONE",
"target": "STEP_WIN_ETAPE1"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "off",
"ws2812_3": "off",
"ws2812_4": "on",
"animation": "breathing",
"brightness": "random_bright",
"rgb": "random_color"
}
},
{
"step_id": "STEP_WIN_ETAPE1",
"screen_scene_id": "SCENE_WIN_ETAPE1",
"audio_pack_id": "PACK_WIN",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_HW_LED_ALERT"
],
"transitions": [
{
"channel": "serial",
"event": "BTN_NEXT",
"target": "STEP_WARNING"
},
{
"channel": "serial",
"event": "FORCE_DONE",
"target": "STEP_WARNING"
},
{
"channel": "esp_now",
"event": "ACK_WARNING",
"target": "STEP_WARNING"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "off",
"ws2812_3": "off",
"ws2812_4": "on",
"animation": "K2000",
"brightness": "K2000",
"rgb": "red"
}
},
{
"step_id": "STEP_WARNING",
"screen_scene_id": "SCENE_WARNING",
"audio_pack_id": "PACK_BOOT_RADIO",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_HW_LED_ALERT"
],
"transitions": [
{
"channel": "audio_done",
"event": "loop",
"target": "STEP_WARNING"
},
{
"channel": "BTN",
"event": "ANY",
"target": "STEP_LEFOU_DETECTOR"
},
{
"channel": "serial",
"event": "FORCE_ETAPE2",
"target": "STEP_LEFOU_DETECTOR"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "on",
"ws2812_3": "on",
"ws2812_4": "on",
"animation": "blink_all",
"brightness": "100%",
"rgb": "red"
}
},
{
"step_id": "STEP_LEFOU_DETECTOR",
"screen_scene_id": "SCENE_LEFOU_DETECTOR",
"audio_pack_id": "",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_QUEUE_SONAR"
],
"transitions": [
{
"channel": "timer",
"event": "ETAPE2_DUE",
"target": "STEP_WARNING"
},
{
"channel": "serial",
"event": "BTN_NEXT",
"target": "STEP_RTC_ESP_ETAPE2"
},
{
"channel": "unlock",
"event": "UNLOCK",
"target": "STEP_RTC_ESP_ETAPE2"
},
{
"channel": "action",
"event": "ACTION_FORCE_ETAPE2",
"target": "STEP_RTC_ESP_ETAPE2"
},
{
"channel": "serial",
"event": "FORCE_WIN_ETAPE2",
"target": "STEP_RTC_ESP_ETAPE2"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "on",
"ws2812_3": "on",
"ws2812_4": "on",
"animation": "dynamic_tuner",
"brightness": "100%",
"rgb": "random_color"
}
},
{
"step_id": "STEP_RTC_ESP_ETAPE2",
"screen_scene_id": "SCENE_WIN_ETAPE2",
"audio_pack_id": "PACK_CONFIRM_WIN_ETAPE2",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_HW_LED_ALERT",
"ACTION_ESP_NOW_SEND_ETAPE2",
"ACTION_QUEUE_SONAR"
],
"transitions": [
{
"channel": "esp_now",
"event": "ACK_WIN2",
"target": "STEP_QR_DETECTOR"
},
{
"channel": "serial",
"event": "FORCE_DONE",
"target": "STEP_QR_DETECTOR"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "off",
"ws2812_3": "off",
"ws2812_4": "on",
"animation": "breathing",
"brightness": "random_bright",
"rgb": "random_color"
}
},
{
"step_id": "STEP_QR_DETECTOR",
"screen_scene_id": "SCENE_QR_DETECTOR",
"audio_pack_id": "",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_QR_CODE_SCANNER_START",
"ACTION_QR_TIMEOUT_30S"
],
"transitions": [
{
"channel": "timer",
"event": "ETAPE2_DUE",
"target": "STEP_RTC_ESP_ETAPE2"
},
{
"channel": "event",
"event": "QR_TIMEOUT",
"target": "STEP_RTC_ESP_ETAPE2"
},
{
"channel": "serial",
"event": "BTN_NEXT",
"target": "STEP_FINAL_WIN"
},
{
"channel": "unlock",
"event": "UNLOCK_QR",
"target": "STEP_FINAL_WIN"
},
{
"channel": "action",
"event": "ACTION_FORCE_ETAPE2",
"target": "STEP_FINAL_WIN"
},
{
"channel": "serial",
"event": "FORCE_WIN_ETAPE2",
"target": "STEP_FINAL_WIN"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "on",
"ws2812_3": "on",
"ws2812_4": "on",
"animation": "bargraph_qr_trigger",
"brightness": "bargraph",
"rgb": "bargraph_red_to_green"
}
},
{
"step_id": "STEP_FINAL_WIN",
"screen_scene_id": "SCENE_FINAL_WIN",
"audio_pack_id": "",
"actions": [
"ACTION_TRACE_STEP",
"ACTION_WINNER"
],
"transitions": [
{
"channel": "timer",
"event": "WIN_DUE",
"target": "SCENE_MEDIA_MANAGER"
},
{
"channel": "serial",
"event": "BTN_NEXT",
"target": "SCENE_MEDIA_MANAGER"
},
{
"channel": "unlock",
"event": "UNLOCK",
"target": "SCENE_MEDIA_MANAGER"
},
{
"channel": "action",
"event": "FORCE_WIN_ETAPE2",
"target": "SCENE_MEDIA_MANAGER"
},
{
"channel": "serial",
"event": "FORCE_WIN_ETAPE2",
"target": "SCENE_MEDIA_MANAGER"
}
],
"led_policy": {
"ws2812_1": "on",
"ws2812_2": "on",
"ws2812_3": "on",
"ws2812_4": "on",
"animation": "blink_all_random",
"brightness": "100%",
"rgb": "random_color"
}
}
]
}
@@ -0,0 +1,172 @@
id: zacus_v2
version: 3
revision: 1
title: "Le mystère du Professeur Zacus — Version Réelle (U-SON, piano LEFOU, QR WIN)"
theme: "Enquête scientifique + stabilisation audio + épreuve Zone 4 + déverrouillage final"
players:
min: 6
max: 14
ages: "614 ans (911 recommandés)"
duration:
act_1_minutes: 45
act_2_minutes: 60
total_minutes: 105
firmware:
board_target: freenove_esp32s3
engine: story_engine_v2
runtime_scenario_id: "DEFAULT"
boot_policy:
startup_mode: story
persist_after_validation: true
rollback_command_required: true
after_success_boot: media_manager
qr_rule:
enabled: true
scene_id: "SCENE_QR_DETECTOR"
expected_payload: "WIN"
match_mode: exact
case_insensitive: true
success_event: "UNLOCK_QR"
failure_event: "QR_INVALID"
timeout_seconds: 30
timeout_event: "QR_TIMEOUT"
media_hub:
enabled: true
hub_scene_id: "SCENE_MEDIA_MANAGER"
entries:
- "SCENE_PHOTO_MANAGER"
- "SCENE_MP3_PLAYER"
- "SCENE_READY"
canon:
prototype: "U-SON"
introduction: >
Le Professeur Zacus a disparu après avoir déclenché une alerte cryptée.
Le prototype U-SON “dérive”: les signaux deviennent instables.
Pour protéger U-SON, l’équipe doit:
(1) stabiliser une référence scientifique (LA 440 Hz),
(2) passer la règle de Zone 4 (installation de l’Électron Fou) via un code piano-alphabet,
(3) récupérer la clé finale (QR “WIN”) cachée aux Archives.
stakes: >
Le vrai test nest pas la vitesse: cest la coopération, la précision et le calme.
reveal_finale: >
Zacus réapparaît: c’était un test d’éthique.
U-SON ne doit pas devenir un objet de panique.
L’équipe gagne parce quelle a fait juste: stabilité, règle, entraide.
lore_truths:
- "Zone 4 = installation personnelle de l’Électron Fou."
- "Piano-alphabet brouillé: lettres collées en ordre aléatoire sur touches blanches."
- "Ancre: A est placé sur la touche correspondant au LA 440 Hz."
stations:
- id: STATION_ONDES
act: 1
name: "Atelier des Ondes"
focus: "Stabiliser LA 440 Hz pour recaler U-SON."
firmware_anchor_step: "STEP_LA_DETECTOR"
- id: STATION_ZONE4_PIANO
act: 2
name: "Zone 4 — Studio de Résonance (Piano Alphabet brouillé)"
focus: "Trouver et jouer le code LEFOU (L-E-F-O-U) via lettres sur touches blanches."
firmware_anchor_step: "STEP_LEFOU_DETECTOR"
clue_soft: "En Zone 4, les lettres comptent plus que les notes. A est sur le LA 440."
clue_hard: "Le code est le nom du propriétaire: LEFOU."
- id: STATION_ARCHIVES_QR
act: 2
name: "Salle des Archives"
focus: "Trouver et scanner la clé finale."
firmware_anchor_step: "STEP_QR_DETECTOR"
qr_location_real: "Derrière le portrait (cadre) dans la Salle des Archives."
puzzles:
- id: PUZZLE_LA_440
act: 1
type: "audio / stabilisation"
objective: "Produire un LA 440 Hz stable."
firmware_step: "STEP_LA_DETECTOR"
- id: PUZZLE_PIANO_ALPHABET_5
act: 2
type: "piano / code lettres (mapping brouillé)"
objective: "Jouer 5 touches correspondant aux lettres du code."
firmware_step: "STEP_LEFOU_DETECTOR"
mapping_rule_real: >
Les 26 lettres AZ sont collées sur des touches blanches dans un ordre aléatoire.
Une seule ancre est vraie: A est placé sur le LA 440 Hz.
code_word_5_letters: "LEFOU"
sequence_letters: ["L","E","F","O","U"]
hint_progression:
soft: "A est sur le LA. Cherchez les lettres, pas les notes."
medium: "Le mot est un nom (propriétaire Zone 4)."
hard: "Jouez L-E-F-O-U."
- id: PUZZLE_QR_WIN
act: 2
type: "recherche / scan"
objective: "Scanner le QR final WIN."
firmware_step: "STEP_QR_DETECTOR"
qr_payload: "WIN"
location: "Derrière le portrait aux Archives"
acts:
- act: 1
title: "Acte 1 — Stabiliser U-SON (LA 440) (≈45 min)"
goal: "Valider Étape 1 via LA 440 Hz."
- act: 2
title: "Acte 2 — Zone 4 (piano LEFOU) + Archives (QR WIN) (≈60 min)"
goal: "Valider Étape 2, puis scanner QR WIN derrière le portrait."
audio:
packs:
- pack_id: PACK_BOOT_RADIO
tracks:
- track_id: boot_intro
script_fr: >
Équipe Zacus… ici le Professeur Zacus.
Le prototype U-SON dérive. Les capteurs ne sont plus fiables.
Pour stabiliser U-SON, il vous faut une référence : le LA, quatre-cent-quarante hertz.
Rendez-vous à lAtelier des Ondes.
Gardez votre calme.
tts_prompt_excerpt: >
Voix adulte calme, rassurante, scientifique. Phrases courtes.
Effets: bip début + souffle léger + bandpass radio.
- track_id: warning_to_zone4
script_fr: >
Alerte.
Prochaine étape : Zone 4.
Les lettres sont brouillées.
Une seule est sûre : A est sur le LA.
Cinq lettres. Cinq touches.
tts_prompt_excerpt: >
Voix plus urgente mais pas anxiogène.
Effets: bips rapides dalarme, puis radio léger.
- pack_id: PACK_CONFIRM_WIN_ETAPE1
tracks:
- track_id: confirm_win1
script_fr: >
Signal stabilisé.
Étape un validée.
Liaison confirmée.
- pack_id: PACK_CONFIRM_WIN_ETAPE2
tracks:
- track_id: confirm_win2_archives
script_fr: >
Étape deux validée.
Rendez-vous aux Archives.
La clé finale est derrière le portrait.
qr:
payload: "WIN"
location: "Derrière le portrait dans la Salle des Archives"
lead_in_clue: "Regarde là où Zacus surveille toujours."
+23
View File
@@ -0,0 +1,23 @@
# ZIP intake — statut après réception bundle (G0 Spec Freeze)
## Contexte
Le bundle annoncé par l'utilisateur est désormais disponible sous :
`scenario-ai-coherence/zacus_conversation_bundle_v3/`.
## Critères d'acceptation (AC)
- Les fichiers du bundle sont présents localement dans le même chemin.
- Le contenu est importé tel quel (pas de transformation fonctionnelle).
- La traçabilité est mise à jour (`artifacts/...` + `evidence/manifest.json`).
- Les validateurs scénario/audio/printables existants passent après import.
## Non-goals
- Aucune promotion automatique de `zacus_v2.yaml` vers `game/scenarios/*.yaml`.
- Aucune modification firmware/hardware.
- Aucune refonte des manifests audio/printables.
## Risques
- Le bundle peut diverger du scénario canonique `game/scenarios/zacus_v1.yaml`.
- Les formats `scenario_runtime.json`/templates peuvent nécessiter une validation dédiée ultérieure.
## Statut Gates
- G0 Spec Freeze : **satisfait** pour l'import brut du bundle.