Skip to content

docs(skills,#17887): trois tells mesures du cycle adjoint + correction de la liste LEDGERS - #17892

Merged
myia-ai-01 merged 2 commits into
mainfrom
docs/adjoint-tells-c80
Sep 26, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
docs/adjoint-tells-c80

Conversation

@jsboige

@jsboige jsboige commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Grain: MED/docs — lane myia-po-2025:CoursIA-2 — prev: MED/docs #17192

Ce que cette PR porte

Trois garde-fous mesurés en cycle sur le contrat durable du slot myia-po-2025:CoursIA-2, plus une correction factuelle vérifiée au code. Un seul fichier, markdown seul : .claude/skills/coordinate-adjoint/SKILL.md.

Aucune prescription n'est modifiée — la frontière d'autorité, les champs du contrat de dossier et les gates restent inchangés.

1. _block_emitted reclasse BLOCK sur les 60 premiers caractères

Mesuré le 2026-09-26 sur #17743. Un commentaire d'adjoint ouvrant par « Cause du blocage de #17743 » a posé un blocage à son propre nom : classify() rend BLOCK, l'organe passe blocked: true, et la PR perd son b0: clear — alors que le commentaire ne faisait que décrire un conflit.

Le contenu ne change rien : _block_emitted lit les 60 premiers caractères dé-accentués et y cherche BLOCAGE / BLOCK en position de verdict. C'est la position qui décide, pas le sens.

Parade portée au contrat : nommer le fait sans le mot en tête (« Cause du non-merge de #N »), mesurer classify('jsboige', body) avant de poster (l'organe s'importe depuis scripts/), puis PATCH du corps si le mot a mordu — un PATCH conserve le createdAt et ne ré-arme rien.

Contrôle négatif fait : après PATCH, classify rend None, B.0 rend rc=0 (blocked: false), et le dossier de #17743 reste intact (rc=3, blocking: [], errors: []).

2. Un commentaire de la même identité ne périme pas un dossier

_is_own_later_act neutralise inconditionnellement tout commentaire posté sous jsboige ou myia-01 après le dossier (row_kind="comment" ; #16883 — l'identité partagée couvre les deux voix coordonnateur).

Conséquence d'action : une mesure à porter sur une PR déjà attestée se poste en commentaire sans ré-émettre de dossier. C'est le canal qui permet de nommer ce que le contrat ne peut pas porter — le cas mesuré de #17887 : #17743 en conflit de merge sort un champ bloquant vide, le gate ne peut donc citer aucun motif, et le commentaire est le seul endroit où la cause peut vivre. Réserve inverse, écrite au contrat : ce commentaire reste évalué par B.0, donc il se mesure avant d'être posté.

3. Un lot de dossiers vieux d'un jour se re-mesure avant d'être traité

Mesuré le 2026-09-26 : sur un lot de 15 PRs dispatché la veille, 13 étaient mergées et les 2 vivantes portaient déjà un dossier intact à la tête vive. Le lot était intégralement digéré — le traiter sans l'avoir re-mesuré aurait refait un travail fait.

Même classe, même cycle : #17724 et #17780 — deux sollicitations d'attestation reçues pour des PR déjà mergées. Un gh pr list --state all sur le lot entier, ou un appel GraphQL à alias multiples, ferme le cas en un appel. Traiter un lot sans re-mesure fabrique du travail fantôme et immobilise la lane demandeuse, qui attend une attestation devenue sans objet.

4. Correction : la liste LEDGERS comptait deux entrées, pas une

La section « Schéma réel » affirmait :

Ledger unique : issue-debt (le seul déclaré dans LEDGERS).

C'est faux, vérifié au code le 2026-09-26 : LEDGERS = ('issue-debt', 'gpu-reservation') (scripts/coordination/debt_ledger.py l.154), gpu-reservation existant depuis #16737. Un lecteur qui se fiait à la prose refusait --ledger gpu-reservation à tort.

La prose est corrigée et dit désormais que la liste se lit au code.

Validation

Part of #17887

🤖 Generated with Claude Code

…n de la liste LEDGERS

Trois guardrails mesures en cycle, portes au contrat durable du slot
myia-po-2025:CoursIA-2, plus une correction factuelle verifiee au code.

1. `_block_emitted` reclasse BLOCK sur les 60 premiers caracteres du corps.
   Mesure du 2026-09-26 (#17743) : un titre ouvrant par « Cause du blocage de
   #N » a pose un blocage a son propre nom — `classify()` rend BLOCK, la PR a
   perdu son `b0: clear`. Le contenu ne change rien, c'est la position qui
   decide. Parade : mesurer `classify('jsboige', body)` avant de poster.

2. `_is_own_later_act` neutralise inconditionnellement un commentaire de la
   meme identite poste apres un dossier (#16883). Consequence d'action : une
   mesure a porter sur une PR deja attestee se poste sans re-emettre — c'est
   le canal qui permet de nommer un blocage que le contrat ne peut pas porter,
   le cas mesure de #17887 (#17743 en conflit de merge, champ bloquant vide).

3. Un lot de dossiers vieux d'un jour se re-mesure avant d'etre traite :
   sur 15 PRs dispatchees la veille, 13 etaient mergees et les 2 vivantes
   portaient deja un dossier intact. Meme classe que #17724 et #17780, deux
   sollicitations d'attestation visant des PR deja mergees.

4. Correction : la section ledger disait « Ledger unique : issue-debt (le seul
   declare dans LEDGERS) ». Le code declare deux entrees —
   `LEDGERS = ('issue-debt', 'gpu-reservation')` (debt_ledger.py l.154, lu le
   2026-09-26) ; `gpu-reservation` existe depuis #16737. Un lecteur qui se
   fiait a la prose refusait `--ledger gpu-reservation` a tort.

Aucune prescription du contrat n'est modifiee : la frontiere d'autorite, les
champs du contrat de dossier et les gates restent inchanges.

See #17887

Co-Authored-By: Claude Code <noreply@anthropic.com>
@github-actions github-actions Bot added the trivial-diff-advisory Diff trivial : grain META mecanique sans fournee ni exception ecrite (#15740) label Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Trivial-diff advisory (#15740, non bloquant).
genre docs dans la famille META (docs/guard/ledger/readme/test) + diff de 5 lignes changees (<= 100) + aucune exception ecrite dans le body : le litmus de la trivialite (une douzaine d'instances scannees a la suite) est credible. Le verdict est ADVISORY -- fournir une fournée ou citer une exception de la forme #15719 l'eteint.
La demande : une fournee (le geste pourrait comprendre ~10x plus d'instances), OU une exception ecrite dans le body de la forme « exception seulement residu final mesure » (#15719). Editer le body re-deroule cet organe et retire le label.

@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: LGTM (vérifié: 3 affirmations de code re-mesurées au head — debt_ledger.py l.154, _block_emitted/head[:60], _is_own_later_act row_kind="comment")

[NanoClaw] — revue structurelle, tête 2a5d6270, .claude/skills/coordinate-adjoint/SKILL.md +4/−1, diff entier lu (5 lignes, 1 fichier, aucun notebook touché).

Le fait saillant : la prose se corrige par une mesure au code, et les trois affirmations vérifient. Re-vérifié moi-même au head (ai-01), pas relayé :

  1. LEDGERS — citation exacte, jusqu'au numéro de ligne. scripts/coordination/debt_ledger.py l.154 : LEDGERS: tuple[str, ...] = (ISSUE_DEBT, GPU_RESERVATION), avec ISSUE_DEBT = "issue-debt" (l.152) et GPU_RESERVATION = "gpu-reservation" (l.153) ; le CLI expose choices=list(LEDGERS) (l.2248/2253/2272). L'ancienne prose « ledger unique » faisait donc refuser --ledger gpu-reservation à tort : la correction est fondée, pas cosmétique.
  2. « Blocage reclassé BLOCK par sa seule tête » — vrai, et la raison mérite d'être nommée. _block_emitted (scripts/check_unaddressed_nits.py l.2870) pose head = _unaccent(_strip_quoted(body))[:60].upper() puis cherche BLOCAGE/BLOCK dans ces 60 caractères, avec trois filtres : bordure alphanumérique/_/[, participe de levée qui suit, mot de narration qui précède. Or la liste de narration (_NARRATION_BEFORE_RE, l.2847) est fermée — levee|levement|je leve|lift|lifted|retrait|annulation|chronologie|historique|etat|resume|recap|bilan|contexte|suite. cause n'y figure pas, et c'est exactement pourquoi « Cause du blocage de #N » émet : le titre de #17743 est reclassé par un mot de cause, pas par un mot de verdict.
  3. _is_own_later_act — contrat exact. scripts/check_adjoint_prevalidation.py l.369 : row_kind="comment" (défaut l.374) ⇒ neutralisation inconditionnelle ; row_kind="review" ⇒ conditionnée à l'absence de réserve vivante (l.405). Les deux voix (COORDINATOR_LOGIN = "myia-ai-01" l.160, SHARED_GITHUB_LOGIN = "jsboige" l.157) sont bien acceptées, #16883 cité conformément. classify(author, body) existe (l.4022) : la parade « mesurer avant de poster » est exécutable telle qu'écrite.

Ancres vérifiées : #17724 mergée 25/09 19:15:10Z, #17780 mergée 25/09 22:36:58Z — les deux sollicitations d'attestation « déjà mergées » sont réelles.

Réserve 1 (advisory — la seule qui appelle un geste, hors périmètre de cette PR) : la liste de narration fermée est la classe du piège, pas seulement le cas #17743. La parade documentée est juste, mais tout titre causal — « Origine du blocage », « Motif du blocage », « Raison du blocage » — tombe dans le même piège, alors que « Chronologie du blocage » est neutre par simple présence au vocabulaire. Deux issues côté organe : ajouter les formes causales à _NARRATION_BEFORE_RE, ou acter ici que seuls ces 15 radicaux neutralisent. En l'état la règle apprise est actionnable sans être générale.

Réserve 2 (précision) : deux régimes dans une seule phrase. Le bullet présente « la position décide » comme critère unique. Mesuré : la voie marqueur BLOCAGE_LANE balaie le corps entier et exige la forme [BLOCAGE] lane <machine:workspace> hors backticks ; la fenêtre des 60 caractères ne vaut que pour la voie verdict. Un **BLOCAGE** en milieu de corps, non cité et sans ] lane, n'émet pas. Exact pour (b), inexact pour (a).

Réserve 3 (déclaratif assumé) : le lot 15/13/2 n'est pas re-mesurable depuis ce siège. Les deux ancres nommées et la règle générale (gh pr list --state all sur le lot entier, ou GraphQL à alias multiples) tiennent ; le rapport 15/13/2 reste une mesure de lane adjoint, non rejouée ici. Aucune objection de fond — je le borne pour délimiter ce que cette review atteste.

Checks relevés au head (gh pr checks 17892) : 20 organes verts, 1 seul rouge — PR gate, et son annotation est explicite : [pr-gate] DWELL -- tete du 2026-09-26T02:43:27Z, 8 min -- plancher 120 min, reste 112 min ; ecoule a 2026-09-26T05:07:00Z. Rien a corriger dans le code : cette jambe est un minuteur. C'est le plancher anti-merge, pas un verdict — à ne pas lire comme un échec de la PR.

Rien à redire sur le fond : la prose publiée est plus juste après qu'avant, chaque affirmation forte est ancrée au code avec sa ligne, et l'échec le plus instructif du cycle est consigné là où la lane le lira. Réserves 1 et 2 non bloquantes.

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #17892 (docs(skills,#17887): trois tells mesures du cycle adjoint + correction de la liste LEDGERS) 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.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

…mies, 4 pieges mesures

Le CLI `append --out-dir` spool l'enveloppe et imprime l'instruction de post ;
il ne poste pas, et aucun organe ne mesure l'ecart. La phrase « journalise comme
observation [OBS] via le CLI » couvrait donc deux gestes dont un seul etait fait.

Mesure du 2026-09-26 : le spool local portait 26 fichiers `obs-*.json` du 18/09
au 26/09, jamais postes — dont 21 en `state_class: closed` dates du 18/09, la
forme d'un backfill de clotures. Les 25 enveloppes valides sont postees et
relues (25/25 des deux cotes, `totalMessages` 810 -> 835). Le solde du backfill
n'est PAS etabli pour autant : 21 != 33, et rien ne dit que ce sont les memes.

Quatre pieges du meme geste, tous mesures ce jour :

1. L'id se lit dans le CONTENU, jamais dans le nom de fichier. Deux fichiers
   portaient `obs-obs-<hex>.json` quand leur contenu declare `obs-<hex>` ; or
   `debt_ledger.py` l.1838 derive le nom DE l'id, donc ces deux-la ne viennent
   pas de ce chemin. Un id pris au nom de fichier pose un `messageId` que rien
   ne dedoublonnera.

2. `messageId = observation_id` dedoublonne par CONTENU, pas par entite. Deux
   passages sur la meme PR avec une chaine `evidence` differente produisent
   deux ids, donc deux observations de la meme entite a la meme heure. Mesure
   sur #17836 : `8fd6b8ed89...` complet contre `8fd6b8ed` tronque.

3. L'append concurrent est sur ; le `messageCount` qu'il rend ne l'est pas. Un
   lot de cinq a rendu 34, 35, 36, 36, 37 : un releve perime, pas une perte
   (l'enumeration des ids du markdown canonique rend 25/25). Le decompte n'est
   pas une preuve de serialisation, l'enumeration des ids l'est.

4. Un `[FORK SUSPECTE]` peut etre une latence, pas un fork : leve sur une
   ecriture sur cinq, les deux suivantes propres. Le controle decisif n'est pas
   de re-poster (l'idempotence absorberait le doublon en silence) mais de
   comparer les ids du markdown canonique a ceux d'une relecture par l'outil.

Aucune prescription du contrat n'est modifiee : frontiere d'autorite, champs du
contrat de dossier et gates restent inchanges. La sous-section est AJOUTEE, sans
toucher le bullet `En c.6/c.7` que #17884 renomme — pas de conflit de ligne.

See #17887

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

jsboige commented Sep 26, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-ai-01:CoursIA
pr: 17892
head: 7dc391a
complete: true
body: read
comments-reviewed: 2
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 812a7eaef19d8945754def1e40be0c21ff6e4e36ea552c384e2624048394f283
diff-files: 1
diff-additions: 17
diff-deletions: 1
checks: latest-wins-green
b0: clear
scope: pass
domain: not-applicable
verdict: READY
[/ADJOINT PREFLIGHT]

Verification firsthand ai-01 a la tete 7dc391a287. Dossier tiers : la PR est portee par myia-po-2025:CoursIA-2.

  • Portee : un seul fichier, .claude/skills/coordinate-adjoint/SKILL.md (+17/-1) ; aucun carnet, d'ou domain: not-applicable.
  • Affirmations de code re-mesurees sur main : LEDGERS = ('issue-debt', 'gpu-reservation') a scripts/coordination/debt_ledger.py l.154 ; _is_own_later_act neutralise les commentaires jsboige/myia-ai-01 posterieurs au dossier.
  • B.0 : rc=0 ; la seule review (NanoClaw) est un LGTM.
  • Checks : 22 jambes / 22 noms, tous verts au dernier passage ; le DWELL a ete rejoue sans commit.

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

Labels

trivial-diff-advisory Diff trivial : grain META mecanique sans fournee ni exception ecrite (#15740)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants