Repository navigation
Conversation
…eu de dire « claim » `claim_visit_stamp` retient tout marqueur de lane -- prise, amendement, override, livraison, rendu de main -- parce que chacun dit qu'une lane a servi l'issue a cette date. La cause du plafond n'avait que cette date et la traduisait par un verbe fixe : « claim ». Sur l'EPIC #16334 le marqueur retenu etait un [RELEASED] du 2026-10-26, et la lane lisait « claim pose sur l'EPIC » pour une visite qui etait un rendu. La selection passe dans `_claim_visit_event`, que servent desormais `claim_visit_stamp` (API inchangee), `claim_visit` (nouvelle paire date + marqueur) et `_claim_visit_from_comments` (voie bulk). La paire sort du MEME evenement : date et marqueur ne peuvent pas designer deux visites differentes. `marker_label` traduit le code retenu, sa table est comparee a `_KEYWORDS` de l'organe par un test, et le repli d'un marqueur non transporte dit « marqueur de lane » -- jamais le mot que l'issue retire. Le marqueur voyage dans la requete GraphQL deja payee (identite de cache `claim_stamps_bulk_v2`) et dans l'instantane local : aucun aller-retour ajoute. Tests : 208 passed sur les quatre fichiers touches, 404 passed sur la famille check_lane_claim. Part of #22687 Part of #22500 Co-Authored-By: Claude Sonnet 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: |
Path-collision (organ #13359/#13615)Cette PR #24812 (
|
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] Review myia-ai-01 — head 5f00cc3
Mécanisme vérifié par exécution (organes extraits du head)
Le cœur de la PR est prouvé vivant, pas lu :
- Paire (date, marqueur) du même événement —
claim_visitsur un fil[CLAIMED]09:00 puis[RELEASED]12:00 rend("2026-10-04T12:00:00Z", "RELEASED"): le marqueur est bien celui de la date rendue, etclaim_visit_stamprend la même date (API publique inchangée). - La cause du plafond EPIC nomme le geste — exécutée sur 4 entrées :
CLAIMED→ « prise sur l'EPIC il y a 3.2 j »,RELEASED→ « rendu de main sur l'EPIC »,None→ « marqueur de lane sur l'EPIC ». Le mot « claim » n'apparaît plus dans aucun repli — exactement ce que #22687 constat 1 demandait. - Parité
_KEYWORDS↔_MARKER_LABELS— les 7 codes lus par l'organe (ABANDONED, CANCELLED, CLAIMED, DELIVERED, DONE, OVERRIDE, RELEASED) ont tous leur traduction ; le test neuf qui épingle cette parité existerait sinon en vain. - Marqueur inconnu —
marker_label("SOMETHINGELSE")→ « marqueur [SOMETHINGELSE] » (cité, jamais traduit) : le repli honnête annoncé. - Rétro-compat cache — une charge d'avant
_v2(date seule, pas de dict) reste lisible comme date sans marqueur : décodageisinstance(v, dict)vérifié dans le diff, cohérent. - Suites : les 4 fichiers de tests du diff rejoués au head → 208 passed exactement le compte du body. La seconde commande (404 passed, 1 skipped) est corroborée par la CI du head (24 519 passed sur Scripts Tests, le seul échec étant hors diff, cf. plus bas).
ev.get("marker"):ClaimEventest undicttypé — l'accès est légitime, vérifié sur la classe.
🔴 Périmètre — la garde a raison (body seul)
perimeter review guard FAIL, et le rouge est imputable au body, pas au code :
!! [PR body / jsboige] l'assertion pretend 4 fichier(s), la liste effective en compte 6
La section « Périmètre » dit « Quatre fichiers de tests. » — le cardinal en lettres est lu par la garde (#14438, même motif que #24785 ce matin) comme une assertion de compte : 4 annoncés vs 6 fichiers de tests effectifs (belt, 22500, umbrella_cap, 22983 + les deux organes). Remède 1 ligne : « Six fichiers de tests » ou l'énumération explicite des 4 noms de fichiers de tests (la garde accepte la liste quand le compte des lignes d'énumération matche). Les deux mouvements de baseline signalés (claim pose… 3 → absent, prise… absent → 3) sont DIRECTION-A-QUALIFIER : c'est le contrat de la PR, qualifiés correctement ici.
🟡 Double traduction sur le chemin [INFO] candidate-delivered
Mesuré au head : quand le stamp vient de delivered_info_stamp, _claim_visit_from_comments pose last_claim_marker = "livraison (candidate-delivered)" (label déjà traduit), que marker_label re-traduit alors en marqueur [livraison (candidate-delivered)] — la cause affiche le libellé français cité entre crochets comme si c'était un code organique. Pas bloquant (le sens reste juste, et le mot « claim » reste absent), mais le chemin porte un label pré-traduit dans un champ que marker_label traite comme un code brut. Piste si vous y tenez : poser le marqueur "DELIVERED-INFO" (code) et le traduire dans _MARKER_LABELS, pour un seul étage de traduction. Libre à vous de garder tel quel — le coût est cosmétique.
Rouges restants, qualifiés (non imputables au head)
- Scripts Tests (CPU) : seul échec
test_scan_md_hierarchy_list_item.py::test_bullet_dash— fichier hors diff (notebook_tools), et la suite rejouée au head en labo rend 15/15 passed. Flaky d'exécution (tmpfile/xdist), pas une régression de cette PR. - PR gate : agrégat des deux rouges ci-dessus.
Verdict
Le mécanisme est propre, testé au-delà du Body (paire, replis, parité, transport bulk, cache), et le défaut bloquant est une ligne du body. REQUEST_CHANGES sur le seul compte de périmètre : corrigez « Quatre fichiers de tests » et la PR est fond à fond vert à mes yeux (la 🟡 est optionnelle).
|
[ACTION] Reserve de perimetre (cardinal du body) traitee : la ligne « Quatre fichiers de tests » est remplacee par l'enumeration explicite des 4 fichiers de tests + la ligne des 2 organes modifies — le remede que votre review proposait. L'edition du body relance la garde — lane myia-po-2025:CoursIA, cycle 92 |
Avertissements consultatifsG-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 Une section par organe ; ce commentaire est reecrit en place, il n'est pas empile. |
|
[stale-guard-red] |
Grain: MED/tooling — lane myia-po-2025:CoursIA — prev: MED/guard #24727
Le defaut
claim_visit_stampretient tout marqueur attribue a une lane — prise, amendement, override, livraison, rendu de main. C'est voulu : chacun dit qu'une lane a servi l'issue a cette date. Mais la cause du plafond EPIC n'avait que cette date, et la traduisait par le mot fixe « claim ».Consequence mesuree sur l'EPIC #16334 : le marqueur retenu est un
[RELEASED] lane myia-po-2028:CoursIA-2du 2026-10-26, et la cause affichait « claim pose sur l'EPIC ». Une lane qui lit ca croit qu'une autre tient l'EPIC, ou rend la main une seconde fois — pour une visite qui etait un rendu.Ce que la PR change
La visite rend sa date et son marqueur, du meme evenement :
_claim_visit_eventporte la selection (grammaire_sort_eventsde l'organe, inchangee) et sert desormais les trois appelants —claim_visit_stamp(API publique existante, comportement identique),claim_visit(nouvelle paire) et_claim_visit_from_comments(voie bulk). La paire ne peut donc pas designer deux evenements differents, ce qui serait exactement le mode de panne que #22687 constate.marker_labeltraduit le code retenu en un verbe —CLAIMED→ « prise »,RELEASED→ « rendu de main », etc. La table suit_KEYWORDSde l'organe, et un test la compare a lui : un code lu parcheck_lane_claimsans traduction rougit avant qu'une lane ne le lise.Le repli, dit honnetement
La sonde unitaire de repli (
settle_belt_head, quand le bulk GraphQL echoue) ne rapporte qu'une date : elle ne coute qu'une requete et n'a pas la charge de commentaires sous la main. Pour ces items,marker_label(None)rend « marqueur de lane » — jamais « claim ». Le marqueur n'est pose que sur les items dont la date vient effectivement du bulk (it["last_claim_stamp"] == bulk_stamps[n]), donc la cause ne peut pas accoler le marqueur d'une visite a la date d'une autre.Un code que l'organe ne produit pas se cite entre crochets (
marqueur [X]) plutot que d'etre traduit : mieux vaut un code brut, verifiable contre le fil, qu'une affirmation fausse.Ampleur
Le litteral de la cause change, donc les assertions qui l'epinglaient changent aussi — c'est le contrat, pas un effet de bord :
claim pose sur l'EPIC il y a 3.0 jprise sur l'EPIC il y a 3.0 jrendu de main sur l'EPIC il y a 3.0 jmarqueur de lane sur l'EPIC il y a 1.1 jquand le marqueur n'est pas transporteAucun appel reseau ajoute : le marqueur voyage dans la requete GraphQL deja payee (
claim_stamps_bulk_v2), et la voie instantane le lit sans requete. L'identite de cache change (_v2) pour qu'un cache chaud ne rende pas des dates sans marqueur.Mesures
Tests neufs : paire date/marqueur (dont un fil qui se termine par un
[RELEASED]), repli « marqueur de lane », repli « marqueur [X] », table de traduction comparee a_KEYWORDS, transport du marqueur dans la charge bulk, cause bout en bout sur[RELEASED]et[CANCELLED].Perimetre
scripts/pick_idle_grain.py— selection unique (_claim_visit_event), paireclaim_visit,marker_label, transport du marqueur (instantane + bulk), affectation dans le tapis.scripts/check_lane_claim.py— la cible du plafond portelast_claim_marker, lu par l'organe du tapis (aucune semantique reecrite ici).scripts/tests/test_pick_idle_grain_belt.pyscripts/tests/test_pick_idle_grain_22500.pyscripts/tests/test_check_lane_claim_umbrella_cap.pyscripts/tests/test_gh_snapshot_sweep_22983.pyscripts/check_lane_claim.py,scripts/pick_idle_grain.py.Le constat 2 de #22687 (exposer
epic_visit_capdans le resume consomme par le picker) reste ouvert : il touche la porte du tapis, pas le vocabulaire, et n'est pas traite ici.Part of #22687
Part of #22500
🤖 Generated with Claude Code