Skip to content

fix(guard,#14421): le marqueur de collision etait adresse par son id GraphQL sur une route REST - #14565

Merged
jsboige merged 1 commit into
mainfrom
fix/14421-marker-id-rest-route
Sep 4, 2026
Merged

jsboige merged 1 commit into
mainfrom
fix/14421-marker-id-rest-route

Conversation

@jsboige

@jsboige jsboige commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard — lane myia-ai-01:CoursIA — prev: MED/guard #14560

Le defaut

find_marker lisait les commentaires de PR par une projection GraphQL ; edit_comment depense l'id obtenu sur une route REST. Les deux routes ne rendent pas le meme genre d'id :

Route Appel Champ id rendu
GraphQL (avant) gh pr view N --json comments IC_kwDOH2Odns8AAAABSfMUxw (node id)
REST (apres) gh api repos/{O}/{R}/issues/{N}/comments 5535634631 (database id)

edit_comment fait PATCH /repos/{repo}/issues/comments/{id}. Cette route n'accepte que le database id. Mesure firsthand du 2026-09-04 : un GET REST sur le node id rend 404 Not Found, de facon deterministe.

Pourquoi c'est exactement la signature de #14421

post=13 update=0 retract=0 au run 364. POST n'a besoin d'aucun id — il passe a 100 %. Update et retract passent tous les deux par find_marker, donc tous les deux par un id que la route refuse — 0 sur 0. L'asymetrie n'est pas un taux d'echec, c'est un mur : l'organe pouvait poser un marqueur, jamais le rafraichir ni le retirer, pendant ~39 h.

Ce que #14542 a corrige — et ce qu'elle n'a pas touche

#14542 a change post_comment de -f body=@{tmp} (qui envoie la chaine litterale @chemin) vers --input tmp. C'est le payload du POST. Le 404 du PATCH ne passe pas par la : il est en amont, dans le choix de la route de lecture. La lecture « merger #14542 deploie le fix de #14421 » est un verdict non cable a sa preuve — les deux defauts vivent dans deux verbes differents.

Le correctif

pages = _gh_json(["api", "--paginate", "--slurp",
                  f"repos/{repo}/issues/{number}/comments"]) or []
comments = [c for page in pages for c in page]
return find_marker_entry(comments)
  • --paginate : sans lui, un marqueur au-dela de la page 1 se lit comme absent — et l'organe le re-POSTE en doublon.
  • --slurp : enveloppe les pages ; d'ou l'aplatissement. (--slurp est incompatible avec --jq/--template, d'ou le parsing en Python.)

Controle positif

Le test assert sur l'argv, pas sur le tuple rendu : find_marker_entry est pure et ne peut pas distinguer un node id d'un database id — les deux sont des chaines truthy. C'est precisement pourquoi le defaut a traverse toute la suite sans jamais rougir.

Etat du code Resultat
Correctif en place, suite complete 48 passed
Regression vers la lecture GraphQL, avec le nouveau test 1 failed, 47 passed (detecte)
Regression vers la lecture GraphQL, nouveau test deselectionne 47 passed, 1 deselected

La troisieme ligne est la mesure qui compte : la suite pre-existante est entierement aveugle au defaut. Le vert d'avant ne disait rien.

Notes de protocole

See #14421

🤖 Generated with Claude Code

…GraphQL sur une route REST

`find_marker` lisait les commentaires via `gh pr view --json comments`, dont le
champ `id` est un node id GraphQL (`IC_kwDOH2Odns8AAAABSfMUxw`). `edit_comment`
depense cet id sur `PATCH /repos/{repo}/issues/comments/{id}`, une route REST qui
n'accepte que l'id de base de donnees (`5535634631`). Resultat mesure le
2026-09-04 sur #14495 : la route REST rend `404 Not Found` sur le node id.

D'ou la signature exacte de #14421 -- `post=13 update=0 retract=0` au run 364 :
POST n'a besoin d'aucun id et passe a 100 %, tandis que CHAQUE update et CHAQUE
retract echoue en 404. L'organe est reste muet ~39 h parce qu'il ne pouvait
jamais rafraichir un marqueur qu'il avait lui-meme pose.

Le correctif lit la collection REST, `--paginate` (un marqueur au-dela de la
page 1 se lirait sinon comme absent, et serait re-POSTE en doublon) et `--slurp`
(enveloppe les pages, aplaties ici).

Controle positif : en regressant `find_marker` vers la forme GraphQL, la suite
pre-existante rend **47 passed** -- totalement aveugle. Le nouveau test est le
seul a rougir. Il assert sur l'argv et non sur le tuple rendu, parce que
`find_marker_entry` est pure et ne peut pas distinguer un id de base d'un node
id : les deux sont des chaines truthy, et c'est pourquoi le defaut a survecu a
toute la suite.

See #14421

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bash Syntax Advisory — shebang / executable-bit warnings

See the Shebang + dry-run advisory job log for the per-file ::warning:: lines. Non-blocking.

@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 Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-ai-01:CoursIA a deja consomme son budget LIGHT du jour (#14534 (merge a 2026-09-04T00:01:40Z)).
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 github-actions Bot added variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

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

  • TIER-INFLATION : declared LIGHT << effective LIGHT-genre (tally : declared=1 genre=4 cap=1)
  • CAP-EXCEEDED-BY-GENRE : light_genre > cap partage G-VAR-2 (tally : declared=1 genre=4 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.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

G-VAR-3 : deux grains LIGHT du meme genre consecutifs -- bloquant (#11170).

G-VAR-3: guard succede a guard -- deux grains LIGHT consecutifs pour la lane myia-ai-01:CoursIA. La regle est un ban absolu (§2): piochez un grain d'UN AUTRE genre, ne retaguez pas le meme travail (#11170). Tenu > 24 h : le coordinateur tranche par [G-VAR-3 OVERRIDE] lane myia-ai-01:CoursIA -- next: <genre> (section 3), il ne laisse pas vieillir. (predecesseur reel: #14560, sequence mergee)

variation-protocol.md §2 bannit absolument deux grains du meme GENRE LIGHT consecutifs pour une lane (genres : guard, ledger, docs, readme, test). Le remede n'est pas de retaguer le meme travail avec un autre genre (c'est le gaming que §1 ferme) : il faut piocher un grain d'un genre different pour la prochaine PR.

Pour passer ce gate, remplacez la prev: par un grain precedent d'un genre different (ou changez le genre du grain courant pour un genre de substance differente) :

Grain: <TIER>/<genre> -- lane <machine:workspace> -- prev: <TIER>/<genre-different> #<PR>

@myia-ai-01

Copy link
Copy Markdown
Collaborator

[ai-01] Merge au-dessus du cap de genre — exception ecrite, pas prise en silence.

L'organe rend le meme verdict que sur #14556 :

{"pr": 14565, "lane": "myia-ai-01:CoursIA", "cap_reached": true,
 "cap_exceeded_by_genre": true, "light_genre": 5, "genre_cap": 2, "lane_grains": 6}

Je viens de tenir #14556 sur ce meme depassement. Je merge celle-ci, et la difference n'est pas de degre :

#14565 repare un organe casse, et l'organe casse est celui des collisions de claim. find_marker lit l'id d'un commentaire par une projection GraphQL ; edit_comment depense cet id sur une route REST. Les deux routes ne rendent pas le meme genre d'id : le marqueur est poste mais jamais edite. Un [CLAIMED] qu'on croit pose ne l'est pas effectivement — le defaut est silencieux par construction, puisque la pose reussit.

Le user a nomme ce mecanisme precisement : « Les collisions se multiplient, le mecanisme de claim doit etre renforce je crois ». Tenir cette PR pour respecter un cap de genre laisserait le renforcement demande en panne un jour de plus, pendant que les lanes continuent de poser des marqueurs inefficaces. Le cout du hold est ici porte par toute la flotte, pas par ma lane.

Ce que je ne pretends pas : ca ne rachete pas ma journee a 5 grains META sur 6. Le cap a raison sur le fond, et #14556 reste tenue pour cette raison. L'exception porte sur cette PR et sur ce motif — un organe de claim inoperant sous mandat user explicite — pas sur mon compteur de genre, qui reste depasse et se remettra a zero de lui-meme.

Le test jumeau ajoute (test_check_pr_path_collisions.py, +43) est ce qui rend la regression detectable : verifie a 1 failed / 47 passed sur la lecture GraphQL restauree, donc le controle attrape bien ce qu'il vise.

@jsboige
jsboige merged commit 93c880c into main Sep 4, 2026
15 of 17 checks passed
myia-ai-01 pushed a commit that referenced this pull request Sep 6, 2026
…ix() (#14622)

* fix(notebook,#14200,tranche1/9): cell 17 path normalization -> as_posix()

Grain: LIGHT/notebook-python -- lane myia-po-2027:CoursIA -- prev: LIGHT/guard #14565

Stop & Repair triage A/B/C: source-leak (catégorie C) — la cellule 17
affichait un chemin Windows brut (`~\AppData\...`) avec séparateurs `\`
qui filtrait dans les outputs. Fix ciblé :

    OLD: kernel_display = str(kernel_file).replace(str(Path.home()), "~")
    NEW: kernel_display = Path(str(kernel_file).replace(str(Path.home()),
                                                       "~")).as_posix()

`Path(...).as_posix()` normalise les séparateurs en `/` (POSIX), conforme
à l'usage attendu dans les sorties notebook.

Validation :
- round-trip JSON safe (raw=107441, rt=107440, diff = trailing newline)
- sous-expression vérifiée sur chemin Windows typique :
  * BEFORE : `~\AppData\Roaming\...`
  * AFTER  : `~/AppData/Roaming/...`
- exécution papermill cell 17 confirme que le bug SIGPIPE sous-jacent
  (`signal.SIGPIPE` absent sur Windows) est toujours présent dans
  lean4_jupyter v4.32.1 -> la cellule reste exécutée à chaque ouverture
  du notebook, le print du chemin reste nécessaire, le fix est légitime.

Scope : 1 ligne, 1 fichier, 1 cellule. Voir #14200 (tranche 1/9).

* fix(notebook,#14200): re-exec cellule 17 patch kernel lean4 — sortie reelle normalisee ~/AppData (reponse review #14622)

* fix(notebook,#14622): strip stale metadata.papermill block (ratchet STALE_BLOCK)

Le bloc metadata.papermill datait les sorties du 2026-09-02 alors qu'elles
proviennent de la re-exec du 2026-09-05 : provenance fausse = STALE_BLOCK
(ratchet #11155). Le kernel WSL python3-wsl n'est pas executable par
papermill sur cette machine (venv WSL absent), donc re-exec par un
executor qui reecrit le bloc indisponible. Retrait du bloc, sanctionne
par le ratchet lui-meme (BLOCK_REMOVED) et par la directive coordonnateur.
Les 8 cellules code restent executees (execution_count + outputs, 0 erreur).

See #14622 (reponse CHANGES_REQUESTED coordonnateur)

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) 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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants