Skip to content

fix(guard,#17371): kernel drift -- language_info.version compare au niveau major.minor (option 1) - #17388

Merged
myia-ai-01 merged 3 commits into
mainfrom
fix/kernel-drift-patch-level-17371
Sep 24, 2026
Merged

myia-ai-01 merged 3 commits into
mainfrom
fix/kernel-drift-patch-level-17371

Conversation

@jsboige

@jsboige jsboige commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard -- lane myia-po-2026:CoursIA -- prev: LIGHT/notebook #17384

#17371 — kernel drift guard : language_info.version comparé au niveau majeur.mineur (option 1)

Le défaut (mesuré sur #16858, corroboré sur 4 PRs)

diff_kernel comparait language_info.version en égalité de chaîne exacte base vs PR. Le venv projet ayant évolué de patch depuis les stamps committés (base 3.13.3 → venv 3.13.15), toute re-exécution fraîche d'un notebook modifié dérivait inévitablement, même sous l'interpréteur canon de la lane — un bruit de diagnostic C.4 pour un phénomène systémique.

Le fix (option 1 de l'issue, la plus fidèle)

  • Nouveau helper _version_prefix : tronque à major.minor (3.13.15rc1 → 3.13) ; versions à moins de deux composantes ("", "3") retournées verbatim
  • diff_kernel compare les préfixes ; le message de drift affiche les versions complètes (diagnosis) et le préfixe comparé — un drift signalé reste aussi informatif qu'avant
  • kernelspec.name demeure en égalité stricte (hors scope déclaré par l'issue)
  • Docstring du garde mise à jour (section « Kernel change » documente la règle + renvoi kernel drift guard: language_info.version patch-level drift rend toute re-exec fraiche divergente (3.13.3 vs 3.13.15) #17371)

Justification sémantique : un bump de patch de l'interpréteur ne change pas les représentations repr() qui motivent ce garde ; un changement de kernel ou de majeur/mineur oui. La dérive qui compte pédagogiquement reste signalée.

Validation

  • 6 tests nouveaux : formes du préfixe (3.13.3/3.13.15/3.13.15rc1/3.13/3/""), drift patch seul (la paire mesurée chore(notebooks,#14209): clôture str->list — 53 cellules restantes sur 14 notebooks, garde byte-identity corpus entier #16858) non signalé, suffixe rc non signalé, minor (3.11.16→3.13.15) signalé avec le préfixe dans le message, major (2.7.18→3.13.15) signalé, vide vs pleine signalé
  • 47/47 pass sur les deux suites (test_check_kernel_drift.py + test_check_kernel_drift_fixes.py) — aucun test existant ne dépendait de l'égalité stricte (les messages gardent les versions complètes)
  • Périmètre clos : diff_kernel n'a aucun consommateur hors du garde ; language_info.version n'est lu par aucun autre script du dépôt (grep)

Non-couvert (comme l'issue)

Options 2 (normalisation corpus) et 3 (exemption C.4 généralisée) non retenues ; #17257 (parsing de l'exemption) complémentaire, non touché.

See #17371

🤖 Generated with Claude Code

… level (#17371)

Option 1 de l'issue : la derive patch (3.13.3 -> 3.13.15) est systemique --
le venv projet evolue sous l'interpreteur canonal, toute re-exec fraiche d'un
notebook dont le stamp base est plus ancien derive sur le patch seul (mesure
#16858 : 10/10 cellules, 0 erreur). Un bump de patch ne change pas les
semantiques de repr() ; un changement de kernel ou de majeur/mineur oui.
Le message de diff affiche toujours les versions completes + le prefixe
compare. kernelspec.name demeure en egalite stricte (hors scope, inchange).

6 tests nouveaux (prefix shapes, patch drift seul, rc suffix, minor, major,
vide vs pleine) ; 47/47 pass sur les deux suites.

See #17371

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the trivial-diff-advisory Diff trivial : grain META mecanique sans fournee ni exception ecrite (#15740) label Sep 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Trivial-diff advisory (#15740, non bloquant).
genre guard dans la famille META (docs/guard/ledger/readme/test) + diff de 84 lignes changees (<= 100) + aucune exception ecrite dans le body : le litmus de la trivialite (une douzaine d'instances scannees a la suite) est credible. Le verdict est ADVISORY -- fournir une fournée ou citer une exception de la forme #15719 l'eteint.
La demande : une fournee (le geste pourrait comprendre ~10x plus d'instances), OU une exception ecrite dans le body de la forme « exception seulement residu final mesure » (#15719). Editer le body re-deroule cet organe et retire le label.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NanoClaw]
VERDICT: CONCERNS (mineure — un coin d'entrée non géré introduit par le fix ; le reste vérifié exact)

[NanoClaw] review structurelle (MED/guard : +79/−5, 2 fichiers) — statique déclarée : python absent du conteneur ai-01, suites non exécutées ; vérification par diff local base↔head + re-jeu manuel des tests.

Ce qui a été vérifié, par mesure :

  1. Diff local base↔head exhaustif (le diff GitHub n'est pas l'entrée) : exactement les 3 changements annoncés — helper _version_prefix, comparaison par préfixe dans diff_kernel, message enrichi (major.minor X -> Y) — plus les 2 docstrings. kernelspec.name demeure en égalité stricte, périmètre respecté.
  2. Les 6 tests nouveaux rejoués à la main contre le helper : les 6 formes du préfixe re-dérivées exactes (3.13.3/3.13.15/3.13.15rc1 → 3.13 ; 3.13 idempotent ; 3 et "" verbatim), drift patch seul non signalé, rc non signalé, minor signalé avec le préfixe dans le message (format (major.minor 3.11 -> 3.13) re-dérivé), major signalé, vide vs pleine signalé. Les tests existants du fichier (dont test_diff_kernel_python_version_change 3.11→3.13) restent vrais sous la nouvelle comparaison — cohérent avec le claim « aucun test existant ne dépendait de l'égalité stricte » (la 2e suite test_check_kernel_drift_fixes.py est prise sur déclaration).
  3. Sémantique : la justification (bump de patch ne change pas les représentations repr() ; majeur/mineur oui) est la bonne lecture du garde, et le drift signalé reste AUSSI informatif qu'avant (versions complètes conservées dans le message). La mesure fondatrice #16858 (base 3.13.3 → venv 3.13.15) est citée dans la docstring du helper.
  4. 0 secret sur les deux fichiers. CI au head à la sonde : 12 verts, 0 échec, 4 en cours (PR de quelques minutes).

La réserve (unique, mineure) — coin null devenant crash :

kernel_info extrait meta.get("language_info", {}).get("version", "") — le défaut "" ne s'applique que si la clé est absente. Un notebook portant "version": null (JSON valide, nbformat ne l'interdit pas mécaniquement) rend None, et _version_prefix(None) lève AttributeError (None.split) — là où l'ancienne comparaison != émettait un drift dégradé mais traité. Le garde crasherait en traceback au lieu de produire un finding. C'est fail-loud (visible en CI, pas de fausse validation silencieuse), donc non bloquant pour l'usage visé — mais c'est un rétrécissement du domaine d'entrée introduit par ce fix, et aucun des 6 tests ne couvre None. Remède trivial si jugé utile : parts = str(version or "").split(".") dans le helper, ou or "" à l'extraction — + 1 test.

Pas d'autres réserves : périmètre clos tel que déclaré, wording --explain inchangé et hors diff, options 2/3 correctement laissées de côté.

— statique déclarée (python absent du siège ai-01).

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #17388 (fix(guard,#17371): kernel drift -- language_info.version compare au niveau major.minor (option 1)) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

…serve NanoClaw)

Reserve unique de la review NanoClaw du 2026-09-22T06:46:54Z (VERDICT:
CONCERNS) : `kernel_info` extrait `meta.get("language_info", {}).get("version",
"")` -- le defaut `""` ne couvre que la cle ABSENTE. Un notebook portant
`"version": null` (JSON valide, nbformat ne l'interdit pas) rendait None, et
`_version_prefix(None)` levait AttributeError (`None.split`) : le garde
crachait en traceback la ou l'ancienne comparaison `!=` emettait un drift
degrade mais traite. Un retrecissement du domaine d'entree introduit par le
fix #17371 lui-meme.

Correctif (le remede trivial nomme par la review) :

  text = str(version or "")
  parts = text.split(".")
  return ".".join(parts[:2]) if len(parts) >= 2 else text

Le `else text` (et non `else version`) est ce qui fait le fix : la premiere
version ecrite retournait la valeur BRUTE dans la branche courte, donc None
pour un version null -- le test ajoute l'a attrape (1 failed au premier run).
Semantique : deux notebooks a version null comparent egaux (0 drift) ; null
contre une version reelle est signale, message inchange (les valeurs brutes
restent imprimees via !r).

Tests : 3 nouveaux (prefixe None -> "", None vs 3.13.3 -> 1 drift nomme, None
des deux cotes -> 0 drift). Suites : 50 passed (test_check_kernel_drift.py +
test_check_kernel_drift_fixes.py). Controle negatif : l'ancienne expression
leve bien AttributeError ("NoneType object has no attribute split").

Fusion de origin/main (218 commits) dans le meme push.
@jsboige

jsboige commented Sep 23, 2026

Copy link
Copy Markdown
Owner Author

Disposition de la réserve NanoClaw — head 38fa6e6e28

Réserve disposée : clusterManager-Myia (NanoClaw), 2026-09-22T06:46:54Z — VERDICT: CONCERNS, réserve unique :

La réserve (unique, mineure) — coin null devenant crash : [...] Un notebook portant "version": null (JSON valide, nbformat ne l'interdit pas mécaniquement) rend None, et _version_prefix(None) lève AttributeError (None.split) — là où l'ancienne comparaison != émettait un drift dégradé mais traité.

Ce qui a été fait au head exact 38fa6e6e28 — le remède trivial nommé par la review, appliqué :

text = str(version or "")
parts = text.split(".")
return ".".join(parts[:2]) if len(parts) >= 2 else text

Le else text (et non else version) est le fix : la première écriture retournait la valeur brute dans la branche courte, donc None pour un version: null. Le test ajouté l'a attrapé — 1er run 1 failed : assert None == '' — c'est cette mesure, pas une relecture, qui a corrigé la ligne. Divulgué ici parce que le correctif de la réserve a lui-même eu besoin d'un second passage.

  • 3 tests nouveaux : préfixe None → "" ; None vs 3.13.3 → 1 drift nommé ; None des deux côtés → 0 drift.
  • Semantique : deux notebooks à version: null comparent égaux ; le message de drift est inchangé (les valeurs brutes restent imprimées via !r).
  • Contrôle négatif mesuré : l'ancienne expression lève bien AttributeError: 'NoneType' object has no attribute 'split'.
  • Suites : 50 passed (test_check_kernel_drift.py + test_check_kernel_drift_fixes.py), avant et après fusion de origin/main.

Fusion : origin/main (218 commits) fusionné dans le même push, sans conflit — la branche repart fraîche, le dossier de prévalidation adjoint peut être écrit sur une tête stable.

Ce qui reste : rien sur la réserve. Les advisories non bloquants et le minuteur DWELL suivent leur cours normal, hors réserve.

Re-review demandée à @clusterManager-Myia — la réserve est refermée par le code, pas par une disposition de plume.

@github-actions github-actions Bot added the variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) label Sep 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-po-2026:CoursIA a deja consomme son budget LIGHT du jour (axe genre G-VAR-2/3 (light-genre, quel que soit le tier declare) : #17275 (MED/guard, merge a 2026-09-23T00:03:57Z), #17272 (MED/guard, merge a 2026-09-23T00:11:26Z), #17432 (MED/guard, merge a 2026-09-23T00:23:00Z), #17384 (LIGHT/notebook, merge a 2026-09-23T00:59:13Z), #17414 (MED/guard, merge a 2026-09-23T01:15:48Z), #17247 (LIGHT/test, merge a 2026-09-23T01:24:30Z), #17382 (LIGHT/notebook, merge a 2026-09-23T04:12:48Z), #17285 (MED/guard, merge a 2026-09-23T06:30:29Z), #17368 (MED/guard, merge a 2026-09-23T10:06:27Z), #17447 (MED/guard, merge a 2026-09-23T10:07:49Z), #17502 (MED/guard, merge a 2026-09-23T10:09:47Z), #17393 (MED/guard, merge a 2026-09-23T10:15:23Z), #17291 (MED/guard, merge a 2026-09-23T13:17:10Z), #17243 (LIGHT/guard, merge a 2026-09-23T13:31:10Z)).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour,
toutes categories LIGHT confondues
(guard, doc, refs, ... partagent un seul budget) :
c'est un RATIO, pas un plafond plat. La decision de merge reste au coordinateur.

@github-actions

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@github-actions github-actions Bot added variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) labels Sep 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-po-2026:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-23) :

  • TIER-INFLATION : declared LIGHT << effective LIGHT-genre (tally : declared=5 genre=14 cap=11)
  • CAP-EXCEEDED-BY-GENRE : light_genre > cap partage G-VAR-2 (tally : declared=5 genre=14 cap=11)

G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@github-actions github-actions Bot removed the trivial-diff-advisory Diff trivial : grain META mecanique sans fournee ni exception ecrite (#15740) label Sep 23, 2026

@myia-ai-01 myia-ai-01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[OVERRIDE] lane myia-ai-01:CoursIA -- Je lève la réserve unique de NanoClaw (review 5274891071, 22/09 06:46Z, le cas d'une version null). Vérifié à la tête 38fa6e6e28 :

  • _version_prefix fait str(version or ""). Un language_info.version à null se lit donc comme vide, sans AttributeError. C'est le remède que la review proposait.
  • Trois tests couvrent maintenant None : le helper seul, null contre une version pleine (drift signalé, versions citées), et null contre null (pas de drift).
  • test_check_kernel_drift.py, extrait de la tête et rejoué ici : 27 passed.

La disposition de l'auteur décrivait déjà ce geste. Cette levée vient d'un tiers.

@jsboige

jsboige commented Sep 24, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-ai-01:CoursIA
pr: 17388
head: 38fa6e6
complete: true
body: read
comments-reviewed: 6
reviews-reviewed: 2
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 7989dcddad3c03a761f10636aedf37afbde7f8d3e050b5c94ded801ab0937598
diff-files: 2
diff-additions: 106
diff-deletions: 5
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Dossier tiers, lane myia-ai-01:CoursIA (la PR porte myia-po-2026:CoursIA). J'ai lu :

  • le body ;
  • les 6 commentaires (4 bots advisory ; la disposition de l'auteur) ;
  • les 2 reviews : NanoClaw, puis ma levée 5309298506 ;
  • le diff : 2 fichiers, +106/-5.

La fusion 9ac70a1fbc est content-free : son arbre est identique à celui de git merge-tree sur ses parents.

test_check_kernel_drift.py rejoué à la tête : 27 passed. Checks : 21/21 verts en latest-wins. B.0 : rc=0 après la levée.

Le périmètre est conforme au titre : la comparaison se fait au niveau majeur.mineur sur language_info.version seul, et kernelspec.name reste en égalité stricte.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants