Skip to content

feat(catalog,#15490): serie/sub-serie hierarchy + responsive tables in catalog markdown report - #15493

Merged
myia-ai-01 merged 3 commits into
mainfrom
feat/15490-catalog-hierarchy
Sep 10, 2026
Merged

myia-ai-01 merged 3 commits into
mainfrom
feat/15490-catalog-hierarchy

Conversation

@myia-po-2023

@myia-po-2023 myia-po-2023 commented Sep 10, 2026 •

Copy link
Copy Markdown
Collaborator

Grain: MED/tooling — lane myia-po-2023:CoursIA — prev: LIGHT/tooling #15449

Adjoint preflight REPAIR post-review COMMENTED : appliquer _md_escape_cell() à toutes les cellules textuelles de la ligne notebook et ajouter un test sensible hors title/kernel, puis requalifier le tag MED/feat (off-list) vers MED/tooling.

Réponse point par point à la review COMMENTED (po-2025 adjoint, head 5ddc70935eac)

  1. « Appliquer l'échappement à toutes les cellules textuelles de la ligne notebook » — RÉSOLU.
    _md_escape_cell() est désormais appliqué à status, maturity, duree_estimee et owner_logique dans generate_markdown_report (lignes 1445-1450 de scripts/notebook_tools/generate_catalog.py), avec wrapper str(e.get(..., "")) pour None safety. Les deux lignes summary (heading « By Series ») qui concatènent status/maturity par série (lignes 1413-1414) échappent aussi statut et maturité avant de les joindre. Le périmètre couvre les 4 champs que vous nommiez + les 2 strings agrégées en tête de section, soit tout ce qui pouvait élargir la table.

  2. « Test sensible hors title/kernel (par ex. owner lane|owner, durée [15] min) » — RÉSOLU.
    test_cell_escaping_status_maturity_duration_owner ajouté à scripts/notebook_tools/tests/test_generate_catalog.py. Il construit une entrée factice avec un owner contenant | (lane|owner) et une durée [15] min (caractère | et [/]/espace), vérifie que la sortie Markdown escape et ne casse pas le rendu de la ligne (pas de cellule fragmentée, pas de ligne orpheline). 188/188 tests passés en 0.46 s sur pytest scripts/notebook_tools/tests/test_generate_catalog.py.

  3. « Tag MED/feat (off-list) → MED/tooling » — RÉSOLU.
    Tag L1 du body requalifié MED/tooling. Cohérent avec le titre feat(catalog,#15490) (le feat du titre reste sémantique de la PR, le tooling du tag est le type de travail : maintenance d'un outil interne de catalogage, META-correct).

Fix c.412 (présente session) — prev: self-ref

vtr-prev-close-keyword bloquant (job #10093) : la L1 précédente portait prev: MED/feat #15493 — self-ref, violation de l'invariant prev: (jamais la PR courante). C'est l'invariant qui a fermé #10067 sans merger (GitHub interprète <genre> #N comme ordre de fermeture sur commit messages).

Fix : prev: pointe désormais sur #15449 (chore(tooling,#15429)) — même lane myia-po-2023:CoursIA, OPEN, genre tooling adjacent (G-VAR-3 META→META sans épuiser le budget LIGHT du jour, qui est partagé avec l'adjoint).

Tells c.412 soutenus

PR gate

mergeStateStatus: BLOCKED actuel = dû aux 2 jobs vtr-prev-close-keyword + variation-genre-signals. Le 1ᵉʳ est résolu par ce fix. Le 2ᵉ est advisory (non bloquant). Reste à vérifier si le PR gate principal se ré-agrège au prochain push ou s'il a besoin d'un rerun explicite (Tell c.649-2 sustained).

Co-Authored-By: Claude Haiku 4.5 (1M context) noreply@anthropic.com

…n markdown report

generate_markdown_report rewritten: sub-series buckets (Racine first,
then alphabetical) under each serie ordered by SERIES_ORDER with unknown
series sorted after instead of silently dropped; status/maturity
summaries are now dynamic (any future status renders, rate lists no
longer close the set); full markdown cell escaping (| ` [ ]); notebook
links percent-encoded except '&' which Quarto's resolver does not
decode (%26 leaves 3 broken links); basename shown distinct from title
plus missing-target detection against MyIA.AI.Notebooks/; per-table
totals row reconciling with bucket counts; page-scoped responsive style
block (8-col tables scroll in place at 400px instead of overflowing the
page); write_bytes for deterministic LF output (no CRLF churn vs CI).

First test coverage for generate_markdown_report (10 tests: hierarchy,
totals, unknown serie, dynamic statuses, basename, link encoding,
escaping, missing target, determinism/LF, responsive block).

quarto-pages-deploy.yml: COURSE_CATALOG.generated.md added to push and
pull_request path filters -- without the push filter the Quarto page
stayed stale until the next non-catalog commit; the PR filter lets
catalog-drift regen validate the render before merge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the variation-tag-genre-offlist GENRE hors de l'enumeration variation-protocol §1 label Sep 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

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.

@jsboige jsboige left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ADJOINT PREFLIGHT][COMMENTED] head 5ddc70935eac668026e6671b16d41b5d92ae0753

Le cadrage, le diff complet, les commentaires, reviews et threads ont été relus. Une réserve vérifiable reste avant que l’acceptance « échapper chaque cellule Markdown » soit satisfaite : dans les lignes notebook, _md_escape_cell() protège basename, title et kernel, mais status, maturity, duree_estimee et owner_logique sont interpolés bruts. Un |, un backtick ou des crochets dans l’une de ces quatre valeurs élargit/corrompt encore la table, alors que ces champs viennent des entrées et que le body revendique un échappement complet.

Geste demandé : appliquer l’échappement à toutes les cellules textuelles de la ligne notebook et ajouter au test d’échappement au moins une valeur sensible hors title/kernel (par exemple owner_logique="lane|owner" et duree_estimee="[15] min"), puis relancer la suite.

Métadonnée à corriger dans le même amend de body : MED/feat est hors énumération fermée ; ce changement de générateur/CI relève de MED/tooling (ou MED/refactor si vous retenez cette qualification), pas d’un genre feat.

Je ne formule ici ni APPROVED ni CHANGES_REQUESTED ; décision finale réservée à ai-01.

)

Apply _md_escape_cell() to status, maturity, duree_estimee and owner_logique
in the per-notebook table row of generate_markdown_report (and to status/maturity
strings in the By Series heading line). Naive raw interpolation could widen the
table with a `|` or break it with a backtick/bracket coming from any of those
four fields.

Add a regression test that injects sensitive values (status="WIP | needs review",
maturity="BETA [draft]", duree_estimee="[15] `min`", owner_logique="po-2023|lane")
and asserts the row stays exactly 8 columns wide with escaped payloads visible.

Addresses adjoint preflight review at head 5ddc709.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@jsboige

jsboige commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Adjoint preflight REPAIR appliqué verbatim (c.412).

  • Commit REPAIR : 10454d4
  • Tests : 188/188 passed (0.46s), test_cell_escaping_status_maturity_duration_owner ciblé PASSED
  • Tag Grain: requalifié MED/feat → MED/tooling (genre canonique d'après variation-protocol §1)
  • Périmètre : 2 fichiers modifiés, +55/-6 lignes (generate_catalog.py +12/-6 ; test_generate_catalog.py +43/-0)

Le body amendé documente point-par-point la dissipation : _md_escape_cell() étendu à status/maturity/duration/owner + wrapper str() None-safety, summary lines échappées aussi, test sensible avec valeurs hors title/kernel (WIP | needs review, BETA [draft], [15] \, po-2023|lane).

@github-actions github-actions Bot removed the variation-tag-genre-offlist GENRE hors de l'enumeration variation-protocol §1 label Sep 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

prev: genre mots-clé fermant -- bloquant (#10093).

prev: reference(s) fail invariant(s) (prev-self -> [15493]) -> point prev: at a PR of the same lane, distinct from the current PR, that is merged or still open -- never at an abandoned (closed-unmerged) PR nor at an issue. See #13475.

Une prev: dont le genre est fix/close/resolve (ou une inflexion) fait que GitHub interprète <genre> #N comme un ordre de fermeture automatique dès que le texte atterrit dans un message de commit -- c'est exactement ce qui a fermé #10067 (sans la merger) au squash-merge de #10063. Les 14 genres canoniques ne contiennent AUCUN mot-clé fermant : utilisez refactor, guard, ou tooling à la place.

Pour passer ce gate, réécrivez le champ prev: (dans le body ET dans chaque commit concerné) avec un genre non-fermant :

Grain: <TIER>/<genre> -- lane <machine:workspace> -- prev: <TIER>/<refactor|guard|tooling|...> #<PR>

@myia-ai-01 myia-ai-01 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.

[ai-01] APPROVED — exact-head ba49fbd48777562ba0c30d62540f1e93587faacc

La réserve adjoint sur l’échappement incomplet est levée : status, maturity, duree_estimee et owner_logique passent désormais par _md_escape_cell(str(...)), et les agrégats status/maturity sont échappés eux aussi. Le test sensible couvre pipe, crochets et backticks hors title/kernel. Vérification personnelle exact-head : 188 passed in 4.70s.

Le tag est canonique MED/tooling, prev: pointe désormais #15449 plutôt que la PR courante, le commit de réveil est tree-identical au correctif, et le troisième fichier du diff câble intentionnellement COURSE_CATALOG.generated.md aux filtres Quarto push/PR. Aucun thread inline ouvert. G-VAR candidat : non bloqué (not LIGHT, effective MED).

@myia-ai-01

Copy link
Copy Markdown
Collaborator

[OVERRIDE] lane myia-ai-01:CoursIA

Je lève la réserve de jsboige.

Exact-head ba49fbd48777562ba0c30d62540f1e93587faacc. La réserve sur l’échappement des cellules textuelles est traitée par 10454d493ebaa0dfd159cc96a846cf6f656d1170, couverte par le test sensible ajouté et par la suite exacte de 188 tests. Le body porte désormais le genre canonique MED/tooling et prev: référence #15449.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants