From 79005f07bee75aeea298582355eb01fb9e682670 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Sat, 3 Oct 2026 16:16:46 +0200 Subject: [PATCH] File the round-4 goals audit's defects and widen items 55 and 62 --- todo.md | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/todo.md b/todo.md index 7842034..eca1829 100644 --- a/todo.md +++ b/todo.md @@ -6,7 +6,7 @@ `Bar = 9` -`Next ID = 63` +`Next ID = 66` | Goal | W | |---|---| @@ -24,11 +24,14 @@ | ID | Release | Exempt | Item | R | S | A | G | Goals | Score | |---|---|---|---|---|---|---|---|---|---| +| 63 | 0.2.0 | defect | **Refuse a cyclic input as `not-an-adf-document` in place of looping forever.** | 2 | 2 | 6 | 9 | 1 | 27.5 | | 7 | 0.2.0 | | **Ship HTML: `adfToHtml`, `htmlToAdf`, and `markdownToHtml` / `htmlToMarkdown` composed through ADF.** | 6 | 9 | 9 | 9 | 2, 3 | 25.8 | -| 55 | 0.2.0 | defect | **Spell through the carry every document the emitter refuses today for a carriage return, a NUL, a code-span line start or a newline inside an emoji, mention or status.** | 5 | 5 | 7 | 9 | 1 | 25.8 | +| 55 | 0.2.0 | defect | **Spell through the carry every document the emitter refuses today for a carriage return, a NUL, a code-span line start, a newline inside an emoji, mention or status, or a text node with empty, missing or content-holding text.** | 5 | 5 | 7 | 9 | 1 | 25.8 | | 45 | 0.2.0 | | **Replace `isAdfDocument` with a reader returning `Result`.** | 2 | 3 | 6 | 8 | 1 | 25.2 | | 6 | 0.2.0 | decision | **Specify the HTML dialect.** | 2 | 6 | 7 | 8 | 2, 3 | 24.7 | +| 64 | 0.2.0 | defect | **Read every JSON key the emitter writes back unchanged on V8, with a fixture whose key holds `\`, `"` or a control character.** | 4 | 4 | 6 | 8 | 1, 7 | 23.0 | | 43 | 0.2.0 | decision | **Give each markdown input its own reader, strict to its own standard.** | 6 | 7 | 8 | 9 | 3, 4 | 22.3 | +| 65 | 0.2.0 | defect | **Read a mid-text or titled CommonMark image as Goal 6 allows, in place of refusing it with `unmappable-image`.** | 5 | 5 | 7 | 7 | 3, 4, 6 | 18.7 | | 49 | 0.2.0 | | **Read a list whose bullet or ordered delimiter changes as two lists in the CommonMark reader.** | 4 | 5 | 5 | 8 | 3, 4 | 17.2 | | 61 | 0.2.0 | decision | **Have the emitter ask the inline reader how a line reads back, in place of `line-escaping.ts` predicting it.** | 6 | 8 | 3 | 8 | 1 | 14.0 | | 52 | 0.2.0 | | **Spell `colwidth` as a comma list, `colwidth="340,420"`.** | 3 | 3 | 5 | 6 | 5 | 13.0 | @@ -37,7 +40,7 @@ | 60 | 0.2.0 | decision | **Collect the questions `parse/` asks `emit/` into one named module.** | 3 | 4 | 2 | 6 | 2 | 10.7 | | 59 | 0.2.0 | decision | **Group the directive grammar into `src/markdown/directive/`, move `Read` to `result.ts`, and move `Flavour` to `markdown/flavour.ts`.** | 3 | 5 | 2 | 6 | 2 | 10.4 | | 50 | 0.2.0 | | **Read `[](/url)` and `[]()` as CommonMark's empty link.** | 4 | 4 | 3 | 6 | 3, 4, 6 | 10.4 | -| 62 | 0.2.0 | decision | **Move the plain reader out of `parse/markdown-to-adf.ts` into `markdown/plain/`.** | 3 | 4 | 2 | 5 | 2 | 8.9 | +| 62 | 0.2.0 | decision | **Move the plain flavour's reading out of `parse/` and its writing out of `emit/` into `markdown/plain/`, so `plain/` and `emit/` no longer import each other.** | 4 | 5 | 2 | 6 | 2 | 9.4 | | 38 | 0.3.0 | | **Spell a lone surrogate in a text node so it survives a UTF-8 encode.** | 2 | 2 | 4 | 7 | 1 | 19.5 | | 47 | 0.3.0 | | **Open the README with what the package is, what it does and for whom.** | 1 | 4 | 7 | 9 | 9 | 14.0 | | 34 | 0.3.0 | | **Read emphasis flanking by the whole character beside an astral symbol.** | 2 | 3 | 3 | 6 | 3, 4 | 12.6 | @@ -54,21 +57,29 @@ ## Details +### 63. Refuse a cyclic input as `not-an-adf-document` in place of looping forever. + +`adfDocumentFault` walks with `isNodeArray` (`adf/document.ts`) and `isJsonValue` (`json-value.ts`), +worklists that record no visited object, so a node whose `content` holds itself hangs +`adfToMarkdown`, `adfToPlainMarkdown` and `isAdfDocument`; README §The guarantees promises no input +loops forever. + ### 7. Ship HTML: `adfToHtml`, `htmlToAdf`, and `markdownToHtml` / `htmlToMarkdown` composed through ADF. Lands after items 6, 59, 60, 61 and 62. The CommonMark spec suite also runs against `markdownToHtml`. The README documents HTML as it documents markdown, and its tagline and `package.json`'s `description` regain HTML. -### 55. Spell through the carry every document the emitter refuses today for a carriage return, a NUL, a code-span line start or a newline inside an emoji, mention or status. +### 55. Spell through the carry every document the emitter refuses today for a carriage return, a NUL, a code-span line start, a newline inside an emoji, mention or status, or a text node with empty, missing or content-holding text. `inline-line.ts` refuses a carriage return or NUL in text (`unspellable-character`) and a paragraph opening with a code-span run (`unspellable-line-start`); `fencedTexts` refuses the same characters in a code block; `directive-syntax.ts` refuses a newline in an emoji, mention or status (`unspellable-whitespace`). The inline carry's JSON escapes all of them, so a lossless spelling exists, and §The code list says a cause the carry answers gets no code. Fixing it revises §Which -code a cause takes and §Markdown in is a canonical fixpoint, which the maintainer decides. Found by -the README-goals audit, 2026-10-03. +code a cause takes and §Markdown in is a canonical fixpoint, which the maintainer decides. Also a +text node whose `text` is empty or missing, or which holds `content`: `inline-line.ts` refuses it +inline and `fencedTexts` in a code block. Found by the README-goals audit, 2026-10-03. ### 45. Replace `isAdfDocument` with a reader returning `Result`. @@ -82,6 +93,15 @@ Element-by-element mapping, the `data-*` fidelity scheme, the opaque-carry form, foreign-element set `htmlToAdf` accepts — the set `markdownToAdf` shares (`spec/flavour.md` §Raw HTML in input). The set sorts per `docs/decisions.md` §Foreign HTML sorts three ways. +### 64. Read every JSON key the emitter writes back unchanged on V8, with a fixture whose key holds `\`, `"` or a control character. + +`property-harness.ts` strips `\`, `"` and control characters from generated JSON keys, citing V8's +`JSON.parse` returning a wrong key for an escaped backslash. The library reads `json` attributes +(`directive-syntax.ts`) and both carries (`opaque-carry.ts`) through that `JSON.parse`, so on Node, +Deno and Chrome the round-trip would refuse its own output. Confirm with a fixture first; then read +JSON with our own parser or record the gap with an ending item. Found by the README-goals audit, +2026-10-03. + ### 43. Give each markdown input its own reader, strict to its own standard. Today `markdownToAdf` reads CommonMark and the lossless flavour as one input: text shaped like a @@ -90,6 +110,12 @@ a code fence whose info string opens `adf:` becomes the block carry where Common caller names the markdown it hands in: CommonMark, read as its spec says, or the lossless flavour, read as `spec/flavour.md` says. Breaking: `MIGRATION.md` says which call a caller takes. +### 65. Read a mid-text or titled CommonMark image as Goal 6 allows, in place of refusing it with `unmappable-image`. + +§CommonMark is a subset keeps the image gap and no item ends it: a bot's `See ![diagram](url) here` +or a titled image is refused, 14 examples in `corpus/commonmark-spec/refusals.json`. Settle what such +an image builds — Goal 6 drops form and keeps the target — and have the decision cite this item. + ### 49. Read a list whose bullet or ordered delimiter changes as two lists in the CommonMark reader. Lands after item 43. Today `- a` then `+ b`, or `1.` then `1)`, reads as one list; CommonMark reads @@ -147,10 +173,12 @@ input. Breaking, so it ships beside item 43: `MIGRATION.md`'s Readings table gai `pending` exceptions go, and its spelling leaves the README's "Four CommonMark spellings" bullet, which counts one fewer. -### 62. Move the plain reader out of `parse/markdown-to-adf.ts` into `markdown/plain/`. +### 62. Move the plain flavour's reading out of `parse/` and its writing out of `emit/` into `markdown/plain/`, so `plain/` and `emit/` no longer import each other. -What moves: the plain reader's code in `markdown-to-adf.ts` — the alert and task-marker reads, the -`mintTaskIds` call and the `inlineLeaves` use. +Reading: the alert and task-marker reads in `parse/markdown-to-adf.ts`, the `mintTaskIds` call and +the `inlineLeaves` use. Writing: `spellPlainBlock`, `quotedUnder`, `tryTaskList` and `taskBlocks` +in `emit/adf-to-markdown.ts`. Every comprehension seat on 2026-10-03 named the plain flavour's +spread across three directories. ### 38. Spell a lone surrogate in a text node so it survives a UTF-8 encode.