Answer stability round 4: the decision's title backs the loop guarantee alone, item 66 filed

This commit is contained in:
2026-10-04 19:21:11 +02:00
parent 58a9c89dfc
commit 9f23c89719
4 changed files with 18 additions and 11 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ In `docs/decisions.md`:
- The flavour spec is read as a source
- The node tables answer to Atlassian's schema
- Nothing recurses unbounded
- The guards take what `JSON.parse` or `structuredClone` builds
- No value `JSON.parse` or `structuredClone` builds loops a call
- Nothing spreads an unbounded array
- A retry loop checks its own termination
- Readers scan by index
+2 -2
View File
@@ -238,8 +238,8 @@ Serves Goals 1, 3 and 4.
input.
- Past that and `~~`, no GFM: an autolink literal and a `- [ ]` marker stay text, and a checklist
is the `taskList` directive — `plainMarkdownToAdf` turns the marker into a `taskList`.
- A document nested deeper than 500 levels is an error result, not a stack overflow, and no value
`JSON.parse` or `structuredClone` builds makes a call loop forever.
- A document nested deeper than 500 levels is an error result, not a stack overflow, and no call
loops forever on a string, or on a value `JSON.parse` or `structuredClone` builds.
- The emitted formats are semver surface
([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#the-formats-are-api)).
- **`0.2.0`** — `htmlToAdf(adfToHtml(doc))` deep-equals `doc`; fidelity HTML cannot express rides
+6 -7
View File
@@ -563,15 +563,14 @@ format, as its parser does. A list giving way to the directive form refuses at z
than walking again; counting every list twice halved the list limit, counting the directive form
once doubled the parser's frames per level.
## The guards take what `JSON.parse` or `structuredClone` builds
## No value `JSON.parse` or `structuredClone` builds loops a call
2026-10-04, the maintainer. Goal 1. Valid while every persona hands in a value `JSON.parse`,
`structuredClone` or an object literal builds.
2026-10-04, the maintainer. Goals 1 and 8. Valid while every persona hands in plain data, as
`JSON.parse` or `structuredClone` builds it.
The guarantees speak of plain data: own enumerable keys and plain arrays, cycles and shared objects
included. The guards walk it by `Object.values` and refuse a cycle. An inherited or non-enumerable
key, a getter, a Proxy or a custom iterator is the caller's to rule out: no persona builds one, and
each guarded shape asked for another.
The guards walk a value by `Object.values` and refuse a cycle in it. An inherited or non-enumerable
key, a getter, a Proxy or a custom iterator is the caller's to rule out: no persona builds one.
Goal 8's size counts ADF as JSON, so a shared object costs once per place it is held.
## Nothing spreads an unbounded array
+9 -1
View File
@@ -6,7 +6,7 @@
`Bar = 9`
`Next ID = 66`
`Next ID = 67`
| Goal | W |
|---|---|
@@ -29,6 +29,7 @@
| 45 | 0.2.0 | | **Replace `isAdfDocument` with a reader returning `Result<AdfDocument>`.** | 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 back unchanged on V8 every JSON key the emitter writes, with a fixture whose key holds `\`, `"` or a control character.** | 4 | 4 | 6 | 8 | 1, 7 | 23.0 |
| 66 | 0.2.0 | | **Refuse an attribute value that is not a plain object, array or JSON primitive.** | 3 | 2 | 5 | 8 | 1 | 22.5 |
| 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 an image not alone in its paragraph as its alt text linked to its URL, and a titled image alone in its paragraph as the image captioned with its title.** | 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 both readers, and retire `!adf:listBreak`.** | 4 | 5 | 5 | 8 | 3, 4 | 17.2 |
@@ -101,6 +102,13 @@ Deno and Chrome the round-trip would refuse its own output or read back a differ
tells which. 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.
### 66. Refuse an attribute value that is not a plain object, array or JSON primitive.
`isJsonValue` (`json-value.ts`) walks any object by `Object.values`, so a `Date`, `Map`, `Set` or
typed array in `attrs`, as `structuredClone` keeps it, passes the guard and is written as `{}` or a
key per element: `ok: true` with content lost. Accept an object whose prototype is
`Object.prototype` or `null`, and an array. Found by the stability review of item 63, 2026-10-04.
### 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