Repository navigation
Fix(ci): la passe de metadonnees git ne doit plus dependre du reseau (#24230) - #24245
Conversation
Le checkout de `catalog-cron.yml` est un clone PARTIEL (`filter: blob:none`) : le contenu des blobs est absent du runner. La detection de renommages par defaut compare le CONTENU des blobs (similarite), donc `git log --name-only` allait chercher chaque blob candidat sur le fil. Le cout suivait la bande passante du runner -- pas son CPU, son disque ni son overlayfs -- d'ou le facteur 50 mesure entre runners (3,6 s -> 149 s) et le depassement de la borne de 180 s le 2026-11-02. `-M100%` restreint la detection aux renommages EXACTS (OID de blob identique), que les objets d'arbre repondent sans aucun contenu de blob : la passe redevient hors-ligne et deterministe. La garde bruyante de #14831 (plafond de 180 s, `GitMetadataUnavailable`) est conservee telle quelle. Mesure (conteneur, overlayfs et disque identiques, reseau injoignable) : forme par defaut rc=128 en 44 s, `-M100%` rc=0 en 2 s. Local : 6,2 s -> 1,5 s. Semantique comparee a travers le parseur de production sur les 1746 carnets suivis : meme ensemble de cles (3358 de part et d'autre), aucune divergence sur `first_commit`, sur le commit le plus recent ni sur les auteurs, et une seule difference de `revisions` -- `GenAI/Texte/09b_Prompt_Security_RedTeam` passe de 11 a 12, ce qui est une CORRECTION (`git log -- <chemin>` donne 12, la forme par defaut en attribue 11 au renommage). Part of #24230 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
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 |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] — review du head 4f7b0c59 (compte clusterManager-Myia, lane myia-ai-01:hermes-agent)
Rejeux exécutés (labo local, fichiers extraits au head)
Suite complète : pytest scripts/notebook_tools/tests/test_generate_catalog.py → 215 passed, 2 skipped (6,6 s). Le body annonce 217 passed — cohérent : 215+2 skips sont probablement des skips environnementaux de mon conteneur, l'essentiel est 0 failed.
Les 2 nouveaux tests rejoués isolément : TestBuildGitMetadataOfflinePartialClone::test_passe_reussit_sur_un_clone_partiel_ou_la_forme_par_defaut_echoue PASSED, test_le_plafond_bruyant_de_14831_est_conserve PASSED.
Témoin inverse (le contrôle qui contrôle) : en remplaçant GIT_LOG_RENAME_FLAG = "-M100%" par la chaîne vide (forme par défaut) dans l'organe, le test offline ROUGIT (1 failed) — le test ne passe pas de complaisance, il mesure réellement la dépendance réseau. Restitué ensuite (fichier byte-identique au head).
La garde #14831 reste armée : GIT_LOG_TIMEOUT_SECONDS = 180 et class GitMetadataUnavailable présents (l. 259/302), le second test vérifie le timeout par mock + pytest.raises, et asserte que l'argv du git log embarque bien -M100%, --name-only et le timeout. Ce n'est pas un débrayage silencieux.
Vérifications croisées
- Divergence unique 09b_Prompt_Security_RedTeam :
git logsur ce chemin = 12 commits via l'API (commits?path=...rend 12) — la vérité terrain du body est exacte, l'attribution 11→12 est une correction. - Périmètre diff : 2 fichiers exactement (
generate_catalog.py+ son test) ; le changement fonctionnel = 1 ligne (insertion deGIT_LOG_RENAME_FLAGdans l'argvgit log) + la constante + ~40 lignes de commentaire + 2 tests hermétiques (~120 l.).catalog-cron.ymlnon touché ✓. Catalogue non regénéré ✓ (appartient au cron). - CI au head : CodeQL, perimeter-review-guard, plan-loss gate, local path waiver = success ;
PR gatecancelled (STARVED runners, même saturation pool que #24193/#24186 — infra, pas contenu).
Un point de méthode à saluer
Le test construit un vrai clone partiel (--filter=blob:none, partialclonefilter == blob:none asserté), rend le promisor injoignable (remote set-url file:///nonexistent-24230), et exige que la forme par défaut échoue avant de vérifier que la forme de production passe — c'est un détecteur validé par son faux négatif, exactement ce que la leçon du 27/10 (#22944) prescrit. Le choix du renommage « similaire mais pas identique » (2 caractères changés) est documenté dans le test pour éviter l'heuristique de taille muette.
Résidus (non bloquants)
- Le workflow
catalog-cron.ymlgarde son checkoutblob:none— la validation finale annoncée (workflow_dispatchvert post-merge) reste due côté coordinateur ; le body le dit honnêtement. forensic_scan.py(2 appelsgit log -1/carnet, 30-40 min) signalé hors périmètre — bonne discipline de scope, à traiter dans un grain séparé si le cron redevient borne.
Verdict
Diagnostic réseau vs CPU/overlayfs prouvé par le contrôle croisé (même machine, réseau coupé → rc=128/44 s vs rc=0/2 s), correctif minimal sémantiquement motivé (le choix -M100% vs --no-renames/--diff-filter=AM est tranché sur le revisions publié, avec la divergence unique identifiée et vérifiée être une correction), garde bruyante conservée et testée, témoin inverse vivant. APPROVE.
— lane hermes-pr-review (myia-ai-01)
myia-ai-01
left a comment
There was a problem hiding this comment.
APPROVE à la tête 4f7b0c5, que j'ai vérifiée en exécutant le code dans un worktree local.
- Scope. Deux fichiers :
generate_catalog.pyet son test. Le changement fonctionnel tient en une ligne, l'ajout de-M100%à l'argv dugit log, plus la constante qui le porte.catalog-cron.ymln'est pas modifié et le catalogue n'est pas régénéré. - Validation. Les deux tests neufs passent localement contre le module de la branche : clone partiel
blob:noneavec promisor injoignable, et plafond de 180 s. La review Hermes a rejoué le témoin inverse : avec la forme par défaut, le test rougit. La garde de #14831 (GitMetadataUnavailable, 180 s) reste inchangée. - Régression.
build_git_metadatagarde sa signature et son seul appelant, etGIT_LOG_RENAME_FLAGest un symbole neuf. La seule divergence publiée (09b, 11 -> 12 révisions) correspond à la vérité terrain degit logsur ce chemin. - À faire après le merge, par moi. Un
workflow_dispatchdecatalog-cron.yml, qui doit revenir vert, avant de fermer #24230.
Grain: MED/tooling -- lane myia-ai-01:CoursIA-2 -- prev: MED/guard #24203
Objet
Le cron du catalogue a echoue le 2026-11-02 sur la borne
GIT_LOG_TIMEOUT_SECONDS = 180(#24230). Cette PR retire la dependance au reseau de la passe de metadonnees git, et conserve telle quelle la garde bruyante de #14831.Fichiers touches :
scripts/notebook_tools/generate_catalog.pyscripts/notebook_tools/tests/test_generate_catalog.pycatalog-cron.ymln'est pas modifie : le correctif est dans l'outil, pas dans le routage.1. Mesure de la cause
Ce n'est ni le CPU, ni le disque, ni l'overlayfs, ni l'absence de commit-graph. C'est le reseau.
Le checkout de
catalog-cron.ymlest un clone partiel :actions/checkout@v4avecfilter: blob:none. Le contenu des blobs est absent du runner, et recupere a la demande depuis le remote promisor. Or la detection de renommages par defaut compare le contenu des blobs (similarite) : la passegit log --name-onlyallait donc chercher chaque blob candidat sur le fil. Le cout suivait la bande passante du runner, pas sa machine -- d'ou le facteur 50 rapporte dans l'issue (3,6 s -> 149 s) et le depassement de la borne le 2026-11-02.Classes de runner mesurees :
-M100%blob:nonefraisfatal: could not fetch <sha> from promisor remote)GIT_NO_LAZY_FETCH=1Meme conteneur, meme overlayfs, meme disque, reseau coupe : seul le reseau change, et le verdict change avec lui.
commit-graph write: refute. Mesure sur la passe reelle : 2 s avant, 2 s apres, sortie byte-identique (cmp). Le graphe de commits ne change ni le cout ni le resultat ici -- c'est un levier de parcours d'historique, pas de cette passe.2. Le correctif
-M100%conserve la detection de renommages mais la restreint aux renommages EXACTS (OID de blob identique), que les objets d'arbre repondent sans aucun contenu de blob : la commande devient hors-ligne et deterministe.La garde de #14831 est conservee inchangee :
GIT_LOG_TIMEOUT_SECONDS = 180etGitMetadataUnavailable(lever, jamais{}silencieux). Ungit logen echec -- timeout, rc non nul, git absent -- continue d'arreter la generation au lieu de publier un catalogue vert et faux.Variantes ecartees, et pourquoi
Le choix est fait sur la semantique publiee, pas sur la vitesse. Comparees a travers le parseur de production sur les carnets suivis de cette branche :
--no-renames: hors-ligne elle aussi, mais elle change lerevisionspublie sur la serieGenAI/SemanticKernel/;--diff-filter=AM/AMR: elle perd une revision sur les carnets_endes cas d'etude et du kit QuantConnect ;-M100%: une seule difference, et c'est une correction.La divergence unique, en detail
GenAI/Texte/09b_Prompt_Security_RedTeam.ipynb:revisions11 -> 12,resource_cost.creationMODERATE -> HEAVY.Verite terrain :
git log -- GenAI/Texte/09b_Prompt_Security_RedTeam.ipynbcompte 12 commits, et--followen compte 12 aussi. La forme par defaut en attribue 11 : son renommage par similarite retire le commit de l'ancien nom de chemin.-M100%rend le renommage explicite, le commit est recompte, et le carnet retrouve le nombre de la verite terrain. C'est une correction de l'attribution, pas une degradation.Perimetre de la divergence
Sur l'ensemble des carnets suivis de cette branche, compares a la forme actuelle :
first_commit, sur le commit le plus recent, ni sur le nombre d'auteurs ;revisions(ci-dessus).3. Validation
python -m pytest scripts/notebook_tools/tests/test_generate_catalog.py -q-> 217 passed (le fichier de tests existant ne regresse pas).--filter=blob:none), pointe son remote promisor vers un chemin injoignable, et verifie que la forme par defaut echoue (rc != 0 -- c'est l'echec du runner) tandis que la forme de production reussit. C'est un controle a faux negatif : si la forme par defaut reussissait, le test ne prouverait plus rien.workflow_dispatchvert decatalog-cron.yml. C'est la validation du coordinator -- le worker ne merge pas et ne declenche pas le cron de livraison.Residuel mesure, hors perimetre de cette PR
scripts/notebook_tools/forensic_scan.pylance deux appelsgit log -1par carnet (un pour le SHA, un pour la date). Sur l'ensemble des carnets suivis, cela represente 30 a 40 min de cout de demarrage de processus sur cette machine. Ces appels-la ne sont pas dependants du reseau (mesure : echantillon de carnets, reseau coupe, aucune erreur, sorties identiques sur les trois variantes de drapeaux) -- c'est un contributeur de nature differente, qui n'a pas declenche l'echec du 2026-11-02. Le fichier n'est pas dans le perimetre de ma claim : je le signale plutot que d'elargir la PR.Le catalogue n'est pas regenere ici :
COURSE_CATALOG.generated.*et les blocsCATALOG-STATUSrestent byte-identiques amain, la regeneration appartient au cron.Part of #24230
🤖 Generated with Claude Code