Skip to content

fix(guard,#17005): detect heading-style rendering of list/blockquote continuation lines - #17009

Merged
myia-ai-01 merged 2 commits into
mainfrom
fix/17005-md-render-puce-continuation
Sep 21, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
fix/17005-md-render-puce-continuation

Conversation

@jsboige

@jsboige jsboige commented Sep 20, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard — lane myia-po-2027:CoursIA-2 — prev: MED/notebook-lean #16950

fix(guard,#17005): detect heading-style rendering of list/blockquote continuation lines

Diagnostic derive

Pattern : une ligne de CONTINUATION de puce / blockquote (2+ espaces
d'indentation, PAS de marqueur de conteneur sur la même ligne) qui
commence par # + non-espace est rendue comme un heading H1-H6 géant par
Jupyter / VSCode / nbviewer — alors que CommonMark refuse ce format
(l'indentation est trop profonde, pas d'opener de conteneur). Le corps de
la ligne est caché derrière un chunk de heading et le rendu diverge de la
prose que la ligne voulait dire.

Fondeur : PR #16888 cellule cell-015 (base e17f600a, fix
c34d5e88d rewrap). Le pattern est disjoint des deux règles existantes :

Règle Pattern Catch déjà
_HEADING_RE ^\s{0,3}(#{1,6})\s+ ## Heading (espace après # obligatoire)
_CONTAINER_HEADING_RE `^(?:[ \t](?:[-+] \d+[.)]
_CONTINUATION_HEADING_RE (nouveau) ^\s{2,}(#{1,6})[^\s#] #15520) (continuation, pas d'opener)

Verdict : CAUSE_FIXED — la nouvelle règle ferme l'angle mort.

Changements

Pourquoi ERROR (bloquant) et pas WARN-first

Validation post-fix relancée

  • python -m pytest scripts/notebook_tools/tests/test_detect_markdown_rendering.py -q
    → 61 passed in 0.30s (3 nouveaux + 58 anciens, aucune régression).
  • Smoke test cellule pilote :
    • AVANT-fix (commit e17f600a) : heading_in_list + heading_continuation (2 findings).
    • POST-fix (commit c34d5e88d) : heading_in_list seul (1 finding, continuation propre).
  • python scripts/notebook_tools/detect_markdown_rendering.py --check --severity error scripts/notebook_tools/tests/
    → OK: no new ERROR-level markdown-rendering violations.
  • python scripts/notebook_tools/detect_markdown_rendering.py --check --severity error MyIA.AI.Notebooks/GenAI/
    → OK: no new ERROR-level markdown-rendering violations. (vérif FP à
    grande échelle sur GenAI, famille à forte densité de markdown indenté).

Tests

Les 3 tests TestHeadingContinuation couvrant :

  • test_continuation_heading_pilote_reference — reproduit la cellule
    pilote de feat(tweety,#15066): laboratoire FOL Tweety vers certificats Lean #16888 cell-015 avant-fix (continuation #15520)).
  • test_continuation_heading_clean_post_fix — vérifie qu'après le
    rewrap c34d5e88d, la cellule propre ne fire plus.
  • test_continuation_heading_no_false_positive_legit_heading — 4
    contrôles négatifs : top-level heading, in-list opener, fenced code,
    ## indent (heading légitime déjà capturé par _HEADING_RE).

…sont commités dans un second commit sur la même branche (PR
séparée à venir, voir #17005 commentaire de suivi), parce que
scripts/notebook_tools/tests/test_detect_markdown_rendering.py
échoue actuellement le hook pré-commit #13326 sur des appels
subprocess.run(..., text=True, ...) pré-existants (lignes 895 et
909 du fichier original, hors scope de ce fix). Étendre le scope ici
ouvrirait un chantier séparé sur TestQuartoClosurePyYAMLMissing.

Acceptance

🤖 Generated with Claude Code

…continuation lines

The Jupyter / VSCode / nbviewer renderers accept `#` + non-space at the start
of a list-item / blockquote CONTINUATION line (2+ spaces indent, no container
marker on the same line) and render it as a giant H1-H6 -- CommonMark refuses
the format, but the renderers do not, so the line's body is hidden behind a
heading-style chunk. The detector gains:

* regex `_CONTINUATION_HEADING_RE = re.compile(r"^\s{2,}(#{1,6})[^\s#]")`
  (disjoint of `_HEADING_RE` -- which requires a space after `#` -- and of
  `_CONTAINER_HEADING_RE` -- which requires a container marker on the same
  line);
* a new ERROR-severity rule `heading_continuation` registered in
  `RULE_SEVERITY` with its own matching loop after the `heading_in_list`
  loop, sharing the fence-awareness / one-finding-per-cell discipline.

Tests covering the new rule will follow in a separate commit / PR (the
existing test file is currently failing the #13326 pre-commit hook on
pre-existing subprocess calls unrelated to this change).

Co-Authored-By: Claude Haiku 4.5 (1M context) <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 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Trivial-diff advisory (#15740, non bloquant).
genre guard dans la famille META (docs/guard/ledger/readme/test) + diff de 51 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.

…FP + encoding utf-8

Trois tests pour la règle `heading_continuation` introduite par le commit
précédent (`ad647451df` sur la branche de PR #17009) :

- `test_continuation_heading_pilote_reference` : reproduit la cellule pilote
  #16888 cell-015 avant-fix (continuation `  #15520)`), vérifie que le
  scanner catch bien le pattern.
- `test_continuation_heading_clean_post_fix` : la cellule rewrap post-fix
  (référence inline `\`) ne fire plus.
- `test_continuation_heading_no_false_positive_legit_heading` : 4 contrôles
  négatifs (top-level heading, in-list opener, fenced code, `## ` indenté)
  — la règle reste disjointe de `_HEADING_RE` et `_CONTAINER_HEADING_RE`.

Les deux appels `subprocess.run(..., text=True, ...)` pré-existants (lignes
895 et 909 du fichier, dans TestQuartoClosureDependency) gagnent
`encoding="utf-8"` — sans cela, le hook pré-commit
`check_subprocess_encoding.py` refuse le commit (le bloc était hors-scope du
premier commit, mais bloquait celui-ci).

Validation : `pytest scripts/notebook_tools/tests/test_detect_markdown_rendering.py`
→ 61/61 (58 pré-existants + 3 nouveaux), aucune régression.

See #17005 (issue, point tests unitaires).
See #17009 (PR, second commit qui manquait au body initial).

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot removed the trivial-diff-advisory Diff trivial : grain META mecanique sans fournee ni exception ecrite (#15740) label Sep 20, 2026
@github-actions

github-actions Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #17009 (fix(guard,#17005): detect heading-style rendering of list/blockquote continuation lines) 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.

@github-actions github-actions Bot added the pr-overlap Advisory: another open PR touches the same files (organ #13615) label Sep 21, 2026
@jsboige

jsboige commented Sep 21, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 17009
head: 5d2c0e0
complete: true
body: read
comments-reviewed: 2
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: bb9263d505566b88aa0f899d3a74b7ff90ce148eff91d1c97fdf7367038631f7
diff-files: 2
diff-additions: 142
diff-deletions: 2
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

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

Labels

pr-overlap Advisory: another open PR touches the same files (organ #13615)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants