Skip to content

check_output_failure_text : MACHINE_PATH confond un utilisateur d'image de conteneur avec un chemin machine (2 faux positifs, 1 controle positif) #20120

Description

@jsboige

Constat

scripts/notebook_tools/check_output_failure_text.py classe en MACHINE_PATH tout motif de MACHINE_PATH_PATTERNS, dont /home/<user>/. Ce motif attrape deux choses différentes que l'organe ne distingue pas :

  • un chemin émis par le runtime — le vrai défaut : il change avec la machine ou l'arbre de travail qui a exécuté le carnet ;
  • un chemin qui est du texte de programme affiché — un littéral dans du code C#/Python que la cellule montre à l'écran : stable, voulu, indépendant du poste.

Mesuré sur main le 2026-10-09 (balayage --all --json) : 2 des 73 occurrences de la classe sont du second type.

Le jeu de calibration (2 faux positifs + 1 contrôle positif)

Faux positifs — les deux dans GenAI/Integrations-DotNet/Aspire/, chacun 1 occurrence, en sortie (la cellule affiche du code) :

Carnet cellule ligne
Aspire/01-Aspire-Orchestration-GenAi.ipynb 3 .WithBindMount(Path.Combine(…SpecialFolder.UserProfile), ".cache/huggingface"), "/home/appuser/.cache/huggingface")
Aspire/02-Aspire-GenAiStack-Reel.ipynb 2 idem

/home/appuser/.cache/huggingface est la cible de montage dans l'image Docker — un choix du programme, pas une trace de poste. Il est identique sur toute machine.

Contrôle positif — il DOIT rester détecté : GenAI/Integrations-DotNet/Orleans/02-Orleans-Aspire-CoHost.ipynb, cellules 12, 16, 19, 21, 23 (5 occurrences), en sortie :

Content root path: /home/user/wt-aspire/MyIA.AI.Notebooks/GenAI/Integrations-DotNet/Orleans/OrleansAspireLab

Le préfixe /home/user/ est bien celui du conteneur, mais wt-aspire est le nom du worktree de l'agent qui a exécuté — même classe que le worktrees/claudish-expansion corrigé par #20119.

Pourquoi ce n'est pas cosmétique

Le contrôle positif interdit le remède évident (« exclure /home/user/ ») : il casserait la détection des 5 vraies occurrences, qui utilisent le même préfixe. Le discriminant n'est donc pas le nom d'utilisateur, c'est la provenance du chemin — programme affiché contre runtime qui parle.

Et l'enjeu est réel : check_output_failure_text est le ratchet bloquant (blocking=True dans fast_lane_registry.py). Un faux positif y coûte à une lane une re-vérification complète pour le dismisser — c'est exactement ce que la classe de cet EPIC fait payer aux autres.

Critère d'acceptation

  1. Les 2 occurrences Aspire ne sont plus classées MACHINE_PATH.
  2. Les 5 occurrences Orleans le sont toujours — contrôle positif obligatoire, sans quoi le remède a déplacé le défaut d'un cran.
  3. Aucune régression sur les 64 occurrences Windows du même balayage.
  4. Le verdict est reproductible : python scripts/notebook_tools/check_output_failure_text.py --all --json, comparaison avant/après sur ces 7 lignes précises.

Note de conception (à trancher par le propriétaire de l'organe)

Je ne prescris pas le mécanisme : une heuristique « la ligne ressemble à un littéral de code » est fragile, et exempter les utilisateurs d'image connus (appuser, user, nonroot, node) raterait Orleans. Je pose le jeu de calibration et le contrôle positif ; le choix du discriminant est un design-gate, pas une décision de lane.

Part of #11044

Activity

  1. jsboige commented on Oct 9, 2026

    @jsboige
    OwnerAuthor

    Contribution de mesure — lane myia-po-2024:CoursIA-2. Aucune PR (la lane est au plafond WIP) et aucune décision de design-gate prise ici : je livre les mesures que réclame l'acceptation, plus deux corrections de chiffres.

    Reproduction du constat

    python scripts/notebook_tools/check_output_failure_text.py --all --json à la tête 977e8bbdbb5f (behind_origin_main: 0) :

    carnets balayés 77
    MACHINE_PATH 73 sur 38 carnets
    dont chemins conteneur 7 (/home/user/ ×5, /home/appuser/ ×2)
    dont hôte/env 66

    Le constat du body est confirmé : les 73 sont en sortie. C'est le premier candidat discriminant testé — et il tombe.

    Deux candidats réfutés par la mesure

    1. « source contre sortie » — 73/73 occurrences sont en sortie, y compris les 2 Aspire. La cellule Aspire n'a pas le chemin dans sa source : elle affiche le contenu d'AppHost.cs, et le chemin est dans le fichier affiché. Le candidat ne sépare donc rien.
    2. « le littéral vit aussi dans une source suivie du dépôt » — git grep --fixed-strings rend 0 fichier (hors .ipynb) pour /home/appuser/.cache/huggingface comme pour /home/user/wt-aspire. L'AppHost.cs affiché est généré (non suivi), donc les deux populations se ressemblent aussi sur cet axe.

    Le troisième candidat évident — le nom d'utilisateur — est déjà exclu par le contrôle positif, comme le body le dit.

    Le discriminant qui sépare, mesuré

    Le chemin ouvre-t-il un littéral de chaîne sur sa ligne de sortie ? C'est-à-dire : le caractère immédiatement à sa gauche est-il un guillemet.

    forme occurrences dont conteneur
    BARE (chemin nu) 71 5 (Orleans)
    OPEN_LITERAL (ouvre un littéral) 2 2 (Aspire)

    Les 2 OPEN_LITERAL sont exactement les 2 faux positifs Aspire ; les 5 Orleans restent BARE. Collatéral sur le reste du corpus : 0 sur 66.

    La raison est celle du body — la provenance — et elle se lit sur les lignes :

    • Aspire : .WithBindMount(Path.Combine(…UserProfile), ".cache/huggingface"), "/home/appuser/.cache/huggingface") → texte de programme affiché ;
    • Orleans : Content root path: /home/user/wt-aspire/MyIA.AI.Notebooks/… → valeur émise par le runtime.

    Sur ce corpus, la forme satisfait les critères 1, 2 et 3 sans nommer aucun utilisateur.

    Deux chiffres à corriger avant d'écrire l'acceptation

    • Critère 3 — le nombre à protéger est 66, pas 64. Mesuré : 73 − 7 = 66 occurrences hôte/env. C'est ce total qu'un --all --json avant/après doit retrouver.
    • Critère 4 — le champ cell de l'organe est 0-based. Les cellules Orleans citées (12, 16, 19, 21, 23) sont des index 0-based ; en convention 1-based — celle qu'emploient les autres organes notebooks du dépôt — ce sont 13, 17, 20, 22, 24. Un test qui rejoue « ces 7 lignes précises » doit épingler la convention, sinon il compare la cellule voisine. (Même piège que celui rencontré sur fix(ml,#19754): rafraichir les outputs des carnets 04-Vision 4.4-4.6 apres le renumerotage (noms 4.2[c-k] residuels en sortie) #19984.)

    Bornes du prédicat — ce qu'il ne dit pas

    C'est un proxy de la provenance, pas la provenance. Deux classes le font mentir, à zéro occurrence mesurée aujourd'hui :

    • faux négatif : un bandeau runtime qui cite le chemin (Serving from "/home/user/x") ouvre un littéral et serait exempté ;
    • faux positif : un chemin en commentaire dans du code affiché (// /home/user/…) n'ouvre rien et resterait signalé.

    0 sur 66 est un chiffre de corpus, pas une couverture — la leçon vaut d'être appliquée ici : le prédicat doit porter son contrôle positif et son contrôle négatif dans le --self-test de l'organe (il en a un), faute de quoi il peut se vider en silence sans qu'aucun rouge ne le dise.

    Je ne tranche pas le choix : c'est le design-gate du propriétaire de l'organe. La mesure, la forme candidate et ses bornes sont ci-dessus.

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