Repository navigation
docs(variation,#15589): le prev: declare n'est pas la cle d'adjacence — l'organe lit la sequence mergee - #15593
Conversation
… — l'organe lit la sequence mergee La ligne 19 de `.claude/rules/variation-protocol.md` affirmait : « le genre est la cle d'adjacence ». C'est faux depuis #12095, et le cout est mesure. L'organe `scripts/ci/variation_adjacency_guard.py` resout le predecesseur reel depuis la SEQUENCE MERGEE de la lane (`--merged-prs-file`) et rend le genre declare dans un champ separe (`declared_prev_genre`) precisement pour ne pas s'y fier. Le `prev:` declare est documentaire, et source de verite seulement en repli (premier grain, ou echec de fetch -- jamais un crash). Le verdict dit toujours sa source (`prev_source`). Pourquoi le champ est fige : il est ecrit a l'ouverture de la PR, donc une lane qui merge pendant que sa PR est ouverte le perime. #11963 a mesure `prev: MED/guard #11841` exact a la redaction puis suivi de quatre grains merges -- le vrai predecesseur etait `notebook-python`. Le cout, mesure publiquement : le 2026-09-11 le coordinateur a derive l'adjacence a la main depuis les `prev:` declares et pose deux HOLD G-VAR-3 faux (#15551, #15552), tous deux retractes apres consultation de l'organe (prev_genre: guard, prev_pr: 15569, prev_source: merged-sequence). Conséquence 2 de l'issue -- la piste « le garde verifie que le prev: vise une PR mergee » -- est tranchee EN NEGATIF, avec sa mesure : l'invariant PREV-ABANDONED (`validate_prev_targets`, `variation_prev_guard.py`) ne rougit que sur une PR fermee sans merge, jamais sur une PR en vol. L'ancienne lecture « not merged » bloquait cinq PRs ouvertes citant quatre predecesseurs tous OPEN, et punissait exactement le comportement que R1 impose. La regle reste succincte (auto-chargee) : le mecanisme, la mesure et le cas « prev: ouvert » vivent dans le detail §2.1. See #15589 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
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 |
Path-collision (organ #13359/#13615)Cette PR #15593 (
|
Grain: LIGHT/docs — lane myia-po-2023:CoursIA — prev: MED/guard #15591
Summary
La ligne 19 de
.claude/rules/variation-protocol.mdaffirmait que « le genre est la clé d'adjacence » — c'est-à-dire que G-VAR-3 se calculerait sur le genre déclaré dansprev:. C'est faux depuis #12095, et le coût est mesuré, pas théorique.L'organe
scripts/ci/variation_adjacency_guard.pyrésout le prédécesseur réel depuis la séquence mergée de la lane (--merged-prs-file) et rend le genre déclaré dans un champ séparé (declared_prev_genre) précisément pour ne pas s'y fier.prev:déclaré est documentaire ; il n'est source de vérité qu'en repli (premier grain, ou échec de fetch — jamais un crash).prev_source∈ {merged-sequence,declared}.Pourquoi le champ est périmé par construction
Il est figé à l'ouverture de la PR. Une lane qui merge des grains pendant que sa PR est ouverte le rend faux. #11963 a mesuré
prev: MED/guard #11841— exact à la rédaction, suivi de quatre grains mergés ; le vrai prédécesseur étaitnotebook-python.Le coût, mesuré publiquement
Le 2026-09-11, au merge-gate, le coordinateur a dérivé l'adjacence à la main depuis les
prev:déclarés et posé deux HOLD motivés G-VAR-3, sur #15551 (prev: LIGHT/readme #15550) et #15552 (prev: LIGHT/readme #15551) — une chaîne de troisLIGHT/readme, qualifiée d'« inexemptable par construction ».L'organe, interrogé ensuite, rend l'inverse sur les deux :
Le prédécesseur réel était #15569 (
MED/guard), mergé à 11:34:51Z, qui s'interpose dans la séquence et rompt l'adjacence. Deux rétractations ont suivi (issuecomment-5633877872,issuecomment-5633878069). Le défaut n'est donc pas réservé aux workers : il a fait écrire un motif faux au coordinateur, dans le geste même que la règle existe pour outiller.Conséquence 2 — tranchée en NÉGATIF, avec sa mesure
L'issue proposait : « le garde de tag vérifie que le
prev:référence une PR mergée de la même lane, en advisory d'abord ».Cette piste a déjà été implémentée, mesurée, puis retirée le 2026-09-08. L'invariant
PREV-ABANDONED(validate_prev_targets) ne rougit désormais que sur une PR fermée sans merge — lignée abandonnée — jamais sur une PR en vol. Mesure : cinq PRs ouvertes bloquées (#15156, #15190, #15207, #15209, #15210) citant quatre prédécesseurs distincts (#15129, #15175, #15199, #15203) — les quatre OPEN, pas un seul abandonné. FlaguerOPENpunissait exactement le comportement que R1 deproactive-coordination.mdimpose (« 1 PR entre 2 wakeups = PLANCHER, jamais plafond »).Seule la relecture trompeuse est un défaut — et elle est traitée par la prose de cette PR, pas par un gate. Ré-introduire le flag serait un retour en arrière sur un correctif mesuré.
Témoin live sur cette PR même
Cette PR en est une démonstration directe. Elle déclare
prev: MED/guard #15591(#15591 est OPEN). L'organe, interrogé sur cette PR avec la séquence mergée réelle :Le prédécesseur réel est
notebook-python(#15448, mergé), pas leguarddéclaré. Autrement dit : un agent qui lit la ligne 19 croit que l'adjacence se joue entredocsetguard; l'organe la joue entredocsetnotebook-python. Les deux lectures ne portent pas sur le même fait — c'est exactement le défaut corrigé ici, reproduit à la demande sur la PR qui le corrige.Acceptance
grep -c "le genre est la clé d'adjacence"= 0 ;grep -ci "séquence mergée"= 1.grep -c 'scripts/ci/variation_adjacency_guard' .claude/rules/variation-protocol.md= 1 (> 0).prev:est distingué par écrit de son rôle de calcul (mot « documentaire » + la clause de repli + « aucune lane ne déplace son adjacence en choisissant sa déclaration »).Hors périmètre respecté : le vocabulaire fail-OPEN de
canonicalize_genre(#13475) n'est pas touché, non fusionné.Review Checklist
check_docs_links.py --checkrelancé après le dernier commit :OK: No new broken links. (0 pre-existing, 6807 total). Les 4 acceptance sont vérifiées pargrepsur le fichier écrit, pas de mémoire.../../scripts/ci/variation_adjacency_guard.py).docs/curriculumbyte-identiques àmain) ; le mécanisme décrit est lu dans le code de l'organe (variation_adjacency_guard.pyL364-381,variation_prev_guard.pyvalidate_prev_targets), pas déduit.Sign-off user requis
.claude/rules/est concerné → PR + sign-off user (CLAUDE.md §A). Je ne m'auto-autorise pas à modifier la doctrine : cette PR corrige un fait faux (le mécanisme réel du calcul d'adjacence, vérifiable dans le code), elle ne change aucune intention. La doctrine G-VAR-3 elle-même (le ban, la boucle de rattrapage, l'exemption) est inchangée.Notes de review
prev:ouvert » vivent dans le détail §2.1, atteint par un pointeur d'une ligne (harness-hygiene, 3 tiers).prev:déclaré n'est pas purely documentaire — il reste le repli. Écrire « purement documentaire » aurait remplacé une affirmation fausse par une autre.Closes #15589
🤖 Generated with Claude Code