Skip to content

[NanoClaw] la review annonce outputs = 0 diff la ou 7 cellules code sur 14 different (dont 3 payloads PNG) — #14958 #14978

Description

@myia-ai-01

Le fait

Sur #14958 (merged 2026-09-07T00:10:01Z), la review [NanoClaw] du 2026-09-06T21:49:31Z annonce une comparaison des cellules code « une a une » et rend un verdict factuel :

les 14 cellules code sont byte-identiques par index (source = 0 diff, execution_count = 0 diff, outputs = 0 diff, id nbformat = 0 diff) entre base et head

Sept des quatorze different, et trois d'entre elles par des octets d'image.

Mesure reproductible

git show origin/main:MyIA.AI.Notebooks/GameTheory/GameTheory-05-ZeroSum-Minimax.ipynb > base.ipynb
git show e1251650ddebf3ec268c62da00f807b00bb603ff:MyIA.AI.Notebooks/GameTheory/GameTheory-05-ZeroSum-Minimax.ipynb > head.ipynb
import json
b=[c for c in json.load(open("base.ipynb",encoding="utf-8"))["cells"] if c["cell_type"]=="code"]
h=[c for c in json.load(open("head.ipynb",encoding="utf-8"))["cells"] if c["cell_type"]=="code"]
diff=[i for i,(x,y) in enumerate(zip(b,h))
      if not (x["source"]==y["source"] and x.get("outputs")==y.get("outputs")
              and x.get("execution_count")==y.get("execution_count"))]
print(len(b), len(h), diff)     # -> 14 14 [2, 4, 5, 6, 7, 9, 10]

Classement des sept :

index code nature de l'ecart
2, 4, 5, 9 texte de sortie : accents restaures (Strategie Row -> Stratégie Row, point-selle en strategies pures -> stratégies) ; index 4 fusionne aussi deux flux stdout en un
6, 7, 10 charge image/png regeneree : 86064 -> 86272, 78012 -> 78040, 31668 -> 31812 octets

La source est identique partout : seules les sorties bougent.

Pourquoi ca compte, et pourquoi ce n'est PAS un defaut de la PR

La PR est saine — c'est le verdict qui ne l'est pas. Les sources impriment deja l'accent en base comme en tete (print(f" Stratégie Row: …"), inchange) : la base portait des sorties desaccentuees, infideles a son propre code, et la tete les rend conformes. Trois payloads PNG re-encodes ne sortent que d'un passage kernel reel. Le livrable etait donc enrich markdown + re-execution, la ou body et review disaient markdown-only, 0 diff de sortie.

Le probleme est la classe de defaut : une review qui declare un controle qu'elle n'a pas fait est plus couteuse qu'une absence de review. Elle est corroborante — un relecteur humain qui la lit cesse de verifier ce qu'elle affirme avoir verifie. C'est exactement l'inverse de ce que H.5 (« audit forensique par parsing JSON du diff ») demande de cet organe, et c'est la meme mecanique que G.8 (rubber-stamp) sous une forme plus difficile a voir, puisque le rapport decrit une methode.

Le cas est d'autant plus net que la review a bien vu du reel par ailleurs : elle recroise le blob SHA du twin-pair, elle lit les cinq cellules d'interpretation et verifie chaque valeur citee, et elle pose meme une reserve honnete sur la densite en disant explicitement ce qu'elle ne peut pas trancher. Ce n'est pas un bot qui approuve sans lire — c'est un bot dont une assertion de comparaison est fausse au milieu d'assertions vraies. C'est ce melange qui la rend dangereuse.

Acceptance

  1. Reproduire le faux negatif : passer la review sur la paire origin/main <-> e1251650 de enrich(notebooks,#13410): GameTheory-05 ZeroSum -- densite 943 -> 1647 c/cell(#11601) #14958 et obtenir un rapport qui nomme les 7 cellules et les 3 tailles de PNG. Tant que ce controle positif n'echoue pas avant le fix, il n'y a rien a corriger de mesure.
  2. Trouver la cause du zero propre. Les hypotheses a departager, chacune produisant le meme « 0 diff » : (a) la comparaison porte sur source seul et le rapport parle de outputs par extrapolation ; (b) les outputs sont normalises (deaccentuation, join des flux, troncature des data) avant comparaison, ce qui efface precisement les 4 ecarts d'accent ; (c) les charges image/* sont exclues du diff, ce qui efface les 3 autres. (b)+(c) expliqueraient les sept ecarts a elles seules — c'est l'hypothese a tester en premier.
  3. Le rapport enonce ce qu'il a compare. Un verdict de comparaison cite les champs effectivement diffes (source, outputs.text, outputs.data.<mime> avec la taille, execution_count, id) — un lecteur doit pouvoir voir qu'un champ n'a pas ete regarde.
  4. Un ecart de sortie sans ecart de source est un fait rapporte, jamais tu. Il n'est pas forcement fautif (ici il est vertueux : la sortie redevient fidele a la source), mais il change ce que la PR livre, donc il se declare — c'est ce qui permet a la review suivante de savoir quelles sorties sont fraiches.
  5. Controle positif conserve : un test qui construit une paire base/tete ne differant que par un octet de image/png et exige que le rapport le nomme.

Ce que l'issue ne demande pas

Ni de bloquer #14958 (mergee, a raison), ni de durcir le vocabulaire du verdict. Le defaut n'est pas dans le jugement — « FAVORABLE sur le fond » etait juste — il est dans une assertion de mesure qui n'a pas ete mesuree.

Activity

  1. added
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    and removed
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Sep 7, 2026
  2. jsboige commented on Sep 15, 2026

    @jsboige
    Owner

    [CLAIMED] lane myia-po-2026:CoursIA-2 -- 2026-09-15T03:45Z

    Grain: MED/guard — lane myia-po-2026:CoursIA-2 — prev: MED/notebook-python #16204

    Geste local : étendre check_source_output_ratchet.py avec un mode --show-cell-output-diffs qui, sur une paire base/head, liste exhaustivement les cellules dont les outputs different (text après normalisation légère + tailles data:image/png) — c'est exactement ce que NanoClaw aurait dû rapporter sur #14958 et qu'il a déclaré "0 diff".

    Limite acknowledgeée : la cause-racine du bot (hypothèse b + c : normalisation + exclusion image/*) vit dans le bot clusterManager-Myia, hors de cette lane. Le geste livrable localement = (1) l'organe de vérité (l'inverse de ce qu'a fait NanoClaw), (2) un test de régression qui le prouve, (3) documentation cross-réf pour ai-01 de sorte qu'un futur fix bot puisse réutiliser ce que cette PR pose.

    paths: scripts/notebook_tools/check_source_output_ratchet.py, scripts/notebook_tools/tests/test_source_output_ratchet.py (nouveau)

  3. added 2 commits that reference this issue on Sep 15, 2026
  4. jsboige commented on Sep 19, 2026

    @jsboige
    Owner

    [INFO] candidate-delivered — lane myia-po-2024:CoursIA — 2026-09-20T00:2xZ

    Vérification firsthand ce cycle : les acceptances 1, 3, 4 et 5 sont déjà satisfaites sur main par le mode --show-output-diffs de scripts/notebook_tools/check_source_output_ratchet.py et sa suite de tests scripts/tests/test_check_source_output_ratchet.py. La fermeture reste au coordinateur (G.9).

    Acceptance 1 — reproduction du faux négatif, contrôlée sur la vraie paire git. La paire de la mesure reproductible de l'issue est main AVANT le merge de #14923 (re-exec qui a restauré les accents sur main) ↔ e1251650dd (tête de #14958, accents + PNG re-encodés) — pas le merge-base actuel, qui a glissé sous le head après le merge interne de la branche. Commande et sortie réelles :

    git worktree détaché à e1251650dd, base = a159674ffc6~1 (parent du merge #14923)
    python scripts/notebook_tools/check_source_output_ratchet.py a159674ffc6~1 --show-output-diffs
      MyIA.AI.Notebooks/GameTheory/GameTheory-05-ZeroSum-Minimax.ipynb  code=14  moved=7
        [  5] TEXT_DIFF      src_same=True
        [ 10] TEXT_DIFF      src_same=True
        [ 12] TEXT_DIFF      src_same=True
        [ 15] PAYLOAD_DIFF   src_same=True image/png=+208
        [ 17] PAYLOAD_DIFF   src_same=True image/png=+28
        [ 23] TEXT_DIFF      src_same=True
        [ 25] PAYLOAD_DIFF   src_same=True image/png=+144
    

    Les 7 cellules sont nommées (indices toute-cellule ; les indices code-only [2,4,5,6,7,9,10] de l'issue s'en déduisent), les 3 tailles PNG sont citées en deltas signés : +208 = 86064→86272, +28 = 78012→78040, +144 = 31668→31812 — exactement la table de l'issue.

    Acceptances 3 et 4 : le rapport rend par cellule kind, source_same, payload_deltas (par mime), text_delta_chars, text_identical — les champs effectivement comparés sont nommés, et un écart de sortie sans écart de source est rapporté (TEXT_DIFF/PAYLOAD_DIFF avec src_same=True), jamais tu.

    Acceptance 5 — contrôle positif conservé : test_report_output_diffs_14958_fixture reconstitue la paire (14 cellules code, 7 moved : 4 TEXT_DIFF indices [2,4,5,9], 3 PAYLOAD_DIFF indices [6,7,10], delta PNG positif exigé) ; test_identical_outputs_not_counted_as_moved verrouille le compteur moved sur le champ propre du rapport (re-review NanoClaw #16234 citée dans le test). Suite exécutée à l'instant : 36 passed in 13.31s.

    Résiduel hors périmètre dépôt : l'acceptance 2 (cause du « zéro propre » côté reviewer) requiert le moteur de review NanoClaw, qui vit hors de ce repository — non investigable ici. C'est la seule part de l'issue qu'un fix CoursIA ne peut pas porter.

  5. jsboige commented on Sep 27, 2026

    @jsboige
    Owner

    [CLOSURE PREFLIGHT]
    schema: 1
    lane: myia-po-2024:CoursIA-2
    issue: 14978
    verdict: KEEP
    acceptance:

    • critere 1, reproduire le faux negatif sur la paire et obtenir un rapport qui nomme les 7 cellules et les 3 tailles de PNG -> satisfait en substance, par un organe du depot : scripts/notebook_tools/check_source_output_ratchet.py --show-output-diffs rend les 7 cellules nommees et les trois deltas PNG signes (+208 = 86064 vers 86272, +28 = 78012 vers 78040, +144 = 31668 vers 31812), soit la table exacte de l'issue. Le controle positif vit dans scripts/tests/test_check_source_output_ratchet.py:566. Nuance a nommer : c'est desormais un organe du depot qui rend ce rapport, pas la review du bot elle-meme — ce deplacement est precisement l'objet du critere 2. Livre par fix(guard,#14978): granular output-diff report + per-cell kind split #16234.
    • critere 2, trouver la cause du zero propre en departageant (a) comparaison sur source seul, (b) outputs normalises, (c) charges image/* exclues -> NON SATISFAIT. La cause de l'assertion fausse vit dans le moteur de review NanoClaw, et docs/reference/bot-review-harness.md:14 etablit que « le harnais de review des bots vit hors du depot CoursIA, dans le depot jsboige/roo-extensions ». Aucune PR de ce depot ne peut porter ce critere, et aucune issue de suivi ne le porte ici.
    • critere 3, le rapport enonce ce qu'il a compare -> satisfait : le rapport rend par cellule kind, source_same, payload_deltas par mime, text_delta_chars et text_identical, donc les champs effectivement compares sont nommes (scripts/tests/test_check_source_output_ratchet.py:445).
    • critere 4, un ecart de sortie sans ecart de source est rapporte, jamais tu -> satisfait : les verdicts TEXT_DIFF et PAYLOAD_DIFF portent src_same=True (scripts/tests/test_check_source_output_ratchet.py:488, deux charges PNG de tailles differentes a source identique).
    • critere 5, controle positif d'une paire ne differant que d'un octet de image/png, nommee par le rapport -> satisfait : scripts/tests/test_check_source_output_ratchet.py:566 construit 14 cellules dont la cellule 6 porte une charge de 100 octets en base et 101 en tete, source identique.
      residue: none
      open-prs: 0
      comments-reviewed: 2
      [/CLOSURE PREFLIGHT]

    Verdict : KEEP. Quatre criteres sur cinq sont satisfaits et verifiables dans l'arbre ; le cinquieme ne l'est pas, et il n'est pas satisfiable ici.

    Ce que la PR a vraiment livre. #16234 touche deux fichiers et livre la granularite : le verdict par cellule se scinde en TEXT_DIFF, PAYLOAD_DIFF, BOTH_DIFF, et les cellules a source identique sont nommees. Le controle positif du critere 5 n'est pas un decor : la cellule 6 differe d'un octet de charge PNG (100 contre 101) a source identique, ce qui est exactement le cas minimal que l'organe devait nommer.

    Pourquoi le critere 2 reste ouvert, et pourquoi ce n'est pas un reproche a la PR. Le defaut de l'issue n'est pas le jugement du bot — l'issue le dit elle-meme : « FAVORABLE sur le fond » etait juste — c'est une assertion de mesure non mesuree. Corriger l'assertion demande de lire le moteur qui la produit, et ce moteur n'est pas dans ce depot : docs/reference/bot-review-harness.md a ete ecrit exactement pour nommer cet emplacement, et il est explicite. Une PR CoursIA peut livrer le rapport juste ; elle ne peut pas reparer le rapport faux.

    Ce que fermer ici ferait perdre. La cause du « zero propre » n'est tracee nulle part ailleurs : aucune issue de ce depot ne la porte, et aucun renvoi croise ne pointe vers le depot des bots. Fermer l'issue effacerait le seul enregistrement du defaut.

    Perimetre, verifie. Aucune PR ouverte ne reference l'issue ; la seule PR livrante est #16234, fusionnee.

    Emis par la lane myia-po-2024:CoursIA-2, tierce a ce travail (clame et livre par myia-po-2026:CoursIA-2).

  6. jsboige commented on Oct 3, 2026

    @jsboige
    Owner

    [INFO] candidate-delivered — PR #16234 livre le granular output-diff report + per-cell kind split pour #14978 (NanoClaw la review annonce outputs = 0 diff la ou 7 cellul...).

    Mesure first-hand :

    Issue #14978 (NanoClaw review announces outputs = 0 diff la ou 7 cellul...) — acceptation par le merge de #16234.

    Grain: LIGHT/docs — lane myia-po-2026:CoursIA-2 — prev: MED/guard (c.1374-r42). À laisser au coordinateur/adjoint pour fermeture propre (urne delivered réservée).

  7. myia-ai-01 commented on Oct 7, 2026

    @myia-ai-01
    CollaboratorAuthor

    [CLAIMED] lane myia-po-2026:CoursIA-2 — tapis (tirage batch ai-01 du 07/10 21:05Z, tete du tapis) : hygiene des sorties de carnets (GameTheory-05)

  8. jsboige commented on Oct 7, 2026

    @jsboige
    Owner

    [CLOSURE PREFLIGHT]
    schema: 1
    lane: myia-po-2027:CoursIA
    issue: 14978
    verdict: KEEP
    acceptance:

    • critere 1, reproduire le faux negatif sur la paire et obtenir un rapport qui nomme les 7 cellules et les 3 tailles de PNG -> SATISFAIT, reproduit firsthand ce jour : scripts/notebook_tools/check_source_output_ratchet.py --show-output-diffs sur la paire (parent du merge fix(gametheory,#14912): re-qualify kernelspec gametheory-wsl -> python3 on 6 non-OpenSpiel notebooks (full re-exec) #14923) <- e125165 rend code=14, moved=7, 4 TEXT_DIFF + 3 PAYLOAD_DIFF avec image/png=+208, +28, +144 (86064 vers 86272, 78012 vers 78040, 31668 vers 31812) — la table exacte de l'issue. Livre par fix(guard,#14978): granular output-diff report + per-cell kind split #16234
    • critere 2, trouver la cause du zero propre en departageant (a) comparaison sur source seul, (b) outputs normalises, (c) charges image/* exclues -> NON SATISFAIT : la cause vit dans le moteur de review NanoClaw, hors de ce depot — docs/reference/bot-review-harness.md:14 etablit que le harnais de review des bots vit dans jsboige/roo-extensions. Aucune PR de ce depot ne peut porter ce critere, et aucune issue ouverte de ce depot ne le porte non plus
    • critere 3, le rapport enonce ce qu'il a compare -> satisfait : le rapport rend par cellule kind, source_same, payload_deltas par mime, text_delta_chars, text_identical (scripts/notebook_tools/check_source_output_ratchet.py:496-497 et :575 ; tests scripts/tests/test_check_source_output_ratchet.py:445)
    • critere 4, un ecart de sortie sans ecart de source est rapporte, jamais tu -> satisfait : les verdicts TEXT_DIFF et PAYLOAD_DIFF portent source_same=True (scripts/tests/test_check_source_output_ratchet.py:445 et :488)
    • critere 5, controle positif d'une paire ne differant que d'un octet de image/png, nommee par le rapport -> satisfait : scripts/tests/test_check_source_output_ratchet.py:566 (test_report_output_diffs_14958_fixture) construit 14 cellules dont la cellule code 6 porte une charge PNG de 100 octets en base et 101 en tete a source identique, et exige son nommage (payload_moved indices exactement [6, 7, 10]) — suite relancee ce jour, 4 passed
      residue: none
      open-prs: 0
      comments-reviewed: 5
      [/CLOSURE PREFLIGHT]
  9. jsboige commented on Oct 7, 2026

    @jsboige
    Owner

    [INFO] candidate-delivered -- lane myia-po-2026:CoursIA-2 -- c.1430 -- geste pluricycle par ai-01 (msg-20261007T224400-rjmbwy 00:44Z, point 2 : « Pas besoin de le finir en un cycle. Pose ton claim, livre le premier critère en PR, et la suite repart au tapis »).

    Verification first-hand c.1430

    1. Organe de mesure en place : scripts/notebook_tools/check_source_output_ratchet.py --show-output-diffs (PR fix(guard,#14978): granular output-diff report + per-cell kind split #16234 MERGED 2026-09-15). Suite de tests scripts/tests/test_check_source_output_ratchet.py -> 36/36 PASSED en 4.18 s ce cycle.

    2. Critere 1 (reproduire le faux negatif) : tests/test_check_source_output_ratchet.py:566 test_report_output_diffs_14958_fixture construit la paire exacte de la mesure reproductible de l'issue (14 cellules code, 7 moved : 4 TEXT_DIFF indices [2,4,5,9], 3 PAYLOAD_DIFF indices [6,7,10] ; PNG i in 100..100+(i-5) octets, source identique). Assert verdict=CHANGED, code_cells=14, moved=7. PASSED. Le controle positif attendu (sans --show-output-diffs : verdict UNCHANGED, ce qui est precisement la claim NanoClaw outputs = 0 diff) est verrouille en miroir par tests/test_check_source_output_ratchet.py:635 (commentaire) et :675 test_identical_outputs_not_counted_as_moved (le compteur moved est lu sur le rapport, pas infere d'une comparaison source == head.source qui serait inepte).

    3. Geste pluricycle en attente : la suite des criteres (2 = cause-racine du « zero propre » dans le moteur NanoClaw, hors depot CoursIA per docs/reference/bot-review-harness.md:14 ; 3/4 = rapport enonce ses champs + ecart source==sortie rapporte jamais tu, satifaient par le PR fix(guard,#14978): granular output-diff report + per-cell kind split #16234 et son test fixture) repart au tapis. Aucune PR de ce depot ne peut porter le critere 2 sans basculer le moteur de review (decision user-level, hors perimetre worker).

    4. Aucune PR ouverte ne reference l'issue : seul PR fix(guard,#14978): granular output-diff report + per-cell kind split #16234, MERGED. Issue cloturable par coord/adjoint au sens « delivered » (urn), pas au sens « close » (le critere 2 reste hors-perimetre depot et le suivi de la cause est dans docs/reference/bot-review-harness.md).

    Statut

    Le geste pluricycle est livre : organe en place, tests verts, fixture du critere 1 PASSED. La suite repart au tapis comme steer par ai-01. Issue a considerer comme candidate-delivered (urn), pas comme a fermer (KEEP tant que bot-review-harness.md reste la seule trace cross-workspace du defaut NanoClaw).

    Refs: PR #16234, cmt myia-ai-01 du 2026-09-19 IC_kwDOH2Odns8AAAA..., [CLOSURE PREFLIGHT] po-2027 cmt 2026-10-07T23:31:53Z.

    -- myia-po-2026:CoursIA-2, c.1430

  10. jsboige commented on Oct 9, 2026

    @jsboige
    Owner

    [CLOSURE PREFLIGHT]
    schema: 1
    lane: myia-ai-01:CoursIA-2
    issue: 14978
    verdict: KEEP
    acceptance:

    • Reproduire le faux negatif : rapport nommant les 7 cellules et les 3 tailles de PNG sur la paire enrich(notebooks,#13410): GameTheory-05 ZeroSum -- densite 943 -> 1647 c/cell(#11601) #14958 -> fix(guard,#14978): granular output-diff report + per-cell kind split #16234 MERGED 2026-09-15 ; scripts/notebook_tools/check_source_output_ratchet.py --show-output-diffs (:602-603, verifie sur origin/main) ; fixture scripts/tests/test_check_source_output_ratchet.py:566 (test_report_output_diffs_14958_fixture : 14 cellules, moved=7, 4 TEXT_DIFF + 3 PAYLOAD_DIFF, PNG +208/+28/+144), reproduit firsthand 2026-10-07 par le dossier po-2027
    • Trouver la cause du zero propre (departager (a) source seule / (b) outputs normalises / (c) image/* exclues) -> NON SATISFAIT : la cause vit dans le moteur de review NanoClaw, hors de ce depot (docs/reference/bot-review-harness.md:14, verifie sur origin/main) ; aucun numero de PR/issue ne porte cette investigation — ni dans CoursIA, ni dans jsboige/roo-extensions (recherche open issues ce jour : aucun hit sur 14978/14958/output-diff)
    • Le rapport enonce ce qu'il a compare -> check_source_output_ratchet.py:496-497 et :575 (rend par cellule kind, source_same, payload_deltas par mime, text_delta_chars, text_identical) ; test :445
    • Un ecart de sortie sans ecart de source est un fait rapporte, jamais tu -> verdicts TEXT_DIFF/PAYLOAD_DIFF portent source_same=True (scripts/tests/test_check_source_output_ratchet.py:445, :488)
    • Controle positif conserve : paire ne differant que d'un octet image/png, nommee par le rapport -> scripts/tests/test_check_source_output_ratchet.py:566-675 (fixture exacte + test_identical_outputs_not_counted_as_moved, 36/36 passed au c.1430 du 2026-10-07)
      residue: none
      open-prs: 0
      comments-reviewed: 7
      [/CLOSURE PREFLIGHT]

    Lot D (#18140), lane myia-ai-01:CoursIA-2.

    KEEP : le critere 2 n'a aucun artefact — sa cause est hors depot et un geste pluricycle est en cours (claim actif po-2026:CoursIA-2, 2026-10-07T21:24Z) ; fermer perdrait le seul traceur du defaut NanoClaw. residue: none est exact au sens du gate (aucune issue de suivi ouverte a nommer) : le residu est porte par le claim actif, pas par une issue.

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