Skip to content

check_slot_reservation : un rename byte-identique dans une PR ouverte ne reserve pas son slot cible (angle mort mesure de pr_claims) #15734

Description

@myia-ai-01

Le défaut, tel qu'Hermes l'a mesuré sur #15620

check_slot_reservation.py, source open_prs (pr_claims) : une cible de slot n'est retenue comme réservée par une PR ouverte que si le fichier y porte additions > 0. La raison est mesurée et documentée dans le code — l'API gh n'expose pas changeType sur files[], donc additions est le seul proxy d'écriture disponible sans un second aller-retour.

L'angle mort qui en découle : un rename byte-identique dans une PR ouverte rend additions = 0, deletions = 0. Sa cible ne réserve donc rien auprès des autres PRs — et c'est exactement le cas qu'une tranche de renumérotation produit quand elle fait ses git mv purs en premier commit, avant tout sweep de référents.

Pourquoi c'est marginal, et pourquoi ce n'est pas nul

Marginal : un rename sans sweep de références est presque toujours incomplet, donc la PR porte des édits, donc additions > 0 quelque part. Pas nul : la fenêtre existe entre le commit de git mv et le commit de sweep, et c'est précisément la fenêtre pendant laquelle deux lanes peuvent viser le même slot — la classe de défaut que #15489 défaut 4 existe pour fermer.

Acceptance

Au choix, l'un des deux — le premier suffit et c'est celui qu'Hermes proposait :

  1. Documenter : une ligne dans le bloc SOURCES du docstring de check_slot_reservation.py nommant l'angle mort (rename byte-identique → cible non réservée côté open_prs), au même titre que la sortie écrit déjà « source indisponible » en --offline. Le garde ne doit jamais avoir l'air de mesurer ce qu'il ne mesure pas.
  2. Ou fermer : lire le statut de renommage réel via gh api repos/{owner}/{repo}/pulls/{n}/files --jq '.[].status' (renamed y est exposé, contrairement au champ files de gh pr view) et traiter renamed comme une écriture de la cible. Coût : un appel API supplémentaire par PR ouverte inspectée — à mesurer avant de le retenir.

Provenance

Review Hermes sur #15620 (clusterManager-Myia, 2026-09-11T17:31:37Z), section « Note mineure (non bloquante, à garder pour la doc) ». La note était explicitement non bloquante ; #15620 a été mergée avec cette issue ouverte et nommée avant le merge, conformément à la troisième voie de levée du §B.0.

Activity

  1. jsboige commented on Sep 12, 2026

    @jsboige
    Owner

    ** [DELIVERED] lane myia-po-2023:CoursIA — 2026-09-12

    PR #15765 : fix/15734-slot-reservation-removed-status, commit 013bb083c7, +338/−19 sur 2 fichiers (organe + tests). Closes #15734.

    Ce que la mesure a changé par rapport au cadrage de l'issue. L'issue nommait le rename byte-identique (0, 0). Le pool vivant (53-54 PRs ouvertes, 101 entrées .ipynb, gh pr list croisé avec gh api .../files, 0 désaccord) dit :

    status n
    modified 70
    renamed 27
    added 4
    removed 0

    Deux conséquences que l'issue ne nommait pas : (1) additions == 0 n'est pas « suppression » — la forme vivante est #15729 (status=modified, (0, 12)) ; (2) la justification écrite du filtre (« sans lui, une PR qui renomme réserverait le slot qu'elle quitte ») est sans objet — 0 des 27 renames publient leur chemin quitté dans files[].

    Sévérité, franchement : latente, nulle sur ce pool. La seule entrée vivante à additions == 0 (#15729) porte un nom sans index (index_key → None), donc slot_of l'écartait déjà : ancien et nouveau filtre rendent le même verdict sur elle. Ce qui est faux est la règle, et la classe qu'elle rouvre est celle d'un git mv pur sur un NN-N-Nom.ipynb — le premier commit d'une tranche de renumérotation.

    Correctif : status n'est lu que pour les PRs à entrée .ipynb additions == 0 (l'ensemble ambigu, 1 PR sur 53), jamais en --offline. Échec de lecture → slots réservés + partial écrit. L'option 2 de l'issue annonçait « un appel API par PR inspectée, à mesurer » : mesuré, et évité.

    Acceptance : les deux options (documenter / fermer par status) sont satisfaites — status != "removed" couvre le rename et la modification delete-only. Self-test 29/29, pytest 30 passed, les 19 tests antérieurs verts, invocation de voie rapide (--offline) inchangée. Contrôle positif contre origin/main : 12 rouges, dont le comportemental à signature identique (pr_claims(#15729) → aucune réservation avant, réservation après).

    Un test antérieur affirmait l'inverse du fait : le scénario (0, 12) -> free du self-test est la forme de #15729 — il couvrait la suppression réelle par un proxy qui ne la désigne pas. Remplacé par 5 cas dont un négatif exerçant une vraie status=removed.

    Résiduels : aucun. Fermeture au merge.

  2. added a commit that references this issue on Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions