Scope the trailing-whitespace and escaping-scan rules, name the totality gap
CI / gate (push) Successful in 4s

This commit is contained in:
Lilleman auf Larv
2026-08-24 12:52:38 +02:00
parent 346bdcc27d
commit 1804d16cce
7 changed files with 56 additions and 13 deletions
+1 -2
View File
@@ -4,8 +4,7 @@ One directory per contract kind:
- `round-trip/``<name>.json` + `<name>.md`: the markdown `adfToMarkdown` must emit for that
document, byte for byte, and that `markdownToAdf` must read back to it (AGENTS.md §2). Grouped
by node family: `commonmark-subset/`, `block-nodes/`, `inline-nodes/`, `opaque-carry/`,
`combinations/`.
by node family.
- `normalization/``<name>.md` + `<name>.json`: markdown input, and the document
`markdownToAdf` must build from it. One-way; the markdown is not canonical.
- `errors/``<name>.md`: markdown input that must not convert. A `<name>.error` beside it
@@ -0,0 +1,18 @@
{
"content": [
{
"attrs": {
"language": "markdown"
},
"content": [
{
"text": "Line one \nLine two",
"type": "text"
}
],
"type": "codeBlock"
}
],
"type": "doc",
"version": 1
}
@@ -0,0 +1,4 @@
```markdown
Line one
Line two
```
@@ -15,6 +15,15 @@
}
],
"type": "paragraph"
},
{
"content": [
{
"text": "Grade 8.8.",
"type": "text"
}
],
"type": "paragraph"
}
],
"type": "listItem"
@@ -1,4 +1,6 @@
9. Bolt M8
Grade 8.8.
10. Nut M8
Zinc-plated.
+6 -5
View File
@@ -38,11 +38,12 @@ normalizes to it through the round-trip.
CommonMark autolink (absolute URI).
- Paragraphs on one line — no soft wrapping; a soft line break in input becomes a single space.
- Entity references in input decode to their characters; output backslash-escapes only where text
would otherwise parse as syntax: escape the leading delimiter of a construct that would
otherwise open, re-scan from there, and repeat — with the opener literal the closer parses as
text, so `*not emphasis*` is `\*not emphasis*`, one backslash.
- Blocks separated by one blank line, no trailing whitespace, single trailing newline; a document
with no blocks is the empty string.
would otherwise parse as syntax, scanning the assembled line rather than each text node: escape
the leading delimiter of a construct that would otherwise open, re-scan from there, and repeat —
with the opener literal the closer parses as text, so `*not emphasis*` is `\*not emphasis*`, one
backslash.
- Blocks separated by one blank line, no trailing whitespace outside a code block's content,
single trailing newline; a document with no blocks is the empty string.
## Directives
+16 -6
View File
@@ -23,12 +23,22 @@ detail is settled at its own milestone.
- [ ] **1d — Corpus start** (§10): checked-in fixtures per spec'd node, in `corpus/`, one
directory per contract kind (`corpus/README.md`).
**Blocked on the maintainer** (§15), not to be guessed: Canonical form has no totality
guard — a `paragraph`, `heading`, `blockquote` or `codeBlock` carrying a `localId`, or a
`blockquote` carrying marks, has no spelling that keeps it, and picking one (directive
sections for the six CommonMark block nodes, or the opaque carry) is a permanent format
decision (§8). Its three collision sites stay out of the corpus until then: an `orderedList`
starting at 1, a `codeBlock` whose info string is empty, and `media` with an empty `alt`
each a choice between the absent attribute and the empty value.
guard. Per `@atlaskit/adf-schema` 57.1.0 every block node it spells — `blockquote`,
`bulletList`, `codeBlock`, `heading`, `listItem`, `orderedList`, `paragraph`, `rule`
carries a `localId` with no spelling, `codeBlock` also `hideLineNumbers`, `uniqueId` and
`wrap`, `blockquote` also marks, and `hardBreak` `text` and `localId` with no section for
the carry fallback to reach. Picking one (directive sections for those nodes, or the opaque
carry) is a permanent format decision (§8). Three collision sites are held out of the corpus
meanwhile, each a choice between the absent attribute and the empty value: a `codeBlock`
whose info string is empty and `media` with an empty `alt`, which one "exactly that shape"
rule — as the CommonMark image already uses — could settle together, and an `orderedList`
starting at 1, independent of the totality answer since `order: 9` keeps the markdown form
either way. **Also blocked**: the link rule covers destination spaces only, so two shapes
break §2 silently — href `https://example.com/a)b` emits `[t](https://example.com/a)b)`,
read back as href `…/a` plus literal `b)`; title `He said "hi"` emits
`[t](u "He said "hi"")`, which holds no title. Two defensible spellings each — angle
brackets or a backslash escape, and for titles `'…'` or `(…)` besides — so §8 leaves the
pick here.
- [ ] **1d1 — The CommonMark subset**: blockquote, bulletList, codeBlock, heading, orderedList,
paragraph, rule, listItem, hardBreak, text, code spans, and the `code`, `em`, `link`,
`strike` and `strong` marks — one mark per text node; nesting is 1d5's.