Skip to content

fix(picker): la reouverture du user reprend la decision de cloture CLOSE (suite de #24172) #24250

Closed

Description

@jsboige

Grain: MED/guard -- lane myia-ai-01:CoursIA-2 -- prev: MED/guard #24189

Part of #24172 (livre par #24173 : le dossier de cloture CLOSE est un signal de livraison TERMINAL).

Defaut

Le dossier [CLOSURE PREFLIGHT] de verdict CLOSE ecarte une issue du tapis sans limite d'age : il est terminal, donc la regle des 48 h de #22500 ne peut pas l'expirer. C'est le comportement voulu, mesure sur #19253.

Mais une decision de cloture prise sur une issue que le user rouvre ensuite n'est plus la decision finale : le user dit « ce n'est pas regle ». Or le tapis ne voit que le fil (commentaires) : il lit le dossier, il n'a aucune lecture de l'etat de l'issue (fermee, puis rouverte). Consequence mesuree : une issue rouverte par le user apres son dossier CLOSE, sans [NOT-DELIVERED], reste ecartee du tapis pour toujours — le dossier etait la, la reouverture aussi, et le tapis ne regardait que le fil.

Le dossier CLOSE est le SEUL signal terminal du tapis (tous les autres marqueurs expirent a 48 h) : c'est donc le seul dont la reouverture doit etre lue.

Pourquoi le predicat litteral du dispatch ne convient pas

Le dispatch propose : « un predicat "annonce de fermeture presente ET issue ouverte" la ressortirait ».

Ce predicat est trop large : il ressortirait toute issue livree et non closee — c'est-a-dire la majorite du pool ecarte par le filtre de livraison. Le filtre s'effondrerait, et le tapis resservirait en boucle des issues dont le travail est fait. Le predicat utile n'est pas « fermee puis ouverte », c'est « une reouverture POSTERIEURE a la decision de cloture ».

Correctif propose

Un evenement reopened de l'issue, lu dans le timeline (REST, bucket de quota distinct du GraphQL -- #17038), remplace la decision de cloture seulement s'il est posterieur a elle :

  • dossier CLOSE (ou annonce de cloture) a T1, reouverture a T2 > T1 -> la decision est reprise, l'issue redevient servable ;
  • reouverture a T0 < T1, dossier a T1 -> le dossier reste la derniere decision, l'issue reste ecartee ;
  • dossier a T1, reouverture a T2, marqueur de livraison a T3 > T2 -> le marqueur rearme : l'issue reste ecartee (elle a ete relivree apres la reouverture).

Le predicat est applique aux trois surfaces qui ecartent un candidat -- la sonde RECENTE, la sonde PLEINE et le reducteur d'evenement -- pour qu'elles ne puissent pas diverger sur un fil qui change entre deux lectures (invariant deja pose pour les deux autres).

Cout : une lecture REST du timeline, et uniquement pour les candidats qui portent une decision de cloture (rares). Une issue livree par un marqueur ordinaire ne coute rien de plus : son marqueur expire a 48 h de toute facon. Lecture en echec -> fail-OPEN cote terminalite (la decision de cloture garde sa force) ; en repli REST du seul fil (bucket GraphQL tombe), la reouverture n'est pas lue et le comportement actuel est conserve.

Acceptance

  1. dossier CLOSE puis reouverture ulterieure -> l'issue redevient servable ;
  2. reouverture ANTERIEURE au dossier -> l'issue reste ecartee (le dossier est la derniere decision) ;
  3. dossier, reouverture, puis marqueur de livraison ulterieur -> l'issue reste ecartee ;
  4. dossier CLOSE sans reouverture -> l'issue reste ecartee sans limite d'age (le comportement de fix(picker): le dossier de cloture CLOSE est un signal de livraison TERMINAL (cas #19253) #24172/Fix(picker,#24172): le dossier de cloture CLOSE est un signal de livraison TERMINAL #24173 est preserve) ;
  5. les trois surfaces (sonde RECENTE, sonde PLEINE, reducteur) rendent le MEME verdict sur le meme fil ;
  6. un marqueur ordinaire ne declenche aucune lecture de timeline (cout nul sur le cas courant) ;
  7. controles positifs et negatifs par test, sans appel reseau (la lecture du timeline est injectee).

Fichiers

  • scripts/pick_idle_grain.py
  • scripts/tests/test_pick_closure_reopened.py

Activity

  1. jsboige commented on Nov 2, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-ai-01:CoursIA-2 -- paths: scripts/pick_idle_grain.py, scripts/tests/test_pick_closure_reopened.py

  2. jsboige commented on Nov 2, 2026

    @jsboige
    OwnerAuthor

    [DELIVERED] lane myia-ai-01:CoursIA-2 -- paths: scripts/pick_idle_grain.py, scripts/tests/test_pick_closure_reopened.py -- PR #24256

  3. added a commit that references this issue on Nov 2, 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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions