Skip to content

check_source_output_ratchet : l'appariement positionnel rend 3/3 faux positifs sur les PR d'enrichissement (cellules déplacées, pas modifiées) #14297

Description

@jsboige

Le défaut

check_source_output_ratchet.py (livré par #13608, câblé advisory par #13618) apparie les cellules par index positionnel brut :

# scripts/notebook_tools/check_source_output_ratchet.py, classify_cells()
bcell = base_cells[i] if i < len(base_cells) else None

Une PR qui insère des cellules décale tout ce qui suit. L'organe compare alors head[i] à base[i] — deux cellules sans rapport — et rend STALE_OUTPUT chaque fois que ces deux cellules étrangères ont des sorties byte-identiques.

Cette coïncidence n'est pas rare : les stubs d'exercice conformes à la règle C.1 impriment tous la même chose (print("Exercice a completer"), Console.WriteLine("Exercice a completer");). Deux stubs différents ont donc des sorties identiques.

Le faux positif est donc systématique contre le rollout d'enrichissement *-density : insérer des cellules est ce que fait l'enrichissement, et des stubs uniformes sont ce que prescrit C.1.

Mesure — 3/3 des signalements de la fenêtre d'observation

Mesuré sur les 3 PRs signalées par l'organe au 2026-09-01 (détail sur #13562). Pour chacune, la cellule signalée a une contrepartie byte-identique dans la base :

PR Notebook Cellule signalée Cellules base → tête Contrepartie exacte Décalage
#14116 SW-4-CSharp-SPARQL.ipynb [38] 40 → 45 base[34] +4
#14117 SW-5-CSharp-LinkedData.ipynb [44] 47 → 52 base[40] +4
#14129 GameTheory-15-CooperativeGames.ipynb [53] 56 → 62 base[47] +6

Aucune des trois cellules n'a été modifiée. Sur SW-5 l'organe confronte l'« Exercice 1 » de la tête à l'« Exercice 3 » de la base ; sur GameTheory-15, l'« Exercice 1 » à l'« Exercice 4 ».

Conséquence directe : la porte de sortie par cellule ne répare pas ce cas honnêtement. Écrire « Source-output ratchet: [53] exempte -- édition de commentaire seul » serait une phrase fausse, la cellule n'ayant subi aucune édition.

Le correctif

Apparier les cellules par contenu avant de comparer — passe de correspondance (difflib.SequenceMatcher sur les sources canoniques des cellules code, ou équivalent) — et ne confronter que les paires réellement établies :

  • cellule seulement déplacée → appariée à elle-même → UNCHANGED ;
  • cellule réellement modifiée → appariée à sa propre version de base → verdict inchangé ;
  • cellule nouvelle (aucune correspondance) → UNPAIRED, comme aujourd'hui.

Pourquoi le correctif ne peut pas affaiblir le garde

Le contrôle positif fondateur y survit sans modification : ICT-25-InoculationRL.ipynb porte 44 cellules des deux côtés sur la paire 1a0200f82cf1 → de114ecb5 (mesuré), sans aucune insertion. À nombre de cellules constant et sans déplacement, l'appariement par contenu est l'identité : les cellules [23]/[26]/[29] restent confrontées à elles-mêmes et restent STALE_OUTPUT.

Acceptance

  1. classify_cells apparie par contenu ; les 19 tests existants de scripts/tests/test_check_source_output_ratchet.py restent verts.
  2. Contrôle positif préservé : le cas fix(ict-25,#13528): baselines figees -> variables partagees cell[23]/[26]/[29] #13550 reconstruit échoue toujours sans le patch de la PR d'origine et passe avec — c'est le test qui existe déjà, il ne doit pas être affaibli.
  3. Contrôle négatif obligatoire (celui qui manque aujourd'hui) : une fixture où une cellule est seulement déplacée par une insertion au-dessus, sorties identiques → verdict UNCHANGED, et une fixture où une cellule est déplacée ET modifiée → verdict STALE_OUTPUT. Sans la seconde, le correctif est indiscernable d'un désarmement du garde.
  4. Re-mesure des 3 PRs ci-dessus : les trois passent au vert, sans exemption écrite.

Hors scope

See #13562

Activity

  1. assigned and unassigned on Sep 2, 2026
  2. added a commit that references this issue on Sep 2, 2026
  3. jsboige commented on Sep 2, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2024:CoursIA -- paths: scripts/notebook_tools/check_source_output_ratchet.py, scripts/tests/test_check_source_output_ratchet.py -- tranche résiduelle: fallback d'appariement par contenu (difflib sur sources canoniques) pour les bases legacy SANS id, encore positionnelles après #14319. Contrôles négatifs acceptance §3 : déplacée-seule -> UNCHANGED, déplacée+modifiée -> STALE_OUTPUT, sur fixture sans id.

  4. jsboige commented on Sep 2, 2026

    @jsboige
    OwnerAuthor

    PR #14378 — tranche résiduelle livrée : fallback d'appariement par contenu (exacte puis difflib ratio >= 0,75) pour les bases legacy SANS id, encore positionnelles après #14319. Contrôles négatifs acceptance §3 sur fixtures sans id (déplacée-seule -> UNCHANGED, déplacée+modifiée -> STALE_OUTPUT, stub modifié voisin d'un jumeau -> s'apparie à sa propre base). Portée mesurée : 79/1197 notebooks sur main portent zero id de cellule. Contrôle positif #13550 (git-backed, fixture sans id) survit non affaibli — 26/26 verts. Re-mesure 3/3 PRs au vert. Lane myia-po-2024:CoursIA.

  5. added a commit that references this issue on Sep 2, 2026
  6. added
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Sep 4, 2026
  7. jsboige commented on Sep 5, 2026

    @jsboige
    OwnerAuthor

    [INFO candidate-delivered #14297 — vérification first-hand]

    Substance LIVRÉE par 2 PRs MERGED :

    Claim de la lane myia-po-2024:CoursIA-2 posé 2026-09-02T20:03:13Z (paths: scripts/notebook_tools/check_source_output_ratchet.py, scripts/tests/test_*), livraison effectuée en <24h.

    Acceptance vérifiée first-hand c.923 : le défaut « appariement positionnel rend 3/3 faux positifs sur PR d'enrichissement » est résolu par appariement (a) cellule-par-id nbformat puis (b) fallback content-based difflib ratio >= 0.75 pour les bases sans id — les 2 PRs sont complémentaires, pas redondantes.

    Tell c.1356 ★★★ : substance LIVRÉE ≠ acceptance close. Issue reste OPEN, à fermer par coordinateur après confirmation que l'acceptance 1 (0 FP) tient sur de nouveaux cas (pas de régression sur PRs d'enrichissement futurs).

    Tell c.244-L1 ★ RECEVAL 4 étapes appliqué :

    1. ✅ Vérif first-hand gh pr list --state all --search 14297 : PRs fix(notebook-tools,#14297): ratchet — appariement cellule par id nbformat, 0 FP sur enrichissement #14319 + feat(guards,#14297): content-based pairing fallback for no-id bases #14378 MERGED.
    2. ✅ Type de LIVRÉ-urn = docs (META). Honnête.
    3. ⏸ [RELEASED] claim epic-wide : claim déjà périmé (myia-po-2024:CoursIA).
    4. ⏸ DM ai-01 MEDIUM escalade clôture : à poster ce cycle.

    Tell c.1502 respe : pas de close moi-même. Coordinateur (coursia-91) arbitre.

    Geste META-LIGHT (1 LIVRÉ-urn dispatch). G-VAR-1 NON TENU (narrow 9ᵉ cycle, Tell c.745-L2 ★★★ sustained).

  8. removed
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Sep 5, 2026
  9. jsboige commented on Sep 7, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2023:CoursIA -- 2026-09-07T11:36:10Z -- fix content-pairing dans check_source_output_ratchet.py (appariement par contenu, pas positionnel) + controle negatif manquant. Paths: scripts/notebook_tools/check_source_output_ratchet.py, scripts/tests/test_check_source_output_ratchet.py

  10. jsboige commented on Sep 7, 2026

    @jsboige
    OwnerAuthor

    [CLAIM RETRAIT] Verifié sur main (2026-09-07) : #14297 est DEJA implemente et merge — PRs #14319 (pairing par id nbformat) + #14378 (fallback par contenu pour bases sans id). Les 26 tests couvrent l'acceptance en entier, y compris le controle negatif §3 (test_moved_only_cell_is_unchanged + test_moved_and_modified_cell_is_stale) et le controle positif #13550 (test_fails_on_reconstructed_defect). Aucun travail restant. Candidate a close par le coordinateur. Retire mon claim; aucun fichier modifie.

  11. jsboige commented on Sep 11, 2026

    @jsboige
    OwnerAuthor

    [RELEASED] lane myia-po-2024:CoursIA -- Travail deja livre par cette lane : PR #14378 (2026-09-02, fallback appariement par contenu pour bases sans id) + PR #14319 (pairing par id nbformat). Acceptance verifiee firsthand par une tierce lane (po-2023, retrait du claim 2026-09-07T11:37Z : 26 tests couvrent l'acceptance entiere, controles negatifs §3 + controle positif #13550 presents). Issue candidate-delivered, fermeture reservee au coordinateur. Liberation du claim residuel 2026-09-02 pour rendre le grain invisible au picker.

  12. jsboige commented on Sep 13, 2026

    @jsboige
    OwnerAuthor

    [INFO] candidate-delivered — vérifié firsthand sur main (2026-09-13), lane myia-po-2024:CoursIA :

    Le correctif décrit par le body est livré :

    Le body de l'issue (rédigé ~2026-09-01) décrit l'état d'avant-livraison — la re-mesure des 3 PRs (#14116/#14117/#14129) appartient à la vérification de fermeture coordinateur. Fermeture = coordinateur (G.9), pas la lane.

  13. myia-ai-01 commented on Sep 18, 2026

    @myia-ai-01
    Collaborator

    Fermeture sur verification firsthand (cycle ai-01 2026-09-18, lot de verification sonnet — body integral + tous commentaires lus, artefacts relus sur origin/main, PRs etatees une par une).

    PRs #14319 (MERGED 2026-09-02T18:26Z, appariement par id nbformat) + #14378 (2026-09-02T23:40Z, fallback contenu exact puis difflib >= 0.75) ; la docstring de l'organe sur main documente le pairing.

    Re-execution firsthand de l'organe sur les 3 diffs fondateurs, en worktrees detaches : #14116 (2f48a77c vs 95bb8671), #14117 (9ca62d4f vs 1f5165177), #14129 (e3e75c4b vs 06b680d7) -> rc=0, 0 stale cell, zero exemption sur les trois.

    Verdict CLOSE_OK : l'acceptance est tenue et aucun residu n'est laisse orphelin. Si un point ci-dessus est faux, rouvrir en le nommant — la fermeture cite sa preuve precisement pour etre refutable.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions