36c - §10 and §11's decisions move to docs/decisions.md #138

Merged
lilleman merged 5 commits from 36c into main 2026-09-28 11:16:16 +02:00
3 changed files with 18 additions and 14 deletions
Showing only changes of commit bbfc8724fc - Show all commits
+14 -13
View File
@@ -294,8 +294,8 @@ nesting a spelling inside its own kind (`*(*a*)*`) names that mark once.
## The gate runs on Deno and Bun
2026-09-01, the maintainer. Goals 7 and 8. Valid while Deno is the only leg refusing an
extensionless specifier and Bun the only engine that is not V8.
2026-09-01, the maintainer. Goals 7 and 8. Valid while Bun is the gate's only engine that is
not V8.
The gate runs the suite under Deno and Bun as well as Node, and neither extra leg is Node's proof
twice. Deno refuses an extensionless or directory specifier, so it holds the module graph to the
@@ -345,7 +345,7 @@ compared against `undefined` — have a half no valid document reaches.
## The size ratchet
2026-09-20, the maintainer. Goal 10. Valid while no measure picks out what readers find hard
(the comprehension panel, 2026-09-20).
better than a function's length.
`.oxlintrc.json`'s single rule, over the files `tsconfig.build.json` builds, is a per-function line
ceiling, set at that set's worst and moving only downward. It covers the built files alone, since
@@ -371,10 +371,11 @@ markdown, on a fixed seed in the gate; a counterexample found becomes a round-tr
2026-09-01, the maintainer. Goal 1. Valid while `spec/flavour.md` restates the node tables in
prose.
`spec/flavour.md` is read as a source, so the node tables cannot drift from the prose they copy: its
node and mark bullets must equal the tables in `adf/`. It guards the attributes alone: nodes that
differ in content model share a bullet, and the argument attribute is spelled ahead of `Attributes:
`, so both answer to the round-trip corpus and to nothing else where a node has no fixture.
`spec/flavour.md` is read as a source, so the node tables cannot drift from the prose they copy:
its node and mark bullets must equal the tables in `adf/`. It guards the attributes alone: nodes
that differ in content model share a bullet, and the argument attribute is spelled outside the
bullet's attribute list, so both answer to the round-trip corpus and to nothing else where a node
has no fixture.
## The node tables answer to Atlassian's schema
@@ -433,12 +434,12 @@ two cannot disagree — which is what makes the kept value a memo rather than a
2026-09-19, the maintainer. Goal 9. Valid while the `commonMarkSpelling` ask spells a node once
per level above it otherwise.
The parse keeps each node's readable spelling in a memo, so the `commonMarkSpelling` ask stops
spelling a node once per level above it. `text` and `spelling` carry no depth and `headroom` is
affine in it, so a read at or above the depth that filled the entry rebases; a read below re-spells,
because a hit skips the depth guards the walk it replaces runs and an ordered list past the marker
cap gives way, spending two emitter levels where the parser spent one. Only what succeeded is kept,
so no path minted at another position is ever read.
The parse and the plain reduction keep each node's readable spelling in a memo, so the
`commonMarkSpelling` ask stops spelling a node once per level above it. `text` and `spelling` carry
no depth and `headroom` is affine in it, so a read at or above the depth that filled the entry
rebases; a read below re-spells, because a hit skips the depth guards the walk it replaces runs and
an ordered list past the marker cap gives way, spending two emitter levels where the parser spent
one. Only what succeeded is kept, so no path minted at another position is ever read.
## Only the hard break holds a raw newline
+1 -1
View File
@@ -20,7 +20,7 @@ type BlockSpelling = 'commonmark' | 'directive' | 'list'
type EmittedBlock = { headroom: number; spelling: BlockSpelling; text: string }
type KeptSpelling = { block: EmittedBlock | undefined; depth: number }
type PlacedBlock = Omit<EmittedBlock, 'headroom'> & { node: AdfNode }
// Keyed by reference: the parse builds one object per position; a consumer's document may share one, so adfToMarkdown passes none.
// Keyed by reference: only a caller building one object per position (the parse, the plain reduction) passes one; a consumer's document may share a node.
export type SpellingMemo = Map<AdfNode, KeptSpelling>
type Walk = { blocks: readonly PlacedBlock[]; headroom: number }
type WalkedItem = { node: AdfNode; walk: Walk }
+3
View File
@@ -73,6 +73,9 @@
so the first raise to the measured figure reddens a run that changed nothing. Make the
measurement repeatable, or state the number the floor may be raised to and why it is not the
measured one.
- **37 — State what the Deno leg proves that Node's does not, or drop it.** `docs/decisions.md` §The
gate runs on Deno and Bun credits Deno with holding the module graph to fully-spelled specifiers,
which Node already refuses under `"type": "module"`, and `tsc` under `NodeNext`.
- **33 — Make a carried mark run cost the line one re-emit.** `adfToMarkdown` spends 23 s on one
paragraph of 2000 × `un` plus `**-r**`: each run its flanking cannot spell re-emits the whole line
before riding the carry, quadratic in the runs (Goal 9), and the plain reduction's