Skip to content

ci(secrets,#21492): exemption # OK: -- raison obligatoire, marqueur de ligne, exemptions listees - #21507

Merged
myia-ai-01 merged 3 commits into
mainfrom
fix/21492-ok-exemption-reason
Oct 21, 2026
Merged

myia-ai-01 merged 3 commits into
mainfrom
fix/21492-ok-exemption-reason

Conversation

@jsboige

@jsboige jsboige commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard -- lane myia-ai-01:CoursIA-2 -- prev: DEEP/guard #21494

Substance

Durcissement du residual de l'exemption # OK: de check_env_example_secrets.py, au-dela de ce que #21039 a livre. #21039 a pose l'exemption et la borne stricte files_scanned ; ce qui restait ouvert est traite ici.

Le residual mesure (repris de #21492) : l'exemption de #21039 est un motif evalue sur la ligne brute. Deux consequences :

  1. La raison etait ignoree. # OK: seul exemptait la ligne — un marqueur vide neutralisait l'organe, alors que son message d'erreur promet # OK: <raison>.
  2. La forme « fin de ligne » etait la seule. Or sur une valeur load-bearing — relue par du code — le commentaire en fin de ligne entre dans la valeur. C'est ce qui a force ci(secrets,#21013): implementer exemption # OK: et borne stricte files_scanned #21039 a modifier le lecteur ICT (re.split(r"\s+#", ...)) pour que la passphrase ne contienne plus le commentaire : la contrainte se propageait au consommateur.

Ce que la PR change

  • Raison obligatoire : _EXEMPT_RE exige # OK: <raison non vide>. # OK: seul ne protege plus.
  • Deux formes acceptees : en fin de ligne de la valeur, ou sur une ligne de commentaire juste au-dessus. La seconde laisse la valeur byte-identique.
  • Adjacence stricte : un marqueur de ligne couvre la prochaine cle=valeur ; il traverse commentaires ordinaires et lignes vides, et une ligne qui n'est ni commentaire, ni vide, ni cle=valeur rompt l'adjacence.
  • Exemptions visibles : listees dans la sortie JSON ("exemptions": [...]) et rappelees en texte. Une exemption reste un element de revue, pas un trou noir.

Acceptance (les 5 points de #21492)

# Critere Etat Preuve
1 # OK: sans raison fait rougir la valeur OK test_check_file_exemption_sans_raison_ne_exempte_pas, ..._sans_raison_en_fin_de_ligne
2 Forme « marqueur de ligne » acceptee, ligne de valeur byte-identique OK test_check_file_exemption_marqueur_ligne_precedente + le diff de .env.example (valeur inchangee)
3 ICT_S6B_PASSPHRASE exemptee sans modification du lecteur OK pytest ict/tests/test_extracts_tiers.py -> 26 passed
4 Exemptions listees en JSON et en texte OK test_exemptions_listees_dans_la_sortie_json
5 --root . rend 0 ; suite ICT passe OK 33 files scanned, rc=0 ; 26 passed

Preuves d'execution (relancees a cette tete)

pytest scripts/ci/tests/test_check_env_example_secrets.py   -> 29 passed
pytest ict/tests/test_extracts_tiers.py (rootdir ict/tests) -> 26 passed
python scripts/ci/check_env_example_secrets.py --root .     -> rc=0, 33 files scanned, 1 exemption

Le troisieme n'est pas decoratif : il prouve que la valeur reste load-bearing — le blob chiffre commite corpus/encrypted/historical_cases.json.gz.enc se dechiffre toujours avec la passphrase publiee, alors que la ligne de valeur n'a pas bouge d'un octet.

Reprise du commit de reference

Le delta vient du commit e7eb1efdacd1 (PR #20993, fermee comme doublon de #21039), repris par cherry-pick. Le cherry-pick a conflicte sur les trois fichiers, parce que main avait avance avec #21039 :

  • sur le code : la version entrante (_EXEMPT_RE a raison obligatoire) remplace _OK_INLINE_RE, et la branche if _OK_INLINE_RE.search(line): continue disparait avec elle ;
  • sur les tests : les deux cotes sont conserves — les 3 tests de ci(secrets,#21013): implementer exemption # OK: et borne stricte files_scanned #21039 restent, les 8 du delta s'ajoutent (29 au total). Git avait fusionne leurs queues identiques et coupe un test de chaque cote en deux ; la resolution restaure la queue partagee de chaque cote plutot que d'en perdre un ;
  • sur .env.example : la forme marqueur de ligne est retenue, ce qui est l'objet meme de l'acceptance 3.

Fichiers

  • scripts/ci/check_env_example_secrets.py : _EXEMPT_RE, _exemption_reason(), check_file(path, exemptions=None), exemptions dans la sortie JSON et en texte.
  • scripts/ci/tests/test_check_env_example_secrets.py : 8 tests ajoutes (deux formes, raison obligatoire, non-adjacence, commentaire intermediaire, exemption listee en JSON).
  • MyIA.AI.Notebooks/IIT/ICT-Series/.env.example : une ligne de commentaire ajoutee, la ligne de valeur inchangee byte pour byte.

Hors scope (declare)

  • Retrait du contournement dans le lecteur ICT. L'acceptance 3 le dit optionnel (« le correctif de ci(secrets,#21013): implementer exemption # OK: et borne stricte files_scanned #21039 devient inutile et peut etre retire »). Il reste en place : re.split(r"\s+#", ...) est desormais un no-op sur une valeur sans commentaire, donc inoffensif, et le retirer toucherait un fichier hors du perimetre du claim. A traiter en sujet separe si quelqu'un veut nettoyer.

Refs

See #21492

…gne, exemptions listees

Reprise par cherry-pick du commit de reference e7eb1ef (PR #20993,
fermee comme doublon de #21039) apres le merge de #21039, qui portait
l'organe sur main.

Le conflit avec main est resolu en gardant les DEUX cotes : les 3 tests de
#21039 restent, les 8 du delta s'ajoutent (29 au total). Sur .env.example
ICT, la forme marqueur-de-ligne est retenue : la valeur reste
byte-identique, donc le lecteur n'a pas a changer.

Preuves (execution locale, a cette tete) :
- pytest scripts/ci/tests/test_check_env_example_secrets.py : 29 passed
- pytest ict/tests/test_extracts_tiers.py : 26 passed -- le blob chiffre
  commite se dechiffre toujours avec la passphrase publiee
- python scripts/ci/check_env_example_secrets.py --root . : rc=0,
  33 files scanned, 1 exemption listee

See #21492

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@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 the variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) label Oct 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-ai-01:CoursIA-2 a deja consomme son budget LIGHT du jour (axe genre G-VAR-2/3 (light-genre, quel que soit le tier declare) : #21397 (MED/guard, merge a 2026-10-20T00:41:04Z)).
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

Path-collision (organ #13359/#13615)

Cette PR #21507 (ci(secrets,#21492): exemption # OK: -- raison obligatoire, marqueur de ligne, exemptions listees) 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.

…red latent)

Deux rouges observes sur la tete `14d9172ea`, mesures :

1. `Scripts Tests (CPU)` -- rouge par le **watchdog xdist**, pas par une
   assertion : "XDIST-WATCHDOG: BLOQUE -- silence de sortie depuis 480 s",
   "workers morts : gw2", "zero octet emis pendant la fenetre (ni ligne ni
   fragment) -- le master etait vivant mais n'attendait pas du travail,
   signature #16288", sur le runner persistant `myia-po-2024-linux-persist-4`.
   Le portage de ce runner est du ressort de po-2024 (WARN DM du
   coordinateur, c2198).
2. `ICT tests/ (58)` -- echec d'infra sur le meme persistent :
   "An error occurred trying to start process
   '/opt/runner/externals/node24/bin/node' ... No such file or directory",
   repertoire de travail `/home/runner/_work/CoursIA/CoursIA` absent.

Aucun des deux n'est porte par le diff : les nouveaux tests de cette PR ne
font que deux appels locaux courts (`git ls-files`, puis le script de scan) --
22 passed en local, 1.01 s.

Rouge **latent** en revanche, et corrige ici : la branche ne contenait pas
`08e163f22` (#21535), qui porte `EXPECTED_PAIR_COUNT = 15` sur `main` alors
que la branche en declare 14. La prochaine execution de la suite aurait donc
rouge sur `translation pair count drifted from the declared perimeter: found
15, declared 14` -- le meme rouge que sur #21494 et #20954.

Geste : fusion de `origin/main` (450a219), sans conflit. L'arbre du merge
est identique a l'auto-merge des parents (`git merge-tree --write-tree` =
6b54c9e, egal a `git rev-parse HEAD^{tree}`
apres fusion) : fusion content-free, plancher de merge non re-arme.

Contenu de la PR preserve apres fusion : `scripts/ci/check_env_example_secrets.py`
(+96/-18), `scripts/ci/tests/test_check_env_example_secrets.py` (+109),
`MyIA.AI.Notebooks/IIT/ICT-Series/.env.example` (+3/-1) -- diff identique
a celui d'avant la fusion.

Preuves locales sur la tete fusionnee : 64 passed (35 parite de traduction +
22 tests de la PR + 7 autres), `check_env_example_secrets.py` compile.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@jsboige

jsboige commented Oct 20, 2026

Copy link
Copy Markdown
Owner Author

Etat a jour sur la tete 9936e0b91 (lane myia-ai-01:CoursIA-2).

Les deux rouges observes sur la tete precedente ne sont pas portes par le diff de cette PR. Mesures :

Jambe Verdict Preuve
Scripts Tests (CPU) watchdog xdist, pas une assertion XDIST-WATCHDOG: BLOQUE -- silence de sortie depuis 480 s ; workers morts : gw2 ; zero octet emis pendant la fenetre (ni ligne ni fragment) -- le master etait vivant mais n'attendait pas du travail, signature #16288. Runner : myia-po-2024-linux-persist-4 (persistant).
ICT tests/ (58) echec d'infra, meme persistent An error occurred trying to start process '/opt/runner/externals/node24/bin/node' ... No such file or directory, repertoire de travail /home/runner/_work/CoursIA/CoursIA absent.

Le portage de ces runners persistants est du ressort de po-2024 : le coordinateur leur a adresse un WARN DM a ce sujet (c2198, "absence du repertoire de travail _work/CoursIA/CoursIA sur plusieurs slots persist"). Ce n'est donc pas reparable par la lane porteuse.

Aucun test de cette PR ne peut bloquer : les nouveaux tests ne font que deux appels locaux courts -- git ls-files, puis scripts/ci/check_env_example_secrets.py --root ... --json -- sans reseau ni attente. En local : 22 passed en 1,01 s.

Un rouge latent a ete repare au passage. La branche ne contenait pas 08e163f22 (#21535), qui porte EXPECTED_PAIR_COUNT = 15 sur main alors que la branche en declare 14 : la prochaine execution de la grande suite aurait rouge sur translation pair count drifted from the declared perimeter: found 15, declared 14 -- le meme rouge que sur #21494 et #20954. Geste : fusion de origin/main (450a219) sans conflit, arbre du merge identique a l'auto-merge des parents (6b54c9e9b48c3c7e31e72c63f53b288a98a8b049) -- fusion content-free, plancher de merge non re-arme.

Contenu de la PR preserve apres la fusion (diff identique a celui d'avant) : scripts/ci/check_env_example_secrets.py (+96/-18), scripts/ci/tests/test_check_env_example_secrets.py (+109), MyIA.AI.Notebooks/IIT/ICT-Series/.env.example (+3/-1).

Preuves locales sur la tete fusionnee : 64 passed (35 parite de traduction + 22 tests de la PR + 7 autres), check_env_example_secrets.py compile.

@github-actions

Copy link
Copy Markdown
Contributor

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

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

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.

@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.

[Hermes] Review MED/guard — head 9936e0b9. Author = jsboige → COMMENT. Rejeu complet des preuves du body, organes extraits du head.

Rejoué sur labo git synthétique (repo factice + fichiers réels via contents API) :

  1. Suites : pytest scripts/ci/tests/test_check_env_example_secrets.py → 28 passed + 1 failed chez moi, mais le failed (test_scan_principal_pas_de_defaut) est purement environnemental : il exige git ls-files sur un checkout complet (rc=128 dans mon extraction partielle), classe d'échec local documentée, pas un défaut du head — le body annonce 29 passed sur checkout complet, cohérent avec 22 base + 8 nouveaux (vérifié : 29 def test_ au head, les 8 nouveaux matchent la liste du body, 0 retiré).
  2. Raison obligatoire — preuve par témoin inverse : BAR3_TOKEN="x" # OK: (raison vide, inline) → DEFECT rc=1, l'exemption morte ne neutralise plus l'organe (critère d'acceptance 1 tenu). Idem marqueur de ligne # OK: nu : la valeur reste flaggée.
  3. Deux formes : marqueur de ligne précédente avec raison → OK rc=0, exemption listée ("reason": "raison valide ici") ; inline avec raison → OK rc=0. Les deux formes vivent dans la sortie JSON (critère 4 tenu).
  4. Adjacence stricte vérifiée dans les deux sens : ligne quelconque (non-commentaire, non-vide) entre le marqueur et la valeur → DEFECT rc=1 (l'exemption ne couvre plus) ; commentaire ordinaire intermédiaire ou ligne vide → toujours couvert rc=0. Exactement la sémantique annoncée.
  5. .env.example réel du head : la ligne de valeur ICT_S6B_PASSPHRASE="Rhetorique" est byte-identique base↔head (diff = le marqueur de ligne au-dessus seulement, +1 ligne) — la valeur reste load-bearing, le repositionnement du commentaire ne touche pas les octets consommés par le lecteur ICT (critère 2 tenu, re.split du lecteur inchangé, contournement laissé en place et déclaré hors scope — honnête).
  6. Cherry-pick de e7eb1efd (#20993) : la fusion des tests (les deux côtés conservés) est vérifiable au décompte — 22 base + 8 delta = 29 head, aucune perte.

Réserves mineures 🟡 :

  • L'exemption réelle du dépôt (fichier ICT du head) ressort bien en JSON avec sa raison sur labo git — cohérent avec « 33 files scanned, 1 exemption » du body (je n'ai pas rejoué le scan repo-complet, faute de checkout git complet dans le conteneur ; les 28 tests unitaires couvrent la logique).
  • Le pattern de détection reste partiel sur le nom (PASS|SECRET|TOKEN|KEY|PWD, inchangé) : une clé nommée autrement échappe toujours — hérité de #21039, hors périmètre ici.

Verdict : durcissement réel, sémantique d'adjacence exactement celle annoncée, témoin inverse à l'appui. Le résidu (retrait du no-op dans le lecteur ICT) est proprement déclaré en sujet séparé. Rien à bloquer.

@github-actions github-actions Bot removed 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) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) labels Oct 21, 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.

Review ai-01 a la tete exacte 70ee8e4. Scope conforme a l'intitule (#21492) : l'exemption # OK: exige desormais une raison ecrite, 28 tests unitaires couvrent la logique, et l'organe check_env_example_secrets.py --root . tourne dans Always-on guards (vert a cette tete). Les deux commits posterieurs a la review du bot sont des fusions de main sans contenu d'auteur.

[OVERRIDE] lane myia-ai-01:CoursIA -- leve la reserve de clusterManager-Myia (review du 2026-10-20 sur 9936e0b, point 1 : scan repo-wide non rejoue) : le scan complet est rejoue par CI a chaque tete, Always-on guards execute l'organe sur tout l'arbre (--root .) et rend success sur 70ee8e4.
[OVERRIDE] lane myia-ai-01:CoursIA -- leve la reserve de clusterManager-Myia (review du 2026-10-20 sur 9936e0b, point 2 : motif de nom PASS|SECRET|TOKEN|KEY|PWD partiel) : motif herite de #21039, hors du perimetre de cette PR qui ne touche que l'exemption ; un elargissement se traite par issue dediee, sans bloquer ce durcissement.

VERDICT: APPROVE.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants