# Suivi — Dialog Orchestrator (headless)

Etat: préparation Itération 1 (orchestrateur + modal/embed + helpers confirm/form)

## Journal
- [init] Plan validé (PLAN.md) — périmètre et invariants a11y/focus
- [todo] Scaffolder engine + orchestrateur + renderer modal

## Checklist (DoD Itération 1)
- [ ] Orchestrateur + registre d’instances (spawn/activate/close/list)
- [ ] Renderer modal `<sb-modal>` + inline (embed)
- [ ] API `openDialog(def)` + helpers `confirmDialog` / `formDialog`
- [ ] Validateur de schéma côté front (version, limites, champs inconnus, cycles) avant `spawn`
- [ ] Fallback host → `global-modal` si container absent (test unitaire)
- [ ] A11y/focus: 1 modale active; autres inert + aria-hidden + tabindex=-1; ESC sur modale active; retour de focus invocateur
- [ ] TTL/expiry: fermeture propre + toast `INTERACTION_EXPIRED`; mapping `fieldErrors`/`formError`
- [ ] Règle collision (id/scope) par défaut: `LIMIT_REACHED` (sauf `policy.concurrency:"replace"`)
- [ ] Tests unitaires orchestrateur/visibleIf/validation basiques
- [ ] Documentation (README, PLAN, updates)

## Phasage — tâches
- Itération 1 — Orchestrateur + renderers + helpers + remplacement d’un confirm (Admin)
- Itération 2 — Wizard complet (next/review/allowBack), datasets dynamiques, promote(embed→modal)
- Itération 3 — Champs avancés, validations async, queue/priorité/minimized (si besoin)

## Notes techniques
- DSL conditions: eq, ne, in, and, or, not — accès `$data`, `$ctx`
- Sécurité: interactionId signé + TTL; échappements systématiques; limites taille schéma/options
- Validateur (codes): `SCHEMA_UNSUPPORTED_VERSION`, `SCHEMA_UNKNOWN_FIELD`, `SCHEMA_TOO_LARGE`, `SCHEMA_CYCLE_DETECTED`, `SCHEMA_INVALID_DSL`
- Télémétrie: `interactionId`, `durationMs`, `path`, `meta.reason` (SUBMIT|CANCEL|EXPIRED|REPLACED) — sans données perso
