- 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.
312 KiB
[2026-02-28] Reflash + verification run (Freenove SCENE_CREDITS LGFX-only timeline)
- Objectif:
- reflasher la Freenove puis verifier rapidement en serie que la scene credits reste en rendu LGFX-only avec timeline active.
- Actions:
- Upload FW:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Monitor + commandes:
SCENE_GOTO SCENE_CREDITSUI_SCENE_STATUSUI_GFX_STATUSSTATUS
- Upload FW:
- Evidence:
ACK SCENE_GOTO ok=1UI_SCENE_STATUS:scene_id=SCENE_CREDITS,text_backend=lgfx_overlay,lvgl_text_disabled=trueSTATUS:render_lock=lgfx_runtime_onlyUI_GFX_STATUS:fx_scene=1,fx_fpsstable (8->15) sans panic/reboot.
[2026-02-28] SCENE_CREDITS timeline adaptee (BOOT -> HOLO -> STARWARS) + verrou LovyanGFX only
- Objectif:
- appliquer la timeline demandee en full LovyanGFX pour
SCENE_CREDITS, - desactiver completement le rendu LVGL runtime sur scenes cibles (
SCENE_CREDITS,SCENE_WIN_ETAPE1), - utiliser en priorite
credits.txtdu FS pour le crawl.
- appliquer la timeline demandee en full LovyanGFX pour
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_172058_wip.patch/tmp/zacus_checkpoint/20260228_172058_status.txt
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- timeline
SCENE_CREDITS:- phase BOOT (0-15s) style terminal,
- phase HOLO (15-30s) glitch/chroma + scanline,
- phase STARWARS (>=30s) parser credits + perspective/fade,
- source credits: ajout priorite
/credits.txtavant les chemins legacy, - mode STARWARS en
SCENE_CREDITS: scroll non boucle (attend la fin du defilement), - verrou LGFX only par scene:
SCENE_CREDITS/SCENE_CREDIT/SCENE_WIN_ETAPE1forcelgfx_hard_mode.
- timeline
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Monitor PASS:
SCENE_GOTO SCENE_CREDITS-> transition OK +ACK SCENE_GOTO ok=1UI_SCENE_STATUS->scene_id=SCENE_CREDITS,text_backend=lgfx_overlay,lvgl_text_disabled=true.
- Build PASS:
[2026-02-28] Freenove SCENE_CREDITS StarWars crawl + SCENE_WIN_ETAPE1 audio loop
- Objectif:
SCENE_CREDITS: rendu credits en style "Star Wars" (perspective + fade) en LovyanGFX overlay, avec wrap auto conserve.SCENE_WIN_ETAPE1: relancer le son en boucle tant que la scene reste active.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_170548_wip.patch/tmp/zacus_checkpoint/20260228_170548_status.txt
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- mode
credits_scenedetecte (SCENE_CREDITS+ aliasSCENE_CREDIT), - credits crawl LGFX avec perspective/fade type StarWars (horizon + profondeur),
- wrap automatique des lignes credits conserve.
- mode
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- callback
onAudioFinished: si scene activeSCENE_WIN_ETAPE1, replay immediat du meme track au lieu de notifierAUDIO_DONE.
- callback
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Reflash PASS (this run): same env/port, completed with hard reset.
- Build PASS:
[2026-02-28] Freenove SCENE_CREDITS - wrap auto lignes + rendu LovyanGFX
- Objectif: sur
SCENE_CREDIT/SCENE_CREDITS, garder le rendu full LovyanGFX et ajouter des retours a la ligne automatiques sur les textes credits trop longs. - Checkpoint securite:
/tmp/zacus_checkpoint/20260228_170548_wip.patch/tmp/zacus_checkpoint/20260228_170548_status.txt
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- activation du mode credits parser overlay aussi pour
SCENE_CREDITS(et aliasSCENE_CREDIT), - ajout
append_credit_line_wrapped(...)avec word-wrap automatique base surmeasureOverlayText(...), - conservation du parser directives (
[SIZE],[ALIGN],[SPACE],[PAUSE],[END]) et application du wrap sur les lignes texte normales + fallback.
- activation du mode credits parser overlay aussi pour
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301
- Build PASS:
[2026-02-28] A252 off-hook auto playback (dial tone 2s then random file)
- Objectif: au decroche (
OFF_HOOK) sur A252, laisser 2s de tonalite d'appel puis lancer automatiquement un fichier aleatoire. - Checkpoint securite:
/tmp/zacus_checkpoint/20260228_165817_wip.patch/tmp/zacus_checkpoint/20260228_165817_status.txt
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/main.cpp- ajout runtime
OffHookAutoRandomPlaybackState(armement + delai + route aleatoire), - nouvel enchainement:
- transition
OFF_HOOK-> armement auto-play+2000 ms, - fin delai -> stop dial tone/tone puis lecture d'un fichier aleatoire resolu via
pickRandomInterludeRoute, - annulation auto-play si raccroche ou si numerotation commence.
- transition
- ajout runtime
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev - Upload tentative 1 FAIL:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001- erreur initiale: port absent.
- Upload tentative 2 PASS (port revenu):
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001
- Build PASS:
[2026-02-28] Freenove boot route hard-forced to SCENE_WIN_ETAPE
- Objectif: forcer le boot runtime par defaut vers
SCENE_WIN_ETAPEen conservant les prioritestest_labetmedia_manager. - Checkpoint securite:
/tmp/zacus_checkpoint/20260228_165247_wip.patch/tmp/zacus_checkpoint/20260228_165247_status.txt
- Artefacts trackes verifies:
- scan
git ls-filessur.pio/.platformio/logs/dist/build/node_modules/.venv-> aucun fichier tracke detecte.
- scan
- Correctif applique:
hardware/firmware/ui_freenove_allinone/src/app/main.cppkDefaultBootSceneIdpasse deSCENE_U_SON_PROTOaSCENE_WIN_ETAPE.- ordre de routage conserve:
kForceTestLabSceneLockprioritaire,- puis
g_boot_media_manager_mode, - puis fallback
kDefaultBootSceneId.
- Build / flash / validation:
pio run -e freenove_esp32s3_full_with_ui-> OKpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK- monitor
pio device monitor --port /dev/cu.usbmodem5AB90753301 --baud 115200(PTY) -> evidence:[BOOT] route default scene=SCENE_WIN_ETAPE ok=1- transition scenario boot:
from_scene=SCENE_WIN_ETAPE to_scene=SCENE_WIN_ETAPE
[2026-02-28] A252 hotline follow-up - ringback 2..10s + serial validation
- Objectif: finaliser le delta hotline demande:
- ringback aleatoire 2..10s,
- garder sync scene ESP-NOW toutes les 30s + trigger off-hook,
- conserver interlude 15..30 min + force test,
- verifier absence de rejet payload
payload too large.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_124635_wip.patch/tmp/zacus_checkpoint/20260228_124635_status.txt
- Etat code confirme:
hardware/RTC_SLIC_PHONE/src/main.cppkHotlineRingbackMinMs=2000,kHotlineRingbackMaxMs=10000.kEspNowPeerDiscoveryIntervalMs=30000,kEspNowSceneSyncIntervalMs=30000.- trigger scene sync au decroche (
reason=off_hook) + periodic. HOTLINE_INTERLUDE_FORCEactif, scheduler interlude 15..30 min actif.- validation WIN_ETAPE auto
ACK_WIN1conservee apres media one-shot.
hardware/firmware/ui_freenove_allinone/src/system/network/network_manager.cppsendEspNowTarget(...)respecte maintenant une cible MAC explicite (unicast) au lieu de forcer broadcast.
- Build / upload:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> OKpio run -e freenove_esp32s3_full_with_ui-> OKpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK
- Validation serie (A252):
HOTLINE_STATUS-> scene sync runtime enabled + interlude fields exposes.HOTLINE_TRIGGER 2-> evidence:[Hotline] ringback profile=UK_GB duration_ms=8013 ...(dans fenetre 2..10s).- pas de log
EspNowBridge send rejected: payload too large.
HOTLINE_INTERLUDE_FORCE-> ring + fichier random:file=/interlude_tts/interlude_07_mystere_henri.wav.
- Observation cross-board a suivre:
- apres flash Freenove, le port serie A252
/dev/cu.usbserial-0001n'est plus apparu sur ce poste (retest scene_sync ACK A252 non rejouable immediatement). - bloc hotline principal valide avant ce point (ringback 2..10s, interlude force, payload compact sans rejet).
- retest ulterieur Freenove (monitor direct) valide la correction unicast ESP-NOW:
SCENE_GOTO SCENE_WARNING->[HOTLINE_SYNC] ... ok=1puis[WARN_SIREN] remote start.UI_SCENE_STATUSreponse + ack entrant:code=UI_SCENE_STATUSdepuis peerA0:B7:65:E7:F6:44.STATUSFreenove pendant warning:espnow=1 peers=1.
- apres flash Freenove, le port serie A252
[2026-02-28] A252 hotline WIN_ETAPE: one-shot scene routes + suffix matching + auto-ACK plumbing
- Objectif: completer le lot hotline en production reelle:
- garder les routes scene en one-shot (pas boucle forcee),
- resoudre les fichiers
hotline_ttsavec suffixes voix variables (*_mystere_*.mp3), - armer ACK
ACK_WIN1auto (compose 440) apres fin MP3 deSCENE_WIN_ETAPE, - conserver busy tone post-MP3.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_063900_wip.patch/tmp/zacus_checkpoint/20260228_063900_status.txt
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/main.cpp- ajout
resolveHotlineSceneDirectoryVariantRoute(...)pour matcher les fichiers scenestem_suffix.mp3dans/hotline_tts/SCENE_*, triggerHotlineRouteForDigits(...): suppression de la boucle forcee sur les routes FILE venant des scenes (routed_from_scene_hint=true),- ajout helper central
sendHotlineValidationAckEvent(...), - ajout pipeline WIN_ETAPE auto-validation:
- armement
g_win_etape_validation_after_mp3_pendingau demarrage post-ringback d'un MP3 one-shot enWIN_ETAPE, - emission
ACK_WIN1sourceauto_440en fin playback (si off-hook), - reset flag dans
clearHotlineRuntimeState()ettickPlaybackCompletionBusyTone().
- armement
- ajout
- Build / upload executes:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> OKpio run -e freenove_esp32s3-> OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OKpio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301-> OK
- Validation serial / evidence:
- SLIC:
SLIC_CONFIG_GET->hook_active_high=trueSLIC_CONFIG_SET {"hook_active_high":true}-> persisted / re-read OKSTATUS(combine decroche) ->hook=OFF_HOOK
- Audit SD (
FS_LIST):/hotline_ttspresent (scene dirs + voix suffixees),/interlude_ttspresent (45 fichiers),/music/v8_packabsent sur SD (fallback requis cote firmware).
- WIN_ETAPE runtime:
- evidence observee:
[RTC_BL_PHONE] WIN_ETAPE post-ringback mp3 armed for auto 440 validation (...) - evidence observee: lecture MP3 scene WIN_ETAPE depuis
/hotline_tts/... - limitation en cours: sur ce banc, la fin de lecture (et donc logs
busy tone+auto-compose 440) n'a pas ete observee dans une fenetre 240s.
- evidence observee:
- Smoke scripts:
./tools/dev/run_smoke_tests.sh(dual) -> FAIL (resolver mappe A252 comme ESP32 story, commandes story non supportees)ZACUS_COMBINED_BOARD=1 ... run_smoke_tests.sh --combined-board-> FAIL (scenario DEFAULT bloque sur LA, timeout completion)
- SLIC:
[2026-02-28] Freenove scenes + A252 hotline (ringback 5-25s, LEFOU sequence, U_SON playlist root)
- Objectif: appliquer le lot prioritaire du plan global sans toucher
hardware/firmware/esp32/:- hotline A252: ringback aleatoire 5..25s,
- Freenove: playlist random U_SON via
audio.ambient_random.mode=random_file+playlist_root, - LEFOU: validation par sequence de notes configurable (
render.lefou_detector.note_sequence_hz), - WARNING: nouveaux flags de rendu
render.warning.lgfx_only+render.warning.siren.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_060439_wip.patch/tmp/zacus_checkpoint/20260228_060439_status.txt
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/main.cpp- ringback random ramene a
kHotlineRingbackMinMs=5000,kHotlineRingbackMaxMs=25000.
- ringback random ramene a
hardware/firmware/ui_freenove_allinone/include/runtime/runtime_config_types.h- ajout config sequence LA/LEFOU (
mic_la_sequence_*) + etat runtime sequence.
- ajout config sequence LA/LEFOU (
hardware/firmware/ui_freenove_allinone/src/runtime/la_trigger_service.cpp- trigger etendu a
SCENE_LEFOU_DETECTOR, - branche sequence stricte (ordre impose) avec hold par note et progression stable.
- trigger etendu a
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- parser
audio.ambient_random.mode,playlist_root,playlist_recursive, - scan playlist (LittleFS/SD_MMC) + selection random d'un fichier audio,
- fallback robuste sur
tracksi playlist vide/invalide, - parser
render.lefou_detector.note_sequence_hz+note_hold_ms, - activation scene LEFOU sans timeout (timeout LA force a 0 sur LEFOU, restore default hors LEFOU),
- statut enrichi (
la_trigger.sequence_*).
- parser
hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.hhardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- parser
render.warning.lgfx_onlyetrender.warning.siren, SCENE_WARNINGforce LGFX overlay (pas de gyrophare LVGL quandlgfx_only=true).
- parser
- Source de verite scene + ecrans:
../../game/scenarios/scene_editor_all.yamldata/story/screens/SCENE_U_SON_PROTO.jsondata/story/screens/SCENE_LA_DETECTOR.jsondata/story/screens/SCENE_WARNING.jsondata/story/screens/SCENE_LEFOU_DETECTOR.json- U_SON:
mode=random_file,playlist_root=/music/v8_pack. - LA:
hourglass_x_offset_px=-25,hourglass_width_px=80,hourglass_height_px=150,bargraph_peak_hold_ms=900. - LEFOU: sequence par defaut
[440, 880, 330, 349, 147, 98].
- Gates executees:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OK.pio run -e freenove_esp32s3-> OK.python3 ../../tools/scenario/validate_scenario.py ../../game/scenarios/default_unlock_win_etape2.yaml-> FAIL (schema non compatible avec ce validateur: champstitle/players/...requis).python3 ../../tools/scenario/export_md.py ../../game/scenarios/default_unlock_win_etape2.yaml-> OK.python3 ../../tools/audio/validate_manifest.py ../../audio/manifests/zacus_v1_audio.yaml-> OK.python3 ../../tools/printables/validate_manifest.py ../../printables/manifests/zacus_v1_printables.yaml-> OK.
[2026-02-28] A252 hotline - hybrid telco clock + telephony power forced on
- Objectif: garder le SLIC alimente en permanence sur A252 et permettre un playback adaptable a la source (policy hybrid).
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_052436_wip.patch/tmp/zacus_checkpoint/20260228_052436_status.txt
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/config/A252ConfigStore.h- defaults A252:
clock_policy=HYBRID_TELCO,adc_dsp_enabled=false,adc_fft_enabled=false.
- defaults A252:
hardware/RTC_SLIC_PHONE/src/config/A252ConfigStore.cpp- validation
clock_policy: accepteHYBRID_TELCOetFIXED_TELCO.
- validation
hardware/RTC_SLIC_PHONE/src/main.cpp- ajout helper
isHybridTelcoClockPolicy(...)et application runtime du policy dansbuildI2sConfig. ensureA252AudioDefaults()force: capture off, adc dsp/fft off,clock_policy=HYBRID_TELCO.applyAudioPatch(...)force aussi ces valeurs sur profil A252.
- ajout helper
hardware/RTC_SLIC_PHONE/src/telephony/TelephonyService.h/.cpp- policy A252:
slic_powerforceon(pas de power-down idle/probe).
- policy A252:
- Build execute:
pio run -e esp32dev-> OK.
[2026-02-28] Telephony gating - no boot autoplay (on-hook) + hard stop on hangup
- Objectif: garantir "aucune lecture au boot sauf combine deja decroche" et "stop total audio au raccroche".
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/telephony/TelephonyService.cpp- blocage auto-relance dial tone quand un media est deja en cours (
!audio_->isPlaying()requis), - blocage dial tone instantane a l'entree OFF_HOOK si playback actif.
- coupure immediate tone+playback des le premier edge ON_HOOK (avant fin de debounce hangup).
- blocage auto-relance dial tone quand un media est deja en cours (
hardware/RTC_SLIC_PHONE/src/main.cpp- gate setup: si hook ON_HOOK au boot ->
stopPlayback()+stopTone()+ log explicite, - gate loop:
enforceOnHookSilence()stoppe toute lecture/tonalite des que hook ON_HOOK.
- gate setup: si hook ON_HOOK au boot ->
- Validation:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> OK- log boot observe:
[RTC_BL_PHONE] boot hook=ON_HOOK -> audio autoplay blocked.
[2026-02-28] A252 audio - hard-disable auto loudness processing
- Objectif: verrouiller la desactivation du loudness auto (normalize/limiter) au runtime pour eviter toute reactivation via config.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_032602_wip.patch/tmp/zacus_checkpoint/20260228_032602_status.txt
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpp- ajout d'un verrou runtime
kHardDisableAutoLoudnessProcessing=true, - centralisation de la policy via
wavAutoLoudnessEnabled(...), - forçage
wav_auto_normalize_limiter=falsedansAudioEngine::begin(...), - desactivation explicite des chemins analyse loudness dans
prepareWavPlayback,analyzeWavLoudnessGainDbetprobePlaybackFileFromSource.
- ajout d'un verrou runtime
- Effet attendu:
playback_loudness_auto=false,loudness_gain_db=0,limiter_active=falseen playback/probe.
[2026-02-28] A252 HOT-LINE - sync scene ESP-NOW + dial/ringback aleatoires
- Objectif: stabiliser la coherence hotline avec Freenove en ajoutant:
- refresh ESP-NOW toutes les 30s,
- synchro scene/status Freenove au decroche + periodique,
- dial tone aleatoire (FR_FR/ETSI_EU/UK_GB/NA_US),
- ringback aleatoire 5..25s avant lecture media hotline.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_015105_wip.patch/tmp/zacus_checkpoint/20260228_015105_status.txt
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/telephony/TelephonyService.h/.cpp- ajout profil dial off-hook aleatoire et relance deterministic du dial tone selectionne.
hardware/RTC_SLIC_PHONE/src/main.cpp- interval peer discovery ESP-NOW ramene a 30s,
- runtime
scene syncESP-NOW (requestUI_SCENE_STATUS, ack tracking, updateg_active_scene_id/g_active_step_id, validation state inferee), - trigger scene sync au decroche + periodique,
- ajout ringback aleatoire (profil + duree 5..25s) avant
post_ringback_route, - enrichissement statut hotline/espnow avec telemetrie ringback + scene sync.
- Build execute:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OK.
[2026-02-27] Hotfix FX rearm + line-buffer fallback (SCENE_U_SON_PROTO)
- Objectif: restaurer le fond anime direct-FX apres regression (
fx_enabled=1maisfx_frames=0) et stopper les boucles d'allocationfx_line. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_232630_wip.patch/tmp/zacus_checkpoint/20260227_232630_status.txt
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/fx/fx_engine.cpp:- fallback line-buffer
allocDefault(...)quandUI_FX_DMA_BLIT=0(CPU blit) siallocInternalDmaAlignedechoue. FxEngine::setEnabled(...)conditionne aready_+ ajout getterready().
- fallback line-buffer
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpp:- rearm direct-FX avec retry
begin(...)+ fallback sprite compact. - cooldown retry (
fx_rearm_retry_after_ms_) pour eviter retry every-frame.
- rearm direct-FX avec retry
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp:- application du cooldown dans les deux chemins de rearm (
update+renderScene). - telemetry
UI_GFX_STATUSenrichie:fx_enabled,fx_scene.
- application du cooldown dans les deux chemins de rearm (
hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.h:- ajout etat runtime
fx_rearm_retry_after_ms_.
- ajout etat runtime
- Validation executee:
pio run -e freenove_esp32s3-> OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK- Serie:
SCENE_GOTO SCENE_U_SON_PROTOpuisUI_GFX_STATUS->fx_enabled=1,fx_scene=1,fx_frames=121,fx_fps=9.- plus de spam continu
alloc_fail ... fx_lineen regime nominal.
[2026-02-27] SCENE_WIN_ETAPE - anti-saccade overlay LGFX (DMA busy recovery)
- Objectif: reduire le blink/saccade et les pertes de texte LGFX sur
SCENE_WIN_ETAPEen cas de contention flush/DMA. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_220518_wip.patch/tmp/zacus_checkpoint/20260227_220518_status.txt
- Audit cible:
- contention constatee dans
UiManager::update()entre rendu FX, flush LVGL et overlay LGFX (timeoutsoverlay_skip_busy_count_). - mode
SCENE_WIN_ETAPEdetecte comme scene sensible entext_backend=lgfx_overlay.
- contention constatee dans
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp:- cadence frame WIN_ETAPE LGFX alignee a 25 FPS via
kUiUpdateFrameMsLaDetectorLgfx(40 ms), - ajout d'un mode priorite overlay WIN_ETAPE (budget attente DMA augmente + retry drain DMA final),
- ajout d'un mecanisme de recovery court: suspension FX sur 2 frames apres timeout overlay pour restaurer la lisibilite texte,
- conservation stricte de l'ordre de rendu (FX -> LVGL -> overlay LGFX).
- cadence frame WIN_ETAPE LGFX alignee a 25 FPS via
hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.h:- ajout etat runtime
overlay_recovery_frames_.
- ajout etat runtime
- Gates executees:
pio run -e freenove_esp32s3-> OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OKpython3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --timeout 3-> PASS (PING/PONGstable)
- Limitation / suite:
- validation visuelle et serie hardware encore a confirmer sur banc (
UI_GFX_STATUS,overlay_skip_busy, perception blink). - injection scene manuelle
SCENE SCENE_WIN_ETAPEnon disponible sur ce binaire (retour serie:UNKNOWN SCENE SCENE_WIN_ETAPE).
- validation visuelle et serie hardware encore a confirmer sur banc (
[2026-02-27] SCENE_LA_DETECTOR — preset reutilisable wirecube+rotozoom (LGFX)
- Objectif: remplacer le fond sablier de
SCENE_LA_DETECTORpar un preset fond demoscene subtil (wirecube + rotozoom) avec sync micro lissee, en restant retro-compatible. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_191811_wip.patch/tmp/zacus_checkpoint/20260227_191811_status.txt
- Correctifs appliques:
hardware/firmware/hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.h:- ajout enums
LaBackgroundPreset/LaBackgroundSync, - ajout etats runtime
la_bg_preset_,la_bg_sync_,la_bg_intensity_pct_,la_bg_mic_lpf_,la_bg_last_ms_.
- ajout enums
hardware/firmware/hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp:- parsing JSON
render.la_detector.background_preset|background_sync|background_intensity_pct, - clamp strict
background_intensity_pct(0..100), - branche rendu
kLegacyHourglassvskWirecubeRotozoomSubtle, - sync micro lissee (LPF) + mode
fixed/mic_smoothed/mic_direct, - sablier legacy affiche uniquement si preset legacy.
- parsing JSON
hardware/firmware/data/story/screens/SCENE_LA_DETECTOR.json:show_hourglass=false,- activation preset:
background_preset=wirecube_rotozoom_subtle, - sync:
background_sync=mic_smoothed, - intensite:
background_intensity_pct=32.
hardware/firmware/data/ui/fx/demoscene_fx_manifest.v1.json:- version
1.3.3, - notes preset
la_detectormaj (wirecube+rotozoom + fallback legacy), - ajout
overlay_fx_types.la_detector_bg_wirecube_rotozoomavec contrat payload.
- version
- Gates executees:
python3 /Users/cils/.codex/skills/demoscene-fx-creator/scripts/fx_inventory.py --repo-root /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus --check-manifest --strict-> OKpio run -e freenove_esp32s3-> OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK
- Artefacts trackes scan:
- aucun fichier tracke detecte dans
.pio,.platformio,logs,dist,build,node_modules,.venv.
- aucun fichier tracke detecte dans
[2026-02-27] SCENE_LA_DETECTOR — fond demoscene wirecube+rotozoom discret (LGFX)
- Objectif: renforcer le fond sablier en style demoscene (wirecube + rotozoom), sombre et non intrusif, avec modulation sur niveau micro.
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_185939_wip.patch/tmp/zacus_checkpoint/20260227_185939_status.txt
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp:- fond plein ecran sombre explicite sur overlay LGFX (evite rendu parasite LVGL visible),
- waveform LA recadree (zone cible ~75% largeur / ~50% hauteur, centree en Y),
- jauge circulaire recadree a droite (diametre derive de 30% largeur / 50% hauteur, centree en Y),
- ajout fond demoscene discret: grille rotozoom sombre + wirecube filaire, vitesse/intensite liees a
mic_level_percent, - aucun glitch/jitter ajoute.
- Gates executees:
pio run -e freenove_esp32s3-> OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK
- Artefacts trackes scan:
- aucun fichier tracke detecte dans
.pio,.platformio,logs,dist,build,node_modules,.venv.
- aucun fichier tracke detecte dans
[2026-02-27] SCENE_LA_DETECTOR LGFX only (sans glitch) + double jauge
- Objectif: rendre
SCENE_LA_DETECTORen overlay LovyanGFX visible-only (LVGL masque), sans effet glitch, avec sablier wireframe 3D timeout + double anneau timeout/stabilite + spectre vert->rouge. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_184236_wip.patch/tmp/zacus_checkpoint/20260227_184236_status.txt
- Correctifs appliques:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp:- desactivation runtime du preset FX direct pour
SCENE_LA_DETECTOR(direct_fx_scene_runtimeexclut LA detector), - overlay LA refondu sans jitter/glitch local,
- sablier wireframe pseudo-3D anime (roto doux) pilote par
gate_remain, - double anneau circulaire (externe timeout 96 segments, interne stabilite 84 segments),
- spectre 60 bandes conserve en pleine largeur, couleur mappee par amplitude vert->jaune->rouge.
- desactivation runtime du preset FX direct pour
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpp:- masquage explicite des widgets LVGL de base (
setBaseSceneFxVisible(false)) quand LA detector est enlgfx_overlay.
- masquage explicite des widgets LVGL de base (
- Gate executee:
pio run -e freenove_esp32s3-> OK
- Artefacts trackes scan:
- aucun fichier tracke detecte dans
.pio,.platformio,logs,dist,build,node_modules,.venv.
- aucun fichier tracke detecte dans
[2026-02-27] A252 FS_LIST firmware (liste SD/LittleFS paginee)
- Objectif: exposer une commande firmware
FS_LISTpour inventorier les fichiers depuis la carte A252 sans montage PC. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_164113_wip.patch/tmp/zacus_checkpoint/20260227_164113_status.txt
- Implémentation:
hardware/RTC_SLIC_PHONE/src/main.cpp: ajoutFS_LIST(defaults SD, pagination JSON, recursion DFS, filtres dirs/files, shorthandsd|littlefs|auto, parse JSON args, codes erreursinvalid_*,mount_failed,open_failed,not_directory).hardware/RTC_SLIC_PHONE/README.md: ajout section usageFS_LIST(serie/API control, pagination).
- Build/flash:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> OK
- Smoke serie:
FS_LIST-> JSON valide (source_requested=SD,source_used=SD, pagination activehas_next/next_page).FS_LIST littlefs-> JSON valide avec assets locaux (/welcome.wav,/souffle.wav,/radio.wav...).- pagination valide (
page=0/1disjointe). - erreurs valides:
invalid_source,invalid_path,invalid_page,invalid_page_size.
[2026-02-27] Hotfix ESP-NOW bench Freenove/A252 (usbmodem + usbserial)
- Objectif: restaurer le flux HOT-LINE A252 -> Freenove avec
SC_EVENT espnow ACK_*sur banc PIO local. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_160846_wip.patch/tmp/zacus_checkpoint/20260227_160846_status.txt
- Correctifs appliques:
- Freenove: alignement canal radio preferentiel
6(fallback AP + hint ESP-NOW) et exposition du canal dans les statuts. - Freenove: parsing envelope
SC_EVENTcorrige (argsobjet JSON correctement lu). - A252: envoi
HOTLINE_VALIDATErepasse enbroadcastet bridge ESP-NOW auto-enregistre le peer (incluant broadcast) avant envoi.
- Freenove: alignement canal radio preferentiel
- Builds/flash:
pio run -e freenove_esp32s3-> OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> OK
- Validation E2E serie:
- Freenove
ESPNOW_STATUS_JSONexposechannel=6, receptionrx_countincrementee. - Freenove recoit
SC_EVENT ACK_WIN1depuis A252 et transitionneRTC_ESP_ETAPE1 -> WIN_ETAPE1. - Freenove recoit
SC_EVENT ACK_WARNINGet transitionneWIN_ETAPE1 -> STEP_WARNING. - Freenove recoit
SC_EVENT ACK_WIN2et transitionneRTC_ESP_ETAPE1 -> RTC_ESP_ETAPE2. - A252 recoit
WAITING_VALIDATION(last_notify_event=waiting_validation, last_notify_ok=true).
- Freenove
[2026-02-27] Focus PIO Freenove usbmodem + A252 usbserial
- Scope: validation ciblee sur deux cartes uniquement (Freenove + A252), sans toucher
hardware/firmware/esp32/. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_153546_wip.patch/tmp/zacus_checkpoint/20260227_153546_status.txt
- Builds/gates executes:
./tools/dev/story-gen validate-> OK./tools/dev/story-gen generate-bundle-> OK (artifacts/story_fs/deploy)pio run -e freenove_esp32s3-> OKpio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> OK./build_all.sh-> FAIL connu surui_rp2040_ili9488etui_rp2040_ili9486(input in flex scanner failed), autres envs OK./tools/dev/run_matrix_and_smoke.sh-> build FAIL (RP2040), port resolve SKIP (CP2102 non distinguables par fingerprint/location dans ce banc)
- Flash PIO cible:
- Freenove (
/dev/cu.usbmodem5AB90753301):pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK - A252 (
/dev/cu.usbserial-0001):pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> OK
- Freenove (
- Probes serie rapides (115200):
- Freenove:
UI_LINK_STATUSretourneUNKNOWN UI_LINK_STATUSsur ce binaire. - A252:
HOTLINE_STATUSretourne JSON attendu. - A252: correctif applique sur
HOTLINE_VALIDATEpour cibler le premier peer configure (fallback broadcast). - A252:
HOTLINE_VALIDATE WIN1retourne maintenantOK HOTLINE_VALIDATE ACK_WIN1. - E2E actuel: A252 compte
tx_failet Freenove garderx=0(paire vue des deux cotes mais message non recu dans ce banc; probable mismatch radio/channel a valider sur setup physique). - A252:
WAITING_VALIDATIONen commande serie directe ->unsupported_command(chemin prevu: commande entrante ESP-NOW).
- Freenove:
- Artefacts run matrix:
artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260227-145416
[2026-02-27] Sprint global en cours — audit scenes LGFX + audio chain + BL/WS2812 sync (Freenove)
- Scope verrouille:
freenove_esp32s3_full_with_ui, sans modificationhardware/firmware/esp32/. - Checkpoint securite:
/tmp/zacus_checkpoint/20260227_133431_wip.patch/tmp/zacus_checkpoint/20260227_133431_status.txt
- Etat preflight:
- worktree deja dirty (modifications pre-existantes dans
main.cpp,ui_manager.cpp,display_hal_lgfx.cpp,hourglass.cpp). - artefacts trackes verifies: aucun dans
.pio,.platformio,logs,dist,build,node_modules,.venv.
- worktree deja dirty (modifications pre-existantes dans
- Plan d'execution:
- audit global scenes YAML/JSON/fallback + chaines runtime overlay/audio,
- durcissement overlay LGFX (retry/counters foreground) et correction sablier LA,
- correction audio U_SON (ambient random espace) + verification sonar LA,
- reintegration BL/WS2812 sync micro U_SON + build/upload/uploadfs Freenove.
- Verifications executees:
python3 /Users/cils/.codex/skills/zacus-scene-screen-specialist/scripts/scene_screen_sync.py --repo-root ../.. audit-all->summary: scenes=24 mismatched=0./tools/dev/story-gen validate-> OKpython3 tools/dev/check_no_duplicate_payload_files.py --repo-root ../.. --scope data-> OKpython3 tools/dev/audit_scene_trigger_chain.py --repo-root ../.. --focus ALL_DEFAULT-> OK (artifacts/rc_live/audit_scene_trigger_chain_20260227T125339Z.json)- build matrix:
esp32devOK,esp32_releaseOK,esp8266_oledOK,ui_rp2040_ili9488/ili9486FAIL preexistant (input in flex scanner failedsur generation.../esp32_audio/.pio.pio.h),freenove_esp32s3_full_with_uiFAIL avec build dir default.pio(depfiles intermittents manquants). - rebuild Freenove avec build dir dedie:
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui-> OK. - flash code Freenove:
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK. - flash LittleFS Freenove:
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301-> OK. - checkpoint complementaire (diag texte absent):
/tmp/zacus_checkpoint/20260227_141500_wip.patch,/tmp/zacus_checkpoint/20260227_141500_status.txt. - ajustements complementaires Freenove (demande utilisateur):
- retrait du blocage overlay texte quand
intro_active_dansui_manager.cpp, - fallback police builtin force si atlas custom LGFX ne dessine aucun pixel (
display_hal_lgfx.cpp), - FX sablier background LA inverse + cadence sur 60s (
data/ui/fx/timelines/la_detector_hourglass.json,hourglass.cpp).
- retrait du blocage overlay texte quand
- validations Freenove:
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui-> OK.... -t upload --upload-port /dev/cu.usbmodem5AB90753301-> OK.python3 tools/dev/check_no_duplicate_payload_files.py --repo-root ../.. --scope data-> OK.... -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301-> OK.
[2026-02-26] Run en cours — strict triggers + U_SON/LA overlay + audit chain
- Scope verrouille: Freenove
freenove_esp32s3_full_with_ui(aucun changementhardware/firmware/esp32/). - Checkpoint securite:
/tmp/zacus_checkpoint/20260226_231605_wip.patch/tmp/zacus_checkpoint/20260226_231605_status.txt
- Etat preflight:
- worktree deja dirty (nombreuses modifs pre-existantes, conflit non resolu
tools/fonts/ttf/README.mdconserve hors scope). - artefacts trackes verifies: aucun dans
.pio,.platformio,logs,dist,build,node_modules,.venv.
- worktree deja dirty (nombreuses modifs pre-existantes, conflit non resolu
- Plan d'execution applique:
- normalisation triggers
U_SON -> LA -> WIN_ETAPE -> WIN_ETAPE1(strict production), - timeout LA -> retour scene
SCENE_U_SON_PROTO, - U_SON (titre reduit + zoom subtil + BG plus sombre + mods glitch timeline),
- LA_DETECTOR (jauge circulaire + sablier timeout + caption bas),
- audit automatisé chain triggers + gates build/flash.
- normalisation triggers
[2026-02-26] Freenove scenes lock (LA_DETECTOR / WIN_ETAPE / WIN_ETAPE1 / U_SON_PROTO) + anti-doublons uploadfs
- Decision STOP: cleanup massif conserve (decision produit utilisateur) ;
docs/STOP_REQUIRED.mdgarde la trace. - Checkpoint securite:
/tmp/zacus_checkpoint/20260226_175805_wip.patch/tmp/zacus_checkpoint/20260226_175805_status.txt
- Anti-doublons:
- ajout
tools/dev/check_no_duplicate_payload_files.py(scandata/**sur motifs* 2.*,* 3.*). - ajout hook PlatformIO pre-uploadfs
tools/dev/pio_check_no_duplicate_payloads.py. - branchement env Freenove via
platformio.ini(extra_scripts). - export workbench renforce (
tools/dev/export_scene_editor_workbench.py) pour ignorer les copies suffixees.
- ajout
- Scenes:
SCENE_U_SON_PROTO: theme accent magenta, titre taille 100, backlight/WS2812 enlevel_syncavec bornes<100.SCENE_WIN_ETAPE1:effect=tunnel3daligne YAML/JSON.SCENE_LA_DETECTOR: oscilloscope force en palette verte (lisibilite constante).
- Runtime:
main.cpp: ajout modelevel_syncbacklight + WS2812 (single random blink, brightness dynamique sur niveau micro).ui_manager.cpp: titre U_SON plus grand + zoom pulsé en overlay LGFX.
[2026-02-26] Desactivation mire TEST_LAB forcee
- Checkpoint securite:
/tmp/zacus_checkpoint/1772091501_wip.patch/tmp/zacus_checkpoint/1772091501_status.txt
- Correctif:
kForceTestLabSceneLockpasse afalsedanshardware/firmware/ui_freenove_allinone/src/app/main.cpp.
- Validation:
pio run -e freenove_esp32s3_full_with_ui✅
[2026-02-26] Correctif structurel PlatformIO (src_dir global firmware) + build/upload OK
- Checkpoint securite:
/tmp/zacus_checkpoint/1772088629_wip.patch/tmp/zacus_checkpoint/1772088629_status.txt
- Correctif structurel applique:
platformio.ini:[platformio].src_dirpasse dehardware/firmware/esp32_audio/srcahardware/firmware.- recalage
build_src_filterpour toutes les cibles afin de pointer explicitement les sous-arbres source:esp32dev/esp32_release->esp32_audio/src+ story libs (../libs/story/...)freenove_esp32s3_full_with_ui->ui_freenove_allinone/src(+ exclusions legacy root)ui_rp2040_ili9488etui_rp2040_ili9486->ui/rp2040_tft/srcesp8266_oled->ui/esp8266_oled/src
- Resultat:
- les objets Freenove sont maintenant generes dans
.pio/build/freenove_esp32s3_full_with_ui/src/ui_freenove_allinone/...(plus de sortie parasite.pio/build/ui_freenove_allinone/...). - echec
No such file or directorysurapp_coordinator.cpp.oresolu.
- les objets Freenove sont maintenant generes dans
- Validation:
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t upload✅- port auto-detecte:
/dev/cu.usbmodem5AB90753301
[2026-02-26] Triage build Freenove full_with_ui (legacy duplicate + variant dir PlatformIO)
- Checkpoint securite:
/tmp/zacus_checkpoint/1772088629_wip.patch/tmp/zacus_checkpoint/1772088629_status.txt
- Analyse:
- echec initial sur mismatch API
AudioManagerentre:hardware/firmware/ui_freenove_allinone/src/audio_manager.cpp(legacy)hardware/firmware/ui_freenove_allinone/include/audio/audio_manager.h+src/audio/audio_manager.cpp(actuel)
- echec structurel additionnel PlatformIO: generation d'objets/deps dans
.pio/build/ui_freenove_allinone/src/...avec erreur recurrenteNo such file or directoryau moment d'ecriture (app_coordinator.cpp.o,*.cpp.d), y compris en-j 1.
- echec initial sur mismatch API
- Correctifs appliques:
platformio.ini(env:freenove_esp32s3_full_with_ui):- exclusion des unites legacy root migrees (
src/main.cpp,src/audio_manager.cpp,src/camera_manager.cpp,src/ui_manager.cpp, etc.) pour ne compiler que l'arborescence moderne (src/app,src/audio,src/camera,src/ui, ...). - ajout
build_unflags = -MMD(reduction des erreurs sur fichiers.dhors variant dir). - ajout
extra_scripts = pre:tools/dev/pio_prepare_variant_dirs.py.
- exclusion des unites legacy root migrees (
- ajout script
tools/dev/pio_prepare_variant_dirs.py(creation pre-build de la hierarchie.pio/build/ui_freenove_allinone/src/**).
- Resultat actuel:
- mismatch
AudioManagercorrige (erreurs symboles disparues). - blocage persistant sur creation d'objets externes dans
.pio/build/ui_freenove_allinone/src/app/*.o(build toujours FAIL).
- mismatch
- Commandes executees:
pio run -e freenove_esp32s3_full_with_ui -t cleanpio run -e freenove_esp32s3_full_with_uipio run -e freenove_esp32s3_full_with_ui -j 1- tentative precreate dirs
.pio/build/ui_freenove_allinone/src/**avant build
- Limitation:
- upload non lance tant que le build ne passe pas.
[2026-02-26] Calibration demandee "BGR565" (passe B compile-time)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T055214Z_wip.patch/tmp/zacus_checkpoint/20260226T055214Z_status.txt
- Decision appliquee:
- En pratique, le mode reste RGB565 avec ordre panneau BGR (
TFT_RGB_ORDER=TFT_BGR), pas un format bpp different. hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h(3 variantes LCD).
- En pratique, le mode reste RGB565 avec ordre panneau BGR (
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload✅
- Verification serie:
UI_GFX_STATUS:depth=16 mode=RGB565✅SCENE_GOTO SCENE_TEST_LAB:ACK ... ok=1✅UI_SCENE_STATUS:scene_id=SCENE_TEST_LAB, subtitle palette canonique ✅
- Validation visuelle ecran:
- en attente retour utilisateur sur l'ordre percu mire + scroller.
[2026-02-26] Alignement final LVGL DMA sur contrat FX + recalibration BGR
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T052733Z_wip.patch/tmp/zacus_checkpoint/20260226T052733Z_status.txt
- Retour visuel:
- mire:
NBBGRJCM - texte:
BGRJMC
- mire:
- Correctif:
pushImageDmaLGFX n'utilise pluspushImageDMA<T>(chemin d'interpretation different).pushImageDmapasse maintenant par:setAddrWindow(...)writePixelsDMA(..., swap=true)
- objectif: appliquer strictement le meme contrat RGB565+swap que
pushColors(..., true)(parite LVGL/FX). - fichier:
hardware/firmware/ui_freenove_allinone/src/drivers/display/display_hal_lgfx.cpp - calibration panneau remise en
TFT_BGR(3 variantes) danshardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h.
[2026-02-26] Recalibration panneau apres validation visuelle (RGB retenu)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T052733Z_wip.patch/tmp/zacus_checkpoint/20260226T052733Z_status.txt
- Retour utilisateur apres lot precedent:
- mire:
NBBGRJMC - texte:
RVBJMC
- mire:
- Decision:
- le contrat pipeline LVGL+FX reste unifie (RGB565), mais calibration panneau bascule en
TFT_RGB.
- le contrat pipeline LVGL+FX reste unifie (RGB565), mais calibration panneau bascule en
- Correctif:
hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.hTFT_RGB_ORDERrepasse aTFT_RGBpour les 3 variantes.
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload✅
- Verification serie:
UI_GFX_STATUSconfirmedepth=16 mode=RGB565✅SCENE_GOTO SCENE_TEST_LAB+UI_SCENE_STATUSconfirment scene test lock active ✅
[2026-02-26] Correction pipeline couleur LVGL+LGFX (contrat RGB565 unifie)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T051611Z_wip.patch/tmp/zacus_checkpoint/20260226T051611Z_status.txt
- Baseline pre-patch capturee:
- commandes serie:
UI_GFX_STATUS,SCENE_GOTO SCENE_TEST_LAB,UI_SCENE_STATUS - observation ecran reference user:
- mire:
NOIR, BLANC, ROUGE, BLEU, VERT, CYAN, JAUNE, MAGENTA - texte FX:
BLEU, VERT, ROUGE, JAUNE, MAGENTA, CYAN
- mire:
- commandes serie:
- Correctif applique (scope pipeline uniquement):
- contrat HAL documente:
pushImageDmaetpushColors(..., true)doivent consommer le meme format logique RGB565.hardware/firmware/ui_freenove_allinone/include/drivers/display/display_hal.h
- chemin LVGL DMA aligne sur RGB565 LGFX (plus de voie
swap565implicite):hardware/firmware/ui_freenove_allinone/src/drivers/display/display_hal_lgfx.cpppushImageDMA(..., reinterpret_cast<const lgfx::rgb565_t*>(pixels))
- calibration panneau compile-time reglee en BGR sur les 3 variantes:
hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h
- contrat HAL documente:
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload✅
- Verification post-flash:
UI_GFX_STATUSconfirmedepth=16 mode=RGB565 backend=LGFX✅SCENE_GOTO SCENE_TEST_LAB+UI_SCENE_STATUSconfirment mire active (TEST_LAB_LOCK) ✅- regression
SCENE_U_SON_PROTO,SCENE_LA_DETECTOR,SCENE_FINAL_WINexecutee; lock test lab force le retourSCENE_TEST_LAB(comportement attendu en mode calibration) ⚠️
[2026-02-26] Calibration couleur: alignement LGFX flush DMA + retour RGB global
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T044708Z_wip.patch/tmp/zacus_checkpoint/20260226T044708Z_status.txt
- Symptome recu:
- mire observee:
NOIR BLANC ROUGE BLEU VERT CYAN JAUNE MAGENTA - scroller LGFX observe:
BLEU VERT ROUGE JAUNE MAGENTA CYAN
- mire observee:
- Correctif applique:
- retour
TFT_RGB_ORDERaTFT_RGB(3 variantes LCD):hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h
- restauration du type LGFX attendu sur flush DMA LVGL:
display_.pushImageDMA(..., reinterpret_cast<const lgfx::swap565_t*>(pixels));hardware/firmware/ui_freenove_allinone/src/drivers/display/display_hal_lgfx.cpp
- retour
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload✅
- Verification serie post-flash:
UI_GFX_STATUS:depth=16 mode=RGB565 dma_async=1 backend=LGFX✅SCENE_GOTO SCENE_TEST_LAB+UI_SCENE_STATUS: scene test lock active + subtitle palette canonique ✅
[2026-02-26] Correction couleur globale UI Freenove: passage RGB (LCD panel)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T043651Z_wip.patch/tmp/zacus_checkpoint/20260226T043651Z_status.txt
- Baseline pre-fix (avant flash RGB):
- commandes serie:
UI_GFX_STATUS,UI_SCENE_STATUS,SCENE_GOTO SCENE_TEST_LAB - statut:
mode=RGB565, scene activeSCENE_TEST_LAB, subtitle palette canonique presente. - observation utilisateur precedente conservee comme evidence: inversion R/B visible a l'ecran.
- commandes serie:
- Correctif applique:
TFT_RGB_ORDERforce aTFT_RGBpour les 3 variantes LCD danshardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h.- mapping LovyanGFX conserve via
cfg.rgb_orderderive deTFT_RGB_ORDER(hardware/firmware/ui_freenove_allinone/src/drivers/display/display_hal_lgfx.cpp). - pas de changement sur
LV_COLOR_16_SWAP, policy theme, JSON story, ni cycle scroller.
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload✅
- Verification post-flash:
UI_GFX_STATUS:depth=16 mode=RGB565 theme256=0✅SCENE_GOTO SCENE_TEST_LAB+UI_SCENE_STATUS: scene/test payload actifs ✅- lock scene test toujours actif (
kForceTestLabSceneLock=true), donc lesSCENE_GOTOvers autres scenes reviennent surSCENE_TEST_LAB(comportement attendu dans ce mode).
- Limitation:
- regression visuelle multi-scenes non executable tant que le lock test est actif compile-time.
- validation visuelle finale demandee sur hardware: ordre mire + couleurs du scroller RVBCMJ.
[2026-02-26] TEST_LAB lock + FX texte wave + RGB confirme
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T040721Z_wip.patch/tmp/zacus_checkpoint/20260226T040721Z_status.txt/tmp/zacus_checkpoint/20260226T040313Z_wip.patch/tmp/zacus_checkpoint/20260226T040313Z_status.txt
- Correctifs:
- lock test scene reactive:
kForceTestLabSceneLock=truedansui_freenove_allinone/src/app/main.cpp. - ajout FX texte wave sur
SCENE_TEST_LAB(anim sinus sur sous-titre) dansui_freenove_allinone/src/ui/ui_manager.cpp. TFT_RGB_ORDERlaisse enTFT_RGB(demande "remettre en RGB").
- lock test scene reactive:
- Build/flash:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
[2026-02-26] Palette globale LVGL+GFX: alignement TFT_RGB_ORDER sur Freenove
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T034545Z_wip.patch/tmp/zacus_checkpoint/20260226T034545Z_status.txt
- Correctif global couleur:
- declaration explicite
TFT_RGB_ORDER TFT_BGRajoutee pour variantes ST7796:hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h
- backend LovyanGFX aligne sur macro panel:
cfg.rgb_orderderive deTFT_RGB_ORDERdanshardware/firmware/ui_freenove_allinone/src/drivers/display/display_hal_lgfx.cpp
- mire
SCENE_TEST_LABremise en palette canonique (plus de compensation locale RGB):hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp
- declaration explicite
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
[2026-02-26] SCENE_TEST_LAB: suppression fond noir sous titre/sous-titre
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T034545Z_wip.patch/tmp/zacus_checkpoint/20260226T034545Z_status.txt
- Correctif (scene test uniquement):
- retrait du fond noir opacifie sous les labels de
SCENE_TEST_LAB. - styles labels forces en fond transparent (
LV_OPA_TRANSP), padding0, radius0. - applique dans les deux passes de stylage (state static + post dynamic) pour eviter le retour des blocs noirs.
- retrait du fond noir opacifie sous les labels de
- Build/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie:
UI_SCENE_STATUSconfirmescene_id=SCENE_TEST_LAB,step_id=TEST_LAB_LOCK,show_title=true,show_subtitle=true✅
[2026-02-26] SCENE_TEST_LAB: texte force visible + scene lock test + flash FS
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T032507Z_wip.patch/tmp/zacus_checkpoint/20260226T032507Z_status.txt
- Correctifs cibles (SCENE_TEST_LAB uniquement):
- verrou runtime test actif (
kForceTestLabSceneLock=true) pour rester surSCENE_TEST_LAB. - override rendu: scene forcee
SCENE_TEST_LAB+ step logiqueTEST_LAB_LOCK. - labels titre/sous-titre re-styles apres dynamic state avec
lv_obj_remove_style_all(...)puis style explicite (font, couleur, opa, bg, padding, align) pour eviter blocs noirs sans texte. - payload scene test aligne avec sous-titre compact:
NOIR | BLANC | ROUGE | VERT | BLEU | CYAN | MAGENTA | JAUNE
- verrou runtime test actif (
- Flash/gates executes:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅
- Verification serie:
UI_SCENE_STATUS:scene_id=SCENE_TEST_LAB,step_id=TEST_LAB_LOCK,show_title=true,show_subtitle=true, payload/story/screens/SCENE_TEST_LAB.json✅
[2026-02-26] Boot: desactivation auto scene palette + backlight par defaut 30
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T015322Z_wip.patch/tmp/zacus_checkpoint/20260226T015322Z_status.txt
- Correctifs:
- scene boot palette automatique desactivee (
kBootPaletteAutoOnBoot=false) pour ne plus rester sur la mire au boot. - retroeclairage LCD par defaut au boot fixe a
30(g_lcd_backlight_level=30).
- scene boot palette automatique desactivee (
- Build + upload Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie:
STATUSau boot:step=SCENE_U_SON_PROTO✅LCD_BACKLIGHT:level=30✅
[2026-02-26] SCENE_TEST_LAB: compensation ordre couleur TFT_BGR
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T031015Z_wip.patch/tmp/zacus_checkpoint/20260226T031015Z_status.txt
- Constat:
- la mire etait bien active mais les couleurs etaient lues
NOIR BLANC BLEU ROUGE VERT JAUNE CYAN MAGENTA. - cause: panel en ordre
TFT_BGR, donc inversion R/B sur les barres RGB de test.
- la mire etait bien active mais les couleurs etaient lues
- Correctif:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- ajout d'une conversion
toPanelOrder(...)appliquee uniquement a la mireSCENE_TEST_LABquandTFT_RGB_ORDER == TFT_BGR. - objectif: conserver l'ordre visuel canonique
NOIR BLANC ROUGE VERT BLEU CYAN MAGENTA JAUNEsur l'ecran physique.
- Gates/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
[2026-02-26] SCENE_TEST_LAB: overlay texte force (titre + liste)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T031519Z_wip.patch/tmp/zacus_checkpoint/20260226T031519Z_status.txt
- Constat:
- titre/sous-titre non visibles sur la mire selon validation ecran.
- la liste multi-ligne passait par un mode
LV_LABEL_LONG_DOTqui ne convient pas a une mire en lignes.
- Correctif:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- en
SCENE_TEST_LAB:- fond contraste noir semi-opaque sur titre/sous-titre
- pads/rayon pour lisibilite
- subtitle en
LV_LABEL_LONG_WRAP+ largeur forcee - alignement explicite top/bottom
- reset des styles de fond/padding hors
SCENE_TEST_LABpour eviter regressions.
- Gates/flash:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅
[2026-02-26] SCENE_TEST_LAB: mire fixe visible au boot
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T025819Z_wip.patch/tmp/zacus_checkpoint/20260226T025819Z_status.txt
- Correctif:
SCENE_TEST_LABn'est plus forcé vide côté UI fallback.- Le fallback interne de
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cppexpose désormais la mire fixe par défaut (texte + fond noir, aucun FX). - La scène est forcée côté boot via
SCENE_TEST_LABdans le code runtime (déjà en place), et la payload/story/screens/SCENE_TEST_LAB.jsonest chargée côté FS.
- Gates/flash/validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅
[2026-02-26] Pre-scene boot palette + commande LCD_BACKLIGHT
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T013435Z_wip.patch/tmp/zacus_checkpoint/20260226T013435Z_status.txt
- Ajouts:
- pre-scene boot palette temporaire (
SCENE_BOOT_PALETTE) affichee avant la scene story initiale. - payload ajoute:
data/story/screens/SCENE_BOOT_PALETTE.jsondata/screens/SCENE_BOOT_PALETTE.json
- commande serie ecran:
LCD_BACKLIGHT [0..255](set/get) dansui_freenove_allinone/src/app/main.cpp.
- pre-scene boot palette temporaire (
- Build + upload Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie:
LCD_BACKLIGHT 140->ACK LCD_BACKLIGHT ok=1LCD_BACKLIGHT->LCD_BACKLIGHT level=140✅
[2026-02-26] Verrou temporaire NVS media manager (STEP_MEDIA_MANAGER)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T011719Z_wip.patch/tmp/zacus_checkpoint/20260226T011719Z_status.txt
- Correctif:
- blocage explicite de l'action
ACTION_SET_BOOT_MEDIA_MANAGERpour empecher toute ecriture NVS vers le mode media manager. - fichier:
hardware/firmware/ui_freenove_allinone/src/app/main.cpp - comportement: force le mode runtime
STORYet log[ACTION] SET_BOOT_MEDIA_MANAGER blocked nvs_lock=1.
- blocage explicite de l'action
- Build + upload Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie:
BOOT_MODE_STATUSavant/apresSCENE_GOTO SCENE_MEDIA_MANAGERrestemode=story- log de blocage observe:
[ACTION] SET_BOOT_MEDIA_MANAGER blocked nvs_lock=1✅
[2026-02-26] Wildcard bouton ANY -> BTN*_SHORT/LONG (global runtime)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226T010816Z_wip.patch/tmp/zacus_checkpoint/20260226T010816Z_status.txt
- Correctif applique globalement (sans changement de schema scenario):
button/ANYmatche maintenant tout nom bouton non vide (ex:BTN1_SHORT,BTN3_LONG) dans:hardware/firmware/ui_freenove_allinone/src/app/scenario_manager.cpphardware/libs/story/src/core/story_engine_v2.cpp
- matching strict conserve pour les autres types d'evenements.
- Documentation contrat:
- note runtime ajoutee dans
docs/protocols/story_specs/README.md.
- note runtime ajoutee dans
- Gates executees:
python3 tools/dev/verify_story_default_flow.py✅pio run -e freenove_esp32s3✅
[2026-02-26] UI Freenove conforme /data (palette v3 + UI_SCENE_STATUS + verification profonde)
- Skills chain active (ordre):
freenove-firmware-orchestratorfirmware-story-stackfirmware-littlefs-stackfirmware-graphics-stackfirmware-build-stack
- Checkpoint securite reutilise (run en cours):
/tmp/zacus_checkpoint/20260225_235911_wip.patch/tmp/zacus_checkpoint/20260225_235911_status.txt
- Lot 1 (source de verite
/data):- ajout palette canonique:
data/story/palette/screens_palette_v3.yaml
- ajout commande tooling:
./tools/dev/story-gen sync-screens(--checksupporte)- fichiers:
lib/zacus_story_gen_ai/src/zacus_story_gen_ai/cli.py,lib/zacus_story_gen_ai/src/zacus_story_gen_ai/generator.py
- regeneration ecrans depuis palette:
data/story/screens/*.json(set canonique complet)data/screens/*.json(mirror legacy durable)
- source prioritaire intro Win Etape alignee:
data/ui/scene_win_etape.json
- ajout palette canonique:
- Lot 2 (runtime UI + diagnostic):
- metadata source payload ecran exposee:
StorageManager::ScenePayloadMeta+lastScenePayloadMeta()hardware/firmware/ui_freenove_allinone/include/storage/storage_manager.hhardware/firmware/ui_freenove_allinone/src/storage/storage_manager.cpp
- snapshot rendu scene ajoute:
UiSceneStatusSnapshot+sceneStatusSnapshot()hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.hhardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp
- nouvelle commande serie JSON mono-ligne:
UI_SCENE_STATUShardware/firmware/ui_freenove_allinone/src/app/main.cpp
- reduction overrides tardifs lock/win_etape (JSON domine le statique) + cache parse payload hors changements de scene:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp
- metadata source payload ecran exposee:
- Lot 3 (verification profonde UI):
- nouveau validateur:
tools/dev/verify_story_ui_conformance.py
- combine transitions deep + lecture
UI_SCENE_STATUS+ comparaison/data/story/screensavec allowlist dynamique QR/WIN_ETAPE.
- nouveau validateur:
- Stabilite complementaire:
- correction fallback
SC_LOADquand scenario JSON est volumineux (NoMemory):- parse filtree des seuls champs id dans
loadScenarioIdFromFile hardware/firmware/ui_freenove_allinone/src/app/scenario_manager.cpp
- parse filtree des seuls champs id dans
- correction fallback
- Gates build/tooling executees (vert):
./tools/dev/story-gen validate✅./tools/dev/story-gen sync-screens --check✅./tools/dev/story-gen generate-cpp✅./tools/dev/story-gen generate-bundle --out-dir /tmp/zacus_bundle_final_ui✅pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
- Flash/FS USB modem:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification hardware USB modem (vert):
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅python3 tools/dev/test_story_4scenarios.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅- log:
artifacts/rc_live/test_4scenarios_20260226-004510.log
- log:
python3 tools/dev/verify_story_transitions_deep.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅- log:
artifacts/rc_live/deep_transition_verify_20260226-004530.log(51/51 pass)
- log:
python3 tools/dev/verify_story_ui_conformance.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅- log:
artifacts/rc_live/ui_conformance_verify_20260226-010143.log(51/51 pass, 0 payload missing)
- log:
[2026-02-25] Lots 3→4→5 Freenove (stabilite unlock + perf cache + validation USB modem)
- Skills chain active (ordre):
freenove-firmware-orchestratorfirmware-story-stackfirmware-littlefs-stackfirmware-graphics-stackfirmware-build-stack
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225-224120_wip.patch/tmp/zacus_checkpoint/20260225-224120_status.txt
- Lot 3 (stabilite/compat transitions):
- support
SC_EVENT unlock <name>sans casserSC_EVENT unlock(fallbackUNLOCK) :hardware/firmware/ui_freenove_allinone/src/app/main.cpphardware/firmware/ui_freenove_allinone/include/app/scenario_manager.hhardware/firmware/ui_freenove_allinone/src/app/scenario_manager.cpp
- ajout du validateur exhaustif runtime:
tools/dev/verify_story_transitions_deep.py
- preuve correction defect
TR_SCENE_QR_DETECTOR_2:- log deep verify:
artifacts/rc_live/deep_transition_verify_20260225-225305.log(51/51 pass, 0 fail)
- log deep verify:
- support
- Lot 4 (optimisations perf):
ui_manager_effects: cache couleurs theme + cache segment timeline (evite updates/recalculs inutiles)hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.hhardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpp
- reduction allocations
Stringhotpath dispatchSC_EVENT/SC_EVENT_RAWhardware/firmware/ui_freenove_allinone/src/app/main.cpp
- extension cache storage scene/audio de single-entry a cache borne (3 slots) + invalidation preservee
hardware/firmware/ui_freenove_allinone/include/storage/storage_manager.hhardware/firmware/ui_freenove_allinone/src/storage/storage_manager.cpp
- campagne perf USB modem (150s, sequence identique avant/apres):
- before (commit
c3efe94):artifacts/rc_live/perf_campaign_before_20260225-231633.logloop avg=136605us,ui_tick avg=97345us,ui_flush avg=2053us
- after (commit
1787e9b):artifacts/rc_live/perf_campaign_after_20260225-232110.logloop avg=164980us,ui_tick avg=102288us,ui_flush avg=2068us
- constat: variance elevee liee charge audio/SD; optimisation UI ne degrade pas la stabilite (panic/reboot non observes pendant campagne) mais gain net non concluant sur cette charge mixte.
- before (commit
- Lot 5 (validation finale USB modem + tooling):
- flash firmware:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅ - smoke/tests:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅python3 tools/dev/test_story_4scenarios.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅ (log:artifacts/rc_live/test_4scenarios_20260225-225245.log)python3 tools/dev/verify_story_transitions_deep.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅ (51 pass / 0 fail)
- tooling/build gates finales:
./tools/dev/story-gen validate✅./tools/dev/story-gen generate-cpp✅./tools/dev/story-gen generate-bundle --out-dir /tmp/zacus_bundle_final✅pio run -e freenove_esp32s3✅ (RAM 74.6%, Flash 32.9%)pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
- flash firmware:
- Notes:
- verification compat explicite:
SC_EVENT unlock UNLOCK_QR->dispatched=1 changed=1 step=SCENE_FINAL_WINSC_EVENT unlockconserve fallbackUNLOCK(compat legacy preservee)
- verification compat explicite:
[2026-02-25] Split lourd ui_manager.cpp (effects/display/intro)
- Skills utilises (ordre):
freenove-firmware-orchestratorfirmware-graphics-stackfirmware-build-stack
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225-222145_wip.patch/tmp/zacus_checkpoint/20260225-222145_status.txt
- Actions:
- scission des implementations
UiManageren 3 unites dediees:hardware/firmware/ui_freenove_allinone/src/ui/ui_manager_display.cpphardware/firmware/ui_freenove_allinone/src/ui/ui_manager_intro.cpphardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpp
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cppconserve l'orchestration + helpers internes et inclut les 3 unites split viaUI_MANAGER_SPLIT_IMPL(pas de changement API publique).
- scission des implementations
- Gates/evidence:
pio run -e freenove_esp32s3✅ (RAM 74.6%, Flash 32.8%)pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
[2026-02-25] USB modem - correction scripts smoke story + rerun
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_215404_wip.patch/tmp/zacus_checkpoint/20260225_215404_status.txt
- Port cible:
/dev/cu.usbmodem5AB90753301(ESP32)
- Correctifs:
tools/dev/verify_story_default_flow.py- flow aligne scenario runtime
DEFAULT(initialSCENE_U_SON_PROTO), - assertions passees de
screenseul astep+screen, - sequence events mise a jour:
button ANY->serial BTN_NEXT->serial FORCE_DONE->serial BTN_NEXT->button ANY.
- flow aligne scenario runtime
lib/zacus_story_portable/test_story_4scenarios.py- migration commandes legacy JSON (
story.load/status,STORY_FORCE_STEP) vers commandes runtime actuelles (SC_LOAD,STATUS,SC_EVENT), - verification
ACK SC_LOAD, - verification status parse (
scenario/step/screen) + check scenario courant.
- migration commandes legacy JSON (
- Gates/evidence:
python3 -m py_compile tools/dev/verify_story_default_flow.py lib/zacus_story_portable/test_story_4scenarios.py✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅python3 tools/dev/test_story_4scenarios.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅- evidence:
artifacts/rc_live/test_4scenarios_20260225-215755.log
- evidence:
./tools/dev/story-gen validate✅
[2026-02-25] Audit + correction/optimisation Freenove (lot refactor+stabilite+perf partiels)
- Skills chain active (ordre):
freenove-firmware-orchestratorfirmware-story-stackfirmware-littlefs-stackfirmware-graphics-stackfirmware-build-stack
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_210711_wip.patch/tmp/zacus_checkpoint/20260225_210711_status.txt
- Scope run:
- refactor
ui_freenove_allinone/src/app/main.cpp - compat story/bundle LittleFS
- refactor
ui_freenove_allinone/src/ui/ui_manager.cpp(defer split lourd, voir limitation) - optimisation hotpaths runtime/UI/storage
- refactor
- Actions:
- ajout des bridges de services runtime app:
include/app/runtime_serial_service.h+src/app/runtime_serial_service.cppinclude/app/runtime_scene_service.h+src/app/runtime_scene_service.cppinclude/app/runtime_web_service.h+src/app/runtime_web_service.cpp- wiring dans
src/app/main.cppavec impl callbacks (*Impl) pour isoler orchestration.
- stabilite story/bundle:
- correction JSON ecrans invalides:
data/story/screens/SCENE_U_SON_PROTO.jsondata/story/screens/SCENE_WIN_ETAPE1.jsondata/story/screens/SCENE_FINAL_WIN.json
generator.py:- auto-generation des
screensconnus deSCENE_PROFILESsi JSON manquant (legacy compat), - maintien FAIL strict pour scene inconnue,
- trace manifest:
autogenerated_resources.screens.
- auto-generation des
- correction JSON ecrans invalides:
- LittleFS/runtime:
storage_manager.cpp: fin du sentinelSCENE_LOCKED, check presence aligne runtime default scenario.- warning rate-limite payload scene manquant au rendu (
main.cpp).
- optimisation perf:
- cache RAM
scene payloadetaudio pack pathdansStorageManager, - invalidation explicite sur
syncStoryFileFromSd,syncStoryTreeFromSd, provisioning embedded.
- cache RAM
- ajout des bridges de services runtime app:
- Gates/evidence:
./tools/dev/story-gen validate✅./tools/dev/story-gen generate-cpp✅./tools/dev/story-gen generate-bundle --out-dir /tmp/zacus_bundle_lot3_20260225_1✅- manifest:
autogenerated_resources.screens = [SCENE_LOCKED, SCENE_READY, SCENE_REWARD, SCENE_SEARCH]
- manifest:
python3 ../../tools/scenario/validate_scenario.py ../../game/scenarios/zacus_v1.yaml✅python3 ../../tools/scenario/export_md.py ../../game/scenarios/zacus_v1.yaml✅python3 ../../tools/audio/validate_manifest.py ../../audio/manifests/zacus_v1_audio.yaml✅python3 ../../tools/printables/validate_manifest.py ../../printables/manifests/zacus_v1_printables.yaml✅pio run -e freenove_esp32s3✅ (RAM 74.6%, Flash 32.8%)pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
- Limitations:
- lot split
ui_manager.cppenui_manager_effects/display/intronon applique dans ce run (risque de regression large sans campagne hardware complete). - gates hardware serie/combined-board/perf 2-3 min non executees ici (pas de port board fourni dans le run).
- lot split
[2026-02-25] Clean ecrans - phase 2 (runtime strict 9)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_203828_wip.patch/tmp/zacus_checkpoint/20260225_203828_status.txt
- Scope:
data/story/screens/*.jsongame/scenarios/scene_editor_all.yamlgame/scenarios/scenario_reel_template.yaml
- Actions:
- suppression de 6 ecrans restants hors runtime principal:
SCENE_LOCKED,SCENE_MP3_PLAYER,SCENE_PHOTO_MANAGER,SCENE_READY,SCENE_REWARD,SCENE_SEARCH.
- regeneration du workbench runtime:
python3 tools/dev/export_scene_editor_workbench.py
- nettoyage template scenario reel pour supprimer les references ecrans retirees:
prompt_input.media_hub.entries: []- retrait des scenes retirees dans les catalogues
scene_screen_audio_catalog_alletscene_action_trigger_catalog_all.
- suppression de 6 ecrans restants hors runtime principal:
- Resultat:
data/story/screens: 15 -> 9 fichiers (runtime strict).scene_editor_all.yaml:unused_scene_ids: [].
- Gates/evidence:
./tools/dev/story-gen validate✅- parse JSON
data/story/screens/*.json✅ (json_screens_ok 9) - check refs
screen_jsonYAML manquants ✅ (missing_screen_json_refs 0) pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
- Limitation:
./tools/dev/story-gen generate-bundle❌ (Missing required screens resource 'SCENE_LOCKED') car les scenarios legacy (hors runtime strict) referencent encore des scenes retirees.
[2026-02-25] Clean ecrans - reduction du catalogue LittleFS (phase 1)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_202801_wip.patch/tmp/zacus_checkpoint/20260225_202801_status.txt
- Scope:
data/story/screens/*.jsongame/scenarios/scene_editor_all.yamlgame/scenarios/scenario_reel_template.yaml
- Actions:
- suppression de 9 ecrans non utilises par le runtime principal:
SCENE_BROKEN,SCENE_CAMERA_SCAN,SCENE_FIREWORKS,SCENE_LA_DETECT,SCENE_MEDIA_ARCHIVE,SCENE_SIGNAL_SPIKE,SCENE_WIN,SCENE_WINNER,SCENE_WIN_ETAPE.
- regeneration workbench scenes:
python3 tools/dev/export_scene_editor_workbench.py
- suppression des references YAML
screen_jsonobsoletes dansscenario_reel_template.yaml(catalogues ecrans + triggers scenes).
- suppression de 9 ecrans non utilises par le runtime principal:
- Resultat:
data/story/screens: 24 -> 15 fichiers.scene_editor_all.yaml:unused_scene_idsreduit de 15 -> 6.
- Gates/evidence:
./tools/dev/story-gen validate✅- parse JSON
data/story/screens/*.json✅ (json_screens_ok 15) - check refs
screen_jsonYAML manquants ✅ (missing_screen_json_refs 0) python3 ../../tools/scenario/validate_scenario.py ../../game/scenarios/zacus_v1.yaml✅python3 ../../tools/scenario/export_md.py ../../game/scenarios/zacus_v1.yaml✅python3 ../../tools/audio/validate_manifest.py ../../audio/manifests/zacus_v1_audio.yaml✅python3 ../../tools/printables/validate_manifest.py ../../printables/manifests/zacus_v1_printables.yaml✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
[2026-02-25] Clean ecrans (screens) - sync workbench + gates
- Scope:
game/scenarios/scene_editor_all.yamldata/story/screens/*.jsondata/screens/*.json
- Actions:
- regeneration du workbench ecrans depuis les JSON canoniques:
python3 tools/dev/export_scene_editor_workbench.py
- controle coherence tokens UI (
effect,timeline.keyframes[].effect,transition.effect) contre le parseur runtimeui_manager.cpp: aucun token invalide detecte. - controle JSON des ecrans (
data/story/screens+data/screens): parse OK.
- regeneration du workbench ecrans depuis les JSON canoniques:
- Resultat:
game/scenarios/scene_editor_all.yamlresynchronise avec l'etat reel des ecrans runtime.- aucune derive restante detectee sur les 6 mirrors legacy
data/screens/*.json(alignes avecdata/story/screens/SCENE_*.jsoncorrespondants).
- Gates/evidence:
./tools/dev/story-gen validate✅jq emptysurdata/story/screens/*.jsonetdata/screens/*.json✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
[2026-02-25] Clean global scenario/scene (YAML + code + assets)
- Skills utilises (ordre):
firmware-story-stackfirmware-littlefs-stack
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_200958_wip.patch/tmp/zacus_checkpoint/20260225_200958_status.txt
- Clean applique:
lib/zacus_story_gen_ai/src/zacus_story_gen_ai/generator.py- classification
workbenchajoutee pour ignorer les YAML d'edition scene (meta+scenes) dansstory-gen validate. - resolution alias actions ajoutee pour les noms courts LittleFS:
ACTION_QR_CODE_SCANNER_START->ACTION_QR_SCAN_STARTACTION_SET_BOOT_MEDIA_MANAGER->ACTION_BOOT_MEDIA_MGR
- classification
- runtime Freenove:
ui_freenove_allinone/src/app/main.cppui_freenove_allinone/src/main.cppexecuteStoryActioncharge maintenant d'abordACTION_ID.json, puis fallback alias fichier court si absent.
- Gates/evidence:
./tools/dev/story-gen validate✅ (scenarios=5,game_scenarios=2)./tools/dev/story-gen generate-cpp✅ (spec_hash=aa9658456a0d)./tools/dev/story-gen generate-bundle --out-dir /tmp/zacus_story_bundle_clean_20260225_201347✅- verification assets actions generes:
/tmp/zacus_story_bundle_clean_20260225_201347/story/actions/ACTION_QR_CODE_SCANNER_START.json(type/config presents)/tmp/zacus_story_bundle_clean_20260225_201347/story/actions/ACTION_SET_BOOT_MEDIA_MANAGER.json(type/config presents)
- verification assets actions generes:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
[2026-02-25] Audit + clean dossier data (story/littlefs)
- Skills utilises (ordre):
firmware-story-stackfirmware-littlefs-stack
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_195727_wip.patch/tmp/zacus_checkpoint/20260225_195727_status.txt
- Audit
data/:- 89 fichiers, 16 dossiers, aucun fichier temporaire suspect detecte.
- derive detectee entre fallback legacy
/screens/*et canonique/story/screens/*pour:data/screens/la_detector.jsondata/screens/locked.json
- fichier legacy non reference detecte:
data/scenarios/data/default_scenario.json
- Clean applique:
- synchronisation fallback
/screensavec les JSON canoniques:data/screens/la_detector.json-> aligne surdata/story/screens/SCENE_LA_DETECTOR.jsondata/screens/locked.json-> aligne surdata/story/screens/SCENE_LOCKED.json
- suppression du legacy non reference:
data/scenarios/data/default_scenario.json
- synchronisation fallback
- Gates/evidence:
- parse JSON complet
data/**/*.jsonviajq empty✅ pio run -e freenove_esp32s3_full_with_ui -t buildfs✅- note:
./tools/dev/story-gen validateechoue sur../../game/scenarios/scene_editor_all.yaml(format workbench non reconnu), anomalie preexistante hors cleandata/.
- parse JSON complet
[2026-02-25] Preparation test utilisateur reel (runbook)
- Carte preparee pour test terrain:
BOOT_MODE_CLEARapplique,SC_LOAD DEFAULT,RESETexecutes.- smoke post-reset valide (
serial_smoke.pyPASS).
- Commande de capture log conseillee pendant test utilisateur:
python3 tools/dev/user_live_logger.py --port /dev/cu.usbmodem5AB90753301 --baud 115200 --duration 1200 --log logs/user_live_test_<timestamp>.log
- Point de vigilance:
- surveiller recurrence potentielle panic SDMMC observee une fois lors d'un run precedent
media-manager.
- surveiller recurrence potentielle panic SDMMC observee une fois lors d'un run precedent
[2026-02-25] FX verificator - scenes non direct-FX en NA + rerun gates
- Objectif:
- supprimer les faux FAIL FX sur scenes runtime LVGL-only (pas de moteur direct-FX).
- Correctif script global:
~/.codex/skills/fx-verificator/scripts/run_fx_verification.sh- nouveau parametre:
non_direct_policy(autopar defaut,strictoptionnel). - mode
auto: scene sans activite FX (fx_fps=0,fx_frames=0,fx_blit=0) =>NAau lieu de FAIL. - mode
strict: comportement historique (fx_fps > 0obligatoire partout).
- Miroir doc repo mis a jour:
docs/skills/fx-verificator.md
- Rerun verification:
run_fx_verification.sh ... \"SCENE_WIN_ETAPE1,SCENE_WIN_ETAPE2,SCENE_FINAL_WIN,SCENE_MEDIA_MANAGER\" 10 auto✅run_fx_verification.sh ... \"SCENE_WINNER,SCENE_FIREWORKS\" 8 strict✅serial_smoke.py✅run_scene_verification.sh(9 scenes runtime) ✅run_hal_verification.sh(9 scenes runtime) ✅run_media_manager_verification.sh✅
- Note:
- une execution intermediaire
media-managera logue un panic SDMMC puis reboot; rerun immediat apres smoke => PASS. - a surveiller si reproduction frequente sous charge longue.
- une execution intermediaire
[2026-02-25] Upload Freenove + smoke + verifs scenes/FX/HAL/media
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_182057_wip.patch/tmp/zacus_checkpoint/20260225_182057_status.txt
- Upload effectues:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Smoke:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅
- Verification scenes runtime (ordre scenario):
run_scene_verification.sh ... "SCENE_U_SON_PROTO,...,SCENE_MEDIA_MANAGER"✅
- Verification FX:
- runtime direct (
SCENE_WIN_ETAPE1,SCENE_WIN_ETAPE2,SCENE_FINAL_WIN,SCENE_MEDIA_MANAGER) ❌SCENE_FINAL_WINrapportefx_fps=0(scene LVGL celebratory sans moteur direct-FX actif).
- fallback direct-FX (
SCENE_WINNER,SCENE_FIREWORKS) ✅
- runtime direct (
- Verification HAL runtime (9 scenes):
run_hal_verification.sh ...✅ (cam=0, amp=0, ws2812=1, led_auto=1 sur les scenes runtime)
- Verification media-manager:
run_media_manager_verification.sh ...✅- QR -> FINAL_WIN -> MEDIA_MANAGER + persistance boot + rollback verifies.
[2026-02-25] Apply workbench runtime -> JSON ecrans (pass simplification)
- Action demandee executee:
python3 tools/dev/export_scene_editor_workbench.py --apply
- JSON ecrans mis a jour (9 scenes runtime):
data/story/screens/SCENE_U_SON_PROTO.jsondata/story/screens/SCENE_LA_DETECTOR.jsondata/story/screens/SCENE_WIN_ETAPE1.jsondata/story/screens/SCENE_WARNING.jsondata/story/screens/SCENE_LEFOU_DETECTOR.jsondata/story/screens/SCENE_WIN_ETAPE2.jsondata/story/screens/SCENE_QR_DETECTOR.jsondata/story/screens/SCENE_FINAL_WIN.jsondata/story/screens/SCENE_MEDIA_MANAGER.json
- Verification:
- parse JSON sur les 9 fichiers: OK
- gate FS:
pio run -e freenove_esp32s3_full_with_ui -t buildfs✅
[2026-02-25] Simplification workbench scenes (utilisees uniquement + ordre runtime)
- Skills utilises:
firmware-story-stackfirmware-scene-ui-editor
- Fichier cible:
game/scenarios/scene_editor_all.yaml
- Actions:
- verification scenes utilisees/non utilisees via
game/scenarios/default_unlock_win_etape2.yaml, - suppression des scenes non utilisees dans le workbench (15 retirees),
- re-ordonnancement des scenes selon l'ordre runtime des steps.
- verification scenes utilisees/non utilisees via
- Ordre final conserve:
SCENE_U_SON_PROTOSCENE_LA_DETECTORSCENE_WIN_ETAPE1SCENE_WARNINGSCENE_LEFOU_DETECTORSCENE_WIN_ETAPE2SCENE_QR_DETECTORSCENE_FINAL_WINSCENE_MEDIA_MANAGER
- Script outille egalement ce besoin:
tools/dev/export_scene_editor_workbench.pyexporte desormais par defaut enruntime_only(ordre scenario), avec option--include-unusedpour reintroduire les scenes hors runtime.
[2026-02-25] Revue complete scene_editor_all (coherence LVGL/FX/audio)
- Skills utilises (ordre):
freenove-firmware-orchestratorfirmware-story-stackfirmware-graphics-stackfirmware-fx-overlay-lovyangfxfirmware-scene-ui-editor
- Fichier revu/mis a jour:
game/scenarios/scene_editor_all.yaml
- Verifications effectuees:
- existence
screen_jsonpour les 24 scenes, - coherence
runtime_step_ids+default_audio_pack_idcontregame/scenarios/default_unlock_win_etape2.yaml, - validite tokens FX/transition supportes par
ui_manager.cpp.
- existence
- Corrections appliquees:
SCENE_WIN_ETAPE1etSCENE_WIN_ETAPE2:fx.effectinvalidesparkle->celebrate(contrat runtime).- scenes QR (
SCENE_CAMERA_SCAN,SCENE_QR_DETECTOR): mode scan stabilise (fx.effect=none, timeline vide,effect_speed_ms=0). - ajout bloc
meta.reviewdans le workbench pour tracer l'etat de coherence.
- Resultat:
- revue complete =
issue_count=0.
- revue complete =
[2026-02-25] Workbench ecrans LVGL/FX + audio (toutes scenes)
- Objectif:
- accelerer l'edition de toutes les scenes (LVGL/FX + son associe) depuis un seul fichier.
- Ajouts:
- script
tools/dev/export_scene_editor_workbench.py:- export JSON ecrans -> YAML editable (
scene_editor_all.yaml), - apply YAML -> JSON ecrans (
--apply).
- export JSON ecrans -> YAML editable (
- fichier genere
game/scenarios/scene_editor_all.yaml(24 scenes).
- script
- Commandes:
- export:
python3 hardware/firmware/tools/dev/export_scene_editor_workbench.py - apply:
python3 hardware/firmware/tools/dev/export_scene_editor_workbench.py --apply
- export:
- Passe proposition visuelle (runtime reel):
game/scenarios/scene_editor_all.yamlajuste pour scenes runtime:SCENE_U_SON_PROTO,SCENE_LA_DETECTOR,SCENE_WIN_ETAPE1,SCENE_WARNING,SCENE_LEFOU_DETECTOR,SCENE_WIN_ETAPE2,SCENE_QR_DETECTOR,SCENE_FINAL_WIN,SCENE_MEDIA_MANAGER.- coherence garde-fou:
- QR scene sans FX intrusif (
effect=none), - final win en celebratory,
- hub media en
radar/pulseboucle lente.
- QR scene sans FX intrusif (
[2026-02-25] Template scenario reel - catalogue complet scenes/ecrans/sons
- Fichier mis a jour:
game/scenarios/scenario_reel_template.yaml
- Ajouts:
prompt_input.scene_screen_audio_catalog_allavec les 24 scenes connues, lien JSON ecran, pack audio par defaut, steps runtime utilises.prompt_input.audio_pack_catalog_allavec les 6 packs audio actuels, chemin JSON, fichier audio cible et steps associes.
- Validation:
- parse YAML OK (
yaml.safe_load) avec compteurs:- scenes catalogue = 24
- packs catalogue = 6
- parse YAML OK (
[2026-02-25] Refonte scenario reel v2 + stabilisation verificators + upload/test Freenove
- Skills utilises (ordre):
freenove-firmware-orchestratorfirmware-story-stackfirmware-espnow-stackfirmware-build-stack
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_162241_wip.patch/tmp/zacus_checkpoint/20260225_162241_status.txt
- Correctifs principaux:
- flow runtime applique sur
DEFAULTavecbutton/espnow, QR gateAPP_QR_UNLOCK, timerWIN_DUE,STEP_MEDIA_MANAGER. - action boot cible maintenue
ACTION_SET_BOOT_MEDIA_MANAGERavec compat runtimeACTION_SET_BOOT_MEDIA. - LittleFS: fichiers action a nom court pour contourner la limite de nom (
ACTION_QR_SCAN_START.json,ACTION_BOOT_MEDIA_MGR.json) tout en conservant les IDs longs en payload. main.cpp:SC_EVENT/SC_EVENT_RAWappliquent maintenantrefreshSceneIfNeeded(true)+startPendingAudioIfAny()sur changement de step (corrige reset lors triggerbutton).main.cpp: commandeRESETstoppe audio/amp/media avant reset scenario puis rerender immediate (corrige panic rollback media-manager).- HAL scene
SCENE_FINAL_WIN: LED fixee (pas de pulse) pour verification RGB stricte. - scripts skills:
scene-verificator: robustesse boot marker + triggers button/espnow + checks LED.hal-verificator-status: attentes par defaut alignees (SCENE_QR_DETECTOR mic=0,SCENE_FINAL_WIN led=252/212/92).media-manager:AUDIO_STOPavant QR et avant reset rollback + detectionscene=SCENE_MEDIA_MANAGER/ACK step media.
- generator story: validation narrative game assouplie (runtime YAML reste strict) pour ne pas bloquer sur
game/scenarios/zacus_v2.yaml.
- flow runtime applique sur
- Gates executes:
- story gen:
PYTHONPATH=lib/zacus_story_gen_ai/src .venv/bin/python -m zacus_story_gen_ai.cli validate✅PYTHONPATH=lib/zacus_story_gen_ai/src .venv/bin/python -m zacus_story_gen_ai.cli generate-cpp✅PYTHONPATH=lib/zacus_story_gen_ai/src .venv/bin/python -m zacus_story_gen_ai.cli generate-bundle✅
- build/upload:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅ (plus de warning LittleFS sur action QR/boot media manager)pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- smoke/verificators:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅~/.codex/skills/scene-verificator/scripts/run_scene_verification.sh /dev/cu.usbmodem5AB90753301 115200✅~/.codex/skills/fx-verificator/scripts/run_fx_verification.sh /dev/cu.usbmodem5AB90753301 115200✅~/.codex/skills/hal-verificator-status/scripts/run_hal_verification.sh /dev/cu.usbmodem5AB90753301 115200✅~/.codex/skills/media-manager/scripts/run_media_manager_verification.sh /dev/cu.usbmodem5AB90753301 115200✅
- story gen:
- Limitation materielle observee (non bloquante):
- erreurs camera DMA sur
SCENE_PHOTO_MANAGER(cam_dma_config ... malloc failed) quand PSRAM libre faible; verifs scene/HAL/media passent malgre ces logs.
- erreurs camera DMA sur
[2026-02-25] Scope ESP-NOW + fix action boot media (LittleFS)
- Objectif:
- inclure ESP-NOW dans le passage vers
STEP_MEDIA_MANAGER, - corriger l'action de boot media qui provoquait un warning buildfs.
- inclure ESP-NOW dans le passage vers
- Actions:
- action renommee
ACTION_SET_BOOT_MEDIA(data/story/actions/ACTION_SET_BOOT_MEDIA.json) pour rester compatible LittleFS. - references scenario mises a jour:
docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yamldata/story/scenarios/DEFAULT.json
- transition ESP-NOW ajoutee:
on_event espnow QR_OK -> STEP_MEDIA_MANAGER.
- compat runtime conservee dans
main.cpp:- accepte
ACTION_SET_BOOT_MEDIA+ alias legacyACTION_SET_BOOT_MEDIA_MANAGER.
- accepte
- action renommee
- Gates:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅- warning
unable to open '/story/actions/ACTION_SET_BOOT_MEDIA_MANAGER.json.disparu.
[2026-02-25] Passes completes ChatGPT examples -> firmware (QR + media + gates)
- Skills utilises:
chatgpt-file-exemple-intakefreenove-firmware-orchestrator
- Pass 1 (QR assets):
- integration des assets exemples dans
data/ui/qr/(ok.png,ok_48.png,bad.png,bad_48.png,reticle.png,scanlines.png,README.txt). - hook runtime ajoute dans
ui/qr/qr_scene_controller.cppavec trace presence assets ([QR_UI] assets ...).
- integration des assets exemples dans
- Pass 2 (audio/media depuis exemples):
- extraction logique "natural sort" pour catalogues media dans
ui_freenove_allinone/src/system/media/media_manager.cpp. MEDIA_LISTretourne maintenant un ordre stable/humain (track2avanttrack10).
- extraction logique "natural sort" pour catalogues media dans
- Pass 3 (QR tool + full gates):
tools/dev/gen_qr_crc16.pyetendu avec--scope data|suffix+--prefix.- builds + uploads executes:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅ (warning LittleFS deja connu surACTION_SET_BOOT_MEDIA_MANAGER.json)pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- verifications executees:
serial_smoke.py✅scene-verificator✅fx-verificator✅ (1er run panic puis rerun PASS apres reset)hal-verificator-status✅media-manager✅run_stress_tests.py❌ (scenarioDEFAULTn'atteint pasSTEP_DONE, sans panic sur ce run).
[2026-02-25] Intake fichiers ChatGPT_file_exemple (integration controlee)
- Skills utilises:
chatgpt-file-exemple-intake(inventaire + mapping source->cible)freenove-firmware-orchestrator(respect architecture Freenove existante)
- Inventaire execute sur
hardware/ChatGPT_file_exemple/**:- candidats utiles identifies sur QR flow (
qr_scan_controller.*,ui_manager.*,gen_qr_crc16.py, assets PNG).
- candidats utiles identifies sur QR flow (
- Decision d'integration:
- conserve architecture canonique actuelle sous
hardware/firmware/**(pas de copie brute des arbres imbriques.../hardware/firmware/hardware/firmware/...). - extraction d'un delta utile depuis l'exemple QR:
tools/dev/gen_qr_crc16.pyenrichi avec:--scope data|suffix--prefix <text>(obligatoire en scopesuffix)- validation prefix + calcul CRC sur suffixe.
- fichiers exemples non integres tels quels (assets/UI patch complet) car deja couverts partiellement ou non references runtime.
- conserve architecture canonique actuelle sous
- Validation rapide:
python3 tools/dev/gen_qr_crc16.py "ZACUS:ETAPE1" --ci --scope data✅python3 tools/dev/gen_qr_crc16.py "ZACUS:ETAPE1:42" --ci --scope suffix --prefix "ZACUS:"✅
[2026-02-25] Scenario reel template - sync etat code + format promptable
- Fichier mis a jour:
game/scenarios/scenario_reel_template.yaml - Refonte du template pour usage "promptable":
- section editable unique
prompt_input(besoin metier), - section reference
current_firmware_snapshot(etat runtime actuel derive du code/spec).
- section editable unique
- Snapshot aligne sur l'etat courant:
- flow
DEFAULTavec finalQR_OK -> STEP_MEDIA_MANAGER, - scenes hub media (
SCENE_MEDIA_MANAGER,SCENE_MP3_PLAYER,SCENE_PHOTO_MANAGER,SCENE_READY), - HAL/LED runtime connus pour scenes critiques.
- flow
- Validation:
- parse YAML OK (
python3+yaml.safe_load).
- parse YAML OK (
[2026-02-25] Etat scenario + template de saisie "reel"
- Etat courant source spec:
docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml- flow actif:
STEP_WAIT_UNLOCK -> STEP_U_SON_PROTO/STEP_WAIT_ETAPE2 -> STEP_ETAPE2 -> STEP_DONE (SCENE_CAMERA_SCAN) -> STEP_MEDIA_MANAGER (SCENE_MEDIA_MANAGER via QR_OK).
- Nouveau fichier de saisie simplifie pour expression besoin metier:
game/scenarios/scenario_reel_template.yaml- format orienté "brief scenario reel" (catalogue scenes, besoins HAL, LED, steps, transitions, acceptance).
- usage: l'utilisateur edite ce template, puis Codex convertit en scenario YAML canonique + JSON runtime.
[2026-02-25] HAL skill update - WS2812 (4 LED Freenove)
- Skill global
hal-verificator-statusetendu pour verifier aussi les LED WS2812:HW_STATUS ws2812(ws2812=0|1)HW_STATUS auto(led_auto=0|1)- couleur exacte optionnelle
HW_STATUS led=R,G,B(led=R/G/Bouled=R,G,B)
- Script mis a jour:
~/.codex/skills/hal-verificator-status/scripts/run_hal_verification.sh- parsing expectations enrichi (
cam|amp|mic|ws2812|led_auto|led) - verdict ligne detaillee avec etats LED.
- Documentation skill:
- global
~/.codex/skills/hal-verificator-status/SKILL.md - global
~/.codex/skills/hal-verificator-status/references/checklist.md - miroir repo
docs/skills/hal-verificator-status.md
- global
- Verification rapide:
run_hal_verification.sh /dev/cu.usbmodem5AB90753301 115200 \"SCENE_READY:cam=0,amp=0,mic=0,ws2812=1,led_auto=1;SCENE_MP3_PLAYER:cam=0,amp=1,ws2812=1,led_auto=1;SCENE_CAMERA_SCAN:cam=0,amp=0,ws2812=1,led_auto=1\"✅
[2026-02-25] QR final + boot MEDIA_MANAGER + skill media-manager
- Checkpoint securite execute:
/tmp/zacus_checkpoint/20260225_102014_wip.patch/tmp/zacus_checkpoint/20260225_102014_status.txt
- Firmware/UI:
- ajout module QR
ui/qr/qr_scan_controller.*+ integrationUiManager(consumeRuntimeEvent,simulateQrPayload, parsing reglesqr.expected/prefix/contains). - pont runtime event UI -> story (
SERIAL:QR_OK/SERIAL:QR_INVALID) dansmain.cpp. - ajout persistance NVS
BootModeStore(zacus_boot,startup_mode,media_validated) + commandesBOOT_MODE_STATUS|SET|CLEAR. - action story
ACTION_SET_BOOT_MEDIA_MANAGERapplique mode persistantmedia_manager. SCENE_CAMERA_SCANrepasse en QR-only, nouvelle sceneSCENE_PHOTO_MANAGER, scene hubSCENE_MEDIA_MANAGER.- policy reset:
RESETreroute versSCENE_MEDIA_MANAGERsi mode boot media actif.
- ajout module QR
- Story/data:
- MAJ scenario YAML:
docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml(transitionQR_OK->STEP_MEDIA_MANAGER). - MAJ runtime JSON:
data/story/scenarios/DEFAULT.json,data/story/screens/SCENE_CAMERA_SCAN.json, ajoutSCENE_MEDIA_MANAGER.json,SCENE_PHOTO_MANAGER.json,ACTION_SET_BOOT_MEDIA_MANAGER.json. - generation:
./tools/dev/story-gen validate✅,./tools/dev/story-gen generate-bundle✅ (artifacts/story_fs/deploy).
- MAJ scenario YAML:
- Skills:
- creation globale
~/.codex/skills/media-manager/(SKILL.md,agents/openai.yaml,scripts/run_media_manager_verification.sh,references/checklist.md). - miroir repo:
docs/skills/media-manager.md.
- creation globale
- Gates executes:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅ (warning d'indexation FS a surveiller surACTION_SET_BOOT_MEDIA_MANAGER.json, build final OK)python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅
[2026-02-25] Skill HAL_VERIFCATOR_STATUS (scene-aware hardware gating)
- Creation skill global:
~/.codex/skills/hal-verificator-status/SKILL.md~/.codex/skills/hal-verificator-status/agents/openai.yaml~/.codex/skills/hal-verificator-status/scripts/run_hal_verification.sh~/.codex/skills/hal-verificator-status/references/checklist.md
- Scope validation couverte:
- camera (
CAM_STATUS rec_scene), amp (AMP_STATUS scene), micro (RESOURCE_STATUS mic_should_run). - verification activation/desactivation par scene via plan explicite
SCENE:cam=,amp=,mic=.
- camera (
- Miroir doc versionne:
docs/skills/hal-verificator-status.md
- Ajustement robustesse:
AMP_STATUS ready=0interprete commeamp=0(pas de faux negatif quand player non initialise).- attentes partielles supportees par scene (
cam|amp|micoptionnels).
[2026-02-25] Follow-up verificators (scene/fx/hal)
scene-verificator:- alias triggers ajoutes (
BTN_*->SC_EVENT serial, noms pointes ->SC_EVENT_RAW). - argument trigger vide supporte (desactive les triggers custom sans fallback implicite).
- critere global assoupli: accepte progression via
SCREEN_SYNCou changementsscene/status.
- alias triggers ajoutes (
fx-verificator:- script etendu (
scenes_csv,seconds_per_scene) et verdict per-scene (max(fx_fps)>0).
- script etendu (
- Gates executes:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅
- Resultats a investiguer:
scene-verificatoravec triggerstory.validateprovoque panic serie (Guru Meditation ... Unhandled debug exception).hal-verificatormontreSCENE_MP3_PLAYERavecmic_should_run=1(si on forcemic=0, echec attendu).
- Integration changement detecte dans workspace:
- fichier
data/screens/la_detect.jsonintegre au scope utilisateur. - ajout alias story
data/story/screens/SCENE_LA_DETECT.jsonpour coherer avecSCENE_LA_DETECTdeja supporte cote runtime. - gate
pio run -e freenove_esp32s3_full_with_ui -t buildfsrelancee ✅ (fichier inclus dans LittleFS).
- fichier
[2026-02-25] Scene/FX orchestrator refactor + VERIFICATOR skills
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225_093916_wip.patch/tmp/zacus_checkpoint/20260225_093916_status.txt
- Refactor runtime:
- ajout orchestrateur
SceneFxOrchestrator(ui_freenove_allinone/include|src/app/scene_fx_orchestrator.*) pour planifier ownershipStory/IntroFx/DirectFx/Amp/Camera. main.cpp: ordre explicite transition ownerpre-exit -> render scene -> post-enter.UiManager: cache scene payload hash +audio_playingpour eviter reinitialisations statiques inutiles; cleanup FX recentre.ScenarioManager: logs de transition structures (from_step,to_step,from_scene,to_scene,event,source,audio_pack) + trace chaines immediates.resolve_ports.py: remap mono-port robuste (esp8266 -> esp32) pour setup Freenove single-usb.
- ajout orchestrateur
- Skills crees (global + scripts):
~/.codex/skills/scene-verificator/~/.codex/skills/fx-verificator/scene-verificatoretendu pour piloter des triggers de test (CMD@SCENE) et verifier la progression post-trigger.
- Miroir doc versionne:
docs/skills/scene-verificator.mddocs/skills/fx-verificator.md
- Verification a executer en fin de run:
- build Freenove, serial smoke, scene chain, FX status, stress test.
[2026-02-24] Plan v4 integration (FX3D modes + SCENE_CAMERA_SCAN recorder Win311)
- Skills chain executee (ordre):
freenove-firmware-orchestrator->firmware-graphics-stack->firmware-camera-stack->firmware-fx-overlay-lovyangfx->firmware-build-stack. - Checkpoint securite:
/tmp/zacus_checkpoint/20260224_214537_wip.patch/tmp/zacus_checkpoint/20260224_214537_status.txt
- Implementations principales:
FxEngine: ajoutFxMode(classic|starfield3d|dotsphere3d|voxel|raycorridor) +setMode()/mode(), renderers 3D integres sans casser le runtime v9.UiManager: parse/applyFX_MODE_A/B/CsurSCENE_WIN_ETAPE(defaultsA=starfield3d,B=dotsphere3d,C=raycorridor), reset mode sur scenes direct FX.CameraManager: session recorder RGB565/QVGA, freeze/save/list/delete/select, restauration mode legacy en sortie.Win311 camera UI+CameraCaptureService: integration overlay LVGL branchee surCameraManager.main.cpp: ownership sceneSCENE_CAMERA_SCAN, mapping boutons physiques (BTN1..BTN5), commandes serieCAM_UI_*+CAM_REC_*, blocage forwarding scenario quand scene camera active.SCENE_CAMERA_SCANpayload reduit (fond neutre, symbole/effects minimaux) pour limiter le bruit visuel sous overlay.
- Contrats data/doc:
data/SCENE_WIN_ETAPE.json+data/ui/scene_win_etape.txt: ajoutFX_MODE_A/B/C.README.mdetdocs/ui/SCENE_WIN_ETAPE_demoscene_calibration.md: doc modes 3D + scene camera recorder + commandes.lv_conf.h:LV_USE_BTN=1,LV_USE_IMG=1,LV_USE_LIST=1.
- Build/flash Freenove:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅ (1er passage)pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301⚠️ echec final pySerialDevice not configuredapres ecriture 100%.
- Verification serie rapide:
SCENE_GOTO SCENE_WIN_ETAPE-> ACK + rendu actif.SCENE_GOTO SCENE_CAMERA_SCAN-> overlay actif, ownership camera engage.CAM_REC_STATUSvisible; sur ce hardware:camera_init_failed(preview indisponible, pas de crash).SCENE_GOTO SCENE_LOCKED-> sortie propre scene camera ([CAM_UI] scene owner=legacy).
- Gates contrat multi-env:
- matrice
pio run -e esp32dev -e esp32_release -e esp8266_oled -e ui_rp2040_ili9488 -e ui_rp2040_ili9486lancee puis interrompue (duree excesive en session interactive);esp32devcompile complet observe ✅ avant interruption.
- matrice
[2026-02-24] Plan v3 integration hardening (FX v9 + MP3 scene + crash fixes)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260224_204345_wip.patch/tmp/zacus_checkpoint/20260224_204345_status.txt
- Correctifs runtime appliques:
amiga_audio_player.cpp: remplacement par overlay LVGL minimal compatible config projet.audio_player_service.cpp: backendAudiosimplifie (API project-safe) + stats/playlist.fx/v9/engine/engine.cpp: retrait RTTI (dynamic_cast) -> binding parclip.fx+static_cast.fx_engine.cpp/.h: injection LUT v9 (services.luts) pour supprimer panicStarfieldFx::render.main.cpp: init AMP en lazy mode surSCENE_MP3_PLAYERpour eviter contention I2S avec audio scenario.main.cpp: scene MP3 active suspendg_audio.update, sortie scene restaure pipeline story.
- Build/flash Freenove:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie (pyserial):
SCENE_GOTO SCENE_WIN_ETAPE->UI_GFX_STATUSavecfx_fps>0(3..4) ✅SCENE_GOTO SCENE_WINNER/SCENE_GOTO SCENE_FIREWORKS->ACK ... ok=1,fx_fps>0, plus de panic ✅SCENE_GOTO SCENE_MP3_PLAYER+AMP_SCAN->tracks=5 base=/music✅AMP_PLAY 0/AMP_STOP-> ACK + status playback ✅- cycle cleanup scenes (
LOCKED -> WIN_ETAPE -> MP3 -> LOCKED) -> logscleanup scene assets transition ...sur chaque transition ✅
- Documentation:
README.md: runtimeFX_ONLY_V9+ section scene MP3 + commandesAMP_*.SCENE_WIN_ETAPE_demoscene_calibration.md: lock runtime v9 + mapping timelines.
[2026-02-24] Upload USB modem + validation scenes WINNER/FIREWORKS
- Port detecte:
/dev/cu.usbmodem5AB90753301. - Flash execute:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Correctif runtime pour
SCENE_GOTOhors steps scenario:ScenarioManager::gotoSceneaccepte desormais un fallback override scene canonique (sans modifiergame/scenarios/*.yaml).- override clear automatiquement lors d'un vrai
enterStep.
- Validation serie (pyserial):
SCENE_GOTO SCENE_WINNER->ACK ... ok=1✅SCENE_GOTO SCENE_FIREWORKS->ACK ... ok=1✅- retour
SCENE_GOTO SCENE_WIN_ETAPE->ACK ... ok=1, logs phase A presetdemo,UI_GFX_STATUSavecfx_fps>0✅
[2026-02-24] Port v2 FX/boing + scenes WINNER/FIREWORKS (iteration)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260224_183508_wip.patch/tmp/zacus_checkpoint/20260224_183508_status.txt
- Integration technique:
- import v9/boing stabilise (includes normalises, compat C++11).
fx_engine.cpp: shadow boing viaboing_shadow_darken_span_half_rgb565(ASM S3 par defaut, fallback C), fast blit 2x (fx_blit_fast) sur ratio exact.platformio.ini: ajoutUI_BOING_SHADOW_ASM=1(env Freenove).timeline_load.cpp: parser ArduinoJson complet (meta/clips/mods/events, params/args typed->string).assets_fs.cpp: lecture LittleFS reelle + fallback texte/palette.- scenes exposees:
SCENE_WINNER,SCENE_FIREWORKS(registry + JSON + defaults UiManager).
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301❌ (port absent)pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301❌ (port absent)
[2026-02-24] Hotfix texte phase A SCENE_WIN_ETAPE (FX v8)
- Symptome utilisateur: texte non visible sur la premiere scene apres integration FX v8.
- Correctifs appliques:
ui_manager.cpp: en modeFX_ONLY_V8, ne plus masquerscene_title_label_,scene_subtitle_label_,scene_symbol_label_.fx_engine.cpp: fallback glyph 6x8 robuste (a..zforce enA..Z, caracteres hors plage -> espace).
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- check serie:
SCENE_GOTO SCENE_WIN_ETAPE-> logs[WIN_ETAPE] phase=A preset=demo bpm=125 font=italic,fx_fps>0, aucun panic/reboot detecte.
[2026-02-24] Skill sync: firmware-lvgl-lgfx-overlay-stack v1.1
- Scope: Standardisation métier documentaire de la stack graphique overlay LVGL/LovyanGFX.
- Actions:
- Mis à jour
~/.codex/skills/firmware-lvgl-lgfx-overlay-stack/SKILL.mden v1.1 (single SPI master, FX→overlay→lv_timer_handler, PSRAM/DRAM, RGB332+LUT, hard guardrails). - Ajout/reprise miroir exact dans
hardware/firmware/docs/skills/firmware-lvgl-lgfx-overlay-stack.md. - Vérification: présence des flags requis, ordre de rendu, invariant no-frame-allocation, checklist d’acceptance.
- Mis à jour
- Validation (read-only):
rg -n \"UI_FX_LGFX|UI_FX_BACKEND_LGFX|UI_COLOR_256|UI_DRAW_BUF_IN_PSRAM|UI_DMA_TX_IN_DRAM|UI_DEMO_AUTORUN_WIN_ETAPE|FX -> invalidate overlay|pushRotateZoom|0 alloc par frame|Acceptance\"sur les deux fichiers.diff -uentre fichiers source et miroir (doit être vide).
[2026-02-24] Resource coordinator + mic profile commandes (SCENE-driven + manual/auto)
- Scope: finaliser le contrôle scène/micro dans
main.cpp. - Changement effectué:
- Ajout de
RESOURCE_PROFILE_AUTO <on|off>sur la chaîne contrôle API/serial. RESOURCE_PROFILE ...force désormais le mode manuel (profile_auto=0) pour éviter les auto-overrides non attendus.- Réactivation auto explicite:
RESOURCE_PROFILE_AUTO ONapplique immédiatement la politique scène courante. - Politique scène élargie:
SCENE_WIN_ETAPEforcegfx_focusaussi viascreen_scene_id(et pas uniquementSTEP_ETAPE2/PACK_WIN).
- Ajout de
- Prochaine vérification:
RESOURCE_STATUS+SCENE_GOTO SCENE_WIN_ETAPEpuisUI_GFX_STATUS/PERF_STATUS.
- Checkpoint local:
/tmp/zacus_checkpoint/1771936163_wip.patch,/tmp/zacus_checkpoint/1771936163_status.txt.
[2026-02-24] SCENE_WIN_ETAPE back-pressure + trans buffer guard (flush/lvgl)
- Scope: Freenove UI SCENE_WIN_ETAPE. Durcissement de la boucle
update(): aucune frame FX/LVGL relancée si flush ou DMA occupés, mise en attentepending_lvgl_flush_request_et relance dès que le bus est libre.displayFlushCbprotège les surcharges (overflow count) sans écraserflush_ctx_. - Mémoire/alloc: si trans buffer plus petit que draw lines (RGB332/PSRAM ou DMA actif), réduction automatique du nombre de lignes draw pour rester aligné sur le buffer trans; reset complet des stats/pending à l’init pipeline.
- Validation:
pio run -e freenove_esp32s3✅,pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅. - Checkpoint:
/tmp/zacus_checkpoint/1771928050_wip.patch,/tmp/zacus_checkpoint/1771928050_status.txt.
[2026-02-24] LVGL pipeline perf (double buffer + DMA RGB332)
- Scope: Freenove UI/LVGL. DMA async désormais autorisé même en RGB332 via trans buffer (conversion RGB332->RGB565) + garde flush; draw lines ajustées si trans buffer plus petit.
- Perf métriques: stats draw ajoutées (
draw_count/avg_us/max_us) dansUI_GFX_STATUSet snapshots; build optimisé-O2 -ffast-mathdansplatformio.ini. - Validation:
pio run -e freenove_esp32s3✅, upload/dev/cu.usbmodem5AB90753301✅.
[2026-02-24] SCENE_WIN_ETAPE flush/fx back-pressure
- Scope: UI Freenove (SCENE_WIN_ETAPE). Guarded LVGL flush re-entrance + FX/LVGL pipeline back-pressure (skip FX when DMA/flush busy; no lv_timer_handler while pending). UI_GFX_STATUS now reports fx_fps/fx_frames/fx_skip_busy + flush block/overflow counters; intro debug overlay shows fx_fps.
- Evidence: code only (no artifacts/logs generated in this session).
- Next steps: run
pio run -e freenove_esp32s3then (if hardware)tools/dev/post_upload_checklist.sh --port <PORT> --baud 115200and check UI_GFX_STATUS (fx_fps≈18, flush pending=0, fx_skip_busy stable).
[2026-02-24] Mic runtime gating by scene
- Scope: Freenove UI runtime. Mic processing can be toggled per scène via
UiManager::renderScene→HardwareManager::setMicRuntimeEnabled, now disabled when waveform/LA overlay not needed (e.g., WIN_ETAPE clean loop). Hardware snapshot cleared when mic is off; re-enabled auto when needed. - Validation:
pio run -e freenove_esp32s3✅, upload ✅/dev/cu.usbmodem5AB90753301. - Next: observe telemetry on SCENE_WIN_ETAPE (mic fields should stay at 0 when disabled); re-run
UI_GFX_STATUS/PERF_STATUSif required.
[2026-02-24] Standardisation checklist post-upload
- Scope: outillage visuel + stabilité Freenove.
- Travaux:
- Added
tools/dev/post_upload_checklist.sh(auto-détection port série, upload optionnel, capture N lignes de logs, validation minimale série,SCENE_GOTOcheck optionnel, confirmation visuelle manuelle). - Added
docs/ui/post_upload_checklist.md(mode d’emploi de la checklist). - Evidence location:
artifacts/post_upload/<timestamp>/post_upload_serial.logartifacts/post_upload/<timestamp>/upload.logartifacts/post_upload/<timestamp>/ports.json
- Added
- Limites constatées:
- la validation visuelle reste manuelle (pas d’accès caméra depuis cette session Codex).
[2026-02-24] Programme Freenove 3 vagues - fondations architecture/memoire/perf
- Checkpoint securite execute:
/tmp/zacus_checkpoint/1771909054_wip.patch/tmp/zacus_checkpoint/1771909054_status.txt
- Baseline runtime ajustee pour mesure realiste (Phase 0):
platformio.iniFreenove:UI_FULL_FRAME_BENCH=0,UI_DEMO_AUTORUN_WIN_ETAPE=0.
- Vague A (architecture) - extraction de l'orchestration:
- nouveaux modules:
runtime/runtime_services.h,runtime/app_coordinator.*,runtime/serial_command_router.*. main.cppdelegue desormais la boucle runtime viaAppCoordinator::tick(...)et le dispatch serie viaAppCoordinator::onSerialLine(...).
- nouveaux modules:
- Vague B (securite memoire) - garde-fous d'allocation:
- nouveaux modules:
runtime/memory/caps_allocator.*,runtime/memory/safe_size.h. ui_manager.cppmigre les alloc/free critiques vers wrappers capability-aware + verification overflow sur tailles de buffers.- nouveau snapshot memoire public UI:
UiMemorySnapshot+UiManager::memorySnapshot().
- nouveaux modules:
- Vague C (performance) - instrumentation:
- nouveau service:
runtime/perf/perf_monitor.*+ sections (loop,ui_tick,ui_flush,scenario_tick,network_update,audio_update). - nouvelles commandes serie:
PERF_STATUS,PERF_RESET. - instrumentation ajoutee sur
AppCoordinator::tick,UiManager::displayFlushCb/completePendingFlush,g_network.update,g_audio.update,g_scenario.tick,g_ui.tick.
- nouveau service:
- Validation/gates:
pio run -e freenove_esp32s3✅ZACUS_ENV=freenove_esp32s3 ./tools/dev/run_matrix_and_smoke.sh✅ (verdict globalSKIPfaute de mapping port strict; evidenceartifacts/rc_live/freenove_esp32s3_20260224-050717/summary.md).
[2026-02-24] Fonts registry completion (aliases + docs + UI cleanup)
- Scope complete for requested multi-family LVGL font pack:
- API aliases added in
ui_fonts.h/.cpp:fontBody(),fontBodyBoldOrTitle(). - optional 1px style shadow support added (
UI_FONT_STYLE_SHADOW, default1) on title/pixel styles. - remaining hardcoded Montserrat usages in
ui_manager.cppreplaced byUiFonts::*getters. - new doc added:
docs/ui/fonts.md(families, sizes, FR subset, bpp, regen flow, flash/RAM notes). docs/ui/fonts_fr.mdupdated to reflect lowercase API names.
- API aliases added in
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 6 --wait-port 10 --no-evidence✅ (RESULT=PASS)
[2026-02-24] SCENE_WIN_ETAPE refonte alignement final + mode test lock
- Checkpoint securite execute:
/tmp/zacus_checkpoint/20260224_045912_wip.patch/tmp/zacus_checkpoint/20260224_045912_status.txt
- Alignement livrables scene:
docs/ui/SCENE_WIN_ETAPE_demoscene_calibration.mdcorrige (B1=4000, bande centre >=50%, padding centre explicite).hardware/firmware/ui_freenove_allinone/README.mdcorrige (B1 3..5s, ordre overrides JSON-first,FONT_MODE).data/ui/scene_win_etape.txtcorrige (B1_MS=4000,FONT_MODE=orbitron, note padding auto scroller centre).
- Demande test hardware verrouillee:
platformio.iniforce pour l'env freenove:UI_FULL_FRAME_BENCH=1UI_DEMO_AUTORUN_WIN_ETAPE=1
- Skill sync:
~/.codex/skills/demoscene-demomaking-generic/SKILL.mdenrichi (profil LVGL 320x480, split B1/B2, regle centre >=50%, padding).- MAJ references:
references/parameter-calibration-guide.mdreferences/engine-adapter-matrix.md
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 6 --wait-port 10 --no-evidence✅ (RESULT=PASS)SCENE_GOTO SCENE_WIN_ETAPEserie ->ACK SCENE_GOTO ok=1✅- Runtime serie (
UI_GFX_STATUS) ✅:full_frame=1,source=PSRAM,mode=RGB332, autorun scene actif ([UI][WIN_ETAPE] phase=...sansSCENE_GOTO).
[2026-02-24] Freenove kit lock FNK0102H + test relance
- Verrouillage confirme pour le kit utilisateur FNK0102H:
platformio.ini:FREENOVE_LCD_VARIANT_FNK0102A=0,...B=0,...H=1.hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h: defaultFREENOVE_LCD_VARIANT_FNK0102H=1.
- Checkpoint securite execute:
/tmp/zacus_checkpoint/20260224_045143_wip.patch/tmp/zacus_checkpoint/20260224_045143_status.txt
- Correctif compile rapide applique:
LV_OPA_65->LV_OPA_60dansui_manager.cpp(compat LVGL 8.4).
- Verification build/flash/runtime:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 6 --wait-port 10 --no-evidence✅ (RESULT=PASS)- Runtime check serie:
UI_GFX_STATUS+SCENE_GOTO SCENE_WIN_ETAPE+ phase logs intro OK.
[2026-02-24] SCENE_WIN_ETAPE demoscene runtime hardening (B1/B2 + morph + TXT/JSON)
- Skills chain appliquee pour la scene:
demoscene-demomaking-genericfirmware-graphics-stackfirmware-scene-ui-editor
- Correctifs firmware (
ui_manager.h/.cpp):- phase B split runtime:
B1crash court (ms clamp 700..1000) puisB2interlude jusqu'aB=15000. - copper rendu circulaire/wavy via rings animees (pool existant reutilise, sans alloc per-frame).
- wirecube: morph geometrique cube<->sphere (interpolation vertices + projection perspective existante).
- scroller C: ping-pong wavy borne sur bande verticale demi-ecran (centre).
- overrides runtime etendus: TXT+JSON (
MID_A_SCROLL,BOT_A_SCROLL,B1_MS,SPEED_MID_A,SPEED_BOT_A, etc.). - instrumentation start/phase gardee et enrichie (B1, vitesses scroll).
- phase B split runtime:
- Docs/livrables:
- calibration refraichie:
docs/ui/SCENE_WIN_ETAPE_demoscene_calibration.md. - exemple override TXT:
data/ui/scene_win_etape.txt. - README scene mis a jour (A/B/C + B1/B2, contrat overrides TXT+JSON, notes perf).
- calibration refraichie:
- Checkpoint securite execute:
/tmp/zacus_checkpoint/20260224_021234_wip.patch/tmp/zacus_checkpoint/20260224_021234_status.txt
[2026-02-24] SCENE_WIN_ETAPE timing lock update (A/B/C long format)
- Timings Freenove verrouilles pour la sequence intro:
- A =
30000 ms - B =
15000 ms - C =
20000 ms(puis boucle C infinie tant que la scene reste active)
- A =
- Alignement doc runtime:
hardware/firmware/ui_freenove_allinone/README.md(section Intro Amiga92)docs/ui/SCENE_WIN_ETAPE_demoscene_calibration.md(table calibration + defaults)
- Correctif build LVGL:
LV_OPA_35remplace parLV_OPA_30dansui_manager.cpppour compat LVGL 8.4.
- Checkpoint securite execute:
/tmp/zacus_checkpoint/20260224_014020_wip.patch/tmp/zacus_checkpoint/20260224_014020_status.txt
- Verification:
pio run -e freenove_esp32s3✅
[2026-02-24] Skill pack demoscene v1.2 + UI skill sync
- Creation du skill global
demoscene-demomaking-genericdans~/.codex/skills/:SKILL.md,agents/openai.yaml,references/*,templates/*.schema.json,- scripts:
build_reference_pack.py,validate_reference_pack.py,validate_demo_spec.py,emit_trackset_example.py.
- Contrat skill v1.2 aligne:
- pipeline obligatoire
References -> ReferencePack -> StyleSheet/Timeline/TrackSet/FxGraph, - baseline parametres chiffrés cracktro/clean/glitch/fireworks,
- mode clean scroller par defaut: rollback
ping_pong.
- pipeline obligatoire
- Skills UI synchronises:
~/.codex/skills/firmware-graphics-stack/SKILL.mdmis a jour (adapter workflow ReferencePack -> runtime LVGL).~/.codex/skills/firmware-scene-ui-editor/SKILL.mdmis a jour (scene tuning via tracks + validationSCENE_GOTO).- ajout metadata UI:
~/.codex/skills/firmware-scene-ui-editor/agents/openai.yaml.
- Playbook repo synchronise:
docs/AGENTS_COPILOT_PLAYBOOK.mdajoute le nouveau skill et l'ordre recommande:$demoscene-demomaking-generic, 2) skill adapter UI, 3) validation hardware.
- Checkpoint securite execute:
/tmp/zacus_checkpoint/20260224_011756_wip.patch/tmp/zacus_checkpoint/20260224_011756_status.txt
[2026-02-24] SCENE_WIN_ETAPE intro Amiga92 JSON-first
- UiManager: intro A/B/C dediee a
SCENE_WIN_ETAPE(state machine +lv_timer33 ms), skip bouton/touch, cleanup strict des anims/objets intro. - Runtime override JSON-only ajoute:
- chemin canonique:
/SCENE_WIN_ETAPE.json - compat lecture:
/ui/SCENE_WIN_ETAPE.json - schema flexible:
logo_text,crack_scroll,clean_title,clean_scroll(+ aliases legacy).
- chemin canonique:
- Assets/exemple:
- fichier exemple ajoute:
data/SCENE_WIN_ETAPE.json.
- fichier exemple ajoute:
- Documentation:
- section
Intro Amiga92+References consultedajoutees danshardware/firmware/ui_freenove_allinone/README.md.
- section
- Verification:
pio run -e freenove_esp32s3OK.pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301OK.pio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301OK.- serial:
SCENE_GOTO SCENE_WIN_ETAPE->ACK SCENE_GOTO ok=1, override JSON charge depuis/SCENE_WIN_ETAPE.json.
[2026-02-24] SCENE_WIN_ETAPE UI sequence (cracktro -> crash -> demo clean)
- UI sequence ajoutee pour
SCENE_WIN_ETAPEen mode Freenove fireworks:- phase A (4-5s): raster/copper bars + starfield multi-couches + logo
PROFESSEUR ZACUSen overshoot + scrolltext bas. - phase B (~0.9s): crash/glitch (blink + jitter + fade) avec burst firework.
- phase C (6-8s): fond sobre type degrade, reveal titre
BRAVO BRIGADE Z, puis scroll lent avec oscillation sinus.
- phase A (4-5s): raster/copper bars + starfield multi-couches + logo
- Implementation principale:
hardware/firmware/ui_freenove_allinone/src/ui_manager.cpp+ nouveaux widgets/etat dansinclude/ui_manager.h. - Verification:
pio run -e freenove_esp32s3OKpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301OK- passage direct scene valide via serie:
SCENE_GOTO SCENE_WIN_ETAPE(ACK SCENE_GOTO ok=1).
[2026-02-23] Audit coherence global (source de verite: firmware Freenove)
- Validation story spec OK:
./tools/dev/story-gen validate. - Regeneration C++ story/apps OK:
./tools/dev/story-gen generate-cpp(spec hasha4e034ba637f). - Build firmware cible Freenove OK:
pio run -e freenove_esp32s3. - Contrat ESP-NOW corrige:
SCENEdocumente commeSCENE <scenario_id>(chargement scenario),SCENE_GOTO <scene_id>documente comme extension one-shot Freenove.
- Drift checker cross-repo aligne:
SCENE_GOTOparsee explicitement,- marquee comme extension
OPTIONAL Zacus-onlypour eviter les faux positifs de drift.
- Coordination cross-repo rendue portable:
- docs mises a jour pour utiliser
RTC_BL_PHONE_REPO(ouRTC_REPO) au lieu d'un chemin machine hardcode.
- docs mises a jour pour utiliser
[2026-02-23] Coherence lock Freenove (Codex)
- Canonical hardware target:
freenove_esp32s3on ESP32-S3-WROOM-1-N16R8. - Canonical upload port for this setup:
/dev/cu.usbmodem5AB90753301(usbmodem flow). - Canonical one-shot scene jump command:
SCENE_GOTO <SCENE_ID>(serial + API control action). - API parity for one-shot jump:
POST /api/controlwithaction=SCENE_GOTO SCENE_WIN_ETAPE. - UI text safety lock: UTF-8 to ASCII fallback is applied before label rendering in
ui_manager.cppto avoid missing-glyph artifacts on the Freenove display. - Skill sync lock:
firmware-scene-ui-editorusesSCENE_GOTOas primary visual validation path.
[2026-02-23] Contrat ESP-NOW compact (1-pager)
- Ajout d'une fiche de synthèse pour intégration externe:
hardware/firmware/docs/ESP_NOW_API_CONTRACT_FREENOVE_V1_QUICK.md(format recommandé v1, réponses ACK, endpoints, erreurs). - Ajout d'une version ultra-légère
hardware/firmware/docs/ESP_NOW_API_CONTRACT_FREENOVE_V1_MINI_SCHEMA.mdpour le second repo. - Coordination API confirmée: la carte pair ESP-NOW Freenove est verrouillée sur
RTC_BL_PHONEbrancheesp32_RTC_ZACUS(Freenove en broadcast-only). - Ajout d'un document d'orchestration API:
docs/ESP_NOW_API_COORDINATION_AGENT.md. - Ajout d'une fiche interne de coordination cross-repo:
docs/CROSS_REPO_INTELLIGENCE.md(contrôle bi-directionnel sans écriture RTC tant qu'autorisé). - Ajout d'un script de contrôle drift:
tools/dev/check_cross_repo_espnow_contract.py. - Intégration du contrôle contractuel cross-repo dans
tools/dev/run_matrix_and_smoke.shvia l'étapecross_repo_contract_check(env:RTC_BL_PHONE_REPO,ZACUS_SKIP_CONTRACT_CHECK).
[2026-02-23] ESP-NOW Freenove (commandes runtime)
- Ajouté support ESP-NOW de
RING(dispatch event story) etSCENE <scenario_id>(charge scénario par id) dansexecuteEspNowCommandPayloaddu firmware Freenove. - Mise à jour du contrat ESP-NOW Freenove (
ESP_NOW_API_CONTRACT_FREENOVE_V1*) pour documenter ces commandes côté pair intégré. - Envoi ESP-NOW simplifié:
ESPNOW_SENDforce désormais l’envoi en broadcast (argument de target ignoré pour la compatibilité existante, WebUI simplifiée).
[2026-02-23] Contrat ESP-NOW Freenove (v1)
- Ajout doc contrat API ESP-NOW Freenove:
hardware/firmware/docs/ESP_NOW_API_CONTRACT_FREENOVE_V1.md(commandes, endpoints, exemples, erreurs/compatibilité).
[2026-02-23] Enchainement scène LA → etape gagnée (Freenove)
STEP_ETAPE2utilise désormaisSCENE_WIN_ETAPEdansdata/story/scenarios/DEFAULT.json(côté runtime actuel);SCENE_SIGNAL_SPIKEreste conservée en flux legacy/compat.- Déploiement provisoire embarqué aligné: mise à jour de
hardware/firmware/ui_freenove_allinone/src/storage_manager.cpp(asset scenario par défaut + ajoutSCENE_WIN_ETAPE.jsonintégré). - Registre runtime mis à jour:
hardware/libs/story/src/resources/screen_scene_registry.cppet fallback C++ de scénario compiléhardware/libs/story/src/generated/scenarios_gen.cpp. - Fichier scène ajouté:
data/story/screens/SCENE_WIN_ETAPE.json(clone visuel deSCENE_WINavec nouvel ID). - Convergence des sources de vérité:
docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yamlaligné surSCENE_WIN_ETAPE+SCENE_MEDIA_ARCHIVE. - Générateur story: ajout de
SCENE_WIN_ETAPEdanslib/zacus_story_gen_ai/src/zacus_story_gen_ai/generator.pypour conserver le mapping canonical et régression C++ alignée. - UI
SCENE_WIN_ETAPE: texte dynamique (Validation en cours.../BRAVO! vous avez eu juste) selon l'état audio pour piloter l'attente de validation côté UI.
Procédure smoke test Freenove
- Vérifier la configuration du port série (résolution dynamique via cockpit.sh ports).
- Flasher la cible Freenove avec cockpit.sh flash (ou build_all.sh).
- Lancer le smoke test avec tools/dev/run_matrix_and_smoke.sh.
- Vérifier le verdict UI_LINK_STATUS connected==1 (fail strict si absent),
sauf en mode carte combinée (
ZACUS_ENV=freenove_esp32s3) où la gate doit êtreSKIP: not needed for combined board. - Vérifier l’absence de panic/reboot dans les logs.
- Vérifier la santé des WebSockets (logs, auto-recover).
- Consigner les logs et artefacts produits (
logs/rc_live/*.log,artifacts/rc_live/<env>_<timestamp>/{meta.json,commands.txt,summary.md,...}). - Documenter toute anomalie ou fail dans AGENT_TODO.md.
TODO -- LA 440Hz en musique (en cours)
- Script
verify_la_music_chain.pyaligné aux délais réels scène + statut MP3 +--bg-musicoptionnel. - Lissage DSP + matching LA en fenêtres courtes implémentés (cumul de stabilité).
- Defaults runtime appliqués (
la_stable_ms=3000,la_release_ms=180). - Run terrain 20 s sans
--bg-music(musique externe déjà lancée), récupérer log et JSON:
✅max_stable_ms=3000obtenu en cumulé, no panic (log/tmp/zacus_la_music_20s_retry5.log, json/tmp/zacus_la_music_20s_retry5.json). - Run terrain 30 s + JSON, valider
max_stable_ms >= 3000etpanic_seen=false:
✅max_stable_ms=3000obtenu en cumulé, no panic (log/tmp/zacus_la_music_30s_retry5.log, json/tmp/zacus_la_music_30s_retry5.json). - Vérification script renforcée côté scènes: alias
SCENE_LA_DETECTaccepté, et attente deaudio/AUDIO_STATUSplus robuste. - Vérifier visuellement la montée continue de
Stabilite ...sur l’écran LA. - Contrôle build ciblé post-ajustements:
pio run -e freenove_esp32s3✅. - Ajustements fins de génération Python pour forcer davantage de LA cumulatif (anchor 70%, interruptions courtes) → passes 20/30 s.
- Gate finale: build + smoke + run terrain validés.
[2026-02-23] Ajustement détection LA musique (Freenove)
- Mission: rendre la progression
la_stable_mscumulative surSCENE_LA_DETECTOR(musique bruyante) sans relancer la fenêtre à chaque coupure courte. - Implémentation:
- ajout d'un lissage court pitch/confidence (3 trames) dans
HardwareManagerpour lissermic_freq_hz,mic_pitch_cents,mic_pitch_confidence. - logique
LaTriggerService::updateadaptée pour cumulerstable_mssur plusieurs fenêtres + exigence de continuité série courte. - état LA étendu avec
la_consecutive_match_count/la_match_start_ms(LaTriggerRuntimeState). - fenêtre de continuité élargie côté config:
la_release_msportée à180dans config runtime embarquée (APP_HARDWARE). - nouveau script
tools/dev/verify_la_music_chain.pyajouté:- génération LA longue + segments hors-LA/noise,
- options:
--target-hz,--stable-ms,--duration,--bg-music,--bg-volume,--la-volume,--seed,--out-json,--log-file, - logs automatiques dans
hardware/firmware/logs/verify_la_music_chain_*.log, - sortie JSON métriques (
first_lock_ms,latency_to_lock,max_stable_ms,freq_at_lock,conf_max,panic_seen), - musique de fond externe pilotée uniquement via
--bg-music(facultatif).
- ajout d'un lissage court pitch/confidence (3 trames) dans
- Vérification:
pio run -e freenove_esp32s3✅- smoke/validation hardware en chaîne de test musique à lancer avec carte branchée (
tools/dev/verify_la_music_chain.py --duration 20 --target-hz 440).
- Ajustement script en cours:
- options ajoutées au test
verify_la_music_chain.pypour les délais réels de scène:--scene-stabilize-ms,--audio-warmup-ms,--first-tuner-sample-ms. - logique de démarrage:
- attente post-
SCENE_LA_DETECTOR, - détection d'audio scène via
STATUS(audio=1outrack!=n/a), - première capture de
MIC_TUNER_STATUSavant chronométrage lock.
- attente post-
- amélioration livrée:
- polling
STATUS+AUDIO_STATUSpour détecter le vrai démarrage audio scène, - capture de
audio_ready_ms(etaudio_ready_scene_msen JSON), - logs de
stable_msà chaque variation (montées + reset), - métriques JSON enrichies (
first_tuner_sample_ms,audio_ready_ms).
- polling
- options ajoutées au test
[2026-02-23] Suite script LA musique — adaptation startup hardware
- Script ciblé ajusté:
wait_screen()renvoie désormais le temps réel d'entrée d'une scène (et exige des échantillons stables).wait_scene_audio()attend explicitement le démarrage piste/lecture en scène (audio,media_play,track).- parseur
STATUSrenforcé pour capturermedia_play,track,packsans sur-généralisation. - métriques enrichies:
scene_locked_ms,scene_la_entry_ms,expected_stable_ms,duration_s.
- Navigation renforcée:
- ajout de
ensure_scene_loaded()pour garantirSCENE_LA_DETECTORavant démarrage des mesures LA. - enchaînement automatique BTN_NEXT (avec fallback
SC_LOAD DEFAULT) si le script démarre depuis un écran inattendu.
- ajout de
- Comportement:
- délai de démarrage scène/audio calculé à l'exécution, avec sauvegarde en JSON et logs détaillés.
- compatible avec son externe déjà actif:
--bg-musicreste optionnel, le script ne dépend plus d'un lancement forcé d'une piste locale.
- Validation récente:
python3 tools/dev/verify_la_music_chain.py --help✅python3 -m py_compile tools/dev/verify_la_music_chain.py✅pio run -e freenove_esp32s3✅
[2026-02-23] PSRAM Freenove (Codex)
- Ajout des toggles build Freenove pour activer des allocations PSRAM ciblées (
FREENOVE_PSRAM_UI_DRAW_BUFFER,FREENOVE_PSRAM_CAMERA_FRAMEBUFFER) et macro de profil (FREENOVE_USE_PSRAM). - UI (
ui_manager.cpp) : allocation dynamique du draw buffer LVGL en PSRAM avec fallback DRAM + logs de source/mémoire. - Caméra (
camera_manager.cpp) : framebuffer PSRAM activable via macro dédiée. - Runtime (
main.cpp) : logs de profil mémoire/PSRAM en boot pour valider capacité disponible.
[2026-02-23] Alignement cible Freenove mémoire
- Cible Freenove corrigée vers ESP32-S3-WROOM-1-N16R8.
- Ajout d’un board custom
boards/freenove_esp32_s3_wroom_n16r8.jsonpour refléter le profil 16MB/16MB (flash+PSRAM), avec alias utilisé parenv:freenove_esp32s3_full_with_ui. - Docs de mapping mises à jour (
docs/RC_FINAL_BOARD.md,hardware/firmware/ui_freenove_allinone/RC_FINAL_BOARD.md).
Verrou opératoire (demande utilisateur)
- Mode de travail verrouillé: utiliser uniquement les commandes
piopour build/flash/FS (pio run ...). - Ne pas exécuter les scripts
tools/dev/*tant que ce verrou est actif.
[2026-02-23] SCENE_LA_DETECT: migration contrôlée vers SCENE_LA_DETECTOR (Codex)
- Source de vérité des scènes:
hardware/libs/story/src/resources/screen_scene_registry.cppgarde le schéma canonique. - Tolérance migration activée:
- alias unique:
SCENE_LA_DETECT -> SCENE_LA_DETECTOR(runtime + générateur). storyNormalizeScreenSceneIdaccepte l’alias et le mappe vers le canonical.
- alias unique:
- Alignement scénarios/payloads:
- la plupart des sources de scenario/payload ont été migrées sur
SCENE_LA_DETECTOR;
- la plupart des sources de scenario/payload ont été migrées sur
- les tests documentent la tolérance/normalisation (
generator.py,test_generator.py,test_story_fs_manager.cpp). - Build hygiene:
- suppression du warning
SUPPORT_TRANSACTIONS redefineden retirant les redéfinitions CLI en doublon pour les envs qui incluentui_freenove_config.h.
- suppression du warning
[2026-02-23] Freenove boutons + triggers (Codex)
- Refactor lecture boutons Freenove vers tâche dédiée + queue RTOS:
ButtonManagerscanne les entrées en tâche dédiée (scan_task) et place les événements dans une queue.- garde-fou fallback synchrone si création queue/tâche RTOS échoue.
- Ajustement mapping runtime boutons:
STEP_WAIT_UNLOCK: tout appui (court/long) 1..5 =>BTN_NEXT(fallbackNEXTviadispatchEvent).SCENE_LA_DETECT/SCENE_LA_DETECTOR(ouSTEP_WAIT_ETAPE2) : réinitialisation du timeout scène LA sur tout appui 1..5.
- Nettoyage du revalidation scénario (suppression des cas de test physiques non actifs).
- Validation:
pio run -e freenove_esp32s3✅.
[2026-02-23] Freenove audit + refactor agressif (RTOS/audio/wifi/esp-now/UI/story) (Codex)
- Checkpoint sécurité exécuté avant modifs:
- branche:
main - patch/status:
/tmp/zacus_checkpoint/20260223-011928_wip.patch,/tmp/zacus_checkpoint/20260223-011928_status.txt - scan artefacts trackés (
.pio,.platformio,logs,dist,build,node_modules,.venv): aucun match.
- branche:
- Audit runtime (focus Freenove) et constats:
main.cppconcentrait bootstrap + orchestration loop + parsing commandes série + bridge ESP-NOW + routes web + actions story (hardware/firmware/ui_freenove_allinone/src/main.cpp:3137,hardware/firmware/ui_freenove_allinone/src/main.cpp:3241,hardware/firmware/ui_freenove_allinone/src/main.cpp:1532).- callback ESP-NOW RX faisait trop de travail en chemin critique; allègement effectué: enqueue brut en callback, parsing envelope au
consume(hardware/firmware/ui_freenove_allinone/src/network_manager.cpp:910,hardware/firmware/ui_freenove_allinone/src/network_manager.cpp:564). - duplication parsing JSON multi-clés dans ScenarioManager; factorisé via helper canonique (
hardware/firmware/ui_freenove_allinone/src/scenario_manager.cpp:82,hardware/firmware/ui_freenove_allinone/src/scenario_manager.cpp:506). - provisioning LittleFS embarqué du bundle story répétitif; factorisé avec
provisionEmbeddedAsset(hardware/firmware/ui_freenove_allinone/src/storage_manager.cpp:667,hardware/firmware/ui_freenove_allinone/src/storage_manager.cpp:703). - UI LVGL présentait des séquences style/hide/show répétées sur rings + overlay LA; extraction helpers
SceneElement/SceneState(hardware/firmware/ui_freenove_allinone/src/ui_manager.cpp:312,hardware/firmware/ui_freenove_allinone/src/ui_manager.cpp:1516).
- Refactor/optimisations appliqués:
- extraction config runtime APP_* dans service dédié (
hardware/firmware/ui_freenove_allinone/src/runtime/runtime_config_service.cpp:102, usagehardware/firmware/ui_freenove_allinone/src/main.cpp:3167). - extraction logique LA/matching/timeout dans service dédié (
hardware/firmware/ui_freenove_allinone/src/runtime/la_trigger_service.cpp:183, usagehardware/firmware/ui_freenove_allinone/src/main.cpp:248). HardwareManagerexposesnapshotRef()+ palette LED centralisée scène->RGB (hardware/firmware/ui_freenove_allinone/src/hardware_manager.cpp:172,hardware/firmware/ui_freenove_allinone/src/hardware_manager.cpp:875).UiManagerlit le snapshot hardware par référence stable (moins de copies hot-loop) viasetHardwareSnapshotRef(hardware/firmware/ui_freenove_allinone/src/main.cpp:3236,hardware/firmware/ui_freenove_allinone/src/ui_manager.cpp:252).- action story
queue_audio_packbranchée (ACTION_QUEUE_SONAR) pour audio hint piloté par scénario (hardware/firmware/ui_freenove_allinone/src/main.cpp:1589).
- extraction config runtime APP_* dans service dédié (
- Update scénario DEFAULT:
- suppression redondance audio sur
STEP_U_SON_PROTO(action media file doublonnaitaudio_pack_id). - ajout
ACTION_QUEUE_SONARsurSTEP_WAIT_ETAPE2. - synchronisation fallback embarqué LittleFS avec le même contenu (
data/story/scenarios/DEFAULT.json:33,data/story/scenarios/DEFAULT.json:60,hardware/firmware/ui_freenove_allinone/src/storage_manager.cpp:69).
- suppression redondance audio sur
- Fichiers manifests demandés:
zacus_v1_audio.yamletzacus_v1_printables.yamlintrouvables dans ce scopehardware/firmware; ignorés conformément à la consigne utilisateur.
- Validation build demandée par verrou utilisateur:
- commande unique exécutée:
pio run -e freenove_esp32s3_full_with_ui - run #1 (01:39): FAIL sur
scenario_manager.cpp(JsonObjectConst::as<>invalide), corrigé via passageJsonVariantConst. - run #2 (01:40): PASS (
freenove_esp32s3_full_with_ui SUCCESS, RAM 55.3%, Flash 73.1%). - timestamp evidence:
2026-02-23 01:40:39 +0100.
- commande unique exécutée:
- Ajustements audio + test ciblé (suite au passage précédent):
audio_manager.cpppasse en mode pump dédié FreeRTOS + protections d'accès concurrents (mutex, queue d'événementsdone) afin de réduire les latences de lecture.ui_freenove_config.hstabilisé pour éviter la redéfinitionSUPPORT_TRANSACTIONS(#ifndefavant#define).- calibration runtime: passage
vTaskDelay(1)->taskYIELD()quand le playback est actif (réduction de jitter potentielle de boucle decode). - build/flash vérifiés:
pio run -e freenove_esp32s3✅,pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅.
[2026-02-23] Migration Freenove vers ESP32-audioI2S (Codex)
- Checkpoint sécurité exécuté avant modifs:
- branche:
main - patch/status:
/tmp/zacus_checkpoint/20260223_151405_wip.patch,/tmp/zacus_checkpoint/20260223_151405_status.txt - scan artefacts trackés (
.pio,.platformio,logs,dist,build,node_modules,.venv): aucun.
- branche:
- Audio backend Freenove migré:
ui_freenove_allinone/src/audio_manager.cppréécrit surESP32-audioI2S(Audio.h) avec maintien de l’API publique (play/stop/update/status/profiles/fx/callback).- normalisation des chemins audio (
/littlefs/...,/sd/...) + validation de présence de fichier avant lecture. - détection codec/bitrate conservée pour le reporting (
AUDIO_STATUS) avec scan MP3 header.
- Dépendances PlatformIO (env Freenove):
- ajout
esphome/ESP32-audioI2S@^2.3.0. - retrait de
earlephilhower/ESP8266Audiosur l’env Freenove. build_src_filterFreenove réduit aux unités Story réellement utilisées (core/scenario_def,generated/scenarios_gen,resources/screen_scene_registry,scenarios/default_scenario_v2,ui/player_ui_model) pour découpler le build des modules legacy audio.
- ajout
- Validation:
pio run -e freenove_esp32s3_full_with_ui✅ (SUCCESS, RAM 56.2%, Flash 80.1%).pio run -e freenove_esp32s3_full_with_ui✅ après découplage build Story (SUCCESS, RAM 56.2%, Flash 79.9%).pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅.pio device monitor -e freenove_esp32s3_full_with_ui --port /dev/cu.usbmodem5AB90753301✅.
- Incident runtime (triage RTOS/audio):
- Repro stable d’un panic
Guru Meditation Error: Core 1 panic'ed (Double exception)sur séquence sérieAUDIO_STOPpuisAUDIO_TEST_FS. - Correctif
audio_manager.cpp:- suppression du
stopSong()redondant juste avantconnecttoFS, - ajout d’un démarrage différé (file d’attente + cooldown 80ms) pour éviter stop/reopen immédiat sur le backend
ESP32-audioI2S. - ajout d’un pump RTOS dédié audio (
audio_pump, coeur 1, loop 1ms actif) avec mutex d’état + file d’événementsdonepour maintenirAudio::loop()hors charge UI/réseau et éviter la saccade.
- suppression du
- Vérification post-correctif:
- séquences répétées
AUDIO_STATUS,AUDIO_STOP,AUDIO_TEST_FS,AUDIO_STATUSsans reboot/panic, - profils
AUDIO_FX/AUDIO_PROFILE+STATUSvalides après arrêt/reprise audio. - reflash + retest matériel validés (
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301) ; boot log confirmepump task=1.
- séquences répétées
- Repro stable d’un panic
[2026-02-22] Verrou transition boutons -> LA detector (Codex)
- Contrat verrouillé: depuis
STEP_WAIT_UNLOCK(SCENE_LOCKED), tout appui bouton (1..5, court/long) déclencheBTN_NEXTet enchaîne versSTEP_WAIT_ETAPE2. - Spécification canonique alignée:
docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yamlannoté +screen_scene_id: SCENE_LA_DETECTOR.
- Data Story alignée:
data/story/scenarios/DEFAULT.json:button_short_1..5 = BTN_NEXT.data/story/scenarios/DEFAULT.json:STEP_WAIT_ETAPE2.screen_scene_id = SCENE_LA_DETECTOR.data/story/screens/SCENE_LA_DETECTOR.jsonajouté (alias écran LA detector).
- Validation hardware série (usbmodem Freenove):
python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 3.0 --settle 3.0✅NEXTdirect validé:STEP_WAIT_UNLOCK/SCENE_LOCKED -> STEP_WAIT_ETAPE2/SCENE_LA_DETECTOR✅
- Correctif robustesse bouton:
ScenarioManager::notifyButton: enSTEP_WAIT_UNLOCK, tout appui bouton (1..5, court ou long) déclencheBTN_NEXT.- revalidation runtime:
SC_REVALIDATE_HW=>changed=1pourBTN1_SHORT,BTN3_LONG,BTN4_LONG,BTN5_SHORT,BTN5_LONG✅
- Outillage test aligné:
tools/dev/verify_story_default_flow.py: attenteSCENE_LA_DETECTOR+ fallback robuste siSC_LOADne renvoie pas d'ACK.
[2026-02-22] Focus validation micro + détection (hardware Freenove)
- Correctifs runtime micro/tuner appliqués dans
hardware/firmware/ui_freenove_allinone/src/hardware_manager.cpp:- capture I2S micro en
32-bitpuis conversion PCM16 (>>8) pour éviter les lectures saturées parasites, - détection LA recentrée sur bande utile (
320..560 Hz) pour réduire les faux positifs hors contexte, - sortie tuner instantanée (
mic_freq_hz/mic_pitch_cents/mic_pitch_confidence) sans lissage décroissant trompeur.
- capture I2S micro en
- Validation firmware sur carte (port USB modem):
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Validation live micro:
./tools/dev/verify_mic_live.py --port /dev/cu.usbmodem5AB90753301 --samples 25 --duration 12✅- verdict observé:
mic_ready_all=1,conf_non_zero>0,freq_non_zero>0.
- Validation comportement détection fréquentielle (campagne locale via
afplay):- 392 Hz -> médiane ~391 Hz (conf élevée),
- 440 Hz -> médiane ~441 Hz (conf élevée),
- 466 Hz -> médiane ~468 Hz (conf élevée),
- 523 Hz -> médiane ~521 Hz (détection présente),
- baseline silencieuse/ambiante: médiane confiance à
0(quelques détections isolées restantes).
- Non-régression Story:
python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 2.2✅- flux validé:
SCENE_LOCKED -> SCENE_BROKEN -> SCENE_LA_DETECT -> SCENE_SIGNAL_SPIKE -> SCENE_MEDIA_ARCHIVE.
[2026-02-22] SCENE_LA_DETECTOR — UI instrumentée + trigger match micro strict (Codex)
- UI
SCENE_LA_DETECTenrichie (dansui_manager):- waveform micro circulaire autour du noyau (input réel micro),
- indicateur niveau micro (barre),
- analyseur fréquentiel simplifié (barres),
- indicateur de justesse (aiguille) + statut (
AUCUNE NOTE/PRESQUE JUSTE/LA VALIDE), - compteur LA détecté et compteur timeout visibles à l’écran.
- accordeur autour du LA au niveau des LED (WS2812) du freenove
- Trigger gameplay LA ajusté:
- validation LA continue à
3s(la_stable_ms=3000) -> passage scène suivante, - timeout global à
60s(la_timeout_ms=60000) -> retour directSCENE_LOCKED.
- validation LA continue à
- Garde-fous “match micro obligatoire” sur l’étape LA:
- blocage des raccourcis
NEXT/UNLOCKmanuels enSTEP_WAIT_ETAPE2(série/web/control/boutons), - seule la validation micro peut déclencher la transition nominale.
- blocage des raccourcis
- Stabilité runtime:
- correction stack canary loopTask (buffers DSP micro déplacés hors pile dans
HardwareManager).
- correction stack canary loopTask (buffers DSP micro déplacés hors pile dans
- Validation exécutée (USB modem Freenove):
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- logs série auto: absence
Guru Meditation/panic ✅ - logs série auto:
NEXTbloqué en scène LA (ACK NEXT ok=0) ✅ - logs série auto: timeout LA ~60s puis reset
STEP_WAIT_UNLOCK / SCENE_LOCKED✅
- Validation visuelle matérielle à confirmer:
- lisibilité des 4 widgets UI (waveform/level/analyzer/timers),
- calibration terrain pour atteindre
LA VALIDEen 3s sur ton setup micro.
[2026-02-22] Freenove lockscreen glitch + LEDs cassées (Codex)
- Renforcement de l'écran
SCENE_LOCKED:- nouvel effet runtime dédié
kGlitch(secousses aléatoires X/Y, flicker aléatoire opacité, particules aléatoires, contraste renforcé). - boucle d'effet enrichie pour les particules en mode
glitchetcelebrate(mode cassé) avec jitter non périodique. - reset explicite des translations LVGL entre scènes pour éviter les résidus d'animation.
- waveform micro ajoutée sur
SCENE_LOCKEDen mode glitch mobile (scan vertical sur l'écran + distorsions aléatoires).
- nouvel effet runtime dédié
- Renforcement LEDs WS2812 (4 LEDs Freenove) en scène cassée:
- pattern “broken hardware” aléatoire sur
SCENE_LOCKED/SCENE_BROKEN/SCENE_SIGNAL_SPIKE(flashs brefs, non simultanés entre LEDs, coupures, sparks, dérive couleur). - vérifié en série via
HW_STATUS(LED#1 majoritairement OFF avec flashs brefs intermittents).
- pattern “broken hardware” aléatoire sur
- Data Story/FS alignées:
data/story/screens/SCENE_LOCKED.json+data/screens/locked.jsonmis à jour (timeline plus agressive, strobe 100, contraste élevé, texte:Module U-SON PROTO/VERIFICATION EN COURS).- fallback embarqué
/story/screens/SCENE_LOCKED.jsonsynchronisé dansstorage_manager.cpp.
- Correctif stabilité:
- régression stack canary détectée avec
StaticJsonDocument<4096>dansUiManager::renderScene. - corrigé via
DynamicJsonDocument(4096)(plus de panic observé sur rechargement scénario).
- régression stack canary détectée avec
- Validations exécutées:
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --baud 115200✅- vérif série:
[UI] scene=SCENE_LOCKED effect=6 speed=90 ... timeline=8+ absenceGuru MeditationsurSC_LOAD DEFAULT✅ python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --timeout 2.2✅ (flux attendu:SCENE_LOCKED -> SCENE_BROKEN -> SCENE_LA_DETECT -> SCENE_SIGNAL_SPIKE -> SCENE_MEDIA_ARCHIVE)- waveform micro déplacée sur un tracé circulaire autour du noyau écran (
scene_core_/scene_ring_outer_) pourSCENE_LA_DETECT. - validation micro Freenove série en condition runtime (
STEP_WAIT_ETAPE2,SCENE_LA_DETECT):mic_ready=1sur tous les échantillons.mic_level_pctvariable (span 45),mic_peaknon nul (max 32768),mic_freq_hz>0etmic_pitch_confidence>0.
- variante scope renforcée:
- double tracé circulaire (anneau principal + anneau externe) autour du noyau (
scene_core_) pour visualiser la forme d'onde directement sur le cercle. - couleur/épaisseur pilotées par la justesse (
mic_pitch_cents) et la confiance (mic_pitch_confidence) pour la détection LA.
- double tracé circulaire (anneau principal + anneau externe) autour du noyau (
- nouvel outil de validation opérateur:
tools/dev/verify_mic_live.py(auto-load scénario, passageSCENE_LA_DETECT, samplingHW_STATUS_JSON, verdict PASS/FAIL).- run validé:
./tools/dev/verify_mic_live.py --port /dev/cu.usbmodem5AB90753301 --samples 20 --duration 10✅ (mic_ready_all=1,level span=40,peak_max=32768,freq_non_zero=17).
- nettoyage anti-doublons:
- purge des artefacts
* 2*non trackés (copies parasites), restauration des fichiers trackés détectés par erreur hors scope firmware. - règles préventives ajoutées:
.gitignoreracine:**/* 2+**/* 2.*hardware/firmware/.gitignore:* 2+* 2.*
- purge des artefacts
- évolution accordeur:
- LEDs (4 WS2812) en mode tuner plus lisible:
flatà gauche (bleu/cyan),in-tuneau centre (vert),sharpà droite (orange/rouge), avec flash extrême en forte dérive. - debug série live ajouté:
MIC_TUNER_STATUS [ON|OFF|<period_ms>].
- LEDs (4 WS2812) en mode tuner plus lisible:
- évolution écran LA_DETECT:
- rendu “vibromètre” accentué sur anneaux circulaires (amplitude/punch renforcés, warp de phase léger, boost niveau micro).
- validations additionnelles:
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- série:
MIC_TUNER_STATUSone-shot +MIC_TUNER_STATUS ON 180(flux live observé) +MIC_TUNER_STATUS OFF✅ ./tools/dev/verify_mic_live.py --port /dev/cu.usbmodem5AB90753301 --samples 20 --duration 10✅ (fallbackMIC_TUNER_STATUSsiHW_STATUS_JSONnon décodable)python3 tools/dev/verify_story_default_flow.py --port /dev/cu.usbmodem5AB90753301 --timeout 2.2✅
[2026-02-21] Firmware workflow hardening (Codex)
- PR de correction et merge:
feat/fix-firmware-story-workflow→ PR #105 → squash merge (main). - Fichier touché:
.github/workflows/firmware-story-v2.yml - Correctifs:
- indentation YAML corrigée sur
concurrency.cancel-in-progress(anciennement bloquant l’exécution du workflow). - correction du répertoire de travail du job
story-toolchain(hardware/firmwareau lieu dehardware/firmware/esp32_audioinexistant). - alignement des artefacts de job
story-toolchainvers les chemins existants.
- indentation YAML corrigée sur
- Validation:
- PR checks:
story toolchain,validate,build env(esp32dev/esp32_release/esp8266_oled/ui_rp2040_*) pass. - PR #105 mergeée (commit
04e4e50) avec workflow OK.
- PR checks:
[2026-02-21] Coordination Orchestrator binôme (Kill_LIFE + Zacus + RTC)
- PR Kill_LIFE
#11a été vérifiée et validée manuellement (scope):- scripts/tools d'orchestration (
tools/ai/zeroclaw_*, y compriszeroclaw_stack_up.sh,zeroclaw_hw_firmware_loop.sh,zeroclaw_watch_1min.sh); - docs techniques
specs/*.
- scripts/tools d'orchestration (
- Vérification stricte:
gh pr checks 11 --repo electron-rare/Kill_LIFE: tous ✅ (api_contract,lint-and-contract,ZeroClaw Dual Orchestrator, etc.).- aucun artefact hors-scope ajouté dans le PR.
- Merge status:
- PR fermé via squash (commit
e8e44048a8b36b7debcb12788183b34045dde7f2) surmain. - commentaire de clôture codex publié (PASS) dans PR #11.
- PR fermé via squash (commit
- Correctif suite: PR Kill_LIFE
#12créé pour durcir le fallback mismatch:tools/ai/zeroclaw_hw_firmware_loop.shvérifie maintenant la stabilité du port USB avant fallback env.- merge PR #12 (squash) validé, commit
5f517ae82b95c1988d6c07e888194dcc28e02ff3.
- Coordination inter-repos:
- PR Zacus déjà alignée côté AP/ESP-NOW/WebUI (PRs/faits et mergeés précédemment dans ce chantier).
RTC_BL_PHONE: aucun PR ouvert en cours au moment du contrôle (gh pr list --state openvide).
- Actions de traçabilité:
- pas de dette bloquante détectée.
- prochaine étape: continuer surveillance post-merge (runbook ZeroClaw/CI + vérification liaison
watcher).
[2026-02-21] Freenove AP fallback dédié (anti-oscillation hors Les cils) (Codex)
- Contexte coordination merge train: PR Zacus #101 mergée, puis patch dédié AP fallback.
- Patch runtime réseau:
- séparation SSID local vs AP fallback (
local_ssid=Les cils,ap_default_ssid=Freenove-Setup) - nouveau flag config:
pause_local_retry_when_ap_client - retry STA vers
Les cilsmis en pause si client connecté à l'AP fallback - nouveaux indicateurs exposés:
- série
NET_STATUS:ap_clients,local_retry_paused - WebUI
/api/status+/api/network/wifi:ap_clients,local_retry_paused
- série
- séparation SSID local vs AP fallback (
- Fichiers touchés:
data/story/apps/APP_WIFI.jsonhardware/firmware/ui_freenove_allinone/include/network_manager.hhardware/firmware/ui_freenove_allinone/src/network_manager.cpphardware/firmware/ui_freenove_allinone/src/main.cpp
- Notes:
- pas de constantes hardcodées nouvelles pour credentials AP en dehors de la config runtime/littlefs
- comportement historique conservé si
pause_local_retry_when_ap_client=false. - validations exécutées (PIO only):
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- série
NET_STATUS,SC_REVALIDATE,SC_REVALIDATE_ALL,ESPNOW_STATUS_JSON✅ - WebUI
GET /api/status,GET /api/network/wifi(champsap_clients,local_retry_paused) ✅
- limite de validation:
- le cas
local_retry_paused=1nécessite un client connecté sur l'AP fallback pendant l'absence deLes cils(non reproduit sur ce run).
- le cas
[2026-02-21] Freenove story/ui/network pass final + revalidate step(x) (Codex)
- Checkpoint sécurité exécuté:
- branche:
feat/freenove-webui-network-ops-parity - patch/status:
/tmp/zacus_checkpoint/20260221_021417_wip.patch,/tmp/zacus_checkpoint/20260221_021417_status.txt - scan artefacts trackés (
.pio,.platformio,logs,dist,build,node_modules,.venv): aucun.
- branche:
- Correctif incohérence revalidate:
SC_REVALIDATE_STEP2renommé enSC_REVALIDATE_STEPX- logs enrichis avec
anchor_step=<step courant>pour éviter l'ambiguïté multi-scénarios.
- Validations PIO:
pio run -e freenove_esp32s3_full_with_uiPASS (x2)pio run -e freenove_esp32s3_full_with_ui -t buildfsPASSpio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301PASSpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS (x2)
- Evidence série (
pio device monitor --port /dev/cu.usbmodem5AB90753301 --baud 115200):SC_COVERAGE scenario=DEFAULT unlock=1 audio_done=1 timer=1 serial=1 action=1SC_REVALIDATEOK avecSC_REVALIDATE_STEPX ... anchor_step=STEP_WAIT_ETAPE2 ... step_after=STEP_ETAPE2ESPNOW_STATUS_JSONOK (ready=true, compteurs cohérents)ESPNOW_SEND broadcast pingOK (ACK ... ok=1)NET_STATUSlocal connecté validé (sta_ssid=Les cils,local_match=1,fallback_ap=0).
- Evidence WebUI:
GET /api/status,GET /api/network/wifi,GET /api/network/espnowOKPOST /api/controlavecSC_EVENT unlock UNLOCKOK (ok=true+ transition observée en série).
[2026-02-20] GH binôme Freenove AP local + alignement ESP-NOW RTC (Codex)
- Branche de travail:
feat/freenove-ap-local-espnow-rtc-sync - Coordination GitHub:
- issue firmware: https://github.com/electron-rare/le-mystere-professeur-zacus/issues/91
- issue RTC (binôme, branche
audit/telephony-webserver): https://github.com/electron-rare/RTC_BL_PHONE/issues/6 - PR firmware: https://github.com/electron-rare/le-mystere-professeur-zacus/pull/92
- Runtime Freenove mis à jour:
- AP fallback piloté par cible locale (
Les cils) + retry périodique (local_retry_ms) - règle appliquée: AP actif si aucun WiFi connu n'est connecté (fallback), AP coupé quand la STA est reconnectée à
Les cils - indicateurs réseau série ajoutés:
local_target,local_match - commande série ajoutée:
ESPNOW_STATUS_JSON(format RTC: ready/peer_count/tx_ok/tx_fail/rx_count/last_rx_mac/peers) - bootstrap peers ESP-NOW au boot via
APP_ESPNOW.config.peers - WebUI embarquée (
http://<ip>/) avec endpoints:GET /api/statusPOST /api/wifi/connect,POST /api/wifi/disconnectPOST /api/espnow/sendPOST /api/scenario/unlock,POST /api/scenario/next- endpoints alignés RTC:
GET /api/network/wifiGET /api/network/espnowGET/POST/DELETE /api/network/espnow/peerPOST /api/network/espnow/sendPOST /api/network/wifi/connect,POST /api/network/wifi/disconnectPOST /api/control(dispatch d'actions)
- correction WebUI:
WIFI_DISCONNECTest maintenant différé (~250 ms) pour laisser la réponse HTTP sortir avant la coupure STA
- Data story apps mises à jour:
data/story/apps/APP_WIFI.json:local_ssid,local_password,ap_policy=if_no_known_wifi,local_retry_msdata/story/apps/APP_ESPNOW.json:peers+ contrat payload enrichi
- AP fallback piloté par cible locale (
- Validations exécutées (PIO only):
pio run -e freenove_esp32s3_full_with_uiPASSpio run -e freenove_esp32s3_full_with_ui -t buildfsPASSpio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301PASSpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS- monitor série (
pio device monitor --port /dev/cu.usbmodem5AB90753301 --baud 115200):- boot config:
local=Les cils ... ap_policy=0 retry_ms=15000 NET_STATUS ... local_target=Les cils local_match=1 ... fallback_ap=0(local connecté)ESPNOW_STATUS_JSONOKWIFI_DISCONNECT=>fallback_ap=1puis retry local- après reconnect WiFi:
ESPNOW_SEND broadcast ping=> recovery auto ESP-NOW +ACK ... ok=1
- boot config:
- WebUI:
GET /api/statusOK (network/local_match,espnow,story,audio)POST /api/scenario/unlocketPOST /api/scenario/nextOK (transitions observées)POST /api/wifi/connectOKPOST /api/network/wifi/disconnect=> réponse HTTP200reçue avant coupure STA (plus de timeout systématique)POST /api/network/espnow/send(payload JSON) OKPOST /api/control(SC_EVENT unlock,WIFI_DISCONNECT) OK
- Note d'incohérence traitée:
- si AP fallback et cible locale partagent le même SSID (
Les cils), le retry local coupe brièvement l'AP fallback pour éviter l'auto-association.
- si AP fallback et cible locale partagent le même SSID (
[2026-02-21] Freenove WebUI parity réseau avec RTC (Codex)
- Branche de travail:
feat/freenove-webui-network-ops-parity - Tracking GitHub:
- issue firmware: https://github.com/electron-rare/le-mystere-professeur-zacus/issues/93
- coordination RTC: https://github.com/electron-rare/RTC_BL_PHONE/issues/6
- PR RTC liée (ops web): https://github.com/electron-rare/RTC_BL_PHONE/pull/8
- Runtime WebUI enrichi (parité endpoints réseau):
POST /api/network/wifi/reconnectPOST /api/network/espnow/onPOST /api/network/espnow/off- routes existantes conservées (
/api/status,/api/network/wifi,/api/network/espnow,/api/network/espnow/peer,/api/network/espnow/send,/api/control)
- Validation exécutée:
pio run -e freenove_esp32s3_full_with_uiPASSpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS- HTTP (
curl):POST /api/network/espnow/off=>{"action":"ESPNOW_OFF","ok":true}POST /api/network/espnow/on=>{"action":"ESPNOW_ON","ok":true}POST /api/network/wifi/reconnect=>{"action":"WIFI_RECONNECT","ok":true}POST /api/control(ESPNOW_OFF,ESPNOW_ON,WIFI_RECONNECT) =>ok=true
- monitor série (
pio device monitor --port /dev/cu.usbmodem5AB90753301 --baud 115200):NET_STATUScohérent (sta_ssid=Les cils,fallback_ap=0)ESPNOW_STATUS_JSONcohérent (ready=1)- logs observés:
[NET] ESP-NOW offpuis[NET] ESP-NOW ready
[2026-02-20] Freenove WiFi/AP fallback local + ESP-NOW bridge/story + UI FX (Codex)
- Exigence appliquée: l'AP ne sert qu'en fallback si la carte n'est pas sur le WiFi local (
Les cils). - Runtime modifié:
- boot auto-connect vers
Les cils/mascarade - AP fallback auto uniquement en absence de connexion STA (et stop auto quand STA connecté)
- boot auto-connect vers
- commandes série enrichies:
WIFI_CONNECT,WIFI_DISCONNECT,ESPNOW_PEER_ADD/DEL/LIST,ESPNOW_SEND <text|json>(broadcast)- bridge ESP-NOW -> events scénario durci (texte + JSON
cmd/raw/event/event_type/event_name)
- bridge ESP-NOW -> events scénario durci (texte + JSON
- Story/UI:
- intégration
APP_WIFI+APP_ESPNOWdans les scénarios/story specs YAML - génération C++ story régénérée (
spec_hash=1834bcdab734) - écran Freenove en mode effect-first (symboles/effets, titres cachés par défaut, vitesses d'effet pilotables par payload JSON)
- intégration
- Vérifications exécutées:
./tools/dev/story-gen validatePASS./tools/dev/story-gen generate-cppPASSpio run -e freenove_esp32s3_full_with_uiPASSpio run -e esp32dev -e esp32_release -e esp8266_oled -e ui_rp2040_ili9488 -e ui_rp2040_ili9486PASSpio run -e freenove_esp32s3_full_with_ui -t buildfsPASSpio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301PASSpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS- contenu repo root via
.venv/bin/python: validate/export scenario + audio manifest + printables manifest PASS
- Evidence série (115200):
- boot:
[NET] wifi connect requested ssid=Les cils+[NET] boot wifi target=Les cils started=1 - statut validé:
NET_STATUS state=connected mode=STA ... sta_ssid=Les cils ... ap=0 fallback_ap=0
- boot:
[2026-02-20] Freenove audio + écran + chaîne scénario/écran (Codex)
- Checkpoint sécurité exécuté: branche
main,git diff --statcapturé, patch/status sauvegardés:/tmp/zacus_checkpoint/20260220_203024_wip.patch/tmp/zacus_checkpoint/20260220_203024_status.txt
- Scan artefacts trackés (
.pio,.platformio,logs,dist,build,node_modules,.venv): aucun chemin tracké. - Build/flash Freenove validés (
/dev/cu.usbmodem5AB90753301):pio run -e freenove_esp32s3_full_with_uiPASSpio run -e freenove_esp32s3_full_with_ui -t buildfsPASSpio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301PASSpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS
- Validation série (
pio device monitor --port /dev/cu.usbmodem5AB90753301 --baud 115200) :AUDIO_TESTPASS (tonalité intégrée RTTTL, sans dépendance LittleFS)AUDIO_TEST_FSPASS (/music/boot_radio.mp3)AUDIO_PROFILE 0/1/2PASS (switch runtime pinout I2S)UNLOCK-> transitionSTEP_U_SON_PROTO, audio packPACK_BOOT_RADIO, puisaudio_done-> transitionSTEP_WAIT_ETAPE2PASS.
- Incohérence restante observée au boot: warning HAL SPI
spiAttachMISO(): HSPI Does not have default pins on ESP32S3!(non bloquant en exécution actuelle).
[2026-02-20] Freenove story step2 hardware + YAML GitHub + stack WiFi/AP + ESP-NOW (Codex)
- Checkpoint sécurité exécuté: branche
main,git diff --statcapturé, patch/status sauvegardés:/tmp/zacus_checkpoint/20260220_211024_wip.patch/tmp/zacus_checkpoint/20260220_211024_status.txt
- Scan artefacts trackés (
.pio,.platformio,logs,dist,build,node_modules,.venv): aucun chemin tracké. - Story specs YAML mis à jour (source of truth):
docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yamlenrichi avec transitions hardware pour l’étape 2:serial:BTN_NEXTunlock:UNLOCKaction:ACTION_FORCE_ETAPE2
- génération revalidée:
./tools/dev/story-gen validatePASS./tools/dev/story-gen generate-cppPASS./tools/dev/story-gen generate-bundlePASS
- fichiers générés synchronisés (
hardware/libs/story/src/generated/*), spec hash:6edd9141d750.
- GitHub pipeline Story restauré:
.github/workflows/firmware-story-v2.ymlremplacé par un workflow fonctionnel (validate + generate-cpp + generate-bundle + check diff + artifact bundle).
- Runtime Freenove enrichi:
- stack réseau ajoutée (
network_manager.{h,cpp}) avec:- WiFi STA + AP management
- ESP-NOW init/send/receive counters
- bridge ESP-NOW payload -> événement scénario (
SERIAL:<event>,TIMER:<event>,ACTION:<event>,UNLOCK,AUDIO_DONE)
- commandes série ajoutées:
NET_STATUS,WIFI_STATUS,WIFI_TEST,WIFI_STA,WIFI_AP_ON,WIFI_AP_OFFESPNOW_ON,ESPNOW_OFF,ESPNOW_STATUS,ESPNOW_SENDSC_LIST,SC_LOAD,SC_REVALIDATE_ALL,SC_EVENT_RAW
- credentials test appliqués:
- SSID test/AP par défaut:
Les cils - mot de passe:
mascarade
- SSID test/AP par défaut:
- stack réseau ajoutée (
- Revalidation transitions via ScenarioSnapshot:
SC_REVALIDATEcouvre events + hardware probes + vérifs ciblées step2:SC_REVALIDATE_STEP2 event=timer ... changed=1SC_REVALIDATE_STEP2 event=action name=ACTION_FORCE_ETAPE2 ... changed=1SC_REVALIDATE_STEP2 event=button label=BTN5_SHORT ... changed=1
SC_REVALIDATE_ALLexécuté sur tous les scénarios built-in.
- Build/flash Freenove validés (
/dev/cu.usbmodem5AB90753301):pio run -e freenove_esp32s3_full_with_uiPASSpio run -e freenove_esp32s3_full_with_ui -t buildfsPASSpio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301PASSpio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS (x2 après patch final)
- Validation série réseau:
WIFI_AP_ONPASS (ssid=Les cils,mode=AP_STA,ip=192.168.4.1)WIFI_AP_OFFPASSWIFI_TESTPASS (requête de connexion STA versLes cils)ESPNOW_SENDPASS (émission OK), pas de loopback RX local observé (rx=0) sur test mono-carte.
TODO Freenove ESP32-S3 (contrat agent)
[2026-02-17] Log détaillé des étapes réalisées – Freenove ESP32-S3
- Audit mapping hardware exécuté (artifacts/audit/firmware_20260217/validate_mapping_report.txt)
- Suppression des macros UART TX/RX pour UI Freenove all-in-one (platformio.ini, ui_freenove_config.h)
- Documentation détaillée des périphériques I2C, LED, Buzzer, DHT11, MPU6050 dans RC_FINAL_BOARD.md
- Synchronisation des macros techniques SPI/Serial/Driver dans ui_freenove_config.h (SPI_FREQUENCY, UI_LCD_SPI_HOST, etc.)
- Ajout d’une section multiplexage dans RC_FINAL_BOARD.md (partage BL/BTN3, CS TFT/BTN4)
- Ajout d’un commentaire explicite multiplexage dans ui_freenove_config.h
- Evidence synchronisée : tous les artefacts et logs sont tracés (artifacts/audit/firmware_20260217, logs/rc_live/freenove_esp32s3_YYYYMMDD.log)
- Traçabilité complète : chaque étape, correction, mapping, doc et evidence sont référencés dans AGENT_TODO.md
[2026-02-17] Rapport d’audit mapping hardware Freenove ESP32-S3
Correspondances parfaites :
- TFT SPI : SCK=18, MOSI=23, MISO=19, CS=5, DC=16, RESET=17, BL=4
- Touch SPI : CS=21, IRQ=22
- Boutons : 2, 3, 4, 5
- Audio I2S : WS=25, BCK=26, DOUT=27
- LCD : WIDTH=480, HEIGHT=320, ROTATION=1
Écarts ou incohérences :
- UART : platformio.ini (TX=43, RX=44), ui_freenove_config.h (TX=1, RX=3), RC_FINAL_BOARD.md (non documenté)
- I2C, LED, Buzzer, DHT11, MPU6050 : présents dans ui_freenove_config.h, absents ou non alignés ailleurs
- SPI Host, Serial Baud, Driver : macros techniques non synchronisées
- Multiplexage : BL/Bouton3 et CS TFT/Bouton4 partagent la broche, à clarifier
Recommandations :
- Aligner UART TX/RX sur une valeur unique et documenter
- Documenter I2C, LED, Buzzer, DHT11, MPU6050 dans RC_FINAL_BOARD.md
- Synchroniser macros techniques dans ui_freenove_config.h et platformio.ini
- Ajouter une note sur le multiplexage dans RC_FINAL_BOARD.md et ui_freenove_config.h
- Reporter toute évolution dans AGENT_TODO.md
Evidence :
- Rapport complet : artifacts/audit/firmware_20260217/validate_mapping_report.txt
[2026-02-17] Synthèse technique – Détection dynamique des ports USB
- Tous les ports USB série sont scannés dynamiquement (glob /dev/cu.*).
- Attribution des rôles (esp32, esp8266, rp2040) selon mapping, fingerprint, VID:PID, fallback CP2102.
- Esp32-S3 : peut apparaître en SLAB_USBtoUART (CP2102) ou usbmodem (mode bootloader, DFU, flash initial).
- RP2040 : typiquement usbmodem.
- Si un seul CP2102 détecté, fallback mono-port (esp32+esp8266 sur le même port).
- Si plusieurs ports, mapping par location, fingerprint, ou VID:PID.
- Aucun port n’est hardcodé : la détection s’adapte à chaque run (reset, flash, bootloader).
- Les scripts cockpit.sh, resolve_ports.py, run_matrix_and_smoke.sh exploitent cette logique.
- Traçabilité : logs/ports_debug.json, logs/ports_resolve.json, artifacts/rc_live/...
- Documentation onboarding mise à jour pour refléter la procédure.
- Recommandation : toujours utiliser la détection dynamique, ne jamais forcer un port sauf cas extrême (override manuel).
[2026-02-17] Validation RC Live Freenove ESP32-S3 - Port USB corrigé : /dev/cu.SLAB_USBtoUART - Flash ciblé relancé : pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.SLAB_USBtoUART - Evidence synchronisée : summary.md, ui_link.log, logs/rc_live/20260217-211606 - Résultat : UI link FAIL (connected=1 mais status unavailable) - Artefacts : artifacts/rc_live/20260217-211606/summary.md, ui_link.log - Log détaillé ajouté dans AGENT_TODO.md
- Vérifier et compléter le mapping hardware dans platformio.ini ([env:freenove_esp32s3])
- Pins, UART, SPI, I2C, etc. : vérifier cohérence avec la doc.
- Exemple : GPIO22=I2S_WS, GPIO23=I2S_DATA, UART1=TX/RX.
- Aligner ui_freenove_config.h avec platformio.ini et la documentation RC_FINAL_BOARD.md
- Vérifier que chaque pin, bus, périphérique est documenté et codé.
- Ajouter commentaires explicites pour chaque mapping.
- Mettre à jour docs/RC_FINAL_BOARD.md
- Décrire le mapping complet, schéma, photo, table des pins.
- Ajouter procédure de flash/test spécifique Freenove.
- Mentionner les différences avec ESP32Dev.
- Adapter build_all.sh, cockpit.sh, run_matrix_and_smoke.sh, etc.
- Ajouter/valider la cible freenove_esp32s3 dans les scripts.
- Vérifier que le build, flash, smoke, logs fonctionnent sur Freenove.
- Exemple : ./build_all.sh doit inclure freenove_esp32s3.
- Vérifier la production de logs et artefacts lors des tests sur Freenove
- Chemin : logs/rc_live/freenove_esp32s3_YYYYMMDD.log
- Artefacts : artifacts/rc_live/freenove_esp32s3_YYYYMMDD.html
- Référencer leur existence (chemin, timestamp, verdict) dans docs/AGENT_TODO.md.
- Mettre à jour l’onboarding (docs/QUICKSTART.md, docs/AGENTS_COPILOT_PLAYBOOK.md)
- Ajouter section « Flash Freenove », « Test Freenove ».
- Préciser les ports série, baud, procédure de résolution dynamique.
- Vérifier que les gates smoke et stress test sont compatibles et valident strictement la cible Freenove
- Fail sur panic/reboot, verdict UI_LINK_STATUS connected==1.
- Tester WebSocket health, stress I2S, scénario LittleFS.
- Documenter toute évolution ou correction dans docs/AGENT_TODO.md
- Détailler les étapes réalisées, artefacts produits, impasses matérielles.
- Exemple : « Test flash Freenove OK, logs produits dans logs/rc_live/freenove_esp32s3_20260217.log ».
[2026-02-17] ESP32 pin remap test kickoff (Codex)
- Safety checkpoint re-run via cockpit wrappers:
git status,git diff --stat,git branch. - Checkpoint files saved:
/tmp/zacus_checkpoint/20260217-185336_wip.patchand/tmp/zacus_checkpoint/20260217-185336_status.txt. - Tracked artifact scan (
.pio,.platformio,logs,dist,build,node_modules,.venv) returned no tracked paths. - Runtime status at kickoff: UI Link handshake still FAIL (
connected=0) on latest cross-monitor evidence (artifacts/ui_link_diag/20260217-174822/), LittleFS fallback status unchanged, I2S stress status unchanged (last 30 min PASS).
[2026-02-17] ESP32 UI pin remap execution (Codex)
- Applied ESP32 UI UART remap in firmware config:
TX=GPIO23,RX=GPIO18(OLED side staysD4/D5). - Rebuilt and reflashed ESP32 (
pio run -e esp32dev, thenpio run -e esp32dev -t upload --upload-port /dev/cu.SLAB_USBtoUART9). - Cross-monitor rerun:
python3 tools/dev/capture_ui_link_boot_diag.py --seconds 22. - Evidence:
artifacts/ui_link_diag/20260217-175606/. - Result moved from FAIL to WARN: ESP32 now receives HELLO frames (
esp32 tx/rx=48/20,UI_LINK_STATUS connected=1seen), but ESP8266 still receives nothing from ESP32 (esp8266 tx/rx=19/0), so handshake remains incomplete.
[2026-02-17] UI link diagnostic patch kickoff (Codex)
- Safety checkpoint re-run via cockpit wrappers:
git status,git diff --stat,git branch. - Checkpoint files saved:
/tmp/zacus_checkpoint/20260217-181730_wip.patchand/tmp/zacus_checkpoint/20260217-181730_status.txt. - Tracked artifact scan (
.pio,.platformio,logs,dist,build,node_modules,.venv) returned no tracked paths. - Runtime status at kickoff: UI Link strict gate still FAIL (
connected=0), LittleFS scenario load now mitigated by V2 fallback, I2S stress status currently PASS on last 30 min run.
[2026-02-17] Cross-monitor boot capture (Codex)
- Built and flashed diagnostics on both boards:
pio run -e esp32dev -e esp8266_oled, then upload on/dev/cu.SLAB_USBtoUART9(ESP32) and/dev/cu.SLAB_USBtoUART(ESP8266). - Captured synchronized boot monitors with
python3 tools/dev/capture_ui_link_boot_diag.py --seconds 22. - Evidence:
artifacts/ui_link_diag/20260217-173005/(esp32.log,esp8266.log,merged.log,summary.md,ports_resolve.json,meta.json). - Verdict remains FAIL: no discriminant RX observed on either side (
ESP32 tx/rx=48/0,ESP8266 tx/rx=19/0, noconnected=1), indicating traffic still not seen on D4/D5 at runtime.
[2026-02-17] Cross-monitor rerun after pin inversion (Codex)
- Re-ran
python3 tools/dev/capture_ui_link_boot_diag.py --seconds 22after manual pin inversion test. - Evidence:
artifacts/ui_link_diag/20260217-174330/. - Verdict unchanged: FAIL with
ESP32 tx/rx=48/0,ESP8266 tx/rx=19/0, noconnected=1.
[2026-02-17] Cross-monitor rerun after inverted wiring confirmation (Codex)
- Re-ran
python3 tools/dev/capture_ui_link_boot_diag.py --seconds 22after updated wiring check. - Evidence:
artifacts/ui_link_diag/20260217-174822/. - Verdict unchanged: FAIL with
ESP32 tx/rx=48/0,ESP8266 tx/rx=19/0, noconnected=1.
[2026-02-17] D4/D5 handshake + strict firmware_tests rerun (Codex)
- Safety checkpoint re-run via cockpit wrappers:
git status,git diff --stat,git branch. - Checkpoint files saved:
/tmp/zacus_checkpoint/20260217-173556_wip.patchand/tmp/zacus_checkpoint/20260217-173556_status.txt. - Tracked artifact scan (
.pio,.platformio,logs,dist,build,node_modules,.venv) returned no tracked paths. - Build gate rerun:
./build_all.shPASS (5/5 envs) after firmware updates. - Reflash completed:
pio run -e esp32dev -t upload --upload-port /dev/cu.SLAB_USBtoUART9andpio run -e esp8266_oled -t upload --upload-port /dev/cu.SLAB_USBtoUART. firmware_toolingrerun PASS (plan-only+ full run); all--helppaths stay non-destructive.firmware_testsstrict rerun (ZACUS_REQUIRE_HW=1) still FAIL at gate 1:artifacts/rc_live/20260217-164154/summary.md(UI_LINK_STATUS connected=0, esp8266 monitor FAIL).- Strict smoke rerun uses repo-root resolver (
tools/test/resolve_ports.py) and strict ESP32+ESP8266 mapping; gate FAIL remains UI link only (artifacts/smoke_tests/20260217-164237/smoke_tests.log), whileSTORY_LOAD_SCENARIO DEFAULTnow succeeds through fallback (STORY_LOAD_SCENARIO_FALLBACK V2 DEFAULT+STORY_LOAD_SCENARIO_OK). audit_coherence.pyrerun PASS (artifacts/audit/20260217-164243/summary.md).- Content validators rerun PASS from repo root: scenario validate/export + audio manifest + printables manifest.
- Stress rerun completed PASS (
python3 tools/dev/run_stress_tests.py --hours 0.5):artifacts/stress_test/20260217-164248/summary.md(87iterations, success rate100.0%, no panic/reboot markers in log). - Runtime status after reruns: UI Link = FAIL (
connected=0), LittleFS default scenario = mitigated by V2 fallback in serial path, I2S stability = PASS over 30 min stress run (no panic/reboot markers).
[2026-02-17] Fix handshake/UI smoke strict kickoff (Codex)
- Safety checkpoint executed via cockpit wrappers: branch
story-V2,git status,git diff --stat,git branch. - Checkpoint files saved:
/tmp/zacus_checkpoint/20260217-155753_wip.patchand/tmp/zacus_checkpoint/20260217-155753_status.txt. - Tracked artifact scan (
.pio,.platformio,logs,dist,build,node_modules,.venv) returned no tracked paths; no untrack action required. - Runtime status at kickoff: UI Link = FAIL (
connected=0), LittleFS default scenario = missing (/story/scenarios/DEFAULT.json), I2S stability = FAIL/intermittent panic in stress recovery path.
[2026-02-17] Copilot sequence checkpoint (firmware_tooling -> firmware_tests)
- Safety checkpoint executed before edits via cockpit wrappers: branch
story-V2,git status,git diff --stat,git branch. - Checkpoint files saved:
/tmp/zacus_checkpoint/20260217-162509_wip.patchand/tmp/zacus_checkpoint/20260217-162509_status.txt. - Tracked artifact scan (
.pio,.platformio,logs,dist,build,node_modules,.venv) returned no tracked paths; no untrack action required. - Kickoff runtime status: UI Link still failing in prior smoke evidence, default LittleFS scenario still missing in prior QA notes, I2S panic already known in stress path.
[2026-02-17] Copilot sequence execution + alignment fixes
- Plan/runner alignment applied: root
tools/dev/plan_runner.shnow delegates tohardware/firmware/tools/dev/plan_runner.sh; firmware runner now executes from repo root and resolves active agent IDs recursively under.github/agents/(excludingarchive/). run_matrix_and_smoke.shnow supports--help/-hwithout side effects and returns explicit non-zero on unknown args (--bad-arg-> rc=2).- Agent briefs synchronized in root + firmware copies (
domains/firmware-tooling.md,domains/firmware-tests.md) with repo-root commands and venv-aware PATH (PATH=$(pwd)/hardware/firmware/.venv/bin:$PATH). firmware_toolingsequence: PASS (bash hardware/firmware/tools/dev/plan_runner.sh --agent firmware_tooling).firmware_testsstrict sequence (ZACUS_REQUIRE_HW=1): blocked at step 1 becauserun_matrix_and_smokereports UI link failure; evidenceartifacts/rc_live/20260217-153129/summary.md(UI_LINK_STATUS connected=0).- Remaining test gates executed manually after the blocked step:
run_smoke_tests.shstrict: FAIL (port resolution), evidenceartifacts/smoke_tests/20260217-153214/summary.md.run_stress_tests.py --hours 0.5: FAIL, scenario does not complete (DEFAULT), evidenceartifacts/stress_test/20260217-153220/summary.md; earlier run also captured I2S panic evidenceartifacts/stress_test/20260217-153037/stress_test.log.audit_coherence.py: initially FAIL on missing runbook refs, then PASS aftercockpit_commands.yamlrunbook fixes + regenerated commands doc; evidenceartifacts/audit/20260217-153246/summary.md(latest PASS).
- RP2040 docs/config audit: no env naming drift detected (
ui_rp2040_ili9488,ui_rp2040_ili9486) acrossplatformio.ini,build_all.sh,run_matrix_and_smoke.sh,docs/QUICKSTART.md, anddocs/TEST_SCRIPT_COORDINATOR.md. - Runtime status after this pass: UI Link = FAIL (
connected=0), LittleFS default scenario = missing (/story/scenarios/DEFAULT.json), I2S panic = intermittent (observed in stress evidence above).
[2026-02-17] Audit kickoff checkpoint (Codex)
- Safety checkpoint run from
hardware/firmware: branchstory-V2, working tree dirty (pre-existing changes),git diff --statcaptured before edits. - Checkpoint files saved:
/tmp/zacus_checkpoint/20260217-141814_wip.patchand/tmp/zacus_checkpoint/20260217-141814_status.txt. - Tracked artifact scan (
.pio,.platformio,logs,dist,build,node_modules,.venv) returned no tracked paths, so no untrack action was needed. - Runtime status at kickoff: UI Link
connected=0in previous smoke evidence, LittleFS default scenario still flagged as missing by prior QA notes, I2S panic previously reported in stress recovery path.
[2026-02-17] Audit + coherence pass (Codex)
- Tooling/scripts corrected:
tools/dev/run_matrix_and_smoke.sh(broken preamble/functions restored, non-interactive USB path now resolves ports, acceptedlearned-mapreasons, story screen skip evidence),tools/dev/serial_smoke.py(ports map loading re-enabled, dead duplicate role code removed),tools/dev/cockpit.sh(rcno longer forcesZACUS_REQUIRE_HW=1, debug banner removed),tools/dev/plan_runner.sh(portable paths/date and safer arg parsing), UI OLED HELLO/PONG now built with protocol CRC viauiLinkBuildLine. - Command registry/doc sync fixed:
tools/dev/cockpit_commands.yamlnormalized under onecommands:key (includingwifi-debug) and regenerateddocs/_generated/COCKPIT_COMMANDS.mdnow lists full evidence columns without blank rows. - Protocol/runtime check:
protocol/ui_link_v2.mdexpects CRC frames; OLED runtime now emits CRC on HELLO/PONG. Remaining runtime discrepancy logged: Story V2 controller still boots from generated scenario IDs (DEFAULT) rather than directly fromgame/scenarios/zacus_v1.yaml; root YAML remains validated/exported as canonical content source. - Build gate result:
./build_all.shPASS (5/5 envs) with loglogs/run_matrix_and_smoke_20260217-143000.logand build artifacts in.pio/build/. - Smoke gate result:
./tools/dev/run_matrix_and_smoke.shFAIL (artifacts/rc_live/20260217-143000/summary.json) — ports resolved, thensmoke_esp8266_usbandui_linkfailed (UI_LINK_STATUS missing, ESP32 log in bootloader/download mode). Evidence:artifacts/rc_live/20260217-143000/ui_link.log,artifacts/rc_live/20260217-143000/smoke_esp8266_usb.log. - Content gates result (run from repo root): scenario validate/export PASS (
game/scenarios/zacus_v1.yaml), audio manifest PASS (audio/manifests/zacus_v1_audio.yaml), printables manifest PASS (printables/manifests/zacus_v1_printables.yaml). - Runtime status after this pass: UI Link = FAIL on latest smoke evidence (
connectedunavailable), LittleFS default scenario = not revalidated in this run (known previous blocker remains), I2S panic = not retested in this pass (stress gate pending).
[2026-02-17] Rapport d’erreur automatisé – Story V2
- Correction du bug shell (heredoc Python → script temporaire).
- Échec de la vérification finale : build FAIL, ports USB OK, smoke/UI/artefacts SKIPPED.
- Rapport d’erreur généré : voir artifacts/rapport_erreur_story_v2_20260217.md
- Recommandation : analyser le log de build, corriger, relancer la vérification.
Agent TODO & governance
1. Structural sweep & merge
- Commit the pending cleanup described in
docs/SPRINT_RECOMMENDATIONS.md:18-80(structure/tree fixes + PR #86 merge/tag) so the repo is back on main. - Consolidation 2026-02-21 exécutée:
feat/fix-firmware-story-workflow,feat/freenove-ap-fallback-stable,feat/freenove-webui-network-ops-parityintégrés dans l’historique demain; CI GitHub Actions désormais limité àmainseulement. - Branches de travail supprimées (local + remote):
feat/freenove-ap-local-espnow-rtc-sync,origin/feat/fix-firmware-story-workflow,origin/feat/freenove-ap-fallback-stable,origin/feat/freenove-webui-network-ops-parity. - Tags de sauvegarde créés avant suppression:
backup/20260221_212813/feat-fix-firmware-story-workflow-1b4c328,backup/20260221_212813/feat-fix-firmware-story-workflow-b530be3,backup/20260221_212813/feat-freenove-ap-fallback-stable,backup/20260221_212813/feat-freenove-webui-network-ops-parity,backup/20260221_212813/feat-freenove-ap-local-espnow-rtc-sync.
2. Build/test gates
- Re-run
./build_all.sh(build_all.sh:6); artifacts landed underartifacts/build/and logs live inlogs/run_matrix_and_smoke_*.logif rerun again via the smoke gate. - Re-launch
./tools/dev/run_matrix_and_smoke.sh(tools/dev/run_matrix_and_smoke.sh:9-200) – run completed 2026-02-16 14:35 (artifactartifacts/rc_live/20260216-143539/), smoke scripts and serial monitors succeeded but UI link still reportsconnected=0(no UI handshake). Need to plug in/validate UI firmware before closing gate. - Capture evidence for HTTP API, WebSocket, and WiFi/Health steps noted as blocked or TODO in
docs/TEST_SCRIPT_COORDINATOR.md:13-20–tools/dev/healthcheck_wifi.shcreatedartifacts/rc_live/healthcheck_20260216-154709.log(ping+HTTP fail) and the HTTP API script logged connection failures underartifacts/http_ws/20260216-154945/http_api.log(ESP_URL=127.0.0.1:9). WebSocket skipped (wscat missing). All failures logged to share evidence.
3. QA + automation hygiene
- Execute the manual serial smoke path (
python3 tools/dev/serial_smoke.py --role auto --baud 115200 --wait-port 3 --allow-no-hardware) – passed on /dev/cu.SLAB_USBtoUART + /dev/cu.SLAB_USBtoUART9, reporting UI link still down (same failure as matrix run). - Run the story QA suite (
tools/dev/run_smoke_tests.sh,python3 tools/dev/run_stress_tests.py ...,make fast-*loops) documented inesp32_audio/TESTING.md:36-138and capture logs (smoke_tests failed: DEFAULT scenario missing/story/scenarios/DEFAULT.json; run_stress_tests failed with I2S panic during recovery;make fast-esp32/fast-ui-oledbuilt & flashed but monitor commands quit in non-interactive mode,fast-ui-tftnot run because no RP2040 board connected). Need scenario files/UI recovery to unblock. - Ensure any generated artifacts remain untracked per agent contract (no logs/artifacts added to git).
4. Documentation & agent contracts
- Update
AGENTS.mdandtools/dev/AGENTS.mdwhenever scripts/gates change, per their own instructions (AGENTS.md,tools/dev/AGENTS.md). - Keep
tools/dev/cockpit_commands.yamlin sync withdocs/_generated/COCKPIT_COMMANDS.mdviapython3 tools/dev/gen_cockpit_docs.pyafter edits, and confirm the command registry is reflected indocs/TEST_SCRIPT_COORDINATOR.mdguidance. - Review
docs/INDEX.md,docs/ARCHITECTURE_UML.md, anddocs/QUICKSTART.mdafter significant changes so the onboarding picture matches the agent constraints.
5. Reporting & evidence
- When publishing smoke/baseline runs, include the required artifacts (
meta.json,commands.txt,summary.md, per-step logs) underartifacts/…as demanded bydocs/TEST_SCRIPT_COORDINATOR.md:160-199. - Document any pipeline/test regressions in
docs/RC_AUTOFIX_CICD.mdor similar briefing docs and flag them for the Test & Script Coordinator.
Traçabilité build/smoke 17/02/2026
- Succès : esp32dev, esp32_release, esp8266_oled
- Échec : ui_rp2040_ili9488, ui_rp2040_ili9486
- Evidence : logs et artefacts dans hardware/firmware/artifacts/build, logs/
- Actions tentées : correction du filtre build_src_filter, création de placeholder, relance build/smoke
- Problème persistant : échec RP2040 (sources/configuration à investiguer)
- Prochaine étape : escalade à un agent expert RP2040 ou hand-off
[2026-02-18] Story portable + V3 serial migration
- Added host-side story generation library
lib/zacus_story_gen_ai(Yamale + Jinja2) with CLI:story-gen validatestory-gen generate-cppstory-gen generate-bundlestory-gen all
- Replaced legacy generator entrypoint
hardware/libs/story/tools/story_gen/story_gen.pywith compatibility wrapper delegating tozacus_story_gen_ai. - Migrated portable runtime internals to tinyfsm-style state handling in
lib/zacus_story_portable/src/story_portable_runtime.cppwhile keepingStoryPortableRuntimefacade. - Introduced Story serial V3 JSON-lines handlers (
story.status,story.list,story.load,story.step,story.validate,story.event) and removedSTORY_V2_*routing from canonical command list. - Updated run matrix/log naming to include environment label:
- log:
logs/rc_live/<env_label>_<ts>.log - artifacts:
artifacts/rc_live/<env_label>_<ts>/summary.md
- log:
run_matrix_and_smoke.shnow supports single-board mode (ZACUS_ENV="freenove_esp32s3"): ESP8266/UI-link/story-screen checks are emitted asSKIPwith detailnot needed for combined board.tools/test/resolve_ports.pynow honors--need-esp32and--need-esp8266explicitly via required roles, while still emitting bothesp32andesp8266fields in JSON output. [20260218-020041] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260218-020041, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260218-020041/summary.md [20260218-021042] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260218-021042, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260218-021042/summary.md [20260221-222358] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-222358, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-222358/summary.md [20260221-223450] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-223450, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-223450/summary.md
[2026-02-22] Freenove story modular + SD + ESP-NOW v1 envelope + WebUI push
- Story storage rendu modulaire avec fallback intégré:
- bundle Story par défaut provisionné automatiquement en LittleFS (
/story/{scenarios,screens,audio,apps,actions}), - support SD_MMC Freenove activé (
/sd/story/...) avec sync SD -> LittleFS au boot et via commande.
- bundle Story par défaut provisionné automatiquement en LittleFS (
- Commandes/runtime ajoutés pour opérabilité story:
- serial:
STORY_SD_STATUS,STORY_REFRESH_SD, - WebUI/API: bouton + endpoint
POST /api/story/refresh-sd.
- serial:
- Timeline JSON enrichie sur les scènes Story (
data/story/screens/SCENE_*.json) avec keyframesat_ms/effect/speed_ms/theme. - Audio crossfade consolidé:
- correction callback fin de piste (track réel reporté),
- lecture des packs audio depuis LittleFS ou SD (
/sd/...).
- ESP-NOW aligné avec
docs/ESP_NOW_API_CONTRACT_FREENOVE_V1.md:- enveloppe v1 supportée (
msg_id,seq,type,payload,ack), - extraction metadata + statut exposé,
- trames
type=commandexécutées côté runtime et réponse corréléetype=ackrenvoyée siack=true.
- enveloppe v1 supportée (
- WebUI passée en push temps réel:
- endpoint SSE
GET /api/stream(statut Story/WiFi/ESP-NOW), - fallback refresh conservé côté front.
- endpoint SSE
- Générateur Story (
zacus_story_gen_ai) amélioré:- bundle Story injecte désormais le contenu réel des ressources JSON (
data/story/*) au lieu de placeholders minimalistes.
- bundle Story injecte désormais le contenu réel des ressources JSON (
Vérifications exécutées
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- Vérification série post-flash (
STORY_SD_STATUS,WIFI_STATUS,ESPNOW_STATUS_JSON) ✅, IP observée:192.168.0.91 ZACUS_ENV=freenove_esp32s3 ZACUS_PORT_ESP32=/dev/cu.usbmodem5AB90753301 ZACUS_REQUIRE_HW=1 ZACUS_NO_COUNTDOWN=1 ./tools/dev/run_matrix_and_smoke.sh✅./tools/dev/story-gen validate✅./tools/dev/story-gen generate-bundle --out-dir /tmp/story_bundle_test✅.venv/bin/python3 -m pytest lib/zacus_story_gen_ai/tests/test_generator.py✅curl http://192.168.0.91/api/status+curl http://192.168.0.91/api/stream✅ (payloads UTF-8 validés après fix snapshot JSON)- Frontend dev UI:
npm run build✅ (fix TS no-return sursrc/lib/deviceApi.tspour débloquer le flux front) [20260221-234147] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-234147, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-234147/summary.md [20260221-235139] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-235139, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260221-235139/summary.md [20260222-000305] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-000305, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-000305/summary.md
[2026-02-22] Suite autonome — installations + vérifications complètes
- Préflight sécurité refait avant action:
- branch/diff/status affichés,
- checkpoint enregistré:
/tmp/zacus_checkpoint/20260222-005615_wip.patchet/tmp/zacus_checkpoint/20260222-005615_status.txt, - scan artefacts trackés (
.pio,.platformio,logs,dist,build,node_modules,.venv) = aucun trouvé.
- Installations/outillage:
./tools/dev/bootstrap_local.shexécuté (venv + dépendances Python +zacus_story_gen_aieditable),- validation outillage:
pio --version,python3 -m serial.tools.list_ports -v, tools/dev/check_env.shdurci pour fallbackpip3et dépendances optionnelles enWARN(exécution validée).
- Vérifications story/content:
.venv/bin/python3 tools/scenario/validate_scenario.py game/scenarios/zacus_v1.yaml✅.venv/bin/python3 tools/audio/validate_manifest.py audio/manifests/zacus_v1_audio.yaml✅.venv/bin/python3 tools/printables/validate_manifest.py printables/manifests/zacus_v1_printables.yaml✅./tools/dev/story-gen validate✅.venv/bin/python3 -m pytest lib/zacus_story_gen_ai/tests/test_generator.py✅
- Vérifications firmware/hardware Freenove USB modem:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3_full_with_ui -t buildfs✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅ZACUS_ENV=freenove_esp32s3 ZACUS_PORT_ESP32=/dev/cu.usbmodem5AB90753301 ZACUS_REQUIRE_HW=1 ZACUS_NO_COUNTDOWN=1 ./tools/dev/run_matrix_and_smoke.sh✅ (UI_LINK_STATUS=SKIPjustifié combined board).
- Gates build contractuels:
pio run -e esp32dev -e esp32_release -e esp8266_oled -e ui_rp2040_ili9488 -e ui_rp2040_ili9486✅ (5/5).
- Cohérence doc/registry:
.venv/bin/python3 tools/dev/gen_cockpit_docs.py✅.venv/bin/python3 tools/test/audit_coherence.py✅ (RESULT=PASS).
- Statut réseau et API runtime Freenove:
- série
WIFI_STATUS/ESPNOW_STATUS_JSON/STORY_SD_STATUS✅, - IP actuelle observée:
192.168.0.91, curl /api/statusetcurl /api/stream✅ (payloads Story/WiFi/ESP-NOW valides).
- série
[2026-02-22] Clarification doc Story V2 vs protocole série V3
- Alignement documentaire réalisé pour éviter l'ambiguïté "V2/V3":
docs/protocols/GENERER_UN_SCENARIO_STORY_V2.md: V2 explicitée (moteur/spec), commandes de test série basculées en JSON-lines V3 (story.*), chemins outillage alignés (./tools/dev/story-gen).docs/protocols/story_v3_serial.md: sectionScopeajoutée (V3 = interface série, V2 = génération/runtime).docs/protocols/story_README.md: section commandes réorganisée avec recommandation V3 et rappel legacySTORY_V2_*pour debug uniquement.
[2026-02-22] Story UI — génération écrans/effets/transitions (suite)
- Générateur
zacus_story_gen_airenforcé pour les ressources écran:- normalisation automatique d'un profil écran (fallback par
SCENE_*), - timeline normalisée en objet
timeline = {loop, duration_ms, keyframes[]}, - keyframes consolidées (
at_ms,effect,speed_ms,theme) avec garde-fous (ordre, bornes, minimum 2 keyframes), - transition normalisée (
transition.effect,transition.duration_ms).
- normalisation automatique d'un profil écran (fallback par
- Runtime UI Freenove enrichi:
- parse
timeline.keyframes(et compat ancien format array), - support
timeline.loop+timeline.duration_ms, - transitions de scène ajoutées (
fade,slide_left/right/up/down,zoom,glitch) avec durée pilotable.
- parse
- Données Story alignées:
data/story/screens/SCENE_*.jsonmigrés vers format timeline keyframes + transition,- fallback embarqué (
storage_manager.cpp) synchronisé sur le même contrat JSON.
- Vérifications exécutées:
.venv/bin/python3 -m pytest lib/zacus_story_gen_ai/tests/test_generator.py✅ (4 tests),./tools/dev/story-gen validate✅,./tools/dev/story-gen generate-bundle --out-dir /tmp/story_bundle_fx_<ts>✅ (payloads écran keyframes+transition vérifiés),pio run -e freenove_esp32s3✅,pio run -e freenove_esp32s3_full_with_ui -t buildfs✅,pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅,pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅,ZACUS_ENV=freenove_esp32s3 ... ./tools/dev/run_matrix_and_smoke.sh✅ (artefact:artifacts/rc_live/freenove_esp32s3_20260222-002556/),- validation série live (
SC_LOAD/SC_EVENT) avec logs UI montranttransition=<type>:<ms>sur changements de scène. [20260222-002556] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-002556, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-002556/summary.md [20260222-025923] Run artefacts:artifacts/rc_live/freenove_esp32s3_20260222-025923/, logs:logs/rc_live/, summary:artifacts/rc_live/freenove_esp32s3_20260222-025923/summary.md
[2026-02-22] Intégration complète Story + options Freenove (phases 1→3)
- Runtime Freenove branché en modules:
HardwareManagerintégré au cycle principal (init/update/noteButton/setSceneHint),- nouveaux modules
CameraManageretMediaManagerajoutés et initialisés au boot.
- Options Story (
data/story/apps) ajoutées + fallback embarqué synchronisé:APP_HARDWARE.json,APP_CAMERA.json,APP_MEDIA.json,- fallback LittleFS mis à jour dans
storage_manager.cpp(bundle embarqué complet).
- Interfaces publiques ajoutées:
- série:
HW_*,CAM_*,MEDIA_*,REC_*, - API WebUI:
/api/hardware*,/api/camera*,/api/media*, /api/statusenrichi (hardware,camera,media),- commandes ESP-NOW
type=commanddispatchées sur les nouveaux contrôles.
- série:
- Couplage Story actions au changement d'étape:
- exécuteur d'
action_idsbranché, - nouvelles actions supportées (
ACTION_HW_LED_*,ACTION_CAMERA_SNAPSHOT,ACTION_MEDIA_PLAY_FILE,ACTION_REC_*, etc.), - snapshot action
SERIAL:CAMERA_CAPTUREDémis en succès.
- exécuteur d'
- Évolution écran/effets Story:
- effets ajoutés:
radar,wave, - aliases transition ajoutés:
wipe -> slide_left,camera_flash -> glitch, - scènes ajoutées:
SCENE_CAMERA_SCAN,SCENE_SIGNAL_SPIKE,SCENE_MEDIA_ARCHIVE, - docs alignées:
docs/protocols/story_screen_palette_v2.md,docs/protocols/story_README.md.
- effets ajoutés:
- Contrôle de flux: ajout d'un déclencheur
BTN_NEXTdepuisSTEP_WAIT_UNLOCKversSTEP_WAIT_ETAPE2(scène LA détection), pour permettre le passage immédiat viaNEXT//api/scenario/next/SC_EVENT serial BTN_NEXT; artefact build:pio run -e freenove_esp32s3(success 2026-02-22) et fichiers générés mis à jour (docs/protocols/story_specs/scenarios/default_unlock_win_etape2.yaml,hardware/libs/story/src/generated/*). - Contrôle tactile/physique Freenove: adaptation de
ScenarioManager::notifyButtonpour que tout bouton court (1..5) surSTEP_WAIT_UNLOCKdéclencheBTN_NEXTsi disponible (fallbackNEXT), donc passage direct versSTEP_WAIT_ETAPE2depuis n'importe quel bouton. - Validation réalisée (session courante):
- builds:
pio run -e esp32dev -e esp32_release -e esp8266_oled -e ui_rp2040_ili9488 -e ui_rp2040_ili9486✅, - build Freenove:
pio run -e freenove_esp32s3✅, - FS Freenove:
pio run -e freenove_esp32s3_full_with_ui -t buildfs✅, - smoke orchestré:
ZACUS_ENV=freenove_esp32s3 ./tools/dev/run_matrix_and_smoke.sh✅ (run sans hardware -> smoke/UI linkSKIPPED, justif. combined board + port non résolu; artefactartifacts/rc_live/freenove_esp32s3_20260222-025923/), - Story tooling:
./tools/dev/story-gen validate✅,./tools/dev/story-gen generate-bundle --out-dir /tmp/story_bundle_options_20260222T035914✅, - tests Python:
.venv/bin/python3 -m pytest lib/zacus_story_gen_ai/tests/test_generator.py✅ (5 passed), - scénario canonique:
.venv/bin/python3 ../../tools/scenario/validate_scenario.py ../../game/scenarios/zacus_v1.yaml✅, - export brief:
.venv/bin/python3 ../../tools/scenario/export_md.py ../../game/scenarios/zacus_v1.yaml✅.
- builds:
- [!] Limites constatées hors scope firmware:
.venv/bin/python3 ../../tools/audio/validate_manifest.py ../../audio/manifests/zacus_v1_audio.yaml❌ (game/prompts/audio/intro.mdmanquant),.venv/bin/python3 ../../tools/printables/validate_manifest.py ../../printables/manifests/zacus_v1_printables.yaml❌ (promptsprintables/src/prompts/*.mdmanquants),- aucune validation live
curl /api/*ou cycle série ACK HW/CAM/MEDIA possible sans carte connectée pendant cette session.
[2026-02-22] Correctif validateurs contenu + checks intégration API (local/GH/Codex/ChatGPT)
- Correctif robustesse chemins pour exécution depuis
hardware/firmware/et repo root:tools/audio/validate_manifest.py: résolutionsourcemaintenant tolérante (cwd, dossier manifeste, repo root).tools/printables/validate_manifest.py: résolution manifeste/prompt indépendante ducwd(fallbacks repo root + dossier manifeste).hardware/firmware/tools/dev/check_env.sh: check env enrichi avec vérifications d'intégration API (ghauth,codex login status, reachability OpenAI) et diagnosticMCP_DOCKER(daemon Docker).
- Revalidation post-correctif:
- depuis
hardware/firmware:
.venv/bin/python3 ../../tools/audio/validate_manifest.py ../../audio/manifests/zacus_v1_audio.yaml✅
.venv/bin/python3 ../../tools/printables/validate_manifest.py ../../printables/manifests/zacus_v1_printables.yaml✅ - depuis repo root:
hardware/firmware/.venv/bin/python3 tools/audio/validate_manifest.py audio/manifests/zacus_v1_audio.yaml✅
hardware/firmware/.venv/bin/python3 tools/printables/validate_manifest.py printables/manifests/zacus_v1_printables.yaml✅
- depuis
- Cohérence firmware/story toolchain recheck:
python ../../tools/scenario/validate_scenario.py ../../game/scenarios/zacus_v1.yaml✅./tools/dev/story-gen validate✅./tools/dev/story-gen generate-bundle --out-dir /tmp/story_bundle_api_check_<ts>✅.venv/bin/python3 -m pytest lib/zacus_story_gen_ai/tests/test_generator.py✅ (5 passed)
- Vérification accès API outillage:
- GitHub CLI:
gh auth status✅ (accountelectron-rare),gh api user✅,gh api rate_limit✅. - Codex CLI:
codex login status✅ (Logged in using ChatGPT),codex exec --ephemeral✅ (réponse reçue). - OpenAI endpoint reachability:
curl https://api.openai.com/v1/models=>401 Missing bearer(connectivité OK, clé API absente côté shell).
- GitHub CLI:
- [!] Point d'intégration à traiter côté poste:
codex mcp listsignaleMCP_DOCKERactivé mais non opérationnel si daemon Docker arrêté (Cannot connect to the Docker daemon ...).
[2026-02-22] Réparation workspace — déplacement involontaire esp8266_oled/src
- Analyse de l'anomalie:
- suppressions trackées massives sous
hardware/firmware/ui/esp8266_oled/src/**, - dossier non tracké détecté:
hardware/firmware/ui/esp8266_oled/src 2/.
- suppressions trackées massives sous
- Correctif appliqué:
- restauration de l'arborescence par renommage du dossier
src 2verssrc. - résultat: suppressions annulées, structure source ESP8266 OLED rétablie.
- restauration de l'arborescence par renommage du dossier
- Validation:
pio run -e esp8266_oled✅ (build complet OK après réparation). [20260222-113849] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-113849, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-113849/summary.md [20260222-204146] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-204146, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260222-204146/summary.md
Audit test hardware Freenove (2026-02-23)
- Commande:
pio run -e freenove_esp32s3_full_with_ui -t upload - Résultat: flash OK vers
/dev/cu.usbmodem5AB90753301. - Port auto-détecté, upload réussi (RAM/Flash: 55.3% / 73.1%).
- Monitoring runtime (capture locale via
python3 + pyserial, 60s) : boot OK, scénarioDEFAULTexécuté, logs HW/LA/SCENARIO/FS/UI cohérents. - Événement constaté: erreur caméra récurrente lors de la première action
ACTION_CAMERA_SNAPSHOT(cam_dma_config(301): frame buffer malloc failed,camera config failed) sur ce lot matériel. - Comportement attendu LA:
LA_TRIGGER timeoutpuis reset versSCENE_LOCKED. - Aucune régression panic/reboot observée sur la fenêtre de test.
- Notes: scripts de validation demandés par le contrat firmware sont uniquement exécutés pour build + flash; logs hardware non versionnés et non archivés.
Test hardware runtime (séquence réseau/ESP-NOW) - 2026-02-23
- Test en condition carte branchée sur
/dev/cu.usbmodem5AB90753301aprèspio run -e freenove_esp32s3_full_with_ui -t upload. - Commandes série envoyées:
STATUS,NET_STATUS,WIFI_TEST,ESPNOW_STATUS,ESPNOW_ON,ESPNOW_STATUS_JSON,ESPNOW_PEER_LIST,WIFI_AP_ON,ESPNOW_SEND ff:ff:ff:ff:ff:ff {...}. - Bilan WiFi:
- Boot initial déjà en
STAconnecté sur SSIDLes cils, IP192.168.0.91. WIFI_TESTretourneACK WIFI_TEST ... ok=1.WIFI_DISCONNECTprovoque bien la logique de reconnect ([NET] wifi disconnectedpuis[NET] wifi connect requested ...).WIFI_STATUS/WIFI_RECONN: la commandeWIFI_RECONNn’existe pas (retourUNKNOWN WIFI_RECONN).
- Boot initial déjà en
- Bilan ESP-NOW:
ESPNOW_ONactif,ESPNOW_STATUSconfirmeespnow=1et compteurpeers=0avant ajout.ESPNOW_SENDversff:ff:ff:ff:ff:ffrenvoieACK ESPNOW_SEND ok=1.- Après send, statut indique
tx_ok=1, peer broadcast visible viaESPNOW_PEER_LISTpuisNET_STATUS. ESPNOW_STATUS_JSONretourne JSON attendu (ready,peer_count, compteurs).- Pas de réception de payload externe observée (pas de
ESPNOW_RECV, pas deNETRX event).
- API test WebSocket/HTTP non testée en ce cycle (focal hardware UART/serial).
statusglobal reste stable, pas de panic/reboot détecté pendant captures.
Hardening scènes (SCENE) - 2026-02-23
- Scope: firmware Freenove (UI + registry scène).
- Stabilisation demandée:
- Source de vérité
hardware/libs/story/src/resources/screen_scene_registry.cppaveckScenessans alias. - Validation runtime:
SCREEN_SCENE_ID_UNKNOWNsurscreenSceneIdnon reconnu. - Chargement payload: normalisation stricte
screen_scene_idavant lookup dansStorageManager. - UI: règles d'effets/transitions explicites, logs sur token inconnu.
- Source de vérité
- Tests: cas d'IDs inconnues + alias legacy dans validation de scénario + lookup. [20260223-210304] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260223-210304, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260223-210304/summary.md [20260223-210353] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260223-210353, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260223-210353/summary.md [20260223-210410] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260223-210410, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260223-210410/summary.md
Refactor LVGL graphics stack - 2026-02-24
- Checkpoint evidence:
/tmp/zacus_checkpoint/20260224_032248_wip.patch/tmp/zacus_checkpoint/20260224_032248_status.txt
- Scope en cours:
ui_manager.{h,cpp}: pipeline buffers/dma/8bpp + stats/diagnostics.lv_conf.h+platformio.ini: flags build pour mode 256, DMA async, budget mem.main.cpp: commandes sérieUI_GFX_STATUSetUI_MEM_STATUS.- docs ajoutées:
docs/ui/graphics_stack.md,docs/ui/lvgl_memory_budget.md,docs/ui/fonts_fr.md.
- Validation:
pio run -e freenove_esp32s3✅- tentative multi-env (
esp32dev,esp32_release,esp8266_oled,ui_rp2040_ili9488,ui_rp2040_ili9486) interrompue pour limiter le temps de cycle après confirmation Freenove.
Refactor LVGL graphics stack - suite run 2026-02-24
- Checkpoint evidence:
/tmp/zacus_checkpoint/20260224_035128_wip.patch/tmp/zacus_checkpoint/20260224_035128_status.txt
- Validation build matrix terminee:
pio run -e esp32dev -e esp32_release -e esp8266_oled -e ui_rp2040_ili9488 -e ui_rp2040_ili9486✅pio run -e freenove_esp32s3✅
- Flash hardware Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification scene:
SCENE_GOTO SCENE_WIN_ETAPEenvoye via pyserial (ACK recu, logs scene/audio coherents).- test boucle host 95s avec relance scene a
t=90s(ACK recu a chaque injection).
- Observation runtime a investiguer:
UI_GFX_STATUSretournedepth=8maislines=0,double=0,dma_req=0,dma_async=0(pipeline graphique semble retomber en mode non configure).
Refactor LVGL graphics stack - affichage Freenove (2026-02-24)
- Checkpoint evidence:
/tmp/zacus_checkpoint/20260224_040114_wip.patch/tmp/zacus_checkpoint/20260224_040114_status.txt
- Probleme reproduit et corrige:
- boot montrait
draw buffer allocation failed(heap DMA interne trop faible pour le mode initial). - allocation draw buffers rendue robuste: fallback auto SRAM_DMA -> PSRAM, candidats lignes et mono fallback.
- trans buffer DMA rendu adaptatif (fallback par lignes), conversion RGB332->RGB565 sync ligne-par-ligne corrigee.
- guard de stabilite ajoute: async DMA desactive en mode RGB332 (panic
dma_end_callbackobserve sur SCENE_GOTO).
- boot montrait
- Option hardware ajoutee:
FREENOVE_LCD_USE_HSPIdansui_freenove_config.h(switch HSPI/FSPI via flag).- support macro ajoute pour
FREENOVE_LCD_VARIANT_FNK0102H.
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- test runtime 95s avec
SCENE_GOTO SCENE_WIN_ETAPE+ relance a t=90s: pas de panic, scene boucle. - retour utilisateur: affichage OK.
External font pack generation (2026-02-24)
- Checkpoint evidence:
/tmp/zacus_checkpoint/20260224_042527_wip.patch/tmp/zacus_checkpoint/20260224_042527_status.txt
- Generated and committed LVGL external font sources for Freenove UI stack:
- Inter: 14/18/24/32
- Orbitron: 28/40
- IBM Plex Mono: 14/18
- Press Start 2P: 16/24
- Added portable generation toolchain:
tools/fonts/scripts/font_manifest.jsontools/fonts/scripts/generate_lvgl_fonts.shtools/fonts/ttf/README.md
- Build validation:
pio run -e freenove_esp32s3✅
- Commit:
1328897 feat(ui-fonts): generate and enable external LVGL font pack
LCD variant lock FNK0102H (2026-02-24)
- Demande utilisateur: verrouiller la cible kit sur FNK0102H.
- Changements appliques:
hardware/firmware/ui_freenove_allinone/include/ui_freenove_config.h:- defaults:
FREENOVE_LCD_VARIANT_FNK0102B=0,FREENOVE_LCD_VARIANT_FNK0102H=1 - commentaire profil maj en FNK0102H.
- defaults:
platformio.ini(env:freenove_esp32s3_full_with_ui):-DFREENOVE_LCD_VARIANT_FNK0102B=0-DFREENOVE_LCD_VARIANT_FNK0102H=1
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- verification runtime serie:
UI_GFX_STATUSrecu apres flash (depth=8,lines=40,double=1,source=PSRAM). [20260224-050717] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260224-050717, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260224-050717/summary.md [20260224-052021] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260224-052021, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260224-052021/summary.md
Plan Freenove - partition + runtime safety + flash (2026-02-24)
- Checkpoint:
/tmp/zacus_checkpoint/20260224_064903_wip.patch/tmp/zacus_checkpoint/20260224_064903_status.txt
- Baseline (avant lot):
pio run -e freenove_esp32s3 -t size->text=1253534 data=426752 bss=1448701 dec=3128987./build_all.sh freenove_esp32s3->Flash=1664021 / 2097152- map symbols:
__ssvfscanf_rpresent__ssvfiscanf_rpresent_Z19runRuntimeIterationjpresent_ZN12_GLOBAL__N_119handleSerialCommandEPKcjpresent_ZN9UiManager11renderSceneEPK11ScenarioDefPKcS4_S4_bS4_present
- Implemented:
- partition custom Freenove (
partitions/freenove_esp32s3_app6mb_fs6mb.csv) +platformio.inialignement max app 6MB. - hardening concurrence ESP-NOW:
- queue RX lockee (
portMUX_TYPE), enqueue/dequeue atomiques, - suppression recursion ACK-skip dans
consumeEspNowMessage, - callback RX/TX lock sections courtes + parse JSON hors lock.
- queue RX lockee (
- provisioning/auth:
- nouveau module NVS
runtime/provisioning/credential_store.{h,cpp}(sta_ssid,sta_pass,web_token,provisioned), - zero secrets hardcodes par defaut (
RuntimeNetworkConfig,APP_WIFI, fallback embedded), - endpoint
GET /api/provision/status, persist=1sur/api/wifi/connectet/api/network/wifi/connect,- auth policy:
- setup mode: whitelist provisioning sans auth,
- mode normal: Bearer token requis sur
/api/*,
- commandes serie:
WIFI_PROVISION <ssid> <pass>WIFI_FORGETAUTH_STATUSAUTH_TOKEN_ROTATE [token]
- nouveau module NVS
- parsing borne:
HW_LED_SETmigre desscanfvers parse tokenise +strtolborne.
- flash/memory:
UI_LV_MEM_SIZE_KB=128,- reduction String hot path:
network_manager.cpp(sendEspNowTarget, envelope handling),main.cpp(webSendStatusSsesansString payload),
- externalisation bundle story:
- fallback embedded minimal seulement (
APP_WIFI+DEFAULTminimal), - message explicite
buildfs/uploadfsrequis pour bundle complet.
- fallback embedded minimal seulement (
- scripts dev:
tools/dev/healthcheck_wifi.shsupportZACUS_WEB_TOKEN,tools/dev/rtos_wifi_health.shsupportZACUS_WEB_TOKEN(header auth + evidence redacted).
- partition custom Freenove (
- Validation apres lot:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t size✅ ->text=1254606 data=413388 bss=1416005 dec=3083999pio run -e freenove_esp32s3 -t buildfs✅./build_all.sh freenove_esp32s3✅ ->Flash=1651729 / 6291456,RAM=209300 / 327680ZACUS_ENV=freenove_esp32s3 ./tools/dev/run_matrix_and_smoke.sh✅ (smoke SKIPPED: port policy LOCATION mismatch)- content validators:
python3 ../../tools/scenario/validate_scenario.py ../../game/scenarios/zacus_v1.yaml✅python3 ../../tools/scenario/export_md.py ../../game/scenarios/zacus_v1.yaml✅python3 ../../tools/audio/validate_manifest.py ../../audio/manifests/zacus_v1_audio.yaml✅python3 ../../tools/printables/validate_manifest.py ../../printables/manifests/zacus_v1_printables.yaml✅
- Notes:
__ssvfscanf_r/__ssvfiscanf_rrestent dans la map, mais provenance framework (FrameworkArduino/IPv6Address.cpp.o), pas du code Freenove local.- artefacts smoke:
artifacts/rc_live/freenove_esp32s3_20260224-060831/artifacts/rc_live/freenove_esp32s3_20260224-060831_agent/
Audit flash + hardening Freenove ESP32-S3 (2026-02-24)
- Checkpoint evidence:
/tmp/zacus_checkpoint/1771909826_wip.patch/tmp/zacus_checkpoint/1771909826_status.txt
- Scope applique (firmware Freenove):
platformio.ini:CORE_DEBUG_LEVEL=0sur envfreenove_esp32s3_full_with_ui,UI_FONT_PIXEL_ENABLE=0,UI_FONT_TITLE_XL_ENABLE=0.ui_freenove_allinone/include/lv_conf.h: widget set LVGL reduit au strict necessaire (label/line), theme default desactive, fontes Montserrat 18+ desactivees.ui_freenove_allinone/src/ui_fonts.cpp: fallback compile-time pourfontTitleXL()sans Orbitron 40 quandUI_FONT_TITLE_XL_ENABLE=0.ui_freenove_allinone/src/hardware_manager.cpp: suppression warning/risque modulo-zero compile-time sur pattern LED secondaire.
- Mesures build (
pio run -e freenove_esp32s3):- Baseline: Flash
1808605(86.2%), RAM242340. - Apres optimisation: Flash
1664021(79.3%), RAM241996. - Gain flash:
-144584octets (~-7.99%du binaire initial).
- Baseline: Flash
- Gates executees:
pio run -e freenove_esp32s3✅ZACUS_ENV=freenove_esp32s3 ./tools/dev/run_matrix_and_smoke.sh✅ (smoke SKIP attendu: mapping port USB non conforme policy LOCATION) [20260224-060831] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260224-060831, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/freenove_esp32s3_20260224-060831/summary.md
SCENE_WIN_ETAPE - texte LVGL simple (2026-02-24)
- Checkpoint:
/tmp/zacus_checkpoint/20260224_153719_wip.patch/tmp/zacus_checkpoint/20260224_153719_status.txt
- Ajustements:
ui_manager.cppdurcit le mode texte simplifie quandUI_WIN_ETAPE_SIMPLIFIED=1:- suppression des animations texte titre/sous-titre (drop/reveal/sine/jitter/celebrate),
- sous-titre force en rendu statique via
applySubtitleScroll -> kNone, - texte cracktro/clean conserve en labels LVGL simples.
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- capture serie manuelle
/dev/tty.usbmodem5AB90753301✅ (PONG, logs WIN_ETAPE actifs, pas de freeze observe pendant capture).
- Limitation:
./tools/dev/post_upload_checklist.sh --env freenove_esp32s3 --scene SCENE_WIN_ETAPE --required-regex "GFX_STATUS|RESOURCE_STATUS"en echec port auto-detect (Aucun port ESP32 detecte), contournement par port explicite.
Hotfix affichage glitch (2026-02-24)
- Checkpoint:
/tmp/zacus_checkpoint/20260224_154509_wip.patch/tmp/zacus_checkpoint/20260224_154509_status.txt
- Correctif stabilite applique:
platformio.ini:UI_DMA_RGB332_ASYNC_EXPERIMENTAL=0(desactivation chemin async experimental RGB332).ui_manager.cpp: garde explicite dansinitDmaEngine()pour forcer flush sync quand RGB332 async experimental est desactive.
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- monitor serie manuel (
/dev/tty.usbmodem5AB90753301) ✅ (PONG, logs WIN_ETAPE periodiques, pas de freeze observe pendant capture).
Hotfix glitch persistant - mode safe UI-only (2026-02-24)
- Correctif:
ui_manager.cpp: en modeUI_WIN_ETAPE_SIMPLIFIED=1, forcerfx_enabled=falsedansstartIntro()pour isoler totalement le chemin LVGL (pas de blit FX).
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- monitor serie manuel ✅ (
fx_fps=0,ui_fps ~58-61,PONG, logs WIN_ETAPE stables sur capture).
Hotfix rendu FX LovyanGFX (2026-02-24)
- Hypothese suite capture utilisateur: artefacts visuels majoritairement lies au shader de fond FX + blit DMA LGFX.
- Correctifs:
ui_manager.cpp: reactivation du fond FX en mode simplifie (retour architecture demandeesprite LGFX + overlay LVGL).fx_engine.cpp: blit FX en mode sync (UI_FX_DMA_BLIT=0) pour eviter les artefacts DMA LGFX.fx_engine.cpp: shader de fond simplifie (gradient lisse + scanline douce) pour supprimer les motifs "glitch" repetitifs.ui_manager.cpp: taille sprite simplifiee derivee de la resolution ecran (display/2) avec cible10 fps.fx_engine.cpp: hauteur sprite max passe a240pour conserver le ratio sur ecrans hauts.platformio.ini: ajout explicite-DUI_FX_DMA_BLIT=0.
- Validation:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- monitor serie manuel ✅ (
fx_fps~8,PONG, logs WIN_ETAPE actifs).
Skill intake exemples pre-patch (2026-02-25)
- Checkpoint:
/tmp/zacus_checkpoint/20260225_112752_wip.patch/tmp/zacus_checkpoint/20260225_112752_status.txt
- Nouveau skill global ajoute pour les depots d'exemples utilisateur:
~/.codex/skills/chatgpt-file-exemple-intake/SKILL.md~/.codex/skills/chatgpt-file-exemple-intake/agents/openai.yaml~/.codex/skills/chatgpt-file-exemple-intake/references/checklist.md~/.codex/skills/chatgpt-file-exemple-intake/scripts/scan_example_candidates.sh
- Miroir documentation repo:
docs/skills/chatgpt-file-exemple-intake.md
- Regle operationnelle formalisee:
hardware/ChatGPT_file_exemple/**est une source de reference pre-patch, jamais une source compilee.- Integration uniquement par extraction de deltas vers
hardware/firmware/**.
Integration delta depuis hardware/ChatGPT_file_exemple (2026-02-25)
- Source example integree (premier passage):
hardware/ChatGPT_file_exemple/QR validator/zacus_qr_crc16_prefix_patch/.../ui_manager.cpp
- Deltas portes dans code canonique:
hardware/firmware/ui_freenove_allinone/include/ui/ui_manager.hhardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp
- Integration effectuee:
- support optionnel
qr.crc16(bool ou objet{enabled, sep}) dans payload scene, - validation CRC16/CCITT-FALSE sur payload QR (
DATA<sep>CRCHEX), - matching
expected/prefix/containsapplique surDATAapres validation CRC, - reset des regles QR inclut etat CRC16.
- support optionnel
- Validation:
pio run -e freenove_esp32s3✅
- Passes supplementaires (QR examples -> canonique):
- ajout outil local
tools/dev/gen_qr_crc16.py(payload + PNG optionnel), derive du dossier exemple et corrige (quoting/erreurs). - ajout doc canonique
docs/protocols/qr_scan_crc16.md(contrat payloadqr.crc16, format DATA+CRC, usage script). - verification script:
python3 tools/dev/gen_qr_crc16.py "ZACUS:MEDIA_MANAGER" --ci✅
- ajout outil local
- Pass integration QR (suite):
- compat champ longueur payload QR dans
qr_scan_controller.cpp(payloadLen/payload_len) pour robustesse version lib. - gates executes:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅
- compat champ longueur payload QR dans
Orchestrator pass - refactor QR ownership hors UiManager massif (2026-02-25)
- Baseline/checkpoint:
main/tmp/zacus_checkpoint/20260225_114336_wip.patch/tmp/zacus_checkpoint/20260225_114336_status.txt
- Skill chain utilisee (ordre):
freenove-firmware-orchestratorfirmware-graphics-stackfirmware-camera-stackfirmware-build-stack
- Audit constats:
- logique QR payload/rules concentree dans
ui_manager.cpp(couplage parsing+matching+CRC avec rendu), - evenement UI
QR_OKnon consomme par le story runtime (dispatched=0) car scenario compile ne porte pas encore la transition YAML.
- logique QR payload/rules concentree dans
- Phase A (architecture):
- extraction logique matching/payload QR vers module dedie:
hardware/firmware/ui_freenove_allinone/include/ui/qr/qr_validation_rules.hhardware/firmware/ui_freenove_allinone/src/ui/qr/qr_validation_rules.cpp
UiManagerdelegue desormaisqr_rules_.configureFromPayload(...)+qr_rules_.matches(...).
- extraction logique matching/payload QR vers module dedie:
- Phase B (securite memoire):
- copies bornees et parsing CRC16 encapsules dans le module QR dedie,
- suppression de helpers QR redondants dans
ui_manager.cpp(moins de surface mutable).
- Phase C (runtime/perf):
- parsing des regles QR applique uniquement sur changement statique de scene/payload (
qr_scene && static_state_changed).
- parsing des regles QR applique uniquement sur changement statique de scene/payload (
- Correction enchainement scene/story:
main.cpp: fallback orchestration pourQR_OKquand transition story compilee absente:- applique
ACTION_SET_BOOT_MEDIA_MANAGER, - force
SCENE_MEDIA_MANAGERviag_scenario.gotoScene(..., "ui_qr_fallback").
- applique
- Outils/skills verification:
- ajout utilitaire QR CRC:
tools/dev/gen_qr_crc16.py - doc contrat QR:
docs/protocols/qr_scan_crc16.md - mise a jour script skill global media-manager pour flow deterministe:
- force
SCENE_GOTO SCENE_CAMERA_SCANavantQR_SIM, - accepte evidences
UI_EVENTprefixe/non-prefixe, - verification post-reset via
HW_STATUS scene=...(plus de dependancestory.status).
- force
- ajout utilitaire QR CRC:
- Gates executees:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 10✅~/.codex/skills/scene-verificator/scripts/run_scene_verification.sh ...✅~/.codex/skills/fx-verificator/scripts/run_fx_verification.sh ...✅~/.codex/skills/hal-verificator-status/scripts/run_hal_verification.sh ...✅~/.codex/skills/media-manager/scripts/run_media_manager_verification.sh ...✅
- Limitation residuelle:
- la transition
QR_OK -> STEP_MEDIA_MANAGERn'est pas encore presente dans le scenario compile C++ (scenarios_gen.cpp) ; fallback runtime temporaire en place tant que la regeneration C++ canonique n'est pas complete.
- la transition
Live reprise hardware + upload + recheck debuts de scenario (2026-02-25)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225-191240_wip.patch/tmp/zacus_checkpoint/20260225-191240_status.txt- scan artefacts trackes (
.pio/.platformio/logs/dist/build/node_modules/.venv) -> aucun tracke.
- Upload effectif Freenove:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Evidence live:
logs/live_go_20260225-191323.log(capture rapide)logs/live_go_transition_20260225-191745.log(diagnostic commandes serie)
- Verification demarrage scenario (reel):
RESET->scene=SCENE_U_SON_PROTOconfirme viaHW_STATUS.NEXTdepuisSCENE_U_SON_PROTO-> transitionSCENE_LA_DETECTOR+ACTION_QUEUE_SONAR ok=1, sans panic.NEXTdepuisSCENE_LA_DETECTORpeut retournerACK NEXT ok=0par design (gate LA en attente de match).
- Correction live "probleme des le debut":
- cause observee:
BOOT_MODE_STATUS mode=media_manager media_validated=1(le reset revenait sur hub media). - correction appliquee sur hardware connecte:
BOOT_MODE_SET STORYpuisRESET. - verification post-correction:
scene=SCENE_U_SON_PROTOpuisNEXT=>SCENE_LA_DETECTOR+ACTION_QUEUE_SONAR ok=1.
- cause observee:
- Risque residuel observe en live:
- erreurs intermittentes
diskio_sdmmc: sdmmc_read_blocks failed (257)pendantRESET(pas de panic, mais a investiguer cote SD/carte/media).
- erreurs intermittentes
- Gates executes:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 10 --wait-port 20✅~/.codex/skills/scene-verificator/scripts/run_scene_verification.sh /dev/cu.usbmodem5AB90753301 115200✅~/.codex/skills/fx-verificator/scripts/run_fx_verification.sh /dev/cu.usbmodem5AB90753301 115200✅~/.codex/skills/hal-verificator-status/scripts/run_hal_verification.sh /dev/cu.usbmodem5AB90753301 115200✅
Correction SDMMC - diagnostic carte/FS/lecteur (2026-02-25)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260225-194217_wip.patch/tmp/zacus_checkpoint/20260225-194217_status.txt- scan artefacts trackes (
.pio/.platformio/logs/dist/build/node_modules/.venv) -> aucun tracke.
- Cause identifiee:
- les lectures
/story/*passaient par SD en priorite (readTextFileWithOrigin), ce qui exposait le runtime aux erreursdiskio_sdmmcen cas de carte instable, meme quand LittleFS contenait deja les assets.
- les lectures
- Correctif applique (
ui_freenove_allinone/src/storage/storage_manager.cpp):- fallback runtime passe en LittleFS d'abord, SD ensuite (sauf chemin force
/sd/...), - surveillance
errnosurSD_MMC.exists/open/read, - compteur d'echecs SD (
sd_failure_streak_) + coupure SD auto apres erreurs I/O repetees, - remount SD explicite tente dans
syncStoryFileFromSd/syncStoryTreeFromSdquand SD etait degrade.
- fallback runtime passe en LittleFS d'abord, SD ensuite (sauf chemin force
- Interface mise a jour:
ui_freenove_allinone/include/storage/storage_manager.h(etat SD mutable + helpers de diagnostic).
- Build/upload:
pio run -e freenove_esp32s3✅pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Validation live:
- log diagnostic:
logs/sdmmc_diag_20260225-195139.log - resultat:
SUMMARY sd_errors=0 panic_markers=0 ack_next_ok=10 ack_next_fail=0 - gate smoke:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 10 --wait-port 20✅
- log diagnostic:
[2026-02-26] Scene de test persistante (YAML + JSON + runtime)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_025905_wip.patch/tmp/zacus_checkpoint/20260226_025905_status.txt
- Ajouts:
- scene spec editable:
lib/zacus_story_portable/story_generator/story_specs/scenarios/DEFAULT/scene_test_lab.yaml - payload ecran canonique:
data/story/screens/SCENE_TEST_LAB.json - mirror legacy:
data/screens/SCENE_TEST_LAB.json - scene id runtime enregistre:
hardware/libs/story/src/resources/screen_scene_registry.cpp
- scene spec editable:
- Usage test rapide:
SCENE_GOTO SCENE_TEST_LAB
- Build/upload Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie (scene test):
SCENE_GOTO SCENE_TEST_LAB->ACK SCENE_GOTO ok=1✅STATUS->screen=SCENE_TEST_LAB✅UI_SCENE_STATUS->payload_origin=/story/screens/SCENE_TEST_LAB.json✅
- Correctif mirror
data/screens/SCENE_TEST_LAB.json(fichier vide corrige) + re-uploadfs Freenove ✅
[2026-02-26] SCENE_TEST_LAB -> mire validation LVGL/GFX
- Payload mire/validation enrichi:
data/story/screens/SCENE_TEST_LAB.json(timeline palette, transition glitch, demo fireworks, waveform, framing split, marquee)- mirror:
data/screens/SCENE_TEST_LAB.json - spec:
lib/zacus_story_portable/story_generator/story_specs/scenarios/DEFAULT/scene_test_lab.yaml
- Flash FS Freenove:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie:
SCENE_GOTO SCENE_TEST_LAB->ACK SCENE_GOTO ok=1✅UI_SCENE_STATUS->scene_id=SCENE_TEST_LAB,payload_origin=/story/screens/SCENE_TEST_LAB.json,transition=glitch✅
[2026-02-26] SCENE_TEST_LAB -> mire fixe palette (etape 1)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_031933_wip.patch/tmp/zacus_checkpoint/20260226_031933_status.txt
- Scene test simplifiee en mire fixe (sans timeline/effets/particules/waveform):
data/story/screens/SCENE_TEST_LAB.jsondata/screens/SCENE_TEST_LAB.json
- Upload FS Freenove:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Activation:
SCENE_GOTO SCENE_TEST_LAB->ACK SCENE_GOTO ok=1✅UI_SCENE_STATUS->effect=none,timeline=0,accent=#FF0000✅
[2026-02-26] Fix affichage SCENE_TEST_LAB (stabilite lancement)
- Constat:
SCENE_GOTO SCENE_TEST_LABetait bien ACK mais la scene pouvait etre remplacee par transitions scenario automatiques. - Correctif firmware:
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- ajout
isFixedTestSceneActive(...) - quand
screen_scene_id == SCENE_TEST_LAB,g_scenario.tick(now_ms)est saute (freeze transitions auto) pour garder la mire visible pendant calibration.
- Build/upload Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification serie:
SCENE_GOTO SCENE_TEST_LAB->ACK SCENE_GOTO ok=1✅STATUSapres 2s/5s/10s conservescreen=SCENE_TEST_LAB✅
[2026-02-26] Boot scene forcee sur detector
- Correctif boot story:
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- ajout
kBootStorySceneId = SCENE_LA_DETECTOR - au boot (hors media manager), route immediate vers
SCENE_LA_DETECTORviag_scenario.gotoScene(..., "boot_story_default")
- Build + upload Freenove:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification:
STATUSapres reboot ->step=SCENE_LA_DETECTOR screen=SCENE_LA_DETECTOR✅
[2026-02-26] Fix artefacts scene-change (effect=none) sur UiManager
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_093612_wip.patch/tmp/zacus_checkpoint/20260226_093612_status.txt- scan artefacts trackes (
.pio/.platformio/logs/dist/build/node_modules/.venv) -> aucun tracke.
- Correctif applique:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpphardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpphardware/firmware/ui_freenove_allinone/include/ui/ui_manager.h- ajout helper
setBaseSceneFxVisible(...)+ reset force des objets base (core/rings/fx_bar) a chaquestopSceneAnimations(). - scene change: on reapplique ensuite explicitement la visibilite selon
effect(none => cache force). applySceneEffect(kNone)masque explicitement les objets de base (protege timeline/segments intro-display).
- Build/upload Freenove:
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Smoke serie:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 10 --wait-port 20✅ (RESULT=PASS)- rerun apres
uploadfs:python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 20✅ (RESULT=PASS) - observations runtime: plus d'erreur
scene payload missing; audio boot radio redevenu disponible via LittleFS.
[2026-02-26] Re-sync force LittleFS scene/audio boot radio
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_094711_wip.patch/tmp/zacus_checkpoint/20260226_094711_status.txt
- Presence fichiers source verifiee:
data/story/screens/SCENE_U_SON_PROTO.json✅data/music/boot_radio.mp3✅
- Flash LittleFS:
pio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301❌ (.sconsign314.dblitemanquant sur cet alias env)pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification runtime:
- log:
logs/scene_audio_check_20260226_094900.log - grep erreurs
scene payload missing|file missing fs=littlefs path=/music/boot_radio.mp3=>MISSING_FOUND=0 - smoke:
RESULT=PASS
- log:
[2026-02-26] Fix texte scenes (visibles seulement sur TEST_LAB)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_094711_wip.patch/tmp/zacus_checkpoint/20260226_094711_status.txt
- Analyse:
UI_SCENE_STATUSconfirmaitshow_title/show_subtitle=true+ payload/story/screens/...correct, donc la panne n'etait pas le JSON/story.- point fragile identifie dans
ui_manager.cpp: la brancheSCENE_TEST_LABfaisaitlv_obj_remove_style_all(...)sur title/subtitle, puis les scenes suivantes ne reappliquaient pas une baseline texte assez stricte (opa/font/padding/state), provoquant des labels invisibles selon l'etat LVGL.
- Correctif applique:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- suppression des
lv_obj_remove_style_all(...)dans la branche TEST_LAB. - ajout d'une baseline style texte reappliquee a chaque
static_state_changedpour title/subtitle/symbol (font, color, text_opa, opa, padding, angle, align de base subtitle).
- suppression des
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cppstopSceneAnimations()force aussitext_opa=LV_OPA_COVERpour title/subtitle/symbol.
- Build/upload:
pio run -e freenove_esp32s3_full_with_ui✅pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Verification runtime:
- scenes ciblees:
SCENE_LA_DETECTOR,SCENE_SEARCH,SCENE_WINNER->ACK SCENE_GOTO ok=1+UI_SCENE_STATUS show_title=true show_subtitle=true payload_origin=/story/screens/...✅ - smoke:
python3 tools/dev/serial_smoke.py --role esp32 --port /dev/cu.usbmodem5AB90753301 --baud 115200 --timeout 8 --wait-port 20✅ (RESULT=PASS)
- scenes ciblees:
- Note sur les FAIL observes pendant conformance:
- un run
verify_story_ui_conformance.pyintermediaire a genere desui_scene_mismatch(exTR_WIN_ETAPE1_1) car le runtime etait deja en flux d'evenements/audio non deterministe; ce n'etait pas un indicateur fiable de la regression texte elle-meme.
- un run
[2026-02-26] Ajout polices IBM Plex Mono bold/italic (12/24)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_100645_wip.patch/tmp/zacus_checkpoint/20260226_100645_status.txt
- Ajouts assets/fonts:
tools/fonts/ttf/IBMPlexMono-Bold.ttftools/fonts/ttf/IBMPlexMono-Italic.ttf- nouveaux C LVGL generes:
lv_font_ibmplexmono_bold_12.c,lv_font_ibmplexmono_bold_24.c,lv_font_ibmplexmono_italic_12.c,lv_font_ibmplexmono_italic_24.c.
- Integration runtime API:
hardware/firmware/ui_freenove_allinone/include/ui/ui_fonts.h->fontBold12/fontBold24/fontItalic12/fontItalic24hardware/firmware/ui_freenove_allinone/src/ui/ui_fonts.cpp-> declarations + getters relies aux nouvelles fontes.
- Manifest/doc:
tools/fonts/scripts/font_manifest.jsonmaj (bold/italic tailles 12,24)tools/fonts/ttf/README.md+docs/ui/fonts.md+docs/ui/fonts_fr.mdmaj.
- Build/upload Freenove (build dir temporaire pour contourner instabilite
.pio/buildlocale):PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui✅PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅- taille firmware: Flash
33.6%(2115305/6291456), RAM74.9%(245316/327680).
[2026-02-26] In progress - mapping fonts titre/sous-titre (bold24/italic12)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_102040_wip.patch/tmp/zacus_checkpoint/20260226_102040_status.txt
- Demande utilisateur: appliquer globalement
title=Bold24etsubtitle=Italic12sur scenes UI. - Etapes prevues: patch
ui_manager.cpp(baseline + refresh scene), build+upload Freenove full UI, verification serie rapide. - Realisation:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- mapping global scene text:
title -> UiFonts::fontBold24(),subtitle -> UiFonts::fontItalic12()(init widgets + render baseline).
- mapping global scene text:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpp- mapping identique reappliquee dans
stopSceneAnimations()et phases WinEtape (cracktro/clean) pour eviter les retours enfontBodyS/M.
- mapping identique reappliquee dans
- Build/upload executes:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui✅PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
- Usage memoire apres mapping:
- Flash
34.3%(2156785/6291456) - RAM
74.9%(245332/327680)
- Flash
[2026-02-26] In progress - ajout API ESP-NOW v1
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_102555_wip.patch/tmp/zacus_checkpoint/20260226_102555_status.txt
- Demande utilisateur: ajouter la spec API ESP-NOW v1 fournie et la garder coherente avec
docs/espnow_contract.md. - Etapes prevues:
- verifier l'existant doc/firmware (contrat + commandes)
- ajouter/mettre a jour doc API v1
- aligner
docs/espnow_contract.mdsi ecart
- Realisation:
docs/espnow_api_v1.mdremplace par la spec ESP-NOW API v1 fournie (2026-02-23).docs/espnow_contract.mdcree comme contrat canonique miroir pour garder la coherence demandee.
- Extension suite demande utilisateur (broadcast+discovery + device name
U_SON):- firmware
app/main.cpp:- ajout commande
ESPNOW_DISCOVERY(sweep broadcast + aggregation pairs caches), - ajout
ESPNOW_DEVICE_NAME_GET/SETavec persistance NVS (zacus_net/esp_name), - default/fallback device name passe a
U_SON, - enrichissement status (
ESPNOW_STATUS/STATUS/NET_STATUS) avecdevice_name,send_mode,discovery.
- ajout commande
- docs mises a jour (
docs/espnow_api_v1.md,docs/espnow_contract.md) pourESPNOW_DISCOVERYet defaultU_SON.
- firmware
- Ajustement discovery suite retour utilisateur:
- ajout runtime discovery periodique (
15000ms) + commandesESPNOW_DISCOVERY_RUNTIME [on|off]. - correction cache peers: ignore
FF:FF:FF:FF:FF:FFpour eviter faux pair "broadcast".
- ajout runtime discovery periodique (
[2026-02-26] Diagnostic texte scenes (TEST_LAB ok / autres scenes invisibles)
- Verification terrain:
- Upload LittleFS execute pour aligner payloads ecran:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301✅
- Sondage serie
SCENE_GOTO + UI_SCENE_STATUSsur scenes canoniques:payload_origin=/story/screens/...presentshow_title=truesur toutes les scenes verifiees- controle global 24 scenes ->
OK.
- Upload LittleFS execute pour aligner payloads ecran:
- Cause identifiee:
SCENE_TEST_LABforce l'affichage du texte en dur dansui_manager.cpp, alors que les autres scenes dependent des payloads + flags runtime.- Si payload absent/stale, les scenes hors TEST_LAB pouvaient retomber sur un
show_titledefaut trop strict.
- Correctif anti-regression applique:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cppshow_titlepasse atruepar defaut (fallback robuste si payload manquant).
- Build/upload firmware apres patch:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui✅PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-1772097092 pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301✅
[2026-02-26] In progress - skill scene/screen specialist
- Demande utilisateur: travailler scene/ecran de facon coherente et creer un skill dedie.
- Skill cree:
~/.codex/skills/zacus-scene-screen-specialist/SKILL.md(workflow scene par scene YAML -> JSON -> runtime)scripts/scene_screen_sync.py(audit-scene, sync-scene, audit-all)references/repo-scene-map.mdagents/openai.yaml(genere)
- Validation skill:
quick_validate.py->Skill is valid! - Test script:
audit-scene --scene-id SCENE_SEARCH->diff_count=0.
[2026-02-26] In progress - manifest FX demoscene
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_121419_wip.patch/tmp/zacus_checkpoint/20260226_121419_status.txt
- Demande utilisateur: produire un manifest des FX type demoscene pour la stack Freenove.
- Etapes prevues:
- inventorier presets/timelines demoscene existants (
data/ui/fx/timelines/*.json,fx_engine), - formaliser un manifest unique versionne (presets, families FX, tracks cibles, mapping scenes),
- verifier JSON (parse + coherence chemins timeline).
- inventorier presets/timelines demoscene existants (
- Realisation:
- manifest ajoute:
data/ui/fx/demoscene_fx_manifest.v1.json - contenu: mapping presets->timelines, catalogue FX actifs, contrat tracks minimum, scene bindings, gates de validation.
- manifest ajoute:
- Verification:
python3 -m json.tool data/ui/fx/demoscene_fx_manifest.v1.json✅
[2026-02-26] In progress - text glitch FX (glitch 0-100 + size 0-100)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_122359_wip.patch/tmp/zacus_checkpoint/20260226_122359_status.txt
- Demande utilisateur: ajouter un effet texte glitch parametre (
glitch0-100,size0-100) et l'integrer au manifest demoscene. - Plan d'execution:
- mini veille web sur references "text glitch" demoscene,
- patch runtime UI (
ui_manager*) pour parser/applytext.glitch+text.size, - mise a jour
data/ui/fx/demoscene_fx_manifest.v1.json.
[2026-02-26] In progress - alias scene/registry + palette WS2812 dediee
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_124256_wip.patch/tmp/zacus_checkpoint/20260226_124256_status.txt
- Demande utilisateur: renforcer la coherence scene->LED WS2812 (alias/registry + palette dediee) et verifier l'alignement UI couleurs/effets/transitions.
- Plan d'execution:
- auditer mapping scene/alias dans
hardware_manager.cppet registre scenes, - ajouter alias palette dediee et fallback robuste,
- verifier coherence UI (
ui_manager*) et valider via scripts d'audit scene/screen.
- auditer mapping scene/alias dans
[2026-02-26] In progress - SCENE_U_SON_PROTO audit + correction runtime-valid
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_130032_wip.patch/tmp/zacus_checkpoint/20260226_130032_status.txt
- Demande utilisateur: auditer la scene modifiee
SCENE_U_SON_PROTO, corriger incoherences puis upload. - Correctif vise: garder un rendu glitch texte mais avec tokens runtime valides et alignement YAML<->JSON.
[2026-02-26] In progress - audit manifest FX vs implementation runtime
- Demande utilisateur: verifier que tous les effets declares dans le manifest sont bien implementes dans le code.
- Verification effectuee:
fx_types(transition_flash, scrolltext, starfield, rasterbars, shadebobs, plasma, tunnel3d, rotozoom, wirecube) presents dans le registre v9 (src/ui/fx/v9/effects/registry.cpp) et engine (src/ui/fx/v9/engine/engine.cpp).overlay_fx_types.text_glitchpresent dansui_manager.cpp(parsing) +ui_manager_effects.cpp(application).
- Verdict: pas de manque d'implementation detecte pour les IDs declares dans
data/ui/fx/demoscene_fx_manifest.v1.json. - Correctif build/FS anti-doublons applique dans
platformio.ini(envfreenove_esp32s3_full_with_ui):- exclusion compile
* 2.c/.cppet* 3.c/.cppviabuild_src_filter, - exclusion LittleFS
* 2.*,* 3.*et/screens/*viadata_filter.
- exclusion compile
[2026-02-26] In progress - scene UI editor SCENE_U_SON_PROTO (verify + implement)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_132200_wip.patch/tmp/zacus_checkpoint/20260226_132200_status.txt
- Demande utilisateur: verifier puis implementer
data/story/screens/SCENE_U_SON_PROTO.jsonavec le workflow scene editor. - Plan d'execution:
- auditer le JSON scene (
text/visual/effects/theme) et ses champs runtime, - aligner les champs incoherents avec le runtime UI (
ui_manager*), - rebuild + upload firmware/FS pour validation device.
- auditer le JSON scene (
- Actions realisees:
- audit runtime de
SCENE_U_SON_PROTO(tokens valides/invalides pour align + glitch/size + waveform), - correction de
data/story/screens/SCENE_U_SON_PROTO.json(align tokens valides, params text_glitch/size, waveform coherent, transition glitch), - validation JSON locale (
python3 -m json.tool) + upload FS cible Freenove.
- audit runtime de
- Evidence execution:
- commande:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-u-son-json pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301 - resultat: SUCCESS (flash LittleFS) a
2026-02-26.
- commande:
[2026-02-26] Completed - SCENE_U_SON_PROTO glitch layout + fx loop
- Audit/patch: pushed
text.symbol_alignsupport, updated JSON + YAML + fallback storage entry + UI runtime alignment logic so title/subtitle/symbol glitched as requested and symbol can be pinned to top. - Validated with
pio run -e freenove_esp32s3_full_with_ui(build only) and reflashed both firmware and FS assets (PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301+-t uploadfs ...).
[2026-02-26] Run SCENE_U_SON_PROTO (LGFX overlay + timeline 30s + backlight/WS2812 sync)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_140931_wip.patch/tmp/zacus_checkpoint/20260226_140931_status.txt
- Branche + diff stat captures avant mutation.
- Artefacts trackes verifies:
.pio,.platformio,logs,dist,build,node_modules,.venv=> aucun tracke. - Scope prevu:
SCENE_U_SON_PROTO+ runtime UI/FX/HW associe (sans toucher conflit git hors scope). - Realisation:
- scene canonique alignee (
game/scenarios/scene_editor_all.yaml,data/story/screens/SCENE_U_SON_PROTO.json, fallbackstorage_manager.cpp) avecrender.text_backend=lgfx_overlay,disable_lvgl_text=true, timeline 30s, backlight glitch_sync et WS2812 single_random_blink. - runtime UI: overlay texte LGFX foreground (symbol top, title center, subtitle bottom), preset FX dedie
kUsonProto, scroller wave desactive pour cette scene. - runtime hardware: backlight dynamique 0..125 synchronise glitch + mode LED one-led-at-a-time expose dans statuts.
- manifest/timeline outillage: ajout
data/ui/fx/timelines/u_son_proto_30s.json, presetuson_protodansdata/ui/fx/demoscene_fx_manifest.v1.json, syncrender/hardwaredanstools/dev/export_scene_editor_workbench.py.
- scene canonique alignee (
- Gates executes:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e freenove_esp32s3_full_with_ui -j 1=> SUCCESS.PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e esp32dev -e esp32_release -e esp8266_oled -e ui_rp2040_ili9488 -e ui_rp2040_ili9486 -j 1=>- SUCCESS:
esp32dev,esp32_release,esp8266_oled - FAIL:
ui_rp2040_ili9488,ui_rp2040_ili9486(erreur preexistante:input in flex scanner failedsur generation.pio.pio.hdepuis.../esp32_audio/.pio).
- SUCCESS:
- Flash device:
- code:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301=> SUCCESS. - LittleFS:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301=> SUCCESS.
- code:
- Verifications runtime:
python3 tools/dev/verify_story_ui_conformance.py --port /dev/cu.usbmodem5AB90753301 --baud 115200 --firmware-root .- resultat:
runtime_tested=51 pass=50 fail=1 - fail observe:
DEFAULT:TR_SCENE_QR_DETECTOR_3 reason=path_step_mismatch:TR_RTC_ESP_ETAPE2_1:SCENE_U_SON_PROTO->SCENE_QR_DETECTOR - log:
artifacts/rc_live/ui_conformance_verify_20260226-145826.log
- resultat:
python3 tools/dev/verify_scene_text_led_matrix.py --port /dev/cu.usbmodem5AB90753301 --baud 115200 --repo-root ../..- fail observe:
SCENE_LOCKED: tolerant LED expected non-black pattern got=(0, 0, 0)
- fail observe:
- Note build path:
- dans ce workspace avec espaces, build direct sans
PLATFORMIO_BUILD_DIRechoue preexistamment sur.sconsign314.dbliteabsent; contournement stable via build dir/tmp.
- dans ce workspace avec espaces, build direct sans
[2026-02-26] Run focus lock Freenove only
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_170820_wip.patch/tmp/zacus_checkpoint/20260226_170820_status.txt
- Demande utilisateur: verrouiller le focus agent/build sur la cible Freenove.
- Plan: restreindre
default_envsPlatformIO afreenove_esp32s3_full_with_uipour eviter les gates multi-cibles hors scope.
[2026-02-26] Run disable SCENE_TEST_LAB on story boot
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_171007_wip.patch/tmp/zacus_checkpoint/20260226_171007_status.txt
- Demande utilisateur: desactiver
SCENE_TEST_LABau boot story/scenario. - Plan: retirer le routage boot explicite vers
SCENE_TEST_LABet conserver le scene initial du scenario.
[2026-02-26] Run SCENE_LA_DETECTOR en 100% GFX
- Demande utilisateur: passer
SCENE_LA_DETECTORen rendu GFX (sans widgets LVGL de scene). - Realisation:
- scene payload:
render.text_backend=lgfx_overlay,disable_lvgl_text=true,wave=false,visual.waveform.enabled=false. - runtime:
SCENE_LA_DETECTORclassee direct-FX (ui_manager_effects.cpp+scene_fx_orchestrator.cpp), preset demo et scroll texte coupe. - garde-fou runtime: si LGFX-only sur LA detector, forcer
la_detection_scene_=falseetwaveform_enabled=false.
- scene payload:
- Gate:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e freenove_esp32s3_full_with_ui -j 1=> SUCCESS.
[2026-02-26] Run SCENE_LA_DETECTOR oscillo/VU/FFT A4 + WS2812 feedback
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_171933_wip.patch/tmp/zacus_checkpoint/20260226_171933_status.txt
- Demande utilisateur: afficher waveform circulaire + VU + bargraphe FFT focalise 400..480 Hz (A4) et reporter ce spectre sur les 4 WS2812.
- Plan:
- etendre snapshot micro avec bandes spectrales A4,
- brancher rendu overlay detector sur ces bandes (lisible + glitch leger),
- mapper WS2812 (400/440/480) avec intensite proportionnelle.
- Realisation:
- ajout de bins spectre
400/420/440/460/480 HzdansHardwareManager::Snapshot+ estimation Goertzel runtime. - overlay LA: bargraph centre A4 base sur bins reels (fallback ancien profil si bins absents), VU + aiguille conserves.
- WS2812 tuner: mapping 4 LEDs par bande (bas=rouge, centre 440=vert blink, haut=bleu), intensite proportionnelle.
SCENE_LA_DETECTORconserve texte GFX-only mais reactive l'overlay micro (visual.waveform.enabled=true).
- ajout de bins spectre
- Gate:
PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus pio run -e freenove_esp32s3_full_with_ui -j 1=> SUCCESS.
[2026-02-26] Run WIN_ETAPE hotline flow + suppression SCENE_BOOT_PALETTE
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_173053_wip.patch/tmp/zacus_checkpoint/20260226_173053_status.txt
- Scope:
- suppression complete
SCENE_BOOT_PALETTE(runtime + canonique scene + ecrans + script de verification), - scene d'attente HOT-LINE sur
SCENE_WIN_ETAPEavec envoi ESPNOWWAITING_VALIDATION, - transition ACK
ACK_WIN1/ACK_WIN2vers ETAPE1/ETAPE2, SCENE_WIN_ETAPE1en mode GFX direct (demoscene),- maintien LA_DETECTOR cible Freenove (oscillo/VU/FFT + WS2812 tuner).
- suppression complete
- Realisation:
main.cpp: retraitBOOT_PALETTE_PREVIEW+ retrait logique boot palette + aide/dispatch associes.scene_editor_all.yaml: suppression blocSCENE_BOOT_PALETTE, meta export ajustee, maj scenes WIN_ETAPE/WIN_ETAPE1.- suppression fichiers:
data/story/screens/SCENE_BOOT_PALETTE.json,data/screens/SCENE_BOOT_PALETTE.json. DEFAULT.json:RTC_ESP_ETAPE1devient ecranSCENE_WIN_ETAPEavec actionACTION_ESP_NOW_WAITINGet transitions ACK1/ACK2.- ajout action
data/story/actions/ACTION_ESP_NOW_WAITING.json. - UI runtime: desactivation chemin intro WIN_ETAPE (plus de masquage), cleanup scene elargi WIN_ETAPE/1/2, direct-FX active pour
SCENE_WIN_ETAPE1preset demo. verify_scene_text_led_matrix.py: suppression verificationBOOT_PALETTE_PREVIEW.
[2026-02-26] Run implementation LA_DETECTOR GFX-only + WIN_ETAPE/WIN_ETAPE1/U_SON_PROTO
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226-221949_wip.patch/tmp/zacus_checkpoint/20260226-221949_status.txt
- Scope demarre:
- finaliser
SCENE_LA_DETECTORen overlay GFX-only (pas de rendu LVGL actif), - stabiliser
SCENE_WIN_ETAPE(texte/celebrate + flow HOT-LINE ACK), - preset/timeline dedie
SCENE_WIN_ETAPE1, - renforcer rendu
SCENE_U_SON_PROTO(titre plus impactant + zoom/glitch + sync niveau <100), - build + upload code + uploadfs Freenove + verification scripts.
- finaliser
[2026-02-27] Run upload FS complet Freenove (reflash LittleFS)
- Commande executee:
PORT=$(ls /dev/cu.usbmodem5AB907* | head -n1)PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-fs-full pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port "$PORT"
- Resultat:
uploadfsSUCCESS (erase0x00610000..0x00c0ffff, ecriture image LittleFS complete 6MB).- guard anti-doublons copies numerotees OK:
[ok] no duplicate payload copies found (scopes=data).
- Note:
- un upload firmware lance en parallele a echoue sur port lock (
Resource temporarily unavailable) pendant l'uploadfs; non bloquant pour le reflash FS complet.
- un upload firmware lance en parallele a echoue sur port lock (
[2026-02-26] Run nettoyage payloads legacy hors LittleFS
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226-225636_wip.patch/tmp/zacus_checkpoint/20260226-225636_status.txt
- Objectif:
- sortir les payloads legacy (
data/screens/*+data/SCENE_WIN_ETAPE.json) du bundle LittleFS, garder uniquement le canoniquedata/story/screens/*en FS.
- sortir les payloads legacy (
- Realisation:
- deplacement des payloads legacy vers
legacy_payloads/fs_excluded/(horsdata/donc exclus deuploadfs). - mise a jour du sync palette (
story-gen sync-screens) pour ecrire les mirrors legacy danslegacy_payloads/fs_excluded/screens. - mise a jour du guard
tools/dev/check_no_duplicate_payload_files.pypour bloquer les regressionsdata/screens/*.jsonetdata/SCENE_*.json. - documentation palette/contrat mise a jour (
data/story/palette/screens_palette_v3.yaml,docs/protocols/story_screen_palette_v2.md).
- deplacement des payloads legacy vers
- Verification:
python3 tools/dev/check_no_duplicate_payload_files.py --repo-root . --scope data=>[ok] payload guard passed (scopes=data).PORT=$(ls /dev/cu.usbmodem5AB907* | head -n1)PLATFORMIO_BUILD_DIR=/tmp/pio-build-zacus-fs-clean pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port "$PORT"=> SUCCESS.- preuve FS embarquee: liste buildfs ne contient plus aucun chemin
/screens/*(uniquement/story/screens/*).
[2026-02-26] Run boot target change -> SCENE_U_SON_PROTO
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_234923_wip.patch/tmp/zacus_checkpoint/20260226_234923_status.txt
- Scope:
- ajuster le routage de boot story pour arriver directement sur
SCENE_U_SON_PROTOau lieu deSCENE_TEST_LAB.
- ajuster le routage de boot story pour arriver directement sur
[2026-02-26] Run sprint triggers+cleanup DEFAULT (implementation)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260226_235243_wip.patch/tmp/zacus_checkpoint/20260226_235243_status.txt
- Scope:
- debug_only transitions + bypass runtime flag,
- audit complet DEFAULT (YAML/JSON/fallback),
- hard cleanup global des ressources de transition,
- validations + upload Freenove.
2026-02-27 10:02 - Sprint triggers scenes cibles (U_SON->LA->WIN_ETAPE->WIN_ETAPE1)
- checkpoint securite refait (
/tmp/zacus_checkpoint/20260227_095317_*). - objectif du run: finaliser rationalisation triggers prod stricts + hard cleanup global + reset HW scene-owned a chaque transition.
- gates prevues: story validate, audit trigger focus+ALL_DEFAULT, anti-doublons, build/upload/uploadfs Freenove.
- implementation: cleanup transition durci (
main.cpp+ui_manager_effects.cpp), U_SON backlight/WS2812 dynamiques (mic level + couleur freq), LA_DETECTOR overlay LGFX renforce (waveform epaisse + jauge/sablier + VU/FFT + textes). - validations:
story-gen validate,audit_scene_trigger_chain.py --focus U_SON,LA,WIN_ETAPE,WIN_ETAPE1,audit_scene_trigger_chain.py --focus ALL_DEFAULT,check_no_duplicate_payload_files.py --scope data-> OK. - freenove flash: build
pio run -e freenove_esp32s3_full_with_uiOK, upload code + uploadfs OK sur/dev/cu.usbmodem5AB90753301avecPLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus.
2026-02-27 10:22 - Sprint LA_DETECTOR hourglass (agent)
-
Scope: SCENE_LA_DETECTOR uniquement (YAML/JSON/runtime FX/UI + manifest + fallback storage).
-
Checkpoint:
/tmp/zacus_checkpoint/20260227_102221_wip.patchet/tmp/zacus_checkpoint/20260227_102221_status.txt. -
Planned changes: preset
kLaDetector, FX v9hourglass, textes title/subtitle only, symbol off, hide caption/pitch techniques. -
[2026-02-27 10:29] Implementation terminee: SCENE_LA_DETECTOR hourglass v9 + textes title/subtitle only (symbol off) + gating caption/pitch overlay.
- fichiers: scene_editor_all.yaml, screens_palette_v3.yaml, SCENE_LA_DETECTOR.json, ui_manager(.h/.cpp), fx_engine(.h/.cpp), v9 effects registry/engine, storage_manager fallback, manifest + timeline la_detector_hourglass.
- validations:
- audit-scene SCENE_LA_DETECTOR: OK (diff_count=0)
- fx_inventory --check-manifest --strict: OK (hourglass detecte)
- pio run -e freenove_esp32s3_full_with_ui: SUCCESS
-
[2026-02-27 10:35] Sprint U_SON_PROTO: police IBM bold + WS2812 mono-LED par bande dominante + boot_radio.mp3 aleatoire volume faible.
- checkpoint: /tmp/zacus_checkpoint/20260227_103526_wip.patch ; /tmp/zacus_checkpoint/20260227_103526_status.txt
-
2026-02-27 10:47:51 | Sprint U_SON_PROTO: IBM bold text (LVGL), WS2812 dominant_band_single, ambient boot_radio random low volume. Files: scene_editor_all.yaml, SCENE_U_SON_PROTO.json, ui_manager.cpp, main.cpp, hardware_manager.{h,cpp}, storage_manager.cpp.
-
2026-02-27 10:52:27 | Validation: scene_screen_sync audit SCENE_U_SON_PROTO=OK; check_no_duplicate_payload_files=OK; build Freenove OK via
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui(build dir workaround for.sconsign*.dbliteunder .pio/build). -
2026-02-27 10:55:22 | Flash Freenove done: firmware upload OK + uploadfs OK on /dev/cu.usbmodem5AB90753301 (env freenove_esp32s3_full_with_ui, build dir /tmp/pio_build_zacus).
[2026-02-27] Run LGFX runtime-only global + LA_DETECTOR modern (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227T110923_wip.patch/tmp/zacus_checkpoint/20260227T110923_status.txt
- Scope:
- verrou runtime scene backend
lgfx_overlayglobal (story scenes), - pipeline police IBM Bold pour overlay LGFX,
- modernisation
SCENE_LA_DETECTOR(titre top, jauge niveau horizontale bas, sablier renforce, symboles legacy supprimes), - build + upload + uploadfs Freenove.
- verrou runtime scene backend
[2026-02-27] Run LGFX runtime-only global + LA_DETECTOR modern (agent follow-up)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227T112004_wip.patch/tmp/zacus_checkpoint/20260227T112004_status.txt
- Scope execute:
- verrou runtime scenes story en
lgfx_overlay+disable_lvgl_text=true(YAML + JSON + fallback storage), - API overlay fonts
OverlayFontFace+ rendu IBM Bold 16/24 dansdisplay_hal_lgfx.cpp, - modernisation
SCENE_LA_DETECTOR(title/subtitle top, symbol off, sablier renforce, meter horizontal bas, anneau conserve), - statut runtime expose
render_backend_lock=lgfx_runtime_only.
- verrou runtime scenes story en
- Validations executees:
./tools/dev/story-gen validate-> OKpython3 tools/dev/check_no_duplicate_payload_files.py --repo-root ../.. --scope data-> OKpython3 tools/dev/audit_scene_trigger_chain.py --repo-root ../.. --focus ALL_DEFAULT --out /tmp/audit_scene_trigger_chain_after.json-> OKPLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui-> SUCCESS
- Flash Freenove:
- port detecte
/dev/cu.usbmodem5AB90753301 - firmware upload -> SUCCESS
- uploadfs -> SUCCESS (LittleFS complet, guard anti-doublons OK)
- port detecte
[2026-02-27] Run U_SON_PROTO fonts+mic+ambient audio (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227T113737_wip.patch/tmp/zacus_checkpoint/20260227T113737_status.txt
- Scope execute:
- extension
OverlayFontFace(IBM regular/bold/italic + Inter/Orbitron/Bungee/Monoton/RubikGlitch) et mapping rendu LGFX overlay, - parsing payload
text.title_font_face/subtitle_font_face/symbol_font_facedansui_manager.cpp, - U_SON micro force via policy scene (
requires_micinclutSCENE_U_SON_PROTO), - ambient audio random scene-driven (
audio.ambient_random) avec mode non-interruptif + pseudo-pitch EQsoft/warm/bright, - WS2812
dominant_band_singledurci (bins 400/420/440/460/480, 1 LED active, OFF si signal faible), - sync canonique
scene_editor_all.yaml+SCENE_U_SON_PROTO.json+ fallbackstorage_manager.cpp, - workbench export/sync etendu pour conserver
textcomplet +audio.
- extension
- Validation:
./tools/dev/story-gen validate-> OKpython3 tools/dev/check_no_duplicate_payload_files.py --repo-root ../.. --scope data-> OKpython3 tools/dev/audit_scene_trigger_chain.py --repo-root ../.. --focus ALL_DEFAULT-> OKPLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui-> SUCCESS
- Flash Freenove:
- port detecte:
/dev/cu.usbmodem5AB90753301 pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port "$PORT"-> SUCCESSpio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port "$PORT"-> SUCCESS
- port detecte:
[2026-02-27] Run text visibility + LA detector + U_SON timeline/audio (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227T121333_wip.patch/tmp/zacus_checkpoint/20260227T121333_status.txt
- Scope: corriger textes scene overlay LGFX visibles, inverser sens sablier LA, passer analyseur spectre LA a 15 bandes, fiabiliser boucle FX U_SON et lecture simple
/music/boot_radio.mp3en volume max. - [2026-02-27 12:26] Implementation complete:
- texte scenes LGFX rendu en foreground apres flush LVGL (fix visibilite multi-scenes) dans
ui_manager.cpp. SCENE_LA_DETECTOR: inversion sens sablier (overlay + FX hourglass) et analyseur passe a 15 bandes (interpolation visuelle).SCENE_U_SON_PROTO: boucle FX runtime forcee a 30s (fx_engine), audio simplifie en lecture/music/boot_radio.mp3a volume max.- sync canonique U_SON audio:
scene_editor_all.yaml+SCENE_U_SON_PROTO.json+ fallbackstorage_manager.cpp.
- texte scenes LGFX rendu en foreground apres flush LVGL (fix visibilite multi-scenes) dans
- Validations:
./tools/dev/story-gen validate-> OKpython3 tools/dev/check_no_duplicate_payload_files.py --repo-root ../.. --scope data-> OKPLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui-> SUCCESS
- Flash Freenove:
- port:
/dev/cu.usbmodem5AB90753301 - upload firmware -> SUCCESS
- uploadfs -> SUCCESS
- port:
[2026-02-27] Run text visibility recheck + hourglass flow fix (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227T122927_wip.patch/tmp/zacus_checkpoint/20260227T122927_status.txt
- Scope: corriger texte LGFX non visible et corriger sens ecoulement sablier (triangles) selon retour hardware.
[2026-02-27] Run U_SON audio simple playback (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227T123605_wip.patch/tmp/zacus_checkpoint/20260227T123605_status.txt
- Scope: suppression des adaptations EQ/pseudo-pitch U_SON, lecture MP3 simple en volume max,
kUsonAmbientVolumeMinforce au maximum. - [2026-02-27 12:56] Patch overlay foreground reliability: retry
startWrite()with DMA wait indisplay_hal_lgfx.cppand inUiManagerLGFX overlay paths (U_SON + LA text visibility). - [2026-02-27 12:57] Fix LA hourglass bottom chamber orientation in v9 effect (
hourglass.cpp): bottom triangle now wide at base and narrow at neck. - [2026-02-27 13:03] Build Freenove OK (
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui). - [2026-02-27 13:05] Upload firmware OK (
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301). - [2026-02-27 13:07] Upload LittleFS OK + guard anti-doublons (
check_no_duplicate_payload_filespass +pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301). - [2026-02-27 13:16] LA overlay audit: title/subtitle were gated by
active_snapshotpresence inrenderLgfxLaDetectorOverlay; fallback path added so foreground texts remain visible even when mic snapshot is temporarily unavailable. - [2026-02-27 13:17] Build Freenove OK after LGFX text/hourglass fixes (
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui). - [2026-02-27 13:19] Upload firmware OK (
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301). - [2026-02-27 13:20] Upload LittleFS OK (
check_no_duplicate_payload_filespass +pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301).
[2026-02-27] Push GitHub (source of truth requested)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_144640_wip.patch/tmp/zacus_checkpoint/20260227_144640_status.txt
- Contexte git:
- depot en
HEAD (detached)avec rebase interactive en cours; push bloque. - resolution push:
git rebase --quit, creation branchecodex/freenove-source-of-truth-20260227.
- depot en
- Validation effectuee:
PLATFORMIO_BUILD_DIR=/tmp/pio_build_zacus pio run -e freenove_esp32s3_full_with_ui-> SUCCESS.
- Livraison GitHub:
- commit:
520f98d(freenove: publish current story/ui source of truth) - push:
origin/codex/freenove-source-of-truth-20260227 - PR:
https://github.com/electron-rare/le-mystere-professeur-zacus/pull/111[20260227-145416] Run artefacts: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260227-145416, logs: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/logs/rc_live, summary: /Users/cils/Documents/Enfants/anniv isaac 10a/le-mystere-professeur-zacus/hardware/firmware/artifacts/rc_live/esp32dev_esp32_release_esp8266_oled_ui_rp2040_ili9488_ui_rp2040_ili9486_20260227-145416/summary.md
- commit:
[2026-02-27] A252 hotline SD audio mapping + scene routing (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_165549_wip.patch/tmp/zacus_checkpoint/20260227_165549_status.txt
- Scope execute (A252):
- mapping hotline force au boot sur SD (
/hotline/menu_dtmf_short.wav,/hotline/menu_dtmf.wav,/hotline/menu_dtmf_long.wav) pour les digits1/2/3; WAITING_VALIDATIONarme maintenant un media pending SD (/hotline/enter_code_5.wav) avant sonnerie;- integration scene->audio SD (
/hotline/scene_*+fiches-hotline_2) via commandeSCENE; - nouvelle commande runtime
HOTLINE_SCENE_PLAY <scene_id>pour tester/forcer l'audio scene; - web server A252 monte FFat en profile
BOARD_PROFILE_A252(suppression erreur SPIFFS au boot).
- mapping hotline force au boot sur SD (
- Validation effectuee:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> SUCCESSpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> SUCCESS- Smoke serie:
STATUS->dial_media_mapconfirme les 3 routes SD hotlineAUDIO_PROBE sd:/hotline/menu_dtmf.wav-> OKAUDIO_PROBE sd:/hotline/enter_code_5.wav-> OKWAITING_VALIDATION-> OK +STATUS.telephony.pending_espnow_call_audio=/hotline/enter_code_5.wavSCENE SCENE_WIN_ETAPE1/SCENE SCENE_U_SON_PROTO/SCENE SCENE_MEDIA_ARCHIVE-> audio scene mappe et demarreHOTLINE_SCENE_PLAY SCENE_CAMERA_SCAN-> JSON OK (path SD retourne)
- Boot logs A252: plus de
SPIFFS mount failedapres patch WebServerManager (FFat path actif).
[2026-02-27] A252 MP3 decode integration (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_171026_wip.patch/tmp/zacus_checkpoint/20260227_171026_status.txt
- Scope execute:
- ajout decode MP3 Helix dans
AudioEngine(pipeline playback MP3 + WAV); AUDIO_PROBEaccepte maintenant les fichiers MP3 (metadata sample-rate/channels via scan header MP3);- tracking runtime playback MP3 dans
STATUS.audio.playback_input_*/playback_output_*; - dependance firmware ajoutee:
arduino-libhelixdanshardware/RTC_SLIC_PHONE/platformio.ini.
- ajout decode MP3 Helix dans
- Validation:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> SUCCESSpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> SUCCESS- Serie smoke:
AUDIO_PROBE sd:/hotline/scene_ready_2__fr-FR-DeniseNeural.mp3-> OK (input_sample_rate=24000,input_channels=1)PLAY sd:/hotline/scene_ready_2__fr-FR-DeniseNeural.mp3->OK PLAYSTATUSpendant lecture MP3 ->playback_input_sample_rate=24000,playing=true,storage_last_pathMP3 sceneSCENE SCENE_U_SON_PROTO-> audio scene MP3 SD mappe et demarreAUDIO_PROBE sd:/hotline/menu_dtmf.wavetWAITING_VALIDATIONrestent OK (non regression WAV/hotline)
- Boot logs A252 verifies:
- plus d'erreur
SPIFFS mount failed, serveur web OK ([WebServerManager] HTTP server started).
- plus d'erreur
[2026-02-27] Sprint Freenove + A252 hotline ESP-NOW + LA overlay (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_173423_wip.patch/tmp/zacus_checkpoint/20260227_173423_status.txt
- Scope execute:
- Freenove
SCENE_LA_DETECTOR(LGFX overlay):- sablier unique place a gauche centre Y, palette noir/blanc inversee;
- ecoulement sable conserve top->bottom (haut se vide, bas se remplit);
- jauge circulaire de niveau micro deplacee a droite centre Y;
- waveform micro deplacee en bande centrale (horizontale);
- spectre etendu a 60 bandes, hauteur conservee, repere A4 centre en X.
- A252 hotline:
WAITING_VALIDATIONroute audio basculee vers MP3 voix SD (enter_code_5__fr-fr-deniseneural.mp3);HOTLINE_VALIDATE <WIN1|WIN2|WARNING>declenche un cue local MP3 (scene-aware via scene active, fallback win/broken);- fallback runtime MP3->WAV ajoute (
scene_*__fr-fr-deniseneural.mp3->scene_*.wav).
- Audio policy A252:
- gain software lecture remis a 1.0 (
kPlaybackBoostLinear=1.0); - volume ES8388 force a 100 au boot + via
AUDIO_PATCH+VOLUME_SET.
- gain software lecture remis a 1.0 (
- Freenove
- Validation effectuee:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> SUCCESSpio run -e freenove_esp32s3-> SUCCESSpio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> SUCCESSpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> SUCCESS- Smoke serie A252:
VOLUME_GET->{"volume":100}HOTLINE_VALIDATE WIN1 NOACK->OK HOTLINE_VALIDATE ACK_WIN1WAITING_VALIDATION->OK WAITING_VALIDATIONSTATUS.telephony.pending_espnow_call_audio=/hotline/enter_code_5__fr-fr-deniseneural.mp3
[2026-02-27] Freenove LA detector: FFT full-width LGFX (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_181016_wip.patch/tmp/zacus_checkpoint/20260227_181016_status.txt
- Scope execute:
SCENE_LA_DETECTORoverlay LGFX: bargraphe spectre 60 bandes passe en mapping pleine largeur ecran (marges 2px, clamp anti-debordement), sans changer la hauteur FFT.- marqueur A4 force au centre X (
marker_x = width / 2).
- Validation:
pio run -e freenove_esp32s3-> SUCCESSpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> SUCCESS
[2026-02-27] Freenove LA detector: demoscene hourglass background + circular progress gauge (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_181016_wip.patch/tmp/zacus_checkpoint/20260227_181016_status.txt
- Scope execute:
SCENE_LA_DETECTORLGFX overlay: suppression du petit sablier lateral;- ajout d'un sablier de fond style demoscene/3D (wireframe + profondeur + flux de sable anime);
- ajout d'une jauge circulaire d'incrementation autour de la waveform micro centrale (progression detection);
- maintien FFT 60 bandes pleine largeur + marqueur A4 centre X.
- Validation:
pio run -e freenove_esp32s3-> SUCCESSpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> SUCCESS
[2026-02-27] Freenove LA detector: hourglass_demoscene_ultra + oscilloscope 200ms/div (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_194435_wip.patch/tmp/zacus_checkpoint/20260227_194435_status.txt
- Scope execute:
- ajout preset
hourglass_demoscene_ultra(parser + runtime) dansui_managerpourrender.la_detector.background_preset; - remplacement fond LA detector par sablier demoscene LGFX offscreen (
pushImageDma) avec simulation sable, swing amorti, flip 180deg sur timeout; - waveform oscilloscope: base temps verrouillee 200ms/div x10 divisions, trace plus reactive avec head highlight;
- bargraph FFT: degrade vertical par barre vert->jaune->rouge conserve;
- scene data/manifeste mis a jour (
SCENE_LA_DETECTORpreset ultra + contrat manifest).
- ajout preset
- Validation:
pio run -e freenove_esp32s3-> SUCCESSpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> SUCCESSpio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301-> SUCCESS
2026-02-27 20:40 — RTOS triage + U_SON ambient constraints (Codex)
- Scope:
ui_freenove_allinonecrash triage onSCENE_LA_DETECTORand ambient audio policy lock forSCENE_U_SON_PROTO. - Changes:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp: replaced full-framepushImageDma(...)for hourglass ultra background withsetAddrWindow + pushColors(...)to avoid PSRAM DMA instability in loopTask.hardware/firmware/ui_freenove_allinone/src/app/main.cpp: removed U_SON ambient audio FX forcing/restoration; keep track playback non-interruptive only.hardware/firmware/ui_freenove_allinone/src/app/main.cpp: enforced U_SON ambient defaults/floor/ceiling: track/music/boot_radio.mp3, volume fixed 21, delay window 60000..240000 ms.data/story/screens/SCENE_U_SON_PROTO.jsonand builtin mirror inhardware/firmware/ui_freenove_allinone/src/storage_manager.cpp: delay window set to 60000..240000.
- Evidence:
- Build:
pio run -e freenove_esp32s3PASS. - Flash:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301PASS. - FS:
pio run -e freenove_esp32s3 -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301PASS. - Serial triage: 55s after
SCENE_GOTO SCENE_LA_DETECTOR=>PANIC_COUNT=0(no stack canary / guru seen in capture window).
- Build:
- Remaining risk:
post_upload_checklist.shstill reports missing explicitSCENE_GOTOACK in sampled window; functional scene transition logs present.
2026-02-27 20:55 — ESP-NOW only boot mode + display visibility guard (Codex)
- Boot network policy updated in
ui_freenove_allinone/src/app/main.cpp:kBootEspNowOnlyMode=true.- Disable AP/STA/web boot paths while keeping
g_network.begin(...)andg_network.enableEspNow(). - Explicit logs:
[NET] wifi+web disabled (espnow_only_mode=1)and[WEB] disabled (espnow_only_mode=1).
- Display visibility guard:
- default backlight raised from 30 to 80 at boot globals.
- Validation:
- Build PASS:
pio run -e freenove_esp32s3. - Flash PASS:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301. - Serial checks:
STATUS/NET_STATUS:mode=STA sta=0 ap=0 espnow=1 ip=0.0.0.0.LCD_BACKLIGHT level=80.SCENE_GOTOreturnsACK ... ok=1with[UI] render ...logs.- panic scan on LA scene:
panic_hits=0.
- Build PASS:
2026-02-27 21:01 — LA detector hourglass timing/placement/reactivity tuning (Codex)
- Scope:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp - Changes:
- Hourglass flip duration now 10s (
kHourglassFlipDurationMs=10000.0f) when timeout reaches zero. - Swing slowed x10 (initial omega, damping/stiffness path, jitter impulse, flip kick reduced).
- Hourglass shifted right by +20% screen width (
center_x = width * 0.7f). - Waveform temporal window made faster (
max_pointsreduced to 20, oscilloscope now100ms/divover 10 divisions). - FFT bargraph made more reactive with stronger amplitude gain from live spectrum + mic level.
- Hourglass flip duration now 10s (
- LA timeout source sync:
runtime_config_service.cppnow reads/story/apps/APP_LA.jsonconfig.timeout_msand maps it tomic_la_timeout_msso hourglass/timer use scene APP_LA timeout.
- Validation:
- Build PASS:
pio run -e freenove_esp32s3. - Flash PASS:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301. - Serial evidence:
HW_STATUS ... la_timeout_ms=30000 ... scene=SCENE_LA_DETECTOR.- Timeout observed at ~30008ms then routed to
SCENE_U_SON_PROTO(la_timeout_recovery).
- Build PASS:
2026-02-27 21:10 — LA detector hourglass/waveform retune v2 (Codex)
- Scope:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp - Changes:
- Hourglass swing oscillator normalized to ~12s period (inside requested 10..15s), with softer damping.
- Timeout reset flip kept at 10s (
kHourglassFlipDurationMs=10000). - Hourglass height reduced by
/1.33from prior setting (scale_y = 0.9/1.33). - Hourglass render density increased by x3 vertical sub-lines per logical row.
- Hourglass position shifted right by +20% (
center_x = width * 0.7f). - Waveform acquisition window shortened further (
max_points=12) and timescale tightened (50ms/div) for fast audio-player-like trace. - FFT bargraph reactivity boosted again (stronger gain mapping from live spectrum + mic level).
- Validation:
- Build PASS:
pio run -e freenove_esp32s3. - Flash PASS:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301. - Serial check PASS:
HW_STATUSalive.UI_GFX_STATUSstable (no panic/overflow/stall/recover increments in sampled output).
- Build PASS:
2026-02-27 21:19 — LA detector hourglass timeout mapping + reset flip (Codex)
- Scope:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpphardware/firmware/ui_freenove_allinone/include/ui/ui_manager.h
- Changes:
- Hourglass visual depletion stays mapped to 80% of real timeout (
kHourglassTimeoutScale=0.80f) so the visual hourglass finishes earlier. - Added timeout-reset detection (
gate_elapseddrop to ~0 after prior progress) and trigger a 10s hourglass return flip animation (kHourglassFlipDurationMs=10000.0f). - Added runtime state to track previous gate elapsed for reset-edge detection (
la_hg_prev_gate_elapsed_ms_,la_hg_prev_gate_valid_).
- Hourglass visual depletion stays mapped to 80% of real timeout (
- Validation:
- Build PASS:
pio run -e freenove_esp32s3. - Flash PASS:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301.
- Build PASS:
- Notes:
- No FS payload changed in this pass, so no
uploadfsrequired.
- No FS payload changed in this pass, so no
2026-02-27 21:27 — LA hourglass damping retune + reset flip hardening (Codex)
- Scope:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp
- Changes:
- Hourglass swing made much more damped: reduced startup omega, reduced max angle, stronger damping in normal and flip phases.
- Reduced post-flip impulse and edge rebound to avoid visible overshoot/oscillation.
- Reset detection hardened (dynamic min progress threshold + wider near-zero window) and flip restart is now always forced on reset edge.
- 10s flip/rotation path kept unchanged (
kHourglassFlipDurationMs=10000).
- Validation:
- Build PASS:
pio run -e freenove_esp32s3. - Flash PASS:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301.
- Build PASS:
- Notes:
- No FS changes in this pass (
uploadfsnot required).
- No FS changes in this pass (
2026-02-27 21:32 — LA detector flip lock during active 10s animation (Codex)
- Scope:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp
- Change:
- Reset-triggered flip now arms only when
!la_hg_flipping_, preventing relaunch while a 10s flip is already running. - No post-flip cooldown added (new flip allowed immediately after animation end).
- Reset-triggered flip now arms only when
- Validation:
- Build PASS:
pio run -e freenove_esp32s3. - Flash PASS:
pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301.
- Build PASS:
- Notes:
- No FS/story data changes in this pass.
[2026-02-27] Hotline MP3 etat-jeu + synchro scene Freenove->A252 (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260227_214828_wip.patch/tmp/zacus_checkpoint/20260227_214828_status.txt
- Scope execute:
- A252 (
hardware/RTC_SLIC_PHONE/src/main.cpp):- ajout contexte hotline runtime
scene/step/validation_state(none|waiting|granted|refused); SCENEaccepte maintenant JSON enrichi (id/scene_id,step_id,validation_state) et met a jour le contexte;WAITING_VALIDATIONroute un prompt MP3 contextualise avec fallback (enter_code_5);HOTLINE_VALIDATEmet a jour l'etat validation et choisit des cues MP3 contextualises (granted/refused) avec fallback;HOTLINE_TRIGGER 1/2/3tente d'abord des MP3 d'indice contextuels scene+etat, puis fallback sur map hotline WAV existante;STATUS+HOTLINE_STATUSexposentactive_stepethotline_validation_state.
- ajout contexte hotline runtime
- Freenove (
hardware/firmware/ui_freenove_allinone/src/app/main.cpp):- synchro automatique de contexte hotline a chaque changement de scene via ESP-NOW:
- payload
SCENE {"id","step_id","validation_state"}; validation_stateinfere depuisstep_id/screen_scene_id(waiting/granted/refused/none).
- payload
- synchro automatique de contexte hotline a chaque changement de scene via ESP-NOW:
- Doc A252 (
hardware/RTC_SLIC_PHONE/README.md) mise a jour pour le contrat scene/hotline contextualise.
- A252 (
- Validation effectuee:
- Build:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> SUCCESSpio run -e freenove_esp32s3-> SUCCESS
- Flash:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> SUCCESSpio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301-> SUCCESS
- Smoke serie A252:
SCENE {"id":"SCENE_LA_DETECTOR","step_id":"RTC_ESP_ETAPE1","validation_state":"waiting"}-> JSONvalidation_state=waitingHOTLINE_STATUS-> exposescene,step,validation_stateSCENE {"id":"SCENE_WARNING","step_id":"STEP_WARNING"}-> JSONvalidation_state=refusedWAITING_VALIDATION->OK WAITING_VALIDATION
- Smoke serie Freenove:
SCENE_GOTO SCENE_WARNING-> logHOTLINE_SYNC scene=SCENE_WARNING step=STEP_WARNING validation=refused ok=1.
- Note bench dual-board:
HOTLINE_STATUScote A252 restescene=""sur ce run; necessite verification radio/channel peer en conditions E2E ESPNOW pour confirmer la reception live de la synchro scene.
- Build:
[2026-02-28] HOT-LINE MP3 etat/scene: contextualisation WAITING_VALIDATION (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_005032_wip.patch/tmp/zacus_checkpoint/20260228_005032_status.txt
- Scope execute:
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- enrichissement automatique du payload
WAITING_VALIDATIONvers:WAITING_VALIDATION {"scene_id":"...","step_id":"...","validation_state":"waiting"}
- conserve le format legacy
WAITING_VALIDATION(non-breaking).
- enrichissement automatique du payload
hardware/RTC_SLIC_PHONE/src/main.cppWAITING_VALIDATIONaccepte maintenant les args JSON scene/step/validation.- mise a jour du contexte hotline (
g_active_scene_id,g_active_step_id) avant resolution route MP3. - route toujours forcee sur l'etat
waitingpour cette commande.
hardware/RTC_SLIC_PHONE/README.md- doc de la variante
WAITING_VALIDATION {...}.
- doc de la variante
- Validation effectuee:
- Build Freenove PASS:
pio run -e freenove_esp32s3 - Build A252 PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev
- Build Freenove PASS:
[2026-02-28] Hotline ringback 2s + debug lecture MP3 telephone (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_022430_wip.patch/tmp/zacus_checkpoint/20260228_022430_status.txt
- Checkpoint securite (lot suivant):
/tmp/zacus_checkpoint/20260228_023407_wip.patch/tmp/zacus_checkpoint/20260228_023407_status.txt
- Objectif lot:
- forcer provisoirement la sonnerie/ringback hotline a 2 secondes;
- corriger la lecture MP3 A252 (priorite SD) quand le telephone est en appel hotline.
- Modifications appliquees:
hardware/RTC_SLIC_PHONE/src/main.cpp- ringback hotline force a 2s (temporaire).
- rescan du catalogue de suffixes voix quand la SD devient disponible apres boot.
- fallback de routage hotline vers
scene_route(MP3 de scene) avantdial_mapWAV si les hints ne sont pas trouves. - montage SD pour scan hotline/
FS_LISTavec fallback SPI (pins A1S) siSD_MMCechoue. - log hotline SD numerote dans
/hotline/log.txt(events route/ringback/sync/errors) pour debug terrain. - fallback MP3 global (
default_voice_fallback) si scene/hints indisponibles (evite silence sur numerotation). - couverture scene->stem hotline ajoutee pour
SCENE_CREDITSetSCENE_POLICE_CHASE_ARCADE.
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpp- remount SD/LittleFS avec retry periodique (au lieu d'un seul essai au boot).
- fallback montage SD en SPI (
SD.begin(...)) quandSD_MMC.begin()echoue.
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.h- pointeur
sd_fs_pour ouvrir les medias SD sur backend actif (SD_MMCouSDSPI).
- pointeur
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- commande ESP-NOW
UI_SCENE_STATUSexposee dans l'ack JSON (scene_id,step_id,validation_state) pour synchronisation hotline A252.
- commande ESP-NOW
- Validation executee:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev. - Flash PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001. - Build/flash Freenove PASS:
pio run -e freenove_esp32s3pio run -e freenove_esp32s3 -t upload --upload-port /dev/cu.usbmodem5AB90753301
- Runtime:
HOTLINE_TRIGGER 1-> logringback ... duration_ms=2000.FS_LIST {"source":"sd","path":"/hotline","page_size":200}-> OK (count=116,mp3=100), SD accessible.AUDIO_PROBE sd:/hotline/fiches-hotline_2__fr-fr-deniseneural.mp3-> OK (decodage MP3 valide).SCENE {"id":"SCENE_U_SON_PROTO"...}->audio_started=trueavec route MP3 SD./hotline/log.txtdetecte sur SD et taille incrementee apres numerotation hotline (evidence debug).
- Build PASS:
[2026-02-28] Hotline scene list explicite (U_SON/LA/WIN/WARNING/QR/LEFOU/POLICE/CREDITS) (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_025723_wip.patch/tmp/zacus_checkpoint/20260228_025723_status.txt
- Modifications:
hardware/RTC_SLIC_PHONE/src/main.cpp- ajout d'une table explicite
scene_key -> stempour:SCENE_U_SON_PROTOSCENE_LA_DETECTORSCENE_WIN_ETAPESCENE_WARNINGSCENE_CREDITSSCENE_WIN_ETAPE1SCENE_WIN_ETAPE2SCENE_QR_DETECTORSCENE_LEFOU_DETECTORSCENE_POLICE_CHASE_ARCADE
- lookup explicite applique avant les fallbacks historiques.
- ajout d'une table explicite
hardware/RTC_SLIC_PHONE/README.md- documentation de la table de mapping scene hotline.
- Validation:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev-> SUCCESS.
[2026-02-28] Upload A252 apres mapping scenes hotline (agent)
- Flash execute:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001-> SUCCESS.
- Verification serie immediate:
STATUSlu sur/dev/cu.usbserial-0001(115200) -> firmware repondu,espnow.scene_sync_enabled=true,active_scene=""au boot.
[2026-02-28] Triage qualite audio MP3 hotline (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_031139_wip.patch/tmp/zacus_checkpoint/20260228_031139_status.txt
- Diagnostic runtime:
AUDIO_PROBE sd:/hotline/fiches-hotline_2__fr-fr-deniseneural.mp3remontait:input_sample_rate=24000,output_sample_rate=22050,resampler_active=true.
- Pendant
PLAY ...mp3: spam erreurs[E] ResampleStream.h : 191 - write error 0 vs ...(artefacts audio).
- Cause racine:
- 24 kHz n'etait pas considere stable dans
kStableRatesHz; la chaine forçait un resampling inutile24k -> 22.05k.
- 24 kHz n'etait pas considere stable dans
- Correctif:
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpp- ajout de
24000danskStableRatesHzpour eviter le resampling inutile des prompts TTS hotline.
- ajout de
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev. - Flash PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001. AUDIO_PROBEapres fix:input_sample_rate=24000,output_sample_rate=24000,resampler_active=false.
- Re-test
PLAY ...mp3sur meme fichier: plus de logsResampleStream write error.
- Build PASS:
[2026-02-28] A252 MP3 white-noise triage - decoder pacing + fixed I2S output rate lock
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_035946_wip.patch/tmp/zacus_checkpoint/20260228_035946_status.txt
- Skills utilises:
rtc-audio-stackfirmware-embedded-audio-player-expertrtc-a252-bitrate-adaptiveesp32-audio-runtime-gating- nouveau skill cree:
~/.codex/skills/compressed-audio-decoder-libs/SKILL.md
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpp- ajout stockage bitrate MP3 parse (
playback_mp3_bitrate_bps_) pour timing de chunk MP3, - pacing MP3 corrige: calcul delay base sur bitrate compresse (bits/s),
- reset bitrate MP3 sur init/stop,
- lock format sortie A252 sur sample rate I2S base (
_config.sample_rate) pour stabilite ES8388, - log decode MP3 enrichi avec bitrate detecte.
- ajout stockage bitrate MP3 parse (
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.h- ajout champ runtime
playback_mp3_bitrate_bps_.
- ajout champ runtime
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev - Flash PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001 - Commandes runtime envoyees:
TONE_STOP,PLAY sd:/hotline/fiches-hotline_2__fr-fr-deniseneural.mp3->OK. - Etat observe ensuite:
hook=ON_HOOK, donc playback auto-stop conforme policy on-hook. - Watch OFF_HOOK 45s lance pour auto-play direct: timeout (pas de decroche pendant la fenetre).
- Build PASS:
[2026-02-28] A252 MP3 white-noise hotfix follow-up (resampler error loop)
- Symptom observee sur banc:
ResampleStream write error 0 vs ...en boucle pendant lecture hotline,STATUS.audio:playback_input_sample_rate=24000,playback_output_sample_rate=8000,playback_resampler_active=true.
- Cause:
- lock sortie I2S a 8 kHz sur A252 forcait un resampling MP3 24k->8k et degradait la chaine.
- Correctif applique:
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpp- suppression du lock force 8k dans
resolvePlaybackFormat(...), retour policy HYBRID_TELCO (24k stable conserve), - conservation du fix pacing MP3 base bitrate.
- suppression du lock force 8k dans
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev - Flash PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001 - Runtime (serial):
HOTLINE_TRIGGER 2-> logs:mp3 header parsed ... out_sr=24000 ... resampler=falseplay mp3 from SD ...
- Build PASS:
[2026-02-28] A252 MP3 white-noise deep triage v2 (agent)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_042005_wip.patch/tmp/zacus_checkpoint/20260228_042005_status.txt
- Scope cible:
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpphardware/RTC_SLIC_PHONE/src/audio/AudioEngine.hhardware/RTC_SLIC_PHONE/src/audio/AudioOutput.*(si necessaire)
- Objectif:
- eliminer bruit blanc en lecture MP3 SD avec verification decode->buffer->I2S,
- conserver policy: stop playback immediat ON_HOOK.
[2026-02-28] A252 switch MP3 decode path to ESP8266Audio
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_044901_wip.patch/tmp/zacus_checkpoint/20260228_044901_status.txt
- Scope:
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpphardware/RTC_SLIC_PHONE/src/audio/AudioEngine.hhardware/RTC_SLIC_PHONE/platformio.ini
- Actions:
- remplacement du decodeur MP3 Helix AudioTools par
AudioGeneratorMP3(ESP8266Audio) sur la pile A252, - ajout d'un bridge
AudioOutputESP8266Audio -> pipeline AudioTools (resample/channel-convert/volume existants), - activation de la dependance
earlephilhower/ESP8266Audiosur les env A252.
- remplacement du decodeur MP3 Helix AudioTools par
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev.
- Build PASS:
[2026-02-28] A252 MP3 playback verification crash (ESP8266Audio path)
- Actions:
- Flashed
hardware/RTC_SLIC_PHONEon A252 (esp32dev, port/dev/cu.usbserial-0001). - Verified SD catalog with
FS_LISTunder/hotline_tts/SCENE_U_SON_PROTO(MP3 files present). - Forced MP3 playback test:
PLAY sd:/hotline_tts/SCENE_U_SON_PROTO/attente_validation_mystere_denise.mp3.
- Flashed
- Evidence:
- Decoder start log observed:
mp3 header parsed sr=22050 ch=1 bits=16 bitrate=64000. - Immediate runtime crash after
OK PLAY:Guru Meditation Error: Core 1 panic'ed (LoadProhibited)followed by reboot.
- Decoder start log observed:
- Status:
- STOP condition raised (
build/test regression not fixed quickly). - See
docs/STOP_REQUIRED.mdfor required decision.
- STOP condition raised (
[2026-02-28] A252 hotline routing updated for WAV-first assets (pcm_s16le 8k/16-bit)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_115512_wip.patch/tmp/zacus_checkpoint/20260228_115512_status.txt
- Scope:
hardware/RTC_SLIC_PHONE/src/main.cpp
- Actions:
- route resolution
hotline_tts/SCENE_*now expands each requested filename to WAV-first candidates, then MP3 fallback, - keeps compatibility with legacy MP3 names while preferring
.wavlookups for all waiting/validation/hint prompts. - hotspot fix: hotline ESP-NOW notify payload now auto-compacts (short keys + reduced route fields, minimal fallback) to stay under 240 bytes.
- route resolution
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev - Flash PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001 - Serial boot PASS (115200): audio init OK, interlude scheduler active, Web server started.
- Runtime probe PASS:
HOTLINE_TRIGGER 2resolved a WAV prompt route (/hotline_tts/SCENE_U_SON_PROTO/indice_2_mystere_eloise.wav), confirming WAV-first lookup. - Runtime probe PASS: no more
EspNowBridge send rejected: payload too largeonringback/stopped_hangupnotifications.
- Build PASS:
[2026-02-28] Freenove SCENE_WARNING stack canary retest (post-stack trim)
- Scope:
hardware/firmware/ui_freenove_allinone/src/app/main.cpphardware/firmware/ui_freenove_allinone/src/system/network/network_manager.cpp
- Actions:
- warning remote siren sync now gates on ESP-NOW runtime readiness (no hard dependency on peer cache count),
- ESP-NOW send path now retries once on transient internal/interface/channel-ish errors by re-enabling ESP-NOW + channel hint.
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Flash PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Serial runtime probe:
SCENE_GOTO SCENE_WARNINGnow runs without panic/canary markers (PANIC_MARKERS 0over ~18s). - Cross-board warning sync PASS:
- Freenove log:
[WARN_SIREN] remote start(noESP-NOW send failedspam in this run). - A252
HOTLINE_STATUSat t+2/t+5/t+8 after trigger:warning_siren_enabled=true,warning_siren_tone_owned=true.
- Freenove log:
- Build PASS:
- Residual note:
- none blocking in this pass (warning siren sync + scene sync both observed end-to-end).
[2026-02-28] A252 WAV hotline stability pass (direct PCM fallback) + WIN_ETAPE WAV auto-440 scope
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_140551_wip.patch/tmp/zacus_checkpoint/20260228_140551_status.txt
- Skills utilises:
rtc-audio-stackfirmware-espnow-stack
- Correctifs appliques:
hardware/RTC_SLIC_PHONE/src/main.cpp- armement busy-tone + auto-440 WIN_ETAPE generalise aux medias hotline
.wavet.mp3(plus uniquement MP3), - helper media path:
isWavMediaPath()+isPlayableMediaPath().
- armement busy-tone + auto-440 WIN_ETAPE generalise aux medias hotline
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.h- ajout flag runtime
playback_wav_direct_mode_.
- ajout flag runtime
hardware/RTC_SLIC_PHONE/src/audio/AudioEngine.cpp- adoucissement pression write WAV (
kPlaybackCopyRetryCount=24, retries bloquees bornees), BlockingOutput::availableForWrite()force un budget ecriture (evite abort pre-check sur backpressure transitoire),- policy format playback: canaux de sortie alignes sur source (mono WAV conserve),
- mode direct PCM16 pour WAV non-resample/non-upmix (bypass
StreamCopy/WAVDecoderquand applicable), - reset propre
playback_wav_direct_mode_au stop.
- adoucissement pression write WAV (
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev. - Flash PASS (plusieurs iterations):
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001. - Serie PASS (route):
WAITING_VALIDATION {"scene_id":"SCENE_WIN_ETAPE","validation_state":"waiting"}-> resolution explicite stem WAV scene (attente_validation_*.wav).PLAY sd:/hotline_tts/SCENE_WIN_ETAPE/attente_validation_*.wav-> parse WAV OK + sortie routee.
- Limite de banc actuelle:
- verification complete en condition
OFF_HOOKde la chaine finale (ringback -> media -> ACK auto-440) reste a confirmer sur run telephonique complet; banc observe majoritairementON_HOOKpendant cette passe.
- verification complete en condition
- Build PASS:
[2026-02-28] Upload lot complet demande utilisateur (Freenove + A252)
- Freenove code upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301
- Freenove FS upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301
- A252 code upload PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001
- A252 FS upload execute:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t uploadfs --upload-port /dev/cu.usbserial-0001- Note: build SPIFFS a affiche
File system is fullpendant generation image (contenu depasse la partition), puis image partielle ecrite avec succes.
[2026-02-28] A252 hotline trigger priority fix (pending WAITING override)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_143037_wip.patch/tmp/zacus_checkpoint/20260228_143037_status.txt
- Skill utilise:
rtc-audio-stack
- Correctifs:
hardware/RTC_SLIC_PHONE/src/main.cpp- ajout
clearPendingEspNowCallRoute()pour nettoyer la route answer en attente, - appel de ce nettoyage dans
triggerHotlineRouteForDigits()pour forcer la priorite duHOTLINE_TRIGGERsurWAITING_VALIDATION.
- ajout
- maintien du matching
indice_1*deja corrige dans le resolver stem scene (SCENE_*).
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev. - Upload PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001. - Serie PASS:
WAITING_VALIDATION {"scene_id":"SCENE_LA_DETECTOR","validation_state":"waiting"}HOTLINE_TRIGGER 1- evidence: log
pending espnow route cleared reason=dial_trigger ...puis lecture WAV finale.../indice_1_*.wav(plus de replay route attente via answer callback).
- Build PASS:
[2026-02-28] Freenove U_SON ambient random playlist continuous
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_143903_wip.patch/tmp/zacus_checkpoint/20260228_143903_status.txt
- Correctif:
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- U_SON_PROTO: forçage playlist random
/music/v8_packavec cadence continue (delay_min_ms=1000,delay_max_ms=2000) pour couvrir toute la scene sans trou long.
- U_SON_PROTO: forçage playlist random
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui. - Upload Freenove: FAIL (port occupe) sur
/dev/cu.usbmodem5AB90753301.
- Build PASS:
[2026-02-28] A252 volume normal (suppression forcage max)
- Correctifs:
hardware/RTC_SLIC_PHONE/src/main.cpp- ajout constante
kA252CodecNormalVolumePercent=70, - remplacement du forcage volume 100 -> 70 dans
ensureA252AudioDefaults, - remplacement du forcage
VOLUME_SET100 -> 70, - maintien gain logiciel neutre (
[AudioEngine] playback boost set to 1.00x + software 1.00x).
- ajout constante
hardware/RTC_SLIC_PHONE/src/config/A252ConfigStore.h- volume par defaut passe de 100 -> 70.
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev. - Upload PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001. - Serie PASS:
VOLUME_GET->{"volume":70}.
- Build PASS:
[2026-02-28] A252 rollback volume (retour son comme avant)
- Demande utilisateur: restaurer le comportement sonore precedent.
- Correctifs:
hardware/RTC_SLIC_PHONE/src/main.cpp- retour forçage volume A252 a
100(kA252CodecMaxVolumePercent), ensureA252AudioDefaults()repasse en cible100,VOLUME_SETrepasse en forçage100.
- retour forçage volume A252 a
hardware/RTC_SLIC_PHONE/src/config/A252ConfigStore.h- valeur par defaut
volume = 100.
- valeur par defaut
- Validation:
- Build PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev. - Upload PASS:
pio run -d hardware/RTC_SLIC_PHONE -e esp32dev -t upload --upload-port /dev/cu.usbserial-0001. - Serie PASS:
VOLUME_GET->{"volume":100}.
- Build PASS:
[2026-02-28 17:44] Freenove FX all-scenes + scroll text
- Scope: SCENE_* forced to LGFX/FX runtime (LVGL text disabled in scene runtime path).
- Alias parity: SCENE_CREDIT handled as credits timeline/preset path.
- Scroll policy: fallback scroll text enabled for every scene (subtitle/title, fallback message).
- Build gate: pio run -e freenove_esp32s3_full_with_ui => SUCCESS.
- Flash: pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 => SUCCESS.
[2026-02-28 17:51] Credits: StarWars immediate + no LVGL text scroll
- Scene credits path now enters StarWars crawl immediately (no boot/holo pre-phases for SCENE_CREDITS/SCENE_CREDIT).
- Credits elapsed base adjusted to start from scene time 0 to avoid delayed/wrapped crawl.
- Serial evidence after flash:
ACK SCENE_GOTO ok=1forSCENE_CREDITSUI_SCENE_STATUS:scene_id=SCENE_CREDITS,text_backend=lgfx_overlay,lvgl_text_disabled=true
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301
[2026-02-28 18:00] Credits scroll direction audit + StarWars crawl correction
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_175454_wip.patch/tmp/zacus_checkpoint/20260228_175454_status.txt
- Audit code:
- sens vertical credits explicite en
bottom -> topviakCreditsScrollDirectionY=-1. - projection Y StarWars passee en quadratique (compression vers horizon) pour eviter un simple scroll lineaire.
- scroller horizontal FX desactive pour
SCENE_CREDITS/SCENE_CREDIT(texte StarWars uniquement).
- sens vertical credits explicite en
- Fichiers modifies:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpphardware/firmware/ui_freenove_allinone/src/ui/ui_manager_effects.cpp
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Serial PASS:
ACK SCENE_GOTO ok=1onSCENE_CREDITSUI_SCENE_STATUS:scene_id=SCENE_CREDITS,text_backend=lgfx_overlay,lvgl_text_disabled=true
- Build PASS:
[2026-02-28 18:38] Credits StarWars text visibility hardening (LGFX overlay)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_183054_wip.patch/tmp/zacus_checkpoint/20260228_183054_status.txt
- Correctifs:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cppsceneStatusSnapshot()renvoie des compteurs overlay live (overlay_draw_ok/fail/startwrite/skip) pour debug reel.- Credits StarWars: bascule des lignes en fonts built-in LGFX pour robustesse d'affichage.
- Ajout fallback: si aucune ligne du crawl n'est visible sur la frame, affichage d'une ligne credits de secours (centre bas) pour eviter ecran texte vide.
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Serie PASS:
ACK SCENE_GOTO ok=1surSCENE_CREDITUI_SCENE_STATUSmontrescene_id=SCENE_CREDITS,text_backend=lgfx_overlay- compteurs overlay progressent (
overlay_draw_ok: 9 -> 65,overlay_draw_fail: 0)
- Build PASS:
[2026-02-28 19:42] Credits StarWars effet renforce (perspective + inclinaison visuelle)
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_193417_wip.patch/tmp/zacus_checkpoint/20260228_193417_status.txt
- Correctifs:
hardware/firmware/ui_freenove_allinone/src/ui/ui_manager.cpp- horizon remonte (
height/5) pour accentuer la fuite perspective. - couleur crawl forcee en jaune StarWars (
0xFFD34A) en mode credits. - projection verticale passe en cubique (compression plus marquee vers l'horizon).
- squeeze horizontal renforce + couloir top plus etroit.
- ajout d'un tilt vertical par glyph (bords legerement releves) pour un rendu plus "crawl cinema".
- horizon remonte (
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload PASS:
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - Serie PASS:
ACK SCENE_GOTO ok=1surSCENE_CREDITUI_SCENE_STATUS:scene_id=SCENE_CREDITS- overlay actif (
overlay_draw_ok: 1 -> 38,overlay_draw_fail: 0)
- Build PASS:
[2026-02-28 20:14] Boot credits direct + audio SCENE_WIN force loop
- Checkpoint securite:
/tmp/zacus_checkpoint/20260228_195154_wip.patch/tmp/zacus_checkpoint/20260228_195154_status.txt
- Correctifs:
hardware/firmware/ui_freenove_allinone/src/app/main.cpp- boot story par defaut route sur
SCENE_CREDITS. - helper credits ajoute (
isCreditsSceneId,playCreditsWinTrack,isCreditsWinTrackPath). ACTION_QUEUE_SONARen scene credits joue prioritairementSCENE_WIN.mp3.- garde credits audio: si piste non credits (ex: boot_radio), stop + force
SCENE_WIN.mp3. - boucle credits conservee entre
SCENE_CREDITSetSCENE_CREDITavec relance piste credits.
- boot story par defaut route sur
- Validation:
- Build PASS:
pio run -e freenove_esp32s3_full_with_ui - Upload firmware PASS (avant deconnexion USB):
pio run -e freenove_esp32s3_full_with_ui -t upload --upload-port /dev/cu.usbmodem5AB90753301 - UploadFS PASS:
pio run -e freenove_esp32s3_full_with_ui -t uploadfs --upload-port /dev/cu.usbmodem5AB90753301 - Serie PASS (evidence):
[BOOT] route default scene=SCENE_CREDITS ok=1[MAIN] credits boot audio scene=SCENE_CREDITS track=/music/SCENE_WIN.mp3 source=forced prev=/music/boot_radio.mp3AUDIO_STATUS ... track=/music/SCENE_WIN.mp3 ...
- Dernier upload TENTATIVE FAIL: port
/dev/cu.usbmodem5AB90753301disparu (USB non detecte au moment de la commande).
- Build PASS: