Commit Graph

514 Commits

Author SHA1 Message Date
electron a5ebf7c68c Merge pull request 'feat(atelier): P1 — génération de texte (IA) via ailiance' (#126) from feat/p1-text-gen-ailiance into main
Validate Zacus refactor / validate (push) Successful in 11m0s
Repo State / repo-state (push) Failing after 28s
Validate Zacus refactor / validate (pull_request) Successful in 11m14s
Repo State / repo-state (pull_request) Failing after 12m23s
2026-06-13 14:53:10 +00:00
clement c5db426bec feat(atelier): P1 — génération de texte (IA) via gateway.ailiance.fr
Repo State / repo-state (push) Failing after 33s
Repo State / repo-state (pull_request) Failing after 30s
Validate Zacus refactor / validate (pull_request) Failing after 17m17s
Gateway : POST /v1/assets/text/generate (sans token, même origine) proxie le
LLM ailiance (OpenAI-compatible) avec un system-prompt par type — npc_reply,
hint, scene_text, freeform. Setting ailiance_url (défaut gateway.ailiance.fr).

Atelier : panneau flottant « Générer (IA) » (TextGenPanel) — choix du type,
prompt, génération, aperçu, copier. Client lib/textgen.ts (même URL gateway
que share/deploy, donc même origine en prod → zéro CORS).

Validé : POST .../v1/assets/text/generate → réplique NPC / indice en personnage
(modèle Ministral-14B via ailiance). Bundle prod câblé sur zacus.saillant.cc/api.
Première tranche du plan specs/2026-06-13-atelier-asset-authoring-plan.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 16:52:45 +02:00
clement e806fc9634 docs(specs): plan phasé — édition & génération d'assets depuis l'Atelier
Repo State / repo-state (push) Failing after 27s
Validate Zacus refactor / validate (push) Successful in 10m55s
Plan de projet (P0–P5) pour éditer/générer écran, audio et fichiers SD/NFS
depuis l'Atelier web, avec ponts firmware et génération assistée
(gateway.ailiance.fr pour le texte). Inclut l'audit du pipeline d'assets
existant, dépendances entre phases, risques, et chemin web/firmware séparés.

NB: la fondation firmware audio (P4 : playback WAV/MP3, montage SD) est
désormais livrée côté ESP32_ZACUS — voir bump submodule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 16:46:13 +02:00
clement 3e75632486 chore: bump ESP32_ZACUS — P4 audio (WAV/MP3/SD) + box3 fixes
Repo State / repo-state (push) Failing after 22s
Validate Zacus refactor / validate (push) Successful in 11m8s
Avance le submodule ESP32_ZACUS vers main (7f52d3d), qui intègre :
- #8 box3 : SPIFFS label + canal WiFi configurable (relais ESP-NOW).
- #9 P4 : media_manager vrai playback WAV/MP3 (helix), endpoint
  /game/media/play, montage microSD /sdcard, branchement media+/game/file
  sur la SD, mutex I2S TTS↔musique, FATFS LFN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 16:45:37 +02:00
clement b76f2d3c98 fix(scenario): zacus_v3 valide — act/objective/firmware_step sur les 3 puzzles
Repo State / repo-state (push) Failing after 12m35s
Validate Zacus refactor / validate (push) Successful in 17m26s
Les puzzles de zacus_v3.yaml n'avaient ni `act`, ni `objective`, ni
`firmware_step` (requis par le validateur schema V2). Ajout calqué sur
zacus_v2 : Diapason→acte 1, Piano LEFOU→acte 2, QR Archives→acte 2 ;
valeurs déduites du contenu existant (scène, runtime_steps, solution).
Le scénario valide, compile et simule désormais le playthrough complet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 13:07:45 +02:00
electron 54b8d2a9f9 Merge pull request 'Atelier : barre de menu — ouvrir/charger/enregistrer/partager' (#125) from feat/atelier-menubar-share into main
Repo State / repo-state (push) Failing after 25s
Validate Zacus refactor / validate (push) Successful in 11m29s
2026-06-13 10:58:36 +00:00
clement b05264aafe feat(atelier): barre de menu — ouvrir/charger/enregistrer/partager un scénario
Repo State / repo-state (push) Failing after 41s
Repo State / repo-state (pull_request) Failing after 6m58s
Validate Zacus refactor / validate (pull_request) Successful in 11m13s
Ajoute une barre de menu en haut de l'Atelier :
- Ouvrir : menu déroulant de 3 scénarios de départ embarqués (format
  blocks_studio v2) — intro+énigme sonore, maître du jeu adaptatif,
  énigmes→coffre.
- Charger / Enregistrer : import depuis / export vers un fichier .yaml local.
- Partager : publie le scénario sur la gateway et copie un lien court ?s= ;
  useShareLink réimporte automatiquement le scénario au chargement du lien.

Gateway : endpoints publics sans token POST/GET /v1/share (taille plafonnée,
YAML validé), adossés à un store fichier (share-store/).

Corrige aussi l'inlining de VITE_GATEWAY_BASE_URL : accès statique
import.meta.env pour que le build prod vise la vraie gateway
(zacus.saillant.cc/api) — ce qui répare au passage le DeployPanel en prod.
Le build web prod utilise désormais un mode Vite dédié `webdeploy`
(.env.webdeploy) pour ne pas polluer le bundle desktop.

Ajoute ops/deploy-frontend.sh (typecheck → build → tar-over-ssh → reload →
vérif du hash live), le déploiement n'étant pas scripté jusqu'ici.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:53:57 +02:00
electron 2ecad365d1 Merge pull request 'Atelier: blocs Scratch complets (41 to 68) + runner Runtime 3' (#124) from feat/atelier-scratch-blocks into main
Repo State / repo-state (push) Failing after 30s
Validate Zacus refactor / validate (push) Successful in 10m58s
2026-06-13 00:18:20 +00:00
electron 6dd78b3a69 feat(atelier): vagues 3+4 — énigmes manquantes + assemblage code/coffre
Repo State / repo-state (push) Failing after 23s
Repo State / repo-state (pull_request) Failing after 33s
Validate Zacus refactor / validate (pull_request) Successful in 11m37s
Vague 3 (énigmes, catalogue 59→68) : puzzleLED (P2), puzzleRadio (P4),
puzzleMorse (P5), puzzleNFC (P6), puzzleCoffre/keypad (P7), + hwNFCRead.
Types puzzle IR: led, radio, morse, nfc, keypad (validation firmware-miroir).

Vague 4 (catégorie Coffre) : codeAssembly (fragments→code final),
codeFragment (puzzle→positions), coffreVerify. Kinds IR: nfc_read,
code_assembly, code_fragment, coffre_verify.

Le scénario zacus_v3_complete est désormais entièrement exprimable en blocs.

Validé: catalogue 68/68 cohérent, build atelier OK, round-trip gateway +
validation runtime3 (happy path + négatifs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 02:15:05 +02:00
electron 1f524a1ed7 feat(scenario-engine): runner d'exécution Runtime 3 (eval + loop + pilotage firmware)
Repo State / repo-state (push) Failing after 56s
Rend l'IR réellement jouable (avant: simulateur partiel, conditions opaques) :
- expr-eval.ts: parser réel (tokeniser + descente récursive, sans eval())
  pour la grammaire des conditions (comparaisons, and/or/not, arith, vars)
- runner.ts: exécute loop (repeat/while bornés), condition then/else,
  transitions branch/condition triées par priorité
- firmware-driver.ts: pilotage live du master via HTTP (pushScenario
  /game/scenario, armStep /game/step, getPuzzleState, setGroupProfile),
  fetch injecté pour testabilité
- runtime-ir.ts: types TS miroir de runtime3_common.py

Validé: 55 tests (18 existants + 37 nouveaux), build tsc strict OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 01:57:41 +02:00
electron a85f39ba9a feat(atelier): vague 2 — blocs « Maître du jeu » (game-master adaptatif)
8 blocs pour la couche adaptative du scénario (catalogue 51→59) :
phase, gmRule (condition→proactive_hint/skip_to_next/add_bonus_puzzle),
npcSetMood, giveHint (niveau), proactiveHint (intervalle), setParcours
(profil→puzzles), scoreBonus (conditionnel), scorePenalty.
gmRule/scoreBonus réutilisent les reporters de la vague 1.
Nouveaux kinds IR: gm_phase, gm_rule, npc_mood, give_hint, proactive_hint,
set_parcours, score_bonus, score_penalty (+ validation runtime3_common).

Validé: catalogue 59/59 cohérent, build atelier OK, round-trip gateway OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 01:57:41 +02:00
electron 4d169bb990 feat(atelier): vague 1 — blocs Scratch opérateurs/expressions + contrôle
Repo State / repo-state (push) Failing after 43s
Ajoute 10 blocs pour rendre les conditions composables (avant: chaînes
opaques tapées à la main) :
- Reporters: opCompare, opBool, opNot, opArith, valVar, valScore,
  valNumber, valText → sérialisés vers la grammaire d'expression existante
  (ex: "score > 5", "(pct >= 60) and (lives > 0)")
- Contrôle: loopRepeat, loopWhile (nouveau kind IR "loop")
- logicIf/sceneBranch acceptent un reporter branché OU le champ texte
  (rétrocompat totale)

Catalogue 41→51 blocs, catégories Opérateurs + Contrôle. Compilateur
gateway (_reporter_to_expr) miroir du serializeReporter() TS. Hub
Blockly régénéré.

Validé: build atelier OK, 18 tests scenario-engine, round-trip
bloc→IR (reporters + loops + rétrocompat).

NB: le kind IR "loop" exige un support firmware runtime3 (à ajouter
dans une passe firmware) ; les conditions sont déjà évaluées par le
firmware existant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 01:41:24 +02:00
electron fcba0cd310 Merge pull request 'Merge hotload-hub: atelier scene/puzzle blocks + firmware ESP-NOW (sauvegarde claude2)' (#123) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 24s
Validate Zacus refactor / validate (push) Successful in 10m53s
2026-06-12 22:57:15 +00:00
electron b0fc2769d7 docs(gateway): marquer flash_bridge.sh obsolète (collision réseau résolue)
Repo State / repo-state (push) Failing after 28s
Validate Zacus refactor / validate (push) Successful in 11m0s
Diagnostic réseau electron-server (2026-06-12) : la collision 192.168.0.0/20
qui justifiait le contournement n'existe plus. Les ESP sont en LAN 10.2.5.x,
aucun réseau Docker ne capture 10.2.x, et le conteneur gateway (réseau traefik)
route vers 10.2.x via l'hôte. /v1/flash/{board} doit marcher en direct quand la
carte est sous tension. À confirmer par un flash réel puis supprimer le script.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 23:01:37 +02:00
electron fb860238b3 docs: corriger incohérences README + boards.yaml (audit liaison webapp↔firmware)
Repo State / repo-state (push) Failing after 35s
Validate Zacus refactor / validate (push) Successful in 11m32s
Le README et boards.yaml pointaient un canon périmé. Réalité (audit 2026-06-12) :
- canon = frontend-v3/apps/atelier (pnpm+turbo) + ESP32_ZACUS/idf_zacus (ESP-IDF)
  + gateway tools/zacus-gateway (:8400) + scénario zacus_v3_complete.yaml
- frontend-scratch-v2 et hardware/firmware (Arduino freenove) = legacy
- boards.yaml: /game/scenario EST implémenté (game_endpoint.c), commentaire 502 obsolète

Corrections documentaires uniquement, aucun changement de code/comportement.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 22:37:01 +02:00
Claude Worker claude2 2779dc892a chore: bump ESP32_ZACUS (canal espnow CMD/EVT)
Repo State / repo-state (push) Failing after 23s
Repo State / repo-state (pull_request) Failing after 35s
Validate Zacus refactor / validate (pull_request) Successful in 10m55s
2026-06-11 05:47:20 +02:00
Claude Worker claude2 7dc42b7965 docs: spec ESP-NOW commandes/evenements v1 2026-06-11 05:41:10 +02:00
Claude Worker claude2 ac2fa5c2b0 chore: bump ESP32_ZACUS (espnow peers + UAF) 2026-06-11 05:18:55 +02:00
Claude Worker claude2 62eeaa016d test(blocks): export des 4 blocs ESP-NOW
Couvre le mapping blocs->actions IR (register_peer/send/broadcast/
wait + timeout_ms), le defaut 10 s, et la legalite en slot logicIf.
2026-06-11 05:09:05 +02:00
Claude Worker claude2 083bf5a35a chore: bump ESP32_ZACUS (fix horloge intro) 2026-06-11 05:03:04 +02:00
Claude Worker claude2 5f2ad757d4 chore: bump ESP32_ZACUS (pool FX 3D complet) 2026-06-11 04:54:17 +02:00
Claude Worker claude2 c7068380f3 chore: bump ESP32_ZACUS (FX 3D + log P1) 2026-06-11 04:47:53 +02:00
Claude Worker claude2 6e837cc195 merge: ir-puzzle-scene (IR puzzle/scene + blocs) 2026-06-11 04:29:39 +02:00
Claude Worker claude2 a481f130d6 fix(scenario): straight quotes in zacus_v3
Les guillemets typographiques servaient de pseudo-délimiteurs YAML :
les valeurs chargées contenaient littéralement “…” (endpoints LLM/TTS,
names des puzzles) et la séquence du piano valait [“L”,“E”,…] au lieu
de [L,E,F,O,U]. Conversion “”→", ‘’→', …→... ; tirets et « » français
conservés. Parse vérifié avant/après (yaml.safe_load).
2026-06-11 03:37:08 +02:00
Claude Worker claude2 27544fecd1 feat(blocks): scene/puzzle blocks in atelier
Catégorie « Énigmes » dans le catalogue Blockly canonique :
zacus_scene (écran maître title/subtitle/symbol/effect),
zacus_puzzleQR et zacus_puzzleSound. L'export blocks_to_runtime3
les attache au step courant comme objets IR scene/puzzle (pas des
actions), avec clamping/troncature vers les limites strictes du
gateway pour que l'IR émis valide toujours. Copie hub régénérée
via sync_blockly_catalog.sh. 14 tests d'export ajoutés (60 verts).
2026-06-11 03:34:21 +02:00
Claude Worker claude2 b1486b27ff feat(ir): compile solution blocks to puzzles 2026-06-11 03:14:20 +02:00
Claude Worker claude2 dd6df1fa69 docs(ir): example IR + authoring gap note 2026-06-11 03:07:14 +02:00
Claude Worker claude2 7086411ea3 chore: bump ESP32_ZACUS (top README) 2026-06-11 02:58:10 +02:00
Claude Worker claude2 f81601bebd chore: bump ESP32_ZACUS (docs+qr fixes) 2026-06-11 02:57:05 +02:00
Claude Worker claude2 f71a69e4b7 chore: bump ESP32_ZACUS (box3 stimulus) 2026-06-10 23:15:48 +02:00
Claude Worker claude2 261369d50b chore: bump ESP32_ZACUS (puzzles+UI port) 2026-06-10 23:07:00 +02:00
Claude Worker claude2 7e690f5a20 feat(ir): step puzzle + scene fields 2026-06-10 22:57:14 +02:00
Claude Worker claude2 9e78dd7b6b chore: ignore .worktrees/ 2026-06-10 22:52:22 +02:00
Claude Worker claude2 a4838dccf0 docs: plan impl enigmes locales Freenove
Repo State / repo-state (push) Failing after 13m46s
2026-06-10 13:42:56 +02:00
Claude Worker claude2 7ee051827f docs: spec enigmes locales Freenove P1/P3
Repo State / repo-state (push) Failing after 1m7s
2026-06-10 13:34:39 +02:00
Claude Worker claude2 19bce1075a chore: bump ESP32_ZACUS (BOX-3 BSP fix)
Repo State / repo-state (push) Failing after 3m20s
2026-06-10 13:22:03 +02:00
electron 4ae92abcb3 Merge pull request 'feat(hw): projet KiCad du téléphone PLIP' (#122) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 33s
Validate Zacus refactor / validate (push) Successful in 15m20s
2026-06-10 10:55:08 +00:00
Claude Worker claude2 e1a116d0f5 feat(hw): PLIP telephone KiCad project
Repo State / repo-state (push) Failing after 48s
Validate Zacus refactor / validate (pull_request) Successful in 11m10s
Repo State / repo-state (pull_request) Failing after 12m5s
Custom ESP32-WROOM-32E + Si3210 SLIC board replacing the ESP32-A1S
dev kit (final PLIP target, RJ9 handset). Generated via tools/
gen_si3210_lib.py (symbol + QFN-38 footprint), gen_schematic.py
(parses standard KiCad libs, 45 instances, 157 global labels on pin
ends) and gen_pcb.py (58x38mm outline, 41 footprints placed per the
plan, nets assigned, unrouted).

ERC: 0 violations. Schematic follows the spec GPIO map and the plan's
passive network. PCB placed not routed (Freerouting + DRC + gerbers
remain — see README). BOM in JLCPCB format; CP2102N/transformer/RJ9
LCSC parts marked TBD.

WARNINGS (README): the Si3210 -72V DC-DC stage is simplified and must
be checked against the Skyworks datasheet/AN35 before fab; line
protection is minimal; human review required before ordering.
2026-06-10 12:52:43 +02:00
electron ec7fb2bac2 Merge pull request 'chore: bump ESP32_ZACUS (téléphone écran BOX-3)' (#121) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 11m48s
Validate Zacus refactor / validate (push) Failing after 14m35s
2026-06-10 10:45:44 +00:00
Claude Worker claude2 8b9151851f chore: bump ESP32_ZACUS (BOX-3 on-screen phone)
Repo State / repo-state (push) Failing after 43s
Validate Zacus refactor / validate (pull_request) Failing after 14m28s
Repo State / repo-state (pull_request) Failing after 14m48s
Submodule points at the merged on-screen phone + touch keypad + hook
button (PR ESP32_ZACUS#6), flashed and verified on hardware.
2026-06-10 12:44:42 +02:00
electron 456be02133 Merge pull request 'chore: bump ESP32_ZACUS (PLIP virtuel sur BOX-3)' (#120) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 40s
Validate Zacus refactor / validate (push) Failing after 11m7s
2026-06-10 10:30:59 +00:00
Claude Worker claude2 f5328d9d74 chore: bump ESP32_ZACUS (virtual PLIP on BOX-3)
Repo State / repo-state (push) Failing after 43s
Repo State / repo-state (pull_request) Failing after 12m46s
Validate Zacus refactor / validate (pull_request) Successful in 13m39s
Submodule points at the merged phone-less PLIP annex
(PR ESP32_ZACUS#5): PLIP REST contract + speaker ring + BOOT hook
switch + /voice/hook reporting on the BOX-3.
2026-06-10 12:30:30 +02:00
electron f36eac67a2 Merge pull request 'feat: journal sim en console + rate/emotion TTS + peers HTTP' (#119) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 47s
Validate Zacus refactor / validate (push) Failing after 12m54s
2026-06-10 09:57:59 +00:00
Claude Worker claude2 db63da7d2e feat: sim log in console + TTS rate/emotion
Repo State / repo-state (pull_request) Failing after 43s
Repo State / repo-state (push) Failing after 38s
Validate Zacus refactor / validate (pull_request) Failing after 21m48s
- ConsolePane shows the ScenePlayer narration (simLog, green) under
  the validation entries, plus a current-scene badge in the header.
- voice-bridge accepts rate + emotion on /tts: rate (clamped 0.5..2.0)
  drives the F5 sampler speed; emotion is accepted and cache-keyed but
  not rendered yet (no F5 emotion control). Legacy cache keys are
  preserved when both fields are absent/default — the NPC pool
  generator contract is untouched.
- Bump ESP32_ZACUS: GET/POST /game/peers (PR ESP32_ZACUS#4) — PLIP
  provisioning by curl, live registration without reboot.

Verified: py_compile OK, tsc clean, vite build green, master firmware
build green.
2026-06-10 11:56:25 +02:00
electron b84fb19c86 Merge pull request 'feat(atelier): lecteur de scènes pour la simulation 3D' (#118) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 47s
Validate Zacus refactor / validate (push) Failing after 12m51s
2026-06-10 09:44:51 +00:00
Claude Worker claude2 34b7c3144a feat(atelier): scene player for the 3D stage sim
Repo State / repo-state (push) Failing after 11m12s
Repo State / repo-state (pull_request) Failing after 10m58s
Validate Zacus refactor / validate (pull_request) Successful in 11m42s
The Run button fed blocks_studio v2 YAML to the legacy gameplay engine,
which only parses old zacus_v3 scenarios. loadScenario now tries the v2
document first and plays it through a new ScenePlayer: « Zacus dit »
drives the NPC bubble + Web Speech (rate applied, emotion mapped to the
stage mood), timers wait, goto/branch/intent jump between scenes,
hardware actions are narrated into a capped simLog. Legacy YAML still
falls back to ZacusScenarioEngine. Visualization fidelity only — the
authoritative compiler remains blocks_to_runtime3.py.

Verified: tsc clean, vite build green.
2026-06-10 11:43:57 +02:00
electron c325aee8c2 Merge pull request 'feat(atelier): toolbox scènes Runtime 3 partagée (start/end + voix)' (#117) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 1m2s
Validate Zacus refactor / validate (push) Successful in 11m25s
2026-06-10 09:36:47 +00:00
Claude Worker claude2 089cea409e feat(atelier): Runtime 3 scene toolbox, shared
Repo State / repo-state (push) Failing after 49s
Repo State / repo-state (pull_request) Failing after 1m0s
Validate Zacus refactor / validate (pull_request) Successful in 11m31s
The Atelier exposed a legacy 12-block gameplay-config language whose
export the gateway could not compile (no blocks_studio_version) — and
no start/end blocks. It now speaks the same language as the zacus-hub
native Studio: the 38-block scene catalog (sceneStart/sceneEnd, npcSay
voice lines, HW/ESP-NOW/M5/PLIP, logic) lives once in
@zacus/shared/blockly; the hub copy is GENERATED via
tools/dev/sync_blockly_catalog.sh.

- Export/import rewritten to blocks_studio_version: 2 (flat nodes,
  next pointers, logicIf slots) via shared blocks-doc.ts — what
  POST /v1/flash compiles to Runtime 3 IR, and what the hub Studio
  reads/writes (full interop).
- « Zacus dit » gains voice (voice-bridge voice_ref), emotion and rate
  fields; the compiler forwards them as optional tts_say fields
  (omitted at defaults, backward compatible).
- Editor validation now mirrors compiler rules: missing sceneStart,
  duplicate scene ids, unknown goto targets, empty voice lines.

Verified: tsc clean, vite build green, v2->IR round-trip OK
(entry STEP_intro, tts_say{voice_ref,emotion,rate}).
2026-06-10 11:35:24 +02:00
electron 6ddd0d872d Merge pull request 'chore: bump ESP32_ZACUS (dédup scenario_mesh)' (#116) from feat/zacus-hotload-hub into main
Repo State / repo-state (push) Failing after 14m41s
Validate Zacus refactor / validate (push) Failing after 19m35s
2026-06-10 08:53:35 +00:00
Claude Worker claude2 102ee99729 chore: bump ESP32_ZACUS (scenario_mesh dedup)
Repo State / repo-state (push) Failing after 47s
Repo State / repo-state (pull_request) Failing after 33s
Validate Zacus refactor / validate (pull_request) Successful in 11m26s
Submodule now points at the merged scenario_mesh hoist (single copy
in lib/, EXTRA_COMPONENT_DIRS) + sdkconfig.old cleanup.
2026-06-10 10:52:37 +02:00