mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 11:48:29 +01:00
Answer prose round 1: 0 🔴, 5 🟡; state the directive boundary, split the spelling-questions sentence and tighten the plan items
This commit is contained in:
+6
-6
@@ -924,15 +924,15 @@ them. A primitive knowing neither ADF nor a format stays at `src/` root. A const
|
||||
what both read where there are two.
|
||||
|
||||
A flavour's own code, both directions included, sits in its own directory: `markdown/portable/`;
|
||||
`todo.md` item 62 moves what still sits in `parse/` and `emit/`. The directive grammar likewise
|
||||
sits in `markdown/directive/`. Otherwise each format directory parts into `emit/` (ADF→format) and
|
||||
`todo.md` item 62 moves what still sits in `parse/` and `emit/`. The directive grammar, both
|
||||
directions included, sits in `markdown/directive/`, which imports neither `emit/` nor `parse/`.
|
||||
Otherwise each format directory parts into `emit/` (ADF→format) and
|
||||
`parse/` (format→ADF), the rest of it holding what both directions read. A construct's reader lives
|
||||
there beside the regex the emitter escapes against, so the two cannot drift; a reader with no emit
|
||||
counterpart goes in `parse/`, unless it is part of a construct that side already holds — a grammar
|
||||
stays in one file rather than splitting across the seam. A rule both directions must answer alike —
|
||||
whether a list marker interrupts a paragraph — is one function there too, never a copy per
|
||||
direction, however conservative the copy would be. Where the rule is the emitter's own choice, input
|
||||
consults it rather than restating it, and that is the only import `parse/` takes from `emit/`,
|
||||
through `emit/spelling-questions.ts`, which names `commonMarkSpelling`, `openingLinkTakesDirective`
|
||||
and the `SpellingMemo` type — so no fixture the emitter writes can be refused, and a spelling the
|
||||
emitter refuses gives its own error rather than a second name for it.
|
||||
consults it rather than restating it, so no fixture the emitter writes can be refused, and a
|
||||
spelling the emitter refuses gives its own error rather than a second name for it. That consulting
|
||||
is the only import `parse/` takes from `emit/`, through `emit/spelling-questions.ts`.
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ export type ParseError = ConvertError & { position: SourcePosition }
|
||||
|
||||
export type Result<T, E extends ConvertError = ConvertError> = { error: E; ok: false } | { ok: true; value: T }
|
||||
|
||||
// A reader with no path to name; the walk attaches the path where it knows it.
|
||||
// A fault without a path, for a reader that cannot know it; its caller adds the path.
|
||||
export type Read<T> = { fault: ConvertFault; value?: undefined } | { fault?: undefined; value: T }
|
||||
|
||||
export function failure<T>(code: ConvertErrorCode, message: string, path: ConvertErrorPath): Result<T> {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
| 75 | 0.4.0 | | | **Make the generated-markdown property write block carries as `adf:` fences, canonical and hostile.** | 1 | 1 | 1 | 1 | 2 | code health by 2 | 17.4 |
|
||||
| 45 | 0.4.0 | | defect | **Replace `isAdfDocument` with a reader returning `Result<AdfDocument>`.** | 2 | 1 | 3 | 4 | 3 | 1 by 2 | 13.1 |
|
||||
| 68 | 0.4.0 | | defect | **Carry a non-text inline node holding `content` or `text`, a block holding `text`, and a leaf block holding `content`.** | 2 | 1 | 2 | 3 | 3 | 1 by 2 | 13.1 |
|
||||
| 127 | 0.4.0 | | principle | **Hold what `result.test.ts`, `json-text.test.ts` and `entity-references.test.ts` check by asserting outcomes, so none reads source text.** | 2 | 2 | 1 | 3 | 3 | code health by 2 | 13.1 |
|
||||
| 127 | 0.4.0 | | principle | **Hold what `entity-references.test.ts`, `json-text.test.ts` and `result.test.ts` check by asserting outcomes, so none reads source text.** | 2 | 2 | 1 | 3 | 3 | code health by 2 | 13.1 |
|
||||
| 112 | 0.4.0 | | | **Pad a GFM pipe table's short rows with empty cells, read its body rows holding no pipe, and read a one-column table without leading pipes in `portableMarkdownToAdf`.** | 2 | 1 | 2 | 3 | 3 | 4 by 4 | 6.2 |
|
||||
| 80 | 0.4.0 | | | **Name the node's path and the attribute key when `not-an-adf-document` refuses a node inside the document.** | 2 | 1 | 2 | 3 | 3 | 6 by 4 | 6.0 |
|
||||
| 81 | 0.4.0 | | | **Fail the gate unless the README's error tables list exactly the codes `ConvertErrorCode` holds.** | 1 | 1 | 1 | 1 | 2 | 3 by 2 | 4.2 |
|
||||
@@ -63,13 +63,14 @@
|
||||
|
||||
Two boundaries in `docs/decisions.md` §The source parts by ADF and format hold by convention only:
|
||||
`src/markdown/parse/` imports from `src/markdown/emit/` only `emit/spelling-questions.ts`, and
|
||||
`src/markdown/directive/` imports neither `emit/` nor `parse/`. A test scanning the source is
|
||||
refused, since `~/.claude/principles/technical-principles.md` says a test never scans source.
|
||||
oxlint 1.89.0 can hold both with `overrides` carrying `no-restricted-imports`. Verified: a
|
||||
`from '…'`, a bare `import '…'`, a double-quoted and a dynamic `import()` each fail the
|
||||
`size-ratchet` leg, and the exception `!../emit/spelling-questions.ts` passes.
|
||||
`src/markdown/directive/` imports neither `emit/` nor `parse/`. The technical principles refuse a
|
||||
test that scans the source: principle "Assert the outcome" bans it. oxlint 1.89.0 can hold both
|
||||
boundaries with `overrides` carrying `no-restricted-imports`. Verified: a forbidden import fails
|
||||
the `size-ratchet` leg in each form, as `from '…'`, as a bare `import '…'`, with a double-quoted
|
||||
specifier and as a dynamic `import()`. An import of `../emit/spelling-questions.ts`, listed as the
|
||||
exception, passes.
|
||||
|
||||
But §The size ratchet, the maintainer's, gives `.oxlintrc.json` a single rule and says no second
|
||||
But the maintainer's §The size ratchet gives `.oxlintrc.json` a single rule and says no second
|
||||
lint rule joins it. The question for the maintainer: may the config hold a second kind of rule, the
|
||||
import boundaries? If so, amend that entry's "single rule" and "no second lint rule", and rename the
|
||||
`size-ratchet` script and `ci.sh` leg, whose name would no longer say what they hold.
|
||||
@@ -205,23 +206,23 @@ round-trips them; `docs/decisions.md` §The code list gives a cause the carry an
|
||||
them from the README's `unsupported-node-shape` cause "Writing, in `adfToLosslessMarkdown`". Found by the README-goals
|
||||
audit, 2026-10-04.
|
||||
|
||||
### 127. Hold what `result.test.ts`, `json-text.test.ts` and `entity-references.test.ts` check by asserting outcomes, so none reads source text.
|
||||
### 127. Hold what `entity-references.test.ts`, `json-text.test.ts` and `result.test.ts` check by asserting outcomes, so none reads source text.
|
||||
|
||||
Technical principle "Assert the outcome", which bans scanning the source with `ast` or a regex.
|
||||
Three tests read source text:
|
||||
|
||||
- `src/markdown/commonmark/entity-references.test.ts` regex-extracts the `packedReferences` literal
|
||||
from `entity-references.ts`, to guard that each of the 2125 packed references parts into one name
|
||||
and one value the table decodes. Reformatting the literal fails it with the table unchanged.
|
||||
- `src/json-text.test.ts` greps every shipped file for `JSON.parse(`, to guard that only
|
||||
`parseJsonText` reads JSON text. `JSON.parse (` or `JSON['parse'](` escapes it.
|
||||
- `src/result.test.ts` regex-parses the `ConvertErrorCode` union out of `result.ts`, and each
|
||||
`failure('…'` and `code: '…'` out of every shipped file, to guard that every declared code has a
|
||||
production cause and every call site names a declared code. A code held in a variable or passed
|
||||
through another helper escapes it.
|
||||
- `src/json-text.test.ts` greps every shipped file for `JSON.parse(`, to guard that only
|
||||
`parseJsonText` reads JSON text. `JSON.parse (` or `JSON['parse'](` escapes it.
|
||||
- `src/markdown/commonmark/entity-references.test.ts` regex-extracts the `packedReferences` literal
|
||||
from `entity-references.ts`, to guard that each of the 2125 packed references parts into one name
|
||||
and one value the table decodes. Reformatting the literal fails it with the table unchanged.
|
||||
|
||||
Item 81 also touches `result.test.ts`; a lint rule for the `JSON.parse` ban meets item 126's
|
||||
question about what `.oxlintrc.json` may hold. Found by the technical-principles audit of item 60,
|
||||
Item 81 changes `result.test.ts` too. Whether `.oxlintrc.json` may hold a lint rule for the
|
||||
`JSON.parse` ban is item 126's question. Found by the technical-principles audit of item 60,
|
||||
2026-10-22.
|
||||
|
||||
### 112. Pad a GFM pipe table's short rows with empty cells, read its body rows holding no pipe, and read a one-column table without leading pipes in `portableMarkdownToAdf`.
|
||||
@@ -261,9 +262,9 @@ documents markdown, its comparison table names HTML, and its tagline and `packag
|
||||
description and keywords name HTML again. `htmlToAdf` refuses a value that is not a string as
|
||||
`not-a-string` (`docs/decisions.md` §Which code a cause takes).
|
||||
|
||||
`html/` may not import `markdown/`. Whatever it shares with the carry (`opaque-carry.ts`) or the
|
||||
mark spellings (`mark-spellings.ts`) moves out of `markdown/` as `docs/decisions.md` §The source
|
||||
parts by ADF and format says. A composed call naming a markdown `Flavour` sits above both peers.
|
||||
Whatever `html/` shares with the carry (`opaque-carry.ts`) or the mark spellings
|
||||
(`mark-spellings.ts`) splits: the ADF question moves to `adf/`, and each format keeps its own
|
||||
spelling. Where a composed call naming a markdown `Flavour` sits is this item's to settle.
|
||||
|
||||
### 46. Publish the bundle size in the README, failing the release pipeline when it drifts.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user