Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Lint: an unclosed code fence in block prose swallows the rest of the rendered document

未关闭
#39 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
58/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
go, markdown
领域
cli, tooling

调研方向

从 modelith lint 入口开始,阅读现有的 lint 规则和由 fixture 驱动的测试。跟踪块级 prose 字段的检查方式,然后为 /entities/Ticket/definition 这类字段中的未终止 fence 添加覆盖;完成标准是 lint 以约定的 warning 或 error 严重级别报告该字段和行号。

由索引模型根据 Issue 内容生成。

描述

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

主要语言
Go
星标
35
派生
5
平均合并
5 小时 7 分钟
30 天内合并 PR
6

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

stacklok/modelith 的其他 Issue

查看 stacklok/modelith 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。