Skip to content

fix(ci): cliquet split-reading -- faux positif sur une revision en place d'une cellule markdown sans id (#17464, #17044) #17747

Description

@jsboige

Symptome

Le garde bloquant Split-reading ratchet (base vs PR) (scripts/notebook_tools/check_split_reading_cells.py --base-ref) rougit une PR qui n'ajoute aucune cellule : il compte une révision en place comme un ajout dès que la cellule markdown révisée n'a pas d'id et n'est pas classée lecture par is_reading_cell.

Le mandat user cité par l'organe lui-même (« si on rajoute une lecture, on modifie le paragraphe de lecture existant, on n'en rajoute pas un deuxième ») prescrit cette réécriture : c'est le geste que le garde punit.

Cas réel mesuré

PR #17745 (tranche SymbolicAI de #17498, 18 défauts de rendu mathématique → 0). Le seul rouge de la PR après les 35 gardes de la fast lane :

REGRESSED .../SymbolicAI/OR-tools-Stiegler.ipynb  paires 0 -> 0 (+0)
    READING_BEFORE_CODE    cellules [31] src[:120]=### Exercice 3 : Analyse de sensibilite...

Mesure sur ce carnet (base = origin/main vs tête) : 38 cellules des deux côtés, 4 cellules dont la source diffère (indices 5, 15, 31, 33), aucune cellule ajoutée. La cellule 31 a changé pour une seule raison : l'échappement de la devise (39,66 $/an → 39,66 \$/an), correctif de rendu prescrit par #17498.

Cause racine

Le discriminant is_rewrite (ajouté par #17044) a trois signaux, tous manqués ici :

Signal Condition Pourquoi il manque
(a) même index et même source la source a changé (c'est l'objet de la PR)
(b) l'id de la tête existe en base la cellule n'a pas d'id (1 des 3 cellules sans id du carnet)
(c) même index et les deux sont des lectures is_reading_cell est faux : le titre est ### Exercice 3 : ...

La cellule retombe donc dans le diff de multiset comme un ajout, et le bucket READING_BEFORE_CODE (code avec sortie en amont) la signale.

Rayon d'exposition (mesuré)

Sur MyIA.AI.Notebooks/ : 229 carnets sur 1409 portent au moins une cellule markdown sans id (1978 cellules au total). Toute PR qui les réécrit en place — le geste prescrit — est exposée au faux positif.

Porte de contournement : aucune

L'organe n'a aucun mécanisme de justification par body (--pr-body-file, #13491) : contrairement au garde content-loss, un faux positif est un blocage dur, sans porte. À noter : #17744 / #17746 traitent la même classe sur le garde enrich-quality (marqueur body « réécriture assumée ») — ici le correctif porte sur le détecteur lui-même, ce qui évite la cérémonie de marqueur.

Correctif attendu

Étendre le signal topologique (c) de « les deux sont des lectures » à « les deux sont markdown » au même index : le signal ne dépend alors plus de la classification lecture/exercice, et il reste exact (pas de seuil flou) parce que l'empilement réel arrive toujours à un index où la base portait autre chose (ou rien).

Contrôles de non-régression à tenir :

  1. révision en place d'une cellule markdown sans id non-lecture → 0 finding (nouveau) ;
  2. empilement réel d'une lecture à l'index où la base portait du code → rouge (contre-preuve : le signal n'est pas un robinet ouvert) ;
  3. test_cliquet_mord_si_la_lecture_arrive_APRES (guard(notebooks): cabler check_split_reading_cells.py en cliquet bloquant — l'organe existe, 91 findings deja sur main, et la prose du STOP n'a pas tenu 42 minutes #17044) → rouge (inchangé).

Falsification attendue : le test (1) échoue avant le correctif sur l'organe de main.

See #17464 (mode diff), See #17044 (discriminant REWRITE), See #17744 (même classe, garde enrich-quality).

Activity

  1. added 2 commits that reference this issue on Sep 25, 2026
  2. added a commit that references this issue on Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions