You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Audit de couverture : pour chaque action qu'un humain peut faire dans la
webapp faustcode, quel outil MCP permet à une IA de produire le même
effet ?
Snapshot pris le 2026-05-30 (révisé le 2026-05-31 : ajout puis
retrait de inlineAudio, audio_metrics_v1 en 0.5.0 puis _v2 en
0.6.0 pour capturer l'évolution temporelle, et 0.7.0 : submit
accepte des fichiers .lib qui sont injectés dans le FS du compilateur
avant chaque compile pour résoudre import("foo.lib") dans les .dsp),
contrat tools.json version 0.7.0 (37 outils). À refaire si on
ajoute des outils ou si la webapp gagne / perd des surfaces.
Légende : ✓ couvert, ◐ partiellement couvert (effet équivalent
mais sémantique différente), ✗ absent (souvent volontaire), n/a
cosmétique / non pertinent côté IA.
A. Header global (visible quelle que soit la view)
Gestion sessions (suppression, ordre, navigation par usage)
très complète depuis la passe du 2026-05-30
Réglages oscilloscope
absents (UI-only, cohérent) — pour les mesures fines : render_audio
Mesure audio offline déterministe / export WAV
très complète via render_audio (Phase 1 livrée 2026-05-30)
Sélection device MIDI externe
absent (peu critique : l'IA pilote via midi_note_*)
Random / Presets
absents
Download PWA / .dot / SVG
absents (hors scope)
Trous qui mériteraient un outil MCP
Manque
Justification
recall_preset(name)
si le DSP a des presets, l'IA devrait pouvoir les essayer ; couplage avec vendor/faust-orbit-ui/
refresh_session(sha1)
équivalent du bouton ↻ — en standalone redondant avec un re-submit, à ressortir si on rebranche du live
Notes sémantiques
usage_score : compteur cumulatif persisté, incrémenté de 1 par "événement d'usage"
(sélection, re-sélection, tick d'engagement audio toutes les 5 s).
Debounce 700 ms par sha1. Persisté dans metadata.json côté OPFS. Sémantique alignée
avec la version Docker (dist/sessions.js: markSessionUsed).
prev_session / next_session : traversent désormais les sessions dans la
display order (= ce que voit l'humain) gouvernée par get_session_order().
En chronological : prev = plus ancien, next = plus récent (puis empty au-dessus du plus récent).
En usage : prev = score plus bas, next = score plus haut.
Bascule UI ↔ MCP : sessionOrder est partagé via le même pattern que
activeSha1/activeView (api-shim + /api/state + pollState à 1.5 s). Un changement
côté MCP se reflète dans l'indicateur ⏱/★ en ≤ 1.5 s, et inversement.
render_audio : rendu offline déterministe via OfflineAudioContext. N'a pas
besoin que la Run view soit montée — compile le DSP de la session active à neuf, applique
paramSetup, scripte des événements de paramètres dans le temps (granularité = un
render quantum, ~2.7 ms @ 48 kHz), retourne soit un spectrum_summary_v1 (detail: light),
soit un fichier WAV Float32 IEEE_FLOAT écrit sur disque (detail: wav). Le WAV transite
base64 dans le canal WS webapp↔binaire ; le binaire le décode, l'écrit sous
$TMPDIR/faustcode-renders/<sha8>-<paramfp>.wav, et substitue par un champ path
dans la réponse MCP — la base64 n'est jamais dans le contexte de l'IA. Fichiers
1 h supprimés au prochain démarrage du binaire. Le contenu est librosa.load(path, sr=None)-compatible et bit-stable (les rendus avec les mêmes args produisent le même
fingerprint et le même fichier).
Convention des événements à atMs === 0 : un event de script à atMs=0 est appliqué
pendant paramSetup (avant startRendering) — il sert à exprimer l'état initial dans
script pour la symétrie avec les events suivants. Pour qu'une transition de bouton soit
détectable par un DSP à déclenchement (front montant), schedulez la transition à
atMs > 0 (e.g. atMs: 10) avec le bouton initial à 0 dans paramSetup.
render_audio: detail = "metrics" : retourne un audio_metrics_v2 (0.6.0,
remplace audio_metrics_v1 de 0.5.0 — pas de rétro-compat, le v1 n'a vécu que 2 h).
Le rendu est segmenté en phases d'enveloppe détectées par la courbe RMS :
attack (10 % → 90 % du pic RMS), sustain (frames toujours au-dessus de 50 % du pic ;
englobe le decay vers un sustainLevel ADSR), release (sustain → 10 % du pic).
Sortie en 4 blocs :
envelope : attackMs, peakDbFS, sustainStartMs, sustainEndMs,
releaseMs, decaySlopeDbPerS (régression linéaire en dB sur la release).
attack (FFT 512, ~21 ms @ 24 kHz) : centroidHz, rolloff95Hz, flatness,
spectralFluxDb (distance L2 magnitude entre frames successives — élevé pour les
attaques claquées, faible pour les attaques feutrées). Pas de f0/harmonics : trop
court pour être fiable.
sustain (pipeline complet, n_fft=2048 STFT center=True comme librosa) :
f0Hz avec correction sous-harmonique (DSP où H2 ou H3 dominent H1, brass/horn),
harmonicsDb[N], hnrDb, roughnessDb par bandes (5-20/20-50/50-100/100-200 Hz),
features (centroidHz, rolloff95Hz, flatness) — bit-comparables avec
librosa.feature.spectral_*. Cross-validé sur un signal 220+440+660 Hz :
f0/harmonics/HNR/centroid/rolloff/flatness identiques à horn_metrics.py.
release : même shape que attack.
Signaux stationnaires (pas de gate) : attackMs≈0, releaseMs≈0, sustain
englobe tout le rendu. Les blocs attack/release sont émis avec durationMs: 0,
pas d'erreur.
metricsOptions expose les knobs : fmin / fmax (défaut 50-2000 Hz pour
couvrir la majorité des sons musicaux ; passer fmax: 400 pour mimer le défaut
klaxon de horn_metrics.py), nHarm, plateauCapS, roughnessBands.
render_audio et l'accessibilité du path : le fichier WAV est écrit sur le
filesystem de l'hôte du binaire ($TMPDIR/faustcode-renders/). Pour Claude Code
(modèle et binaire sur le même hôte), librosa.load(path) marche directement. Pour
Claude Desktop (outils du modèle dans un container Anthropic disjoint de l'hôte),
le path n'est pas atteignable depuis le sandbox et il faut que l'utilisateur upload
manuellement le fichier dans la conversation (drag-and-drop) pour qu'il apparaisse
sous /mnt/user-data/uploads/. La piste AudioContent/EmbeddedResource MCP standard
a été tentée en 0.4.0 puis retirée en 0.4.1 : ces blocs ne sont pas hydratés par
Claude Desktop (cf. DEBUG.md §8 pour les références doc Anthropic + ticket GitHub).
La vraie fermeture de boucle pour Claude Desktop demande un pont côté infrastructure
Anthropic, hors périmètre faustcode.
Conventions
"UI-only" : l'action concerne l'affichage / l'ergonomie côté humain ; un agent
n'en a pas besoin pour atteindre le même but musical.
"Hors scope" : exclusion délibérée du périmètre faustcode (cf. README, parties
héritées du Docker faustservice qui ne s'appliquent plus).
"Couvert par X" : l'effet musical / observable est identique, même si le
geste humain et l'appel d'outil diffèrent.
À refaire / maintenir
À chaque ajout d'un tool MCP : compléter la colonne correspondante.
À chaque ajout d'un contrôle UI dans la webapp : ajouter la ligne ici.
Si un test révèle qu'une case marquée ✓ ne marche pas dans la pratique,
rebasculer à ◐ ou ✗ et expliquer pourquoi.