Feat/movement trajectory continuity - #343
Merged
Merged
Conversation
…signe MovementAnimation ne connaissait que la consigne en cours et extrapolait son alternance from/to indéfiniment : au changement de step, la courbe annonçait pendant 3 s des mouvements qui n'avaient pas lieu. resolveUpcomingMovementSteps résout la suite de la timeline (mode/from/ to/bpm hérités, même règle que BeepEngine.applyStep). _computeFutureBeats la parcourt et bascule de segment aux frontières, avec une remontée par tip uniquement au franchissement d'une frontière de famille bouche/pas bouche (rhythm/hold/beg/lick/suckle vs hand/biffle/breath/freestyle). Affichage seulement : ni BeepEngine ni le générateur de séances touchés.
Sonde rouge/verte, choix de classement suckle (fiche sas tss2-002), détail de l'implémentation et limites non vérifiées (rien vu en mouvement, précision seconde des frontières, gels runtime non modélisés).
… Manu Le classement transmis à la session d'implémentation était faux : il rangeait beg et lick avec rhythm/hold, et suckle en bloc. Manu, 2026-08-20 : « rythme et tenue pour bouche et le reste de l'autre côté. y a 2 aspire, le aspire gland est dans bouche, l'autre pas. » suckle est le seul mode dont la famille dépend de la position — ses deux valeurs valides (head, balls) tombent de part et d'autre de la frontière — d'où le passage de la position à _familyOf. Les deux tests ajoutés sont rouges sur l'ancien classement (vérifié en le remettant : 2 échecs). 1023 tests verts, analyze propre, format inchangé. Claude-Session: https://claude.ai/code/session_01L4UqzJYEndHBCS3WBayUt6
Le doc-comment de `resolveUpcomingMovementSteps` annonçait que les gels runtime (posture, défi, report TTS) n'étaient pas modélisés. Ils le sont de fait : ces gels décrémentent `_timelineOffset` à chaque tick, donc `elapsed` gèle, et l'ancrage `startSecond * 1000 - elapsedMs` gèle avec lui. Le doc-comment de `_familyOf` justifiait le classement de `suckle` par le nombre de ses positions valides — un fait externe qui devient faux sans que le code bouge (cf. règle 6). Analyze propre, format inchangé.
Rapport de relecture : rétrocompatibilité mesurée exacte sur 6 480 cas, tests prouvés rouges sur le code d'avant dans les deux sens, gels et performance réfutés à la mesure. Constat principal remonté : le gap de transition du moteur (300 / 600 / 1500 ms, mesuré 305 et 1502 ms sur le vrai BeepEngine) n'est pas modélisé, donc une frontière de famille sur deux annonce sa remontée à tip 0,6 à 1,5 s trop tôt sur une fenêtre de 3 s. Erratum posé en tête du rapport de l'auteur : il décrit le classement d'avant 6ec7811 et les chiffres d'avant. Verdict : publiable avec réserves.
…du moteur BeepEngine.applyStep n'attaque le loop d'un nouveau step qu'après un délai (300/600/1500ms selon changement de mode). La trajectoire future posait ses points de frontière (dont la remontée à tip) à l'instant nominal du step, 0,6 à 1,5s trop tôt sur une fenêtre de 3s — mesuré sur le vrai moteur avant et après ce correctif (304/601/1501ms, inchangé). Expose BeepEngine.transitionGap (statique, lecture seule, _needsBigGap factorisée dedans) au lieu de dupliquer la règle dans l'affichage. resolveUpcomingMovementSteps calcule le gap réel de chaque step à venir ; _computeFutureBeats décale son point de frontière de ce gap. Aucun changement de comportement audio : applyStep délègue à transitionGap la même valeur qu'avant, vérifié par mesure directe sur le vrai BeepEngine.
…ition Remesure indépendante du gap sur le vrai BeepEngine (avant et après le correctif de 5ee149f), vérification exhaustive de l'espacement minimal des steps dans les milestones (jamais en dessous du gap max), et complément de date sur l'erratum du rapport initial (réserve 2, déjà corrigée par f8da372).
Passe adverse sur le seul diff du round 2 (5ee149f, e1d38e9). Comportement audio : matrice complète des 162 cas atteignables (9 modes de départ x 9 d'arrivée x to null/non-null) mesurée sur le vrai BeepEngine, avant et après le refactor — relevés identiques. Risque laissé ouvert par le round 2 : fermé par la mesure. 1232 séances générées (dont 592 portant une milestone du catalogue réel), 169 340 paires de steps de bip consécutifs, écart minimal 2000 ms, zéro point de reprise qui recule. Tests : trois mutations posées, chacune relevée rouge avec son statut. Verdict publiable. Deux réserves documentaires, aucune gênante : la phrase du round 2 sur addPoint décrit un garde-fou qui ne joue pas dans le cas qu'elle couvre (mesuré : la courbe fait un aller-retour, pas un segment sauté), et trois de ses paragraphes portent [mesuré] là où ils décrivent du code lu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.