Pin the rebase's magnitude: one overflow list makes a constant accept what the emitter refuses
CI / gate (push) Successful in 27s
CI / publish (push) Has been skipped

This commit is contained in:
2026-09-19 13:43:34 +02:00
parent d6756ea5e6
commit cd3bdf0d5d
3 changed files with 12 additions and 7 deletions
+1 -1
View File
@@ -317,7 +317,7 @@ someone spells it or pins it.
node once rather than once per level above it (18). The node reference is the key, which holds
because the parse builds one object per position; `adfToMarkdown` passes no memo, where a
consumer's document may hold one node at two positions (4b). `text` and `spelling` carry no depth
and `headroom` is affine in it, so a read above the depth that filled the entry rebases; a read
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. A
give-way is kept too and serves any depth, reading the node's shape alone. Only what succeeded is
@@ -690,6 +690,9 @@ test('refuses input nested deeper than the parser carries', () => {
const overflowed = (panels: number): string => asking(overflowing(overflowing(asking(`---\n${nest(repeated('panel', panels), 'Part.\n')}`))))
assert.equal(code(markdownToAdf(overflowed(493))), 'unsupported-node-shape')
assert.equal(code(markdownToAdf(overflowed(494))), 'unsupported-nesting-depth')
const rebasing = (panels: number): string => asking(`---\n${overflowing(asking(`---\n${nest(repeated('panel', panels), 'Part.\n')}`))}`)
assert.ok(markdownToAdf(rebasing(494)).ok)
assert.equal(code(markdownToAdf(rebasing(495))), 'unsupported-nesting-depth')
assert.ok(markdownToAdf(`${'- '.repeat(largestNesting)}a\n`).ok)
assert.equal(code(markdownToAdf(`${'- '.repeat(largestNesting + 1)}a\n`)), 'unsupported-nesting-depth')
})
+8 -6
View File
@@ -840,12 +840,14 @@ The done `todo.md` items in full, as they were written. `todo.md` keeps a one-li
250 nested directive lists fall from 1.22 s to 0.04 s at 16.1 kB and from 5.20 s to 0.12 s at
261 kB; a panel between every pair of lists 1.00 s to 0.05 s, an opaque carry in every item
1.08 s to 0.03 s. No figure enters the gate (§14), as 4c settled for a behaviour-preserving
cost fix; what the gate holds is the refusal. The rebase's sign is pinned by the two
depth-boundary tests already there, its magnitude by a third case the review found: an ordered
list past the marker cap gives way, so the emitter spends two levels where the parser spent
one, and two such lists put a read below the depth that filled its entry — which a hit would
answer without the depth guards the walk runs, naming a different refusal at a different path.
That read re-spells (the stability-reviewer, 2026-09-19). The one list accounting was not
cost fix; what the gate holds is the refusal. An ordered list past the marker cap gives way,
so the emitter spends two levels where the parser spent one: one such list between an ask and
a kept entry cancels the credit the directive form starts with, and two put the read below the
depth that filled it — which a hit would answer without the depth guards the walk runs. That
read re-spells. Three cases hold the arithmetic between them: the two depth-boundary tests
already there pin the sign, the two-overflow case pins the guard, and the one-overflow case
pins the magnitude, a constant rebase accepting there a document the emitter then refuses
(the stability-reviewer, 2026-09-19). The one list accounting was not
taken: 4b settled that accounting the day this was filed, and reopening it is an ask rather
than a chunk.