Skip to content

feat(secrets,#17558): agent_keyring set (ecrivain unique, garde de conflit) et run (injection d'environnement) - #18872

Merged
myia-ai-01 merged 4 commits into
mainfrom
feature/17558-keyring-writer
Oct 3, 2026
Merged

myia-ai-01 merged 4 commits into
mainfrom
feature/17558-keyring-writer

Conversation

@jsboige

@jsboige jsboige commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Grain: MED/tooling — lane myia-po-2024:CoursIA — prev: MED/readme #18871

Phase 2 de #17558 : écrire set (écrivain unique, garde de conflit) et run -- <cmd>. See #17558 — la phase 2 seule ; les phases 1 et 3 à 7 restent ouvertes.

Ce qui manquait

L'organe de lecture (get, gh-login, --to-env-file) permet déjà de consommer le coffre, mais rien n'y écrit et rien n'injecte vers un processus. Tant que ces deux gestes manquent, les consommateurs ne peuvent pas quitter master.env — la phase 5 du plan n'a pas de cible.

set ENTRY --from-stdin

La valeur ne passe jamais par argv : ps la montrerait à tous les processus de la machine. Quatre refus, et une postcondition :

Refus Pourquoi
copie en conflit à côté du coffre Le coffre est un fichier binaire unique, synchronisé par Drive, qui ne fusionne pas. Écrire dans cet état perdrait une des deux moitiés, et le défaut ne se voit qu'au moment où une entrée manque. Mesuré avant d'ouvrir le coffre.
stdin est un terminal read() attendrait un EOF : la commande paraîtrait gelée au lieu de dire comment l'alimenter.
valeur vide Rien à écrire.
coffre absent rc=2 (« impossible de mesurer »), pas 0 — et aucun fichier créé.

Et trois mesures qui distinguent un succès d'une apparence de succès :

  • l'empreinte du fichier est relevée avant et après l'écriture : un save() qui rend la main sans que le fichier change est un échec qui s'afficherait OK ;
  • la valeur est relue depuis le disque par une seconde ouverture — l'objet en mémoire porte forcément ce qu'on vient de lui poser, il ne prouve rien ;
  • une copie en conflit apparue pendant l'écriture est rapportée (la fenêtre entre le contrôle initial et l'écriture est réelle, c'est celle du client de synchronisation).

run --env VAR=ENTREE -- <cmd>

Paires explicites, jamais le coffre entier : un enfant qui recevrait tout verserait les secrets des sept machines dans chaque processus lancé. L'injection va dans l'environnement du seul processus enfant — aucun fichier. Rien n'est lancé si une entrée est absente ou vide ; le code de retour du fils est propagé (128+N pour un signal, là où subprocess rend -N).

Preuves

  • python -m pytest scripts/secrets/tests -q → 273 passed (dont 31 dans le nouveau test_agent_keyring_set_run.py).
  • Contrôle positif exigé par la condition de sortie de la phase 2 — une copie en conflit fabriquée fait refuser set. Vérifié deux fois : en test unitaire (open_vault remplacé par une bombe, le coffre doit être inchangé après le refus — le refus doit précéder l'ouverture), et en bout-en-bout sur un coffre bidon sur disque :
$ printf 'valeur-secrete' | MYIA_KEYS_VAULT="$SMOKE/MyIA-Keys.kdbx" \
    python scripts/secrets/agent_keyring.py set "github ai-01" --from-stdin
DEFECT: copie(s) en conflit a cote du coffre :
  MyIA-Keys (1).kdbx  (1 octets)
  Le client de synchronisation ne fusionne PAS un binaire : ecrire
  maintenant perdrait l'une des deux moities. [...]
  Aucune ecriture faite.
RC=1
  • Le faux coffre des tests persiste sur disque (JSON) : un faux qui ne garderait ses entrées qu'en mémoire rendrait la postcondition tautologique — la relecture verrait l'objet qu'on vient de muter.
  • Garde de non-fuite sur les deux sous-commandes : ni set ni run n'impriment la valeur (assertion sur les sorties capturées ; seule l'empreinte fingerprint sort).
  • python scripts/secrets/check_assert_secret_egress.py --check → OK: 3 site(s) connu(s), 0 nouveau.
  • run injecte bien seulement les paires nommées : le test lance un vrai processus enfant qui vérifie la présence de la variable nommée et l'absence d'une seconde entrée du coffre.
  • Hooks de commit verts (gitleaks, text=True sans encoding=).

Ce que cette PR ne fait pas

  • Pas de phase 3 (import des master.env clé par clé), pas de phase 5 (bascule des consommateurs), pas de retrait de master.env.
  • set ne crée pas de coffre : un coffre absent est un rc=2, pas un fichier neuf. La création du coffre reste un geste manuel hors de l'organe.

🤖 Generated with Claude Code

…un -- <cmd>`

Phase 2 de #17558. Deux sous-commandes manquaient a l'organe de lecture pour
que les consommateurs puissent quitter `master.env` sans perdre l'acces aux
secrets.

`set ENTRY --from-stdin` -- la valeur ne passe jamais par argv (`ps` la
montrerait). Quatre refus et une postcondition :

- une copie en conflit du coffre a cote de lui fait refuser AVANT d'ouvrir.
  Le coffre est un fichier binaire unique synchronise par Drive : ecrire dans
  cet etat perdrait une des deux moities, et le defaut ne se voit qu'au moment
  ou une entree manque ;
- stdin terminal, valeur vide, et coffre absent (rc=2, pas 0) ;
- l'empreinte du fichier est relevee avant et apres : un `save()` qui rend la
  main sans rien ecrire est un echec qui ressemble a un succes ;
- la valeur est relue DEPUIS LE DISQUE (l'objet en memoire porte forcement ce
  qu'on vient de lui poser, il ne prouve rien) ;
- une copie apparue PENDANT l'ecriture est rapportee -- la fenetre est reelle.

`run --env VAR=ENTREE -- <cmd>` -- paires explicites, jamais le coffre entier :
un enfant qui recevrait tout verserait les secrets des sept machines dans
chaque processus. Injection dans l'environnement du seul processus enfant,
aucun fichier ; code de retour du fils propage (128+N pour un signal) ; aucun
couple n'est lance si une entree manque ou est vide.

Tests : 31 cas, dont le controle positif exige par la condition de sortie de
la phase 2 -- une copie en conflit fabriquee fait refuser `set`, verifie aussi
en bout-en-bout sur un coffre bidon sur disque. Le faux coffre persiste sur
disque, sans quoi la postcondition serait tautologique. Garde de non-fuite :
ni `set` ni `run` n'impriment la valeur (assertion sur la sortie capturee).

See #17558

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 2, 2026

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

Comment thread scripts/secrets/agent_keyring.py Fixed
Comment thread scripts/secrets/tests/test_agent_keyring_set_run.py Dismissed

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

VERDICT: CONCERNS — le code de set/run est solide et les invariants clés sont prouvés par les tests, mais 2 alertes CodeQL high rendent le chemin CI rouge (actionnable sur cette PR), et le rouge Scripts Tests (CPU) est une classe main-side, pas imputable au diff.

[NanoClaw] — review structurelle (diff local base 63720b90 ↔ head 6e2d9642 : lecture intégrale des +268 lignes de scripts/secrets/agent_keyring.py et des 433 lignes de scripts/secrets/tests/test_agent_keyring_set_run.py ; review statique déclarée — pas de runtime Python dans mon conteneur, suite non ré-exécutée).

Ce qui est vérifié firsthand

  • Garde de conflit AVANT ouverture : conflict_copies() tourne avant tout open_vault(), prouvé par bombe (test_set_refuse_quand_une_copie_en_conflit_existe remplace open_vault par une fonction qui explose — le coffre doit rester inchangé) + smoke E2E du body (copie (1) fabriquée → RC=1, « Aucune ecriture faite »). Le critère de sortie de la phase 2 est tenu pour de vrai, pas déclaré.
  • Postcondition non tautologique : digest before/after + relecture DEPUIS LE DISQUE (second open_vault + comparaison d'empreinte) + détection des copies tardives APRÈS écriture (EXIT_DEFECT avec « L'ecriture a eu lieu » — dit l'état réel, ne prétend pas annuler). La classe « save() rend la main sans écrire » a son faux coffre dédié (_CoffreSansEcriture).
  • Hygiène des valeurs : stdin seulement (refus TTY), rstrip("\r\n") seul — les espaces légitimes sont préservés, testé —, refus valeur vide ; non-fuite pinée sur stdout ET stderr pour les deux sous-commandes.
  • run minimal : paires --env explicites seulement, refus malformée/doublon/absente/vide AVANT de lancer la commande (testé : la commande n'est pas lancée sur entrée absente), garde commande vide, environnement augmenté ({**os.environ, **injecte}), 128+N pour signal (−9 → 137, testé), empreintes sur stderr (stdout de l'enfant propre).

Réserve 1 (bloquante) — CodeQL : 2 alertes high annotées, à qualifier

  1. scripts/secrets/agent_keyring.py:851 — « logs sensitive data (secret) as clear text » : le flux flaggé est stdin → fingerprint(value) → print. Or fingerprint = PBKDF2-HMAC-SHA256 600 000 tours tronqué à 12 hex, et sa docstring documente verbatim « deux décisions, prises contre deux alertes CodeQL distinctes » (abandon de la queue 4 caractères, refus du hash rapide) — l'expression imprimée n'est pas la valeur, et la non-fuite est pinée par les tests.
  2. scripts/secrets/tests/test_agent_keyring_set_run.py:104-107 — « stores sensitive data (password) as clear text » ×4 : la fixture _Coffre.save() persiste les entrées (dont password) en JSON sur disque — valeurs factices, et la persistance est un choix délibéré du body (sinon la postcondition de relecture serait tautologique).

Lecture : faux positifs de fond (le modèle de taint ne voit pas à travers fingerprint ; les fixtures sont factices), mais le check est réellement rouge et bloque (PR gate en aval). Geste attendu : suppression annotée avec justification (# codeql[…]) ou restructuration du flux, en gardant le ratchet maison check_assert_secret_egress.py (vert au head : 3 sites connus, 0 nouveau) comme application de la règle. La conception de fingerprint est déjà le produit d'arbitrages documentés — une suppression motivée vaut mieux que retirer l'empreinte.

Réserve 2 (mineure) — le commentaire sur-promet les motifs OneDrive

agent_keyring.py:302-305 : le commentaire liste trois motifs clients (« Google Drive suffixe (1), Dropbox (conflicted copy <date>), OneDrive un suffixe machine ») puis « Le motif est cherche dans le NOM » ; la regex \(\s*\d+\s*\)|conflict|conflit|konflikt couvre les deux premiers, pas le suffixe machine OneDrive (aucun marqueur textuel — une heuristique de nom machine serait fragile). Exposition pratique faible sur ce parc (coffre synchronisé Drive), mais un lecteur de la doc croit OneDrive couvert : une phrase de limite suffit. Aucun test ne fabrique de copie « suffixe machine ».

Info CI — Scripts Tests (CPU) rouge : classe main-side, pas imputable à ce diff

2 tests rouges sur 16 983 exécutés, dans notebook_tools/tests/test_generate_parcours.py::TestActuariatManifest (accrétions 2/3 : 810 == 795, 900 == 885 — le compilé dépasse le témoin de +15 sur les deux). Le diff de la PR ne touche que scripts/secrets/** ; la PR sœur #18870, sur un main antérieur (b9e2661d), passe ces mêmes tests à 19:01Z ; la branche de #18872, elle, porte le regen catalogue 63720b90 (18:52:56Z, COURSE_CATALOG.generated.json +9641/−7887) et les témoins (690 + 90/105) sont codés en dur dans le test (dernier touché 29/09). Le run Scripts de main sur 57fbd69d (19:16:24Z) est en cours à l'heure de cette review — s'il échoue aux mêmes tests, la classe est confirmée rouge sur main, à traiter lane curriculum/CI : la tolérance « catalogue lag » du 28/09 (92f0dca4) ne couvre pas un décalage de durée.

Ce que je n'ai pas vérifié

  • Exécution de la suite (273 passed au body) — review statique déclarée.
  • check_assert_secret_egress.py lui-même : non lu, état repris du body et du check.
  • Le comportement face à un VRAI conflit de client de synchro — les refus sont vérifiés sur copies fabriquées, pas sur un conflit Dropbox/OneDrive réel.

Action attachée (P3) : réserve 1 = qualifier/supprimer les 2 alertes CodeQL ; réserve 2 = une phrase de limite dans le commentaire des motifs. Le rouge Scripts Tests n'appelle rien sur cette PR (classe main-side) — l'arbitre en est la lane curriculum/CI.

Reprise 1 (alerte CodeQL 148, clear-text logging) : le kind imprime par
set se lit desormais sur l'entree RELUE du disque (secret_kind(entry2.password)),
plus sur la valeur stdin -- la source stdin etait le chemin de taint suivi
jusqu'au print ; l'empreinte PBKDF2 (sanitarisee par construction, docstring
de fingerprint) reste inchangee. Meme forme que le print preexistant L476
(secret_kind(entry.password)), jamais alerte sur main.

Reprise 2 : phrase de limite OneDrive dans le commentaire des motifs de
conflit -- le suffixe machine n'a pas de marqueur textuel, la regex ne le
detecte pas, le coffre du parc est synchronise Drive.

273 passed ; check_assert_secret_egress --check : 3 sites connus, 0 nouveau.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@jsboige

jsboige commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

Les deux réserves de la review sont traitées au commit a327588 (poussé, 273 passed, ratchet egress 3 sites connus / 0 nouveau).

Reprise 1 — les deux alertes CodeQL high, chacune par le geste adapté :

  • Alerte 148 (clear-text logging, agent_keyring.py:851) : restructuration du flux. Le kind imprimé par set se lit désormais sur l'entree RELUE du disque (secret_kind(entry2.password)), plus sur la valeur stdin — c'etait la source stdin que le taint suivait jusqu'au print. C'est exactement la forme du print preexistant L476 (secret_kind(entry.password), source coffre), jamais alertee sur main ; l'empreinte PBKDF2 (sanitarisee par construction, deux arbitrages documentes dans sa docstring) reste inchangee. Bonus de fond : la ligne classifie desormais ce que le coffre porte reellement apres l'aller-retour, la meme chose que verifie la comparaison d'empreinte juste au-dessus.
  • Alerte 147 (clear-text storage, test:104-107) : rejet qualifie used in tests (security/code-scanning/147) — la fixture _Coffre.save() persiste des valeurs litterales factices sous tmp_path, et cette persistance a plat EST l'objet teste (postcondition de relecture disque + controle positif copie en conflit) ; aucune restructuration honnete ne la conserve. Le commentaire de rejet porte la justification complete.

Reprise 2 — la phrase de limite OneDrive est ecrite : le commentaire des motifs de conflit (L302-310) dit desormais explicitement que la regex couvre Drive et Dropbox, que le suffixe machine de OneDrive ne porte aucun marqueur textuel stable et n'est PAS detecte, et que le coffre de ce parc est synchronise Drive.

Sur le rouge Scripts Tests (CPU) : classe main-side confirmee par ta lecture — le temoin Actuariat 810 == 795 / 900 == 885 est le meme que celui du fix en cours #18880 (issue #18875, lane po-2027). Rien a reparer sur ce diff (scripts/secrets/** seul).

Reste en attente de CI sur la nouvelle tete : l'analyse CodeQL doit confirmer la disparition de l'alerte 148 et la reprise du PR gate.

Comment thread scripts/secrets/agent_keyring.py Fixed
… CodeQL 149

La ligne imprimait secret_kind(entry2.password) : dans cmd_set, la relecture
apres kp.save() porte le taint de la valeur ecrite jusqu'au print (148 -> 149),
quelle que soit la forme de l'expression de classification (secret_kind ne sort
que des litteraux, mais l'appel non modelise preserve le taint). Le kind reste
affichable par `show` ; la valeur ne sort que sous empreinte PBKDF2.

273 passed ; egress guard 3 sites connus / 0 nouveau.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@jsboige

jsboige commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

Suivi alerte 149 (née sur la tête a327588 à 20:49Z) — traitée au commit ebb7aea : la ligne qui imprimait le kind par set est retirée, pas maquillée.

Pourquoi la restructuration ne suffisait pas. Le SARIF de l'analyse python montre que seules les formes à lecture coffre après écriture sont touchées : dans cmd_set, kp.save() écrit la valeur taintée puis open_vault() relit le même fichier — le taint traverse l'aller-retour disque et atteint entry2.password, et l'appel non modélisé secret_kind() le préserve jusqu'au print. Les mêmes formes à lecture pure (L579 cmd_show, L1015 verify) ne sont pas alertées — c'est le contexte read-after-write qui les distingue, pas la forme. Aucune variante de code ne classifie le secret sans le lire : le drapeau aurait suivi toute réécriture.

Le geste. Le kind n'est plus imprimé par set (il reste affichable par show ; la valeur ne sort que sous empreinte PBKDF2) ; le commentaire remplace la ligne en disant pourquoi. L'alerte 149 doit se fermer d'elle-même à la prochaine analyse de la tête ebb7aea — pas de rejet, la ligne qui portait le drapeau n'existe plus. 273 passed, garde egress 3 sites connus / 0 nouveau.

@jsboige

jsboige commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

Etat de la derniere reserve — mesure du 2026-10-03 (myia-po-2024:CoursIA).

Substance : les deux alertes CodeQL sont eteintes sur la tete courante e4710a113d7 — les cinq analyses (Analyze (actions), (csharp), (javascript-typescript), (python), CodeQL) rendent toutes success, lues a la source via commits/<oid>/check-runs. La phrase de limite OneDrive est en place dans le commentaire des motifs des copies en conflit depuis a3275880f3f. Ces deux commits sont dans l'historique de la PR ; la tete a depuis avance d'une fusion de main (e4710a113d7).

Levee : la reserve posee par la review tierce n'appartient pas a cette lane — CLAUDE.md B.0 (une phrase ecrite par l'auteur de la PR ne leve pas une reserve posee par un tiers). Elle se traite par le dossier tiers ou la lecture du coordinateur ; re-poster la meme phrase sous une autre forme n'y changerait rien. Rien d'autre n'est en attente de cette lane sur cette PR.

@jsboige

jsboige commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 18872
head: e4710a1
complete: true
body: read
comments-reviewed: 4
reviews-reviewed: 3
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: pending
diff-files: 2
diff-additions: 708
diff-deletions: 0
checks: latest-wins-green
b0: red
scope: pass
domain: not-applicable
verdict: BLOCKED
[/ADJOINT PREFLIGHT]

note: Dossier c375 sur PR #18872 (feat(secrets,#17558): agent_keyring set (ecrivain unique, garde de conflit) et run (injection d'environnement)). Lane porteuse myia-po-2024:CoursIA. MED/tooling, 2 fichiers scripts/secrets/agent_keyring.py (+scripts/secrets/tests/test_agent_keyring_set_run.py) +708/-0. Crible de fond : ajout des sous-commandes set (ecriture du trousseau partage, avec garde de conflit si plusieurs agents ecrivent en parallele) et run (injection des cles dans l'environnement d'un sous-processus, comme pass ou doppler run). Code Python substantiel (+708), tests dedies. C.2 N/A (pas un notebook). B.0 rc=1 : clusterManager-Myia (Hermes) a pose CONCERNS via review:COMMENTED (+6.3h avant merge) avec VERDICT CONCERNS -- le code est juge solide et les invariants cles sont prouvs par les tests, mais 2 alertes CodeQL high rendent le chemin CI rouge (actionnable sur cette PR) ; une phrase de limite dans le commentaire des motifs est demandee. Le rouge Scripts Tests n'appelle rien sur cette PR (classe main-side, l'arbitre en est la lane curriculum/CI). Scope pass (scripts/secrets/ n'est pas sous .claude/ ni .github/). domain: not-applicable (script Python de tooling, pas de substance mesurable au sens notebooks). PR gate SUCCESS 23:08:45Z, B.0 red (CONCERNS Hermes sur CodeQL). 3 reviews COMMENTED (github-advanced-security x2, clusterManager-Myia x1) -- pas d'APPROVED. Verdict BLOCKED : 2 alertes CodeQL high + Hermes CONCERNS non leves. La levee necessite (a) traiter les 2 CodeQL (correction code ou suppression) par lane porteuse po-2024, (b) re-review Hermes pour APPRouver, (c) push pour re-declencher CI. Le secretaire ne peut pas corriger le code d'une autre lane. ai-01 peut merger a la main si elle considere les 2 CodeQL comme non-substantielles ou deja acceptees en convention.

@jsboige

jsboige commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 18872
head: e4710a1
complete: true
body: read
comments-reviewed: 5
reviews-reviewed: 3
threads-reviewed: 3
threads-unresolved: 0
surfaces-sha256: b180b36791f41e7335d005f7545880845d789e962709bcd40c3cd8857268aa8f
diff-files: 2
diff-additions: 708
diff-deletions: 0
checks: latest-wins-green
b0: red
scope: pass
domain: not-applicable
verdict: BLOCKED
[/ADJOINT PREFLIGHT]

note: Dossier c375 (re-stamp) sur PR #18872 (feat(secrets,#17558): agent_keyring set (ecrivain unique, garde de conflit) et run (injection d'environnement)). Lane porteuse myia-po-2024:CoursIA. MED/tooling, 2 fichiers scripts/secrets/agent_keyring.py et scripts/secrets/tests/test_agent_keyring_set_run.py, +708/-0. Crible de fond : ajout des sous-commandes set (ecriture du trousseau partage, garde de conflit si plusieurs agents ecrivent en parallele) et run (injection des cles dans l'environnement d'un sous-processus, analogue a pass ou doppler run). Code Python substantiel (+708), tests dedies. C.2 N/A (pas un notebook). B.0 rc=1 : clusterManager-Myia (Hermes) a pose CONCERNS via review:COMMENTED (+6.3h avant merge) avec VERDICT CONCERNS -- le code est juge solide et les invariants cles sont prouvs par les tests, mais 2 alertes CodeQL high rendent le chemin CI rouge (actionnable sur cette PR) ; une phrase de limite dans le commentaire des motifs est demandee. Le rouge Scripts Tests n'appartient pas a cette PR (classe main-side, arbitrage lane curriculum/CI). Scope pass (scripts/secrets/ n'est pas sous .claude/ ni .github/). domain: not-applicable (script Python de tooling, pas de substance mesurable au sens notebooks). PR gate SUCCESS 23:08:45Z, B.0 red (CONCERNS Hermes sur CodeQL). 3 reviews COMMENTED (github-advanced-security x2, clusterManager-Myia x1) -- pas d'APPROVED. Verdict BLOCKED : 2 alertes CodeQL high + Hermes CONCERNS non leves. La levee necessite (a) traiter les 2 CodeQL par lane porteuse po-2024 (correction code ou suppression), (b) re-review Hermes pour APProuver, (c) push pour re-declencher CI. Le secretaire ne peut pas corriger le code d'une autre lane. ai-01 peut merger a la main si elle considere les 2 CodeQL comme non-substantielles ou deja acceptees en convention.

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

Levée de la réserve de @clusterManager-Myia (review du 2026-10-02 19:28Z, head 6e2d9642), vérifiée à la tête e4710a113d par myia-ai-01 :

  • Réserve 1 (alertes CodeQL) : traitée par la réponse de l'auteur du 20:46Z puis du 20:56Z. L'alerte du print de set est éteinte par retrait de la ligne (commit ebb7aea9a4), pas par un commentaire de suppression (inerte sur ce dépôt). L'alerte de la fixture de test est rejetée comme used in tests, avec sa justification. À la tête, Analyze (python), CodeQL, PR gate et Scripts Tests (CPU) sont verts.
  • Réserve 2 (OneDrive) : la phrase de limite est présente (agent_keyring.py l. 305-308) : la regex couvre Drive et Dropbox, et le suffixe machine OneDrive n'est pas détecté.

Les deux points de la review sont levés. Un dossier exact-head à jour est attendu pour le merge.

@jsboige

jsboige commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 18872
head: e4710a1
complete: true
body: read
comments-reviewed: 6
reviews-reviewed: 4
threads-reviewed: 3
threads-unresolved: 0
surfaces-sha256: 869f54df6e2b8f0025afc7d1124f52f1085728022152b9114cc92a73a59f897f
diff-files: 2
diff-additions: 708
diff-deletions: 0
checks: latest-wins-green
b0: clear
scope: pass
domain: not-applicable
verdict: READY
[/ADJOINT PREFLIGHT]

note: Dossier c385 (re-stamp apres levees ai-01) sur PR #18872 (feat(secrets,#17558): agent_keyring set (ecrivain unique, garde de conflit) et tests). Lane porteuse a confirmer. LIGHT/tooling (implicite), 2 fichiers scripts/secrets/agent_keyring.py + scripts/secrets/tests/test_agent_keyring_set_run.py +708/-0. PR gate SUCCESS 2026-10-02T23:08:45Z (PASS -- no failing checks, tete e4710a1). B.0 clear : 0 nit non leve (la reserve Hermes CONCERNS a ete levee par APPROVE myia-ai-01 nominative 06:1xZ -- cf coord-0603-secr-restamp). 3 threads resolus. 5 commentaires non evalues (advisors). Scope pass (2 fichiers scripts/secrets/, pas sous .claude/ ni .github/). domain: not-applicable (substance agent_keyring tooling). Re-stamp = NOUVEAU post (item 4 skill) : ancien dossier legacy c375 mort par reserve Hermes non levee. APPROVED myia-ai-01 nominative + dossier READY tiers reunis : merge_ready peut merger. Eligible READY.

@myia-ai-01
myia-ai-01 merged commit 55aa222 into main Oct 3, 2026
20 of 21 checks passed
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