🔀 merge: develop → main — correctifs #41/#42, sécurité et CI sur main - #75
Merged
Conversation
Le site est servi en project page (talkcontrol.github.io/talk-control/) mais base valait '/' : tous les assets étaient référencés à la racine du domaine et 404aient — page publiée sans style ni JS. Vérifié en local : 6 références préfixées, 0 à la racine après build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🐛 fix: base VitePress /talk-control/ — assets 404 sur GitHub Pages
- openspec init — structure openspec/specs/ + openspec/changes/ - config.yaml avec contexte TalkControl (stack, conventions, règles) - 9 skills + 9 commands /opsx:* dans .claude/ pour Claude Code - .gitignore : exceptionner .claude/commands/ et .claude/skills/openspec-*/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le zoom du plugin touch-pointer calculait sa translation à partir de window.innerWidth/innerHeight alors qu'il applique le transform sur #slideViewFrame. En vue presenter, le frame n'occupe que 3/5 de la largeur : mesuré avant correctif, la slide était projetée en x=835..2339 pour une fenêtre de 1280, soit entièrement hors de l'écran. - extraction de la géométrie dans touch-pointer/zoom.ts, testable sans layout (jsdom n'en calcule pas) : t = s · (centre − point), dans le repère du frame ; - plafonnement de la translation à (s − 1) · taille / 2, pour que le frame agrandi recouvre toujours sa boîte — sans quoi un clic en coin décolle un bord et laisse apparaître du vide ; - _toggleZoom reçoit désormais les pourcentages bruts et les convertit contre le rect du frame, plus contre la fenêtre ; - overflow: hidden sur #slideViewSection en filet de sécurité. Tests : 8 cas unitaires sur la fonction pure (dont une propriété de recouvrement balayant toutes les positions de clic), 3 cas sur _toggleZoom, et un e2e golden-path vérifié rouge sans le correctif.
Le pointeur quittait bien le DOM à la désactivation — le symptôme décrit dans l'issue est corrigé depuis le passage au shadow DOM — mais le reste du teardown ne suivait pas. Mesuré sur l'app réelle, trois cycles activer/désactiver faisaient grimper `callbacks` à 1, 2 puis 3 : chaque événement du plugin repartait en autant d'exemplaires. - Plugin.unload() (classe de base) purge les callbacks et repasse `initialized` à false ; les surcharges appellent super.unload() ; - touch-pointer : clearInterval du timer de masquage, restauration des styles posés sur le frame (dimensions, transition, curseur) et remise à zéro du transform — désactiver en état zoomé laissait sinon la slide hors cadre, sans retour possible ; - touch-pointer : le handler `message` était enregistré via une lambda inline, donc impossible à détacher — référence stabilisée ; - keyboard et touch : même traitement. Ils n'étaient pas concernés tant que unload() était un no-op, mais la base remet désormais `initialized` à false : sans détacher, une réactivation doublerait leurs listeners. Tests : contrat de la classe de base, 6 cas de teardown sur touch-pointer, détachement des listeners sur keyboard et touch, et une régression sur pluginService couvrant trois cycles complets.
🔧 chore(tooling): intégrer OpenSpec pour le workflow spec-driven
npm audit remontait 5 failles high sur develop, toutes transitives, sans que rien n'échoue : le contrôle vivait dans scripts/verify.sh mais n'avait aucun job dans la CI. Les vulnérabilités pouvaient donc dériver indéfiniment tant que personne ne lançait le script en local. - npm audit fix (sans --force) : brace-expansion 5.0.7 → 5.0.9, nanoid 3.3.15 → 3.3.18, postcss 8.5.16 → 8.5.26, socket.io-parser 4.2.6 → 4.2.7, undici 7.28.0 → 7.29.0. Cinq bumps patch/mineurs sur des dépendances transitives ; package.json est inchangé, aucune dépendance directe ne bouge ; - job `audit` ajouté à develop.yml. npm audit sort en code non nul dès qu'il trouve quelque chose, donc aucune commande supplémentaire n'est nécessaire pour faire échouer le job ; - CLAUDE.md : verify.sh y était présenté comme le miroir de la CI, ce qui est faux au niveau ligne à ligne et m'a fait conclure à tort que develop était déjà rouge sur l'audit. Nuance ajoutée. ./scripts/verify.sh : typecheck, lint, coverage, e2e, build, audit et docs OK — audit inclus pour la première fois.
Le défaut de `--audit-level` est `null`, soit un échec sur n'importe quelle sévérité, `info` comprise. Le job tel qu'ajouté au commit précédent était donc plus strict que ce qui l'a motivé : les 5 failles corrigées étaient toutes `high`, mais un simple avis `low` sur une transitive de build aurait bloqué la CI. Le coût n'est pas théorique : `npm audit` interroge la base d'avis du registre à l'instant du run, alors que le lockfile est gelé. Un avis publié entre deux commits rend rouge la PR suivante, quels que soient son auteur et son sujet — le job n'accuse pas le coupable, il accuse le prochain qui passe. Autant réserver cette interruption aux failles qui la justifient. - job CI et scripts/verify.sh alignés sur `--audit-level=high` : un écart entre les deux ferait échouer localement ce qui passe en CI, alors que le script sert de garde avant PR ; - CLAUDE.md mis en cohérence : le seuil est explicite, et `npm audit` sans option reste la commande pour la photo complète. Les alertes Dependabot du dépôt, déjà actives, couvrent la veille de fond sur les sévérités inférieures.
🔒 fix(deps): résorber les 5 vulnérabilités high et les surveiller en CI
Aucune PR ciblant `main` ne déclenchait le moindre contrôle : le workflow ne s'abonnait qu'à `develop`. Les trois PR Dependabot ouvertes (#68, #69, #70), qui visent `main`, affichent littéralement « no checks reported » — et `main` est la branche par défaut du dépôt, donc celle où atterrissent les mises à jour de sécurité. - `push` et `pull_request` couvrent désormais `develop` et `main` ; - workflow renommé « CI — Node 24 », l'intitulé « Develop CI » étant devenu faux. Le nom de FICHIER reste `develop.yml` : il est référencé par le badge du README, CLAUDE.md et plusieurs docs d'amélioration, et le renommer casserait les liens vers les runs existants ; - `docs-deploy` est déjà conditionné à `refs/heads/develop`, il skippe donc sur `main` sans rien changer au déploiement des docs. Aucune protection de branche n'est configurée sur le dépôt, donc le renommage du workflow ne casse aucune règle de checks requis.
🔧 chore(ci): faire tourner la CI sur main aussi
This was referenced Aug 13, 2026
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.
Aligne
mainsurdevelop. Merge à blanc vérifié : aucun conflit.mainest la branche par défaut du dépôt. Son lockfile porte encore les 5 versions vulnérables, et c'est cette branche que scanne Dependabot — d'où les 8 alertes toujours ouvertes malgré le correctif déjà livré surdevelop.Contenu
Sécurité
brace-expansion5.0.7 → 5.0.9,nanoid3.3.15 → 3.3.18,postcss8.5.16 → 8.5.26,socket.io-parser4.2.6 → 4.2.7,undici7.28.0 → 7.29.0. Toutes transitives,package.jsoninchangé.audit(seuilhigh), qui n'existait pas.Correctifs
Outillage
main: jusqu'ici, aucune PR vers la branche par défaut ne déclenchait le moindre contrôle.Effet sur les PR Dependabot ouvertes
Ce merge les rend caduques toutes les trois — il va plus loin qu'elles :
socket.io-parser→ 4.2.7mainundici→ 7.29.0mainpostcss→ 8.5.25mainEt il couvre en plus
nanoidetbrace-expansion, pour lesquels Dependabot n'a ouvert aucune PR (ces deux avis remontent vianpm auditmais pas via les alertes du dépôt).Les trois PR devraient se fermer d'elles-mêmes au prochain scan Dependabot. Sinon, à fermer manuellement comme superseded.
Point ouvert : faut-il taguer ?
package.jsonest resté en 0.6.0, et le dernier tag estv0.6.0. Ce merge apporte deux correctifs de bugs et une mise à jour de sécurité par-dessus la 0.6.0 — sémantiquement, une 0.6.1.Je n'ai ni bumpé la version ni créé de tag :
release.ymlse déclenche surpushde tagv*, donc taguer publie. C'est ta décision, et elle mérite d'être prise explicitement plutôt que déduite. Deux options :mainest sécurisée, la publication attend un vrai jalon ;