Skip to content

ci(#docs-links): la reference des liens casses est un fichier fige a 0 — un lien casse sur main rougit check-links, Always-on guards et PR gate de TOUTE PR ouverte #15766

Description

@jsboige

Le defaut

scripts/check_docs_links.py --check ne compare pas les liens casses de la PR a ceux de sa base, mais a un fichier de reference fige :

BASELINE_PATH = REPO_ROOT / "scripts" / "tests" / "baseline_docs_links.json"
...
baseline_targets = {(b["source"], b["target"]) for b in baseline.get("broken_links", [])}
# tout lien casse ABSENT de ce fichier est rapporte comme « REGRESSION »

Ce fichier porte aujourd'hui broken_links: 0 (et aucune cle de generation). Or aucune automatisation ne le regenere : la seule invocation existante est --check —

  • .github/workflows/docs-link-check.yml:35 → python scripts/check_docs_links.py --check
  • scripts/ci/fast_lane_registry.py:431 → idem, comme garde de voie rapide

--baseline n'est appele nulle part (workflow, cron, script). Le fichier est donc un artefact a maintenir a la main, jamais rafraichi depuis sa creation.

Consequence : tout lien casse sur main — meme introduit par une PR mergee — est rapporte comme « REGRESSION : 1 new broken link(s) » sur chaque PR ouverte, et rougit trois checks d'un coup :

check-links            -> failure
Always-on guards ...   -> failure   (« Organes bloquants en echec : fastlane », seul check-links en exit 1)
PR gate                -> failure   (« FAIL -- failing checks: check-links (failure) »)

Instance vivante — mesuree ce jour sur #15508

$ python scripts/check_docs_links.py --check          # arbre origin/main PROPRE, aucun fichier modifie
REGRESSION: 1 new broken link(s):
  MyIA.AI.Notebooks/IIT/ICT-Series/README.md:214 -> ICT-22b-CausalInterventionEngine.ipynb
Baseline had 0 known broken.
$ echo $?
1

Chaine exacte, verifiee :

Element Etat
La ligne README (lien vers ICT-22b-CausalInterventionEngine.ipynb) sur main, ajoutee par #15752 MERGED (a678e440ea, docs(ict,#15636))
Le notebook cible absent de main (git ls-tree -r origin/main : la famille ICT-22 ne porte que ICT-22-LLMSubstrat.ipynb)
Ou il vit PR #15609 OUVERTE (feat(ict,#15479): consumer notebook ICT-22b ... tranche 3/n)
Le moteur, lui present sur main (ict/causal_engine.py, scripts/causal_hooks.py, + tests)

Donc : une PR de documentation a rendu « visible dans l'index » un notebook qui n'existe que dans une PR empilee non mergee. Le constat de fond est documente (lecon de la lane po-2023 : un grain docs/index base sur une pile produit un 404 sur main) — ce qui manque ici, c'est que le garde ne sache pas faire la difference entre « la PR a casse un lien » et « main portait deja ce lien casse ».

Pourquoi ca compte

Le rouge est vrai mais mal attribue : il ne dit rien sur la PR qu'il annote. Chaque lane qui ouvre une PR aujourd'hui voit trois rouges dont aucun n'est de son fait, et doit refaire ce diagnostic avant de conclure — le meme cout que le plafond ICT (#14598) ou le rouge d'adjacence perime (#15739), deja traites.

Scope et acceptance

Scope : scripts/check_docs_links.py (+ le sens du fichier de reference, et l'invocation de voie rapide si son contrat change).

Deux voies, a trancher (decision de conception, pas un choix d'implementation) :

  1. Comparer a la base — --check lit l'arbre de {base_ref} et soustrait les liens casses deja presents a la base. Le verdict devient une fonction de la PR, comme les autres ratchets du depot (« Output-failure ratchet base vs PR », « Translation hot-drift base vs PR »). C'est la voie qui supprime la classe, pas l'instance.
  2. Rafraichir la reference sur main — un cron la regenere comme le fait catalog-cron.yml. Piege a nommer explicitement : passer broken_links de 0 a 1 cache le lien casse au lieu de le reparer. Cette voie doit donc etre couplee a un etat ou le lien cible existe reellement.

Acceptance (dans tous les cas) :

  • Le lien ICT-Series/README.md:214 -> ICT-22b-...ipynb n'est plus rapporte comme une regression de PR quand il est deja casse a la base — preuve par --check sur un arbre origin/main propre avant/apres ;
  • Une PR qui casse elle-meme un lien reste detectee (controle positif : casser un lien dans un fichier de la PR, --check doit la designer) ;
  • Le lien README lui-meme redevient valide (merge de feat(ict,#15479): consumer notebook ICT-22b causal intervention engine (tranche 3/n) #15609, ou neutralisation de la ligne jusqu'a ce que le notebook existe) — les deux moities sont complementaires : celle-ci rend le garde juste, l'autre retire la cause ;
  • Les tests existants de scripts/tests/test_check_docs_links.py restent verts.

Provenance

Trouve en diagnostiquant les 3 rouges de la PR #15508 de la lane myia-po-2023:CoursIA, en traitant PR gate comme un vrai rouge plutot qu'en le supposant perime. Le detail est poste en commentaire de #15508.

Activity

  1. jsboige commented on Sep 12, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2023:CoursIA -- voie 1: --check --base dans scripts/check_docs_links.py + garde check-links needs_base

    (check_lane_claim #9774 -- server-stamped UTC; body timestamps are NOT authoritative. Release with [RELEASED] when your PR lands.)

  2. jsboige commented on Sep 12, 2026

    @jsboige
    OwnerAuthor

    [DELIVERED] lane myia-po-2023:CoursIA — PR #15804 (voie 1) — claim IC_kwDOH2Odns8AAAABUKCblg

    Voie 1 livree : --check --base <ref> excuse un lien casse seulement s'il l'etait deja a la base — source existante a ref, portant la meme cible, cible absente la-bas. Un lien ajoute par la branche, ou une cible que la branche supprime, restent des regressions. Le fichier fige garde son role sur les voies sans base (dispatch). Garde de voie rapide check-links : --base {base_ref} + needs_base=True.

    Acceptance :

    1. satisfaite — instance vivante IIT/ICT-Series/README.md:214 -> ICT-22b-CausalInterventionEngine.ipynb (ajoutee par docs(ict,#15636): ICT-22b et ict/causal_engine.py visibles dans les deux index de la serie (cherry-pick c.1104 dissipation) #15752 MERGED, cible dans feat(ict,#15479): consumer notebook ICT-22b causal intervention engine (tranche 3/n) #15609) : --check exit 1 avant, --check --base origin/main exit 0 apres (« OK: No new broken links. (1 pre-existing, 6845 total) ») ;
    2. satisfaite — controle positif, lien neuf injecte : REGRESSION: 1 new broken link(s) exit 1 ;
    3. non livree ici — le lien README lui-meme redevient valide par feat(ict,#15479): consumer notebook ICT-22b causal intervention engine (tranche 3/n) #15609, l'autre moitie que l'issue nomme. D'ou See #15766 et non Closes ;
    4. satisfaite — 66 tests verts dans test_check_docs_links.py (9 neufs, dont un scenario git reel en tmp_path), 141 avec les suites fast-lane.

    Voie 2 ecartee, argumentee : regenerer la reference par cron ferait passer broken_links de 0 a 1, ce qui cache le lien casse au lieu de le reparer — le piege que l'issue nomme elle-meme.

    Le dashboard porte un design-gate ai-01 sur #15766 : le choix entre les deux voies etait qualifie de decision de conception. La voie 1 y est proposee comme implementation ; si la voie 2 est preferee, #15804 est a rejeter plutot qu'a amender.

  3. added a commit that references this issue on Sep 12, 2026
  4. added a commit that references this issue on Sep 12, 2026
  5. added
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Sep 13, 2026
  6. myia-ai-01 commented on Sep 26, 2026

    @myia-ai-01
    Collaborator

    Fermeture (ai-01) : le dossier de fermeture de l'adjoint (lot 1, 26/09) la classait COMPLET, et une verification independante a l'instant confirme chaque critere sur origin/main.

    PR(s) livrant le travail, toutes mergees : #15804, #15609.

    Verifie : les 4 cases : check_docs_links.py --base et preexisting_broken() sont cables dans le garde de la voie rapide (needs_base=True) ; le test test_unrelated_preexisting_does_not_mask_a_new_link existe ; le lien ICT-22b du README resout ; la suite passe (79 tests).

    Aucune PR ouverte ne reste rattachee a cette issue. Si un critere vous semble manquer, rouvrez-la en le nommant.

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

    automationbugSomething isn't workingcandidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions