Repository navigation
fix(guard,#17005): detect heading-style rendering of list/blockquote continuation lines - #17009
Conversation
…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>
|
Trivial-diff advisory (#15740, non bloquant). |
…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>
Path-collision (organ #13359/#13615)Cette PR #17009 (
Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur |
|
[ADJOINT PREFLIGHT] |
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 parJupyter / 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(basee17f600a, fixc34d5e88drewrap). Le pattern est disjoint des deux règles existantes :_HEADING_RE^\s{0,3}(#{1,6})\s+## Heading(espace après#obligatoire)_CONTAINER_HEADING_RE_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
scripts/notebook_tools/detect_markdown_rendering.py:_CONTINUATION_HEADING_RE = re.compile(r"^\s{2,}(#{1,6})[^\s#]")ajouté après
_CONTAINER_HEADING_RE(ligne ~331) ;heading_continuation(ERROR, bloquant) ajoutée dansRULE_SEVERITYavec un commentaire de fondation detect_markdown_rendering : ligne de continuation de puce commencant par # + non-espace non detectee (rendu titre dans Jupyter) #17005 ;heading_in_list(ligne ~1243), parité fence-awareness / one-finding-per-cell.
hook pré-commit Aucun garde ne parse la source des cellules : une cellule non compilable portant une sortie traverse les 60+ checks #13326 sur le fichier de tests pré-existant.
Pourquoi
ERROR(bloquant) et pasWARN-firstheading_in_list(ERROR, [EPIC] Visual QA suite — couverture des headings imbriqués (listes, blockquotes, inline) #11829) : un atx heading rendu comme un heading géant dans le
notebook publié, c'est un page-breaking defect, pas un cosmétique.
WARN-first aurait alourdi la dette (unclosed_bold/cjk_in_prosesont en WARN précisément parce que leur corpus FP est mesuré non
nul — ici la pattern est disjointe, le test du pilote reproduit, le
test post-fix ne fire pas, le test no-FP couvre 4 contrôles négatifs).
« précision qui achète le statut bloquant ».
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).
e17f600a) :heading_in_list+heading_continuation(2 findings).c34d5e88d) :heading_in_listseul (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
TestHeadingContinuationcouvrant :test_continuation_heading_pilote_reference— reproduit la cellulepilote 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 lerewrap
c34d5e88d, la cellule propre ne fire plus.test_continuation_heading_no_false_positive_legit_heading— 4contrô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
#13326sur des appelssubprocess.run(..., text=True, ...)pré-existants (lignes 895 et909 du fichier original, hors scope de ce fix). Étendre le scope ici
ouvrirait un chantier séparé sur
TestQuartoClosurePyYAMLMissing.Acceptance
TestHeadingContinuationpassent (relancés localementavant commit du détecteur).
🤖 Generated with Claude Code