Lint: an unclosed code fence in block prose swallows the rest of the rendered document
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 58/100
Línea de trabajo
Comienza en el punto de entrada modelith lint y lee las reglas de lint existentes y las pruebas basadas en fixtures. Sigue cómo se comprueban los campos de prosa a nivel de bloque y, después, añade cobertura para un fence sin cerrar en un campo como /entities/Ticket/definition; se considerará terminado cuando lint informe del campo y la línea con una severidad de advertencia o error acordada.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Found while reviewing #37. Pre-existing on main, not a regression from that PR — verified byte-identical between a main-built binary and the #37 branch. Filing separately so it doesn't widen that PR.
What happens
A block-level prose field (entity.definition, model.description, enum.description, entity.derivation, scenario.description) may contain a fenced code block. If the author opens a fence and never closes it, everything after it in the rendered .md — later sections, the attributes table, the Mermaid diagram — falls inside the code block.
Repro
kind: DomainModel
version: v1
title: Unclosed fence
description: Probing an unterminated fence in block prose.
entities:
Ticket:
definition: |
An example of the wire format:
```xml
<ticket id="1"/>
attributes:
- name: id
type: string
description: The identifier printed on the ticket.
$ modelith lint fence.modelith.yaml
0 error(s), 0 warning(s)
$ modelith render fence.modelith.yaml --stdout
...
```xml
<ticket id="1"/>
**Attributes**
| Name | Type | Description |
...
**Attributes**, the table and the trailing ```mermaid block are all inside the unterminated fence as far as any Markdown parser is concerned.
Severity
Not a security issue. Fence content is literal even when the fence is unterminated, so the <ticket id="1"/> above is inert — #37's escaping rule is not defeated. The damage is a broken page: on a Docusaurus build the rest of the document renders as code, or the build fails outright.
Lint passes at every severity, which is the real gap — the model is malformed in a way the tool could catch and doesn't.
Why lint and not the renderer
The renderer now uses goldmark (as of #37) to decide what prose is literal. goldmark exposes no "was this fence closed" flag on ast.FencedCodeBlock — an unterminated fence simply runs to the end of the document, which is CommonMark-correct behaviour, not a parser bug. Detecting it inside the renderer means hand-scanning the source again, which is exactly the layer #37 removed.
A lint rule is the right home: it is an authoring mistake, it is cheap to detect (count fence openers per block-level prose field), and lint is where the model's other structural problems are already reported.
Suggested shape
- A semantic warning, or an error — worth deciding, since the rendered output is genuinely broken rather than merely suboptimal.
- Message should name the field and the line, e.g.
/entities/Ticket/definition: code fence opened but never closed — everything after it renders as code. - Fixture-driven test alongside the other lint rules.
Related: #37 (the renderer hardening that surfaced this), ADR-0014 (prose is Markdown, not HTML).
🤖 Filed by Claude Code
- Lenguaje dominante
- Go
- Estrellas
- 34
- Forks
- 5
- Merge medio
- 5 h 7 min
- PR fusionados (30 d)
- 6
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de stacklok/modelith
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
-
documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 92/100
-
enhancement
Dificultad 2/5 Medio día Aptitud para principiantes 68/100
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 20/100
Todos los issues de stacklok/modelith
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
google/differential-privacy#516 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 90/100
lightninglabs/lndmon#140 ·
-
documentation good first issue ready-for-triage ready-to-code
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
release-engineering/fbc-update-planner#102 · 3 comentarios ·
Los mantenedores suelen responder en 5 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
yetone/magpie#562 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Los mantenedores suelen responder en 4 días