# EEV v1 peak tracks roadmap

> Scope note: this roadmap is written for the public **EEV** implementation path.
> Any mention of **EEVC** is kept only when it matters for read/import compatibility with existing certified files.

## Feuille De Route EEV v1 - Enrichissement `@peak_tracks`
Statut global : en cours (`0`, `A`, `B`, `C`, `D` terminees ; `E` reouverte pour durcir `ultra` ; `F` reportee apres ce cadrage)

Objectif : finaliser `EEV v1.0` en enrichissant `@peak_tracks` de manière additive, en commençant strictement par `ECO` (`48` pas temporels), puis en preparant la montee vers `standard` (`64`), `high` (`96`) et `ultra` (`128`).

Règle de compatibilité :
  si ce mélange n'est pas recommandé
- un document `EEV|1|ENTRY` ne contient qu'une entrée `EEV`
  sérialisé en `EEV|1|LIB`
- le logiciel local peut lire / importer des `EEVC` existantes, mais ne doit ni créer ni exporter `EEVC` / `EEVCZ`
- le logiciel local peut exporter une entrée seule en `EEV|1|ENTRY` ou une bibliothèque en `EEV|1|LIB`
- la lecture / import d'une `EEV` ou `EEVC` doit etre strictement non destructive : le fichier lu ne doit jamais etre modifie, corrige, migre ni reecrit au moment de la lecture
- pour l'instant, le logiciel local doit soit lire une `EEV`, soit enregistrer une nouvelle `EEV` depuis une capture, mais ne doit pas permettre la modification locale d'une entrée déjà présente dans la bibliothèque
- une entree peut porter une illustration externe optionnelle, associee via
  `entry_uuid`, sans champ de chemin dans le payload `EEV`
- cette illustration doit rester un sidecar local nomme `entry_uuid.webp`,
  `.png`, `.jpg` ou `.jpeg`, a cote de la bibliotheque ou du document source
- cette illustration ne doit pas entrer dans le `hash` ni dans la
  serialisation canonique
- l'implémentation doit rester additive et lisible

## Cadrage Fonctionnel Bibliothèque EEV

Décisions verrouillées :
- une seule `bibliothèque active` à la fois
- le `visuel technique` d'une entrée `EEV` est distinct de sa `photo sidecar`
- le visuel technique de la page bibliothèque doit être reconstruit à partir du
  snapshot de référence `EEV`
- `db_id` reste l'UID stable de bibliothèque et `db_label` son nom humain
- le nom physique recommandé du fichier de bibliothèque pour la V1 logicielle
  est : `<db_id_safe>__<db_label_safe>.eev`
- l'image sidecar d'une entrée reste résolue uniquement par `entry_uuid`
  (`.webp`, `.png`, `.jpg`, `.jpeg`) dans le même répertoire logique que la
  bibliothèque active

Périmètre documentaire :
- cette roadmap reste centrée sur le format `EEV` et sur les règles de capture /
  reconstruction associées
- la gestion logicielle détaillée d'une bibliothèque
  (`workspace`, `favoris`, `collections`, `vues enregistrées`,
  `multi-bibliothèques`, `registre JSON`, UX de chargement`) sort de cette
  roadmap et doit vivre dans une documentation runtime séparée

Contrôles critiques à rouvrir avant validation `ECO` :
- vérifier que le runtime n'écrit plus dans un fichier générique de type `library.eev`
- vérifier que le nom physique exposé par le runtime porte bien `db_id` et
  `db_label` sous forme sanitisée
- vérifier que l'UI sait indiquer clairement quelle bibliothèque unique reçoit
  l'écriture

Point différé explicite :
- étudier plus tard si la sélection du snapshot de référence doit intégrer un
  biais métier vers `15-20%` de la durée totale de l'empreinte, sans casser la
  logique mesurée existante autour de `reference_snapshot_bin` /
  `reference_snapshot_time_ms`

## Decision De Cadrage Ultra 1.0

Decision de produit a respecter avant implementation :
- `EEV` n'etant pas encore diffusee, la cible reste `v1.0` et non une `v2`
- `ultra` doit devenir un profil fiable et strict, pas une simple accumulation de hints optionnels
- le writer canonique `ultra` doit emettre tous les blocs avances requis ; s'il ne peut pas les produire proprement, il ne doit pas emettre une entree `ultra` canonique
- les anciens noms `freq48`, `level48`, `present48` doivent etre abandonnes dans la specification canonique au profit de noms non ambigus
- `quality_tier` doit rester une information d'identite de l'entree, dans le bloc
  de tete / meta, et ne doit plus etre duplique canoniquement dans `@global`
- `entry_id`, `entry_uuid` et `instrument_id` doivent etre explicitement traites
  comme des champs couverts par le `hash`
  certifiees figees, incluses dans le `hash` quand elles sont presentes
  ou mutable apres emission
- `ultra_profile=1.0` devient le discriminant unique du profil `ultra` enrichi
- `@matrix tonal` et `@matrix diffuse` doivent rester prudentes : en cas d'ambiguite, produire une separation conservative et jamais un decor arbitraire
- le branchement direct aux oscillateurs est reporte apres stabilisation complete du format `ultra`

### Avis De Cloture - Priorite Des Matrices Ultra

Avis de cadrage retenu pour la fermeture de `Ultra 1.0` :
- passer `ultra` a `128` bins a un vrai impact surtout pour la relecture temporelle, les battements, les derives fines et le pilotage oscillateur
- le gain est reel surtout si `ultra` est pense comme un niveau de resynthese / pilotage et pas seulement comme une archive de consultation
- la matrice la plus rentable reste `@matrix tonal` : elle repond a la question "ou sont les partiels vraiment rejouables comme partiels credibles ?"
- la deuxieme matrice pertinente reste `@matrix diffuse` : elle repond a la question "ou est la matiere non tonale reelle qu'il ne faut pas perdre ?"
- le couple `tonal + diffuse` est plus utile qu'une simple densification supplementaire de `spec`
- une matrice de phase brute n'est pas prioritaire dans ce projet : trop lourde, trop fragile, trop sensible aux conditions reelles de capture
- une matrice d'attaque complete n'est pas prioritaire non plus : elle serait largement redondante avec `env48`, `attack48` et les jalons temporels deja presents
- si un arbitrage taille / cout impose une seule matrice additionnelle, la priorite va a `@matrix tonal`
- `@matrix diffuse` ne doit jamais devenir un simple reste `spec - tonal`
- `@matrix diffuse` doit rester mesuree autant que possible, ou au minimum contrainte par des indices reels de largeur, flatness, contraste local et bruit de fond
- si le duo `tonal + diffuse` n'est pas mesurable proprement, il faut rester prudent ou retrograder le profil, jamais inventer un decor

## Priorité Immédiate - Stabilisation ECO De La Courbe

Diagnostic prioritaire :
- le logiciel enregistre plus d'informations qu'il n'en réutilise au rechargement d'une `EEV`
- la courbe du `Synthé spectral` n'est pas relue comme une vraie coupe temporelle à un instant représentatif
- la reconstruction actuelle reste trop résumée et trop théorique
- le rendu s'appuie encore trop sur `freq_ref_hz`, `peak_db`, `span_cents` et une forme gaussienne plausible
- `freq_series`, `level_series` et `present_series` ne sont pas encore exploitees comme une vraie photo du spectre a un instant donne

Conclusion à respecter avant d'aller plus loin :
- stabiliser d'abord la qualité `ECO`
- garantir qu'une `EEV` rechargée puisse reconstruire une courbe fiable à partir d'un instant réel du son
- faire passer cette stabilisation avant les niveaux `2`, `3` et `4`

## Suivi D'Implémentation

Etat reel du code au moment de cette mise a jour :
- les phases `0`, `A`, `B`, `C` et `D` sont implementees
- la phase `E` historique est implementee pour le premier niveau `ultra`, le parseur/serialiseur, la capture et le runtime
- la phase `E` est maintenant reouverte pour transformer `ultra` en profil `v1.0` strict et durable
- le branchement direct au moteur audio / oscillateurs n'est plus la priorite immediate
- la phase `F` reste a finaliser comme vraie validation transverse apres stabilisation du nouveau `ultra`

### Phase 0 - Stabilisation de la courbe ECO rechargée
- [x] Remplacer la logique de courbe trop théorique par une vraie stratégie de relecture temporelle
- [x] Utiliser `reference_snapshot_bin` comme point d'entrée prioritaire pour relire la courbe
- [x] Relire les `peak_tracks` comme une coupe de temps réelle à partir de `freq_series`, `level_series` et `present_series`
- [x] Garantir que les pics affichés correspondent à leur état réel au moment de référence
- [x] Réduire l'écrasement visuel dû à `peak_db + gaussienne + prominence`
- [x] Vérifier que la courbe rechargée ressemble à une photo spectrale de la zone stable utile
- [x] Conserver un fallback seulement si les données temporelles sont insuffisantes
- [x] Documenter explicitement cette règle de relecture `ECO`

### Phase A - Cadre général
- [x] Créer la copie sur disque de cette feuille de route
- [x] Aligner la documentation format sur les `4` niveaux d'enrichissement `peak_tracks`
- [x] Aligner la documentation d'implémentation sur la logique `ECO -> standard -> high -> ultra`
- [x] Définir les enums courts canoniques nécessaires
- [x] Définir les règles de fallback quand un niveau supérieur n'est pas présent

### Phase B - Niveau 1 / ECO / Référence minimale
- [x] Ajouter `reference_snapshot_bin`
- [x] Ajouter `reference_snapshot_time_ms`
- [x] Étendre l'ordre canonique de `@peak_tracks`
- [x] Étendre parseur / sérialiseur pour ces champs
- [x] Calculer ces champs à la capture EEV
- [x] Exposer ces champs dans le runtime de lecture
- [x] Utiliser ces champs pour la courbe représentative quand disponibles
- [x] Documenter le niveau `ECO / Niveau 1`

### Phase C - Niveau 2 / Visuel enrichi
- [x] Ajouter `display_width_cents`
- [x] Ajouter `display_gain_db`
- [x] Ajouter `display_prominence`
- [x] Ajouter `peak_shape`
- [x] Ajouter `skew`
- [x] Ajouter `core_ratio`
- [x] Ajouter `global_bed_curve_8`
- [x] Ajouter `global_tilt_db_per_oct`
- [x] Ajouter `local_floor_db`
- [x] Étendre parseur / sérialiseur Niveau 2
- [x] Calculer les champs visuels Niveau 2 à la capture
- [x] Utiliser les champs visuels Niveau 2 dans la reconstruction de courbe
- [x] Documenter le niveau `Visuel avancé`

### Phase D - Niveau 3 / Temporel enrichi
- [x] Ajouter `attack_start_bin`
- [x] Ajouter `attack_peak_bin`
- [x] Ajouter `sustain_start_bin`
- [x] Ajouter `decay_start_bin`
- [x] Ajouter `end_bin`
- [x] Ajouter `attack_shape`
- [x] Ajouter `decay_curve`
- [x] Ajouter `decay_rate`
- [x] Ajouter `freq_drift_range_cents`
- [x] Ajouter `freq_drift_speed`
- [x] Ajouter `amp_mod_depth`
- [x] Ajouter `amp_mod_rate_hz`
- [x] Ajouter `stability_time_ratio`
- [x] Étendre parseur / sérialiseur Niveau 3
- [x] Calculer les champs temporels Niveau 3 à la capture
- [x] Utiliser les champs temporels Niveau 3 pour la lecture temporelle
- [x] Documenter le niveau `Temporel avancé`

### Phase E - Niveau 4 / Ultra / Pilotage durable
- [x] Ajouter `synth_mode`
- [x] Ajouter `synth_spread_cents`
- [x] Ajouter `synth_detune_count`
- [x] Ajouter `synth_detune_pattern`
- [x] Ajouter `noise_ratio`
- [x] Ajouter `noise_color`
- [x] Ajouter `jitter_amt`
- [x] Ajouter `jitter_rate_hz`
- [x] Ajouter `beating_depth`
- [x] Ajouter `beating_rate_hz`
- [x] Ajouter `harmonic_lock`
- [x] Ajouter `inharmonic_ratio`
- [x] Ajouter `phase_randomness`
- [x] Ajouter `retrigger_behavior`
- [x] Ajouter `osc_wave_hint`
- [x] Étendre parseur / sérialiseur Niveau 4
- [x] Calculer les champs de resynthèse Niveau 4 à la capture
- [x] Documenter le premier niveau `Ultra`
- [x] Recaler `ultra` sur `128` pas temporels pour `timeline_bins` et `peak_track_bins`
- [x] Renommer les series historiques `freq48` / `level48` / `present48` en `freq_series` / `level_series` / `present_series`
- [x] Introduire `ultra_profile=1.0` comme marqueur unique du profil `ultra` canonique
- [x] Ajouter `@matrix tonal` comme matrice obligatoire de pilotage tonal
- [x] Ajouter `@matrix diffuse` comme matrice obligatoire de matiere diffuse
- [x] Ajouter `osc_recipe` comme sous-bloc obligatoire par piste `ultra`
- [x] Definir la serialisation canonique stricte de `osc_recipe`
- [x] Ajouter `timbre_motion` comme sous-bloc obligatoire par piste `ultra`
- [x] Definir la serialisation canonique stricte de `timbre_motion`
- [x] Ajouter `@track_relations` comme bloc obligatoire du profil `ultra`
- [x] Definir l'ordre canonique, la stabilite de groupe et les regles d'ambiguite de `@track_relations`
- [x] Mettre a jour parseur / serialiseur pour tous les nouveaux blocs `ultra`
- [x] Mettre a jour la capture pour produire un `ultra` fiable et complet
- [x] Mettre a jour le runtime de lecture pour exploiter le nouveau profil `ultra`
- [x] Reporter explicitement le branchement oscillateurs apres stabilisation du format `ultra`

### Phase F - Validation
- Validation actuellement lancee :
- syntaxe JS reverifiee avec `node --check`
- diagnostics IDE reverifies apres corrections recentes
- lecture / import `EEV` et `EEVC` vérifiée dans le code de parse et d'import
- fallback lecture des champs historiques de base reverifie dans les chemins de replay / reconstruction / ghost voices
- [x] Vérifier le fallback lecture si seuls les champs de base existent
- [ ] Vérifier le fallback lecture si seul le Niveau 1 existe
- [x] Vérifier la compatibilité de lecture / import `EEV` et `EEVC`
- [ ] Vérifier qu'une lecture / import n'entraine aucune modification, migration ou reecriture locale du document lu
- [ ] Vérifier que toute `EEV` existante lue / importee reste en lecture seule locale
- [ ] Vérifier les exports locaux autorisés `.eev` et `.eevz`
- [ ] Vérifier explicitement l'absence de creation / export local `EEVC` et `EEVCZ`
- [x] Vérifier les diagnostics IDE
- [ ] Vérifier la cohérence du Synthé spectral après rechargement
- [ ] Aligner le code avec la règle documentaire `quality_tier` en meta uniquement
- [ ] Cesser d'emettre `@global.quality_tier` en ecriture canonique
- [ ] Conserver `@global.quality_tier` seulement comme legacy tolere en lecture, avec priorite a `@entry.quality_tier`
- [ ] Verifier la resolution de l'image sidecar par `entry_uuid` avec priorite
  `.webp` -> `.png` -> `.jpg` -> `.jpeg`

## Source Unique De Suivi

Cette feuille de route devient le document unique de suivi pour `EEV v1`.

Regle de reprise :

- ne plus maintenir en parallele un second plan general `EEV v1`
- centraliser ici la roadmap `peak_tracks`, le cadrage bibliotheque, les
  validations `EEV` et l'audit de fiabilite
- toute reprise future doit repartir de ce fichier

## Audit Transverse De Fiabilite

Ce bloc est a traiter avant toute nouvelle extension ambitieuse du runtime.

Constat de depart :

- une erreur de lecture harmonique ou de fondamentale peut contaminer
  l'affichage, la creation `EEV`, la comparaison et le matching
- certains champs `EEV` peuvent etre renseignes automatiquement sans que leur
  coherence terrain soit encore suffisamment demontree
- il faut distinguer strictement ce qui est `mesure`, `derive` ou `interprete`

Ordre de reprise verrouille :

1. `classification sonore`
2. `creation EEV`
3. `comparaison vibratoire`
4. `restitution UI de la confiance`

### Bloc 1 - Audit classification sonore

Fichiers / fonctions pivots :

- `analyse spectrale/spectral-analyzer.js`
- `_buildAnalysisSnapshot()`
- `_classifySpectrum()`
- `_computeLiveHarmonicSeriesEvidence()`
- `_applyCurveTruthToSnapshot()`

But :

- verifier qu'une classe harmonique ne peut pas gagner sans preuve suffisante
- verifier qu'un faux `f1` ne pollue pas toute l'analyse
- separer clairement `preuves`, `scores` et `libelle final`

Invariants a controler :

- pas de classe harmonique si `H1` est faible
- pas de classe harmonique si `H2/H3/H4` ne suivent pas une serie plausible
- pas de classe harmonique si `chainScore` est faible
- pas de classe harmonique si `curveNoiseScore` domine `curveHarmonicScore`
- pas de conclusion forte si la preuve est seulement heuristique

Corpus minimal a valider :

- sinus pur
- diapason
- voix tenue
- bol stable
- gong
- maracas
- shaker
- bruit blanc
- attaque percussive courte
- deux sinus non lies

Sorties d'audit attendues :

- `f0Hz`
- `f1Evidence`
- `h1Score`
- `lowOrderScore`
- `chainScore`
- `harmonicRatio`
- `curveNoiseScore`
- `curveHarmonicScore`
- classe finale retenue

Critere de fin de bloc :

- pour chaque cas, documenter `resultat attendu`, `resultat interdit`,
  `resultat observe`, `conforme / non conforme`

### Bloc 2 - Audit creation EEV et validations de fichier

Fichiers / fonctions pivots :

- `analyse spectrale/spectral-analyzer.js`
- `_ensureEevEntryIdentity()`
- `_computeEevEntryHash()`
- `_validateEevMeta()`
- `docs/eev-format.md`
- `docs/eev-implementation.md`

Constat de depart :

- la validation actuelle du formulaire ne couvre essentiellement que
  `type`, `instrument`, `name`
- cela ne suffit pas pour declarer un fichier `EEV` coherent

Validations `EEV` a integrer au processus :

- verifier `entry_uuid`, `entry_id`, `instrument_id`
- verifier `created_at`, `captured_at`
- verifier `attack_start`, `attack_end`, `stable_start`, `stable_end`,
  `useful_end`
- verifier `capture_confidence`
- verifier `clipping_detected`
- verifier `reference_snapshot_time_ms`
- verifier `hash`

Regles de coherence a imposer :

- pas de date incoherente ou invalide
- pas de bornes temporelles inversees
- pas de `capture_confidence` silencieusement reparee sans trace de statut
- pas de `reference_snapshot_time_ms` incoherent avec la timeline retenue
- ne jamais presenter un champ derive comme une mesure brute
- ne jamais presenter un fichier comme sain si l'integrite est douteuse

Statuts a rendre possibles pour un champ ou un fichier :

- `valide`
- `derive`
- `repare`
- `fragile`
- `invalide`

Critere de fin de bloc :

- disposer d'une checklist de validite `EEV` exploitable pendant creation,
  lecture, import et comparaison

### Bloc 3 - Audit comparaison vibratoire

Fichiers / fonctions pivots :

- `analyse spectrale/spectral-analyzer.js`
- `_buildCompareSummary()`
- `_computeCompareCompatibilityFromSources()`
- `_buildVibratoryMeasuredMetrics()`
- `_classifyCurrentSignature()`

But :

- verifier qu'un score de comparaison ne masque pas une base fragile
- verifier les branches degradees quand les empreintes sont incompletes
- mesurer l'impact d'un faux `f0` ou d'une classification instable

Tests prioritaires :

- meme son rejoue deux fois
- meme son transpose
- deux sons proches mais differents
- comparaison avec et sans `peak_tracks`
- comparaison avec calibration differente
- comparaison sur entree importee avec reconstruction partielle

Sortie attendue :

- un score accompagne de sa `provenance`
- un niveau de fiabilite :
  `comparaison complete`, `comparaison degradee`, `comparaison indicative`

### Bloc 4 - Restitution UI de la confiance

But :

- rendre visible ce qui est sur, derive ou seulement interprete
- eviter qu'un libelle humain soit compris comme une certitude physique

Restitution cible :

- `mesure brute`
- `calcul derive`
- `interpretation heuristique`

Regles de restitution :

- une conclusion fragile doit etre marquee comme telle
- une reparation automatique ne doit jamais etre invisible
- une hypothese ne doit pas etre affichee comme un fait

## Base Existante À Conserver

Champs historiques conservés :
- `freq_ref_hz`
- `base_freq_hz`
- `peak_db`
- `avg_db`
- `db_floor`
- `db_ceil`
- `strength`
- `stability`
- `presence_ratio`
- `span_cents`
- `freq_series`
- `level_series`
- `present_series`

## Niveaux De Qualité

### Niveau 1 - Référence minimale

But :
- savoir à quel moment la courbe est la plus représentative

Champs :
- `reference_snapshot_bin`
- `reference_snapshot_time_ms`

Usage :
- affichage d'une courbe représentative simple
- meilleure cohérence du drone figé
- base commune aux niveaux supérieurs

### Niveau 2 - Visuel enrichi

But :
- reconstruire une courbe plus fidèle visuellement

Champs :
- `display_width_cents`
- `display_gain_db`
- `display_prominence`
- `peak_shape`
- `skew`
- `core_ratio`
- `global_bed_curve_8`
- `global_tilt_db_per_oct`
- `local_floor_db`

Usage :
- affichage premium
- comparaison d'empreintes
- vue de référence crédible

### Niveau 3 - Temporel enrichi

But :
- décrire la vie de la track dans le temps

Champs :
- `attack_start_bin`
- `attack_peak_bin`
- `sustain_start_bin`
- `decay_start_bin`
- `end_bin`
- `attack_shape`
- `decay_curve`
- `decay_rate`
- `freq_drift_range_cents`
- `freq_drift_speed`
- `amp_mod_depth`
- `amp_mod_rate_hz`
- `stability_time_ratio`

Usage :
- curseur temporel
- animation spectrale
- lecture dynamique de l'empreinte

### Niveau 4 - Ultra / Resynthèse

But :
- decrire un pilotage de synthese durable, fiable et exploitable

Champs :
- `synth_mode`
- `synth_spread_cents`
- `synth_detune_count`
- `synth_detune_pattern`
- `noise_ratio`
- `noise_color`
- `jitter_amt`
- `jitter_rate_hz`
- `beating_depth`
- `beating_rate_hz`
- `harmonic_lock`
- `inharmonic_ratio`
- `phase_randomness`
- `retrigger_behavior`
- `osc_wave_hint`
- `osc_recipe`
- `timbre_motion`

Blocs globaux obligatoires :
- `@matrix tonal`
- `@matrix diffuse`
- `@track_relations`
- `ultra_profile=1.0`

Usage :
- preparation d'un futur moteur audio avance
- lecture spectro-temporelle tres fidele
- pilotage tonal / diffus plus robuste
- base exploitable pour un futur synthe multi-voix

## Noyau Ultra Important

Champs structurants prioritaires :
- `reference_snapshot_bin`
- `display_width_cents`
- `display_gain_db`
- `global_bed_curve_8`
- `attack_start_bin`
- `attack_peak_bin`
- `end_bin`
- `attack_shape`
- `decay_curve`
- `freq_drift_range_cents`
- `synth_mode`
- `synth_spread_cents`
- `synth_detune_count`
- `noise_ratio`
- `jitter_amt`
- `inharmonic_ratio`
- `freq_series`
- `level_series`
- `present_series`
- `osc_recipe`
- `timbre_motion`
- `@matrix tonal`
- `@matrix diffuse`
- `@track_relations`
- `ultra_profile=1.0`

## Arbitrages D'Ingénierie

Fond spectral :
- version riche : `global_bed_curve_8`
- version ultra légère : `global_tilt_db_per_oct`
- préférence actuelle : `global_bed_curve_8`

Géométrie locale :
- version simple : `display_width_cents`
- version riche : `display_width_cents + peak_shape + skew + core_ratio`

Synthèse :
- version minimale fiable : `synth_mode + synth_spread_cents + noise_ratio + osc_recipe`
- version structurelle complete : champs Niveau 4 + `osc_recipe` + `timbre_motion` + `@matrix tonal` + `@matrix diffuse` + `@track_relations`

## Ordre De Livraison

Ordre demandé :
1. `ECO` / `48` pas temporels
2. `standard` / `64` pas temporels
3. `high` / `96` pas temporels
4. `ultra` / `128` pas temporels

Décision de démarrage :
- commencer par `ECO`
- commencer par `Niveau 1`
- ne pas sauter directement aux niveaux supérieurs
