From d803f18f6e5685e3346b327ef16c90efd9b050db Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Sun, 4 Oct 2026 23:46:45 +0200 Subject: [PATCH] Answer prose round 1: item 77 refuses what its detail refuses, names item 45's reader and the keys it drops, and the decision expires with it --- docs/decisions.md | 8 +++----- todo.md | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index e9670cd..b48fd6d 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -577,13 +577,11 @@ once doubled the parser's frames per level. ## No value `JSON.parse` or `structuredClone` builds loops a call -2026-10-04, the maintainer. Goals 1 and 9. Valid while every persona hands in plain data, as -`JSON.parse` or `structuredClone` builds it. +2026-10-04, the maintainer. Goals 1 and 9. Valid until `todo.md` item 77 lands. 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. It -stands until `todo.md` item 77 reads the input once into a plain copy. Goal 9's size counts ADF as -JSON, so a shared object costs once per place it is held. +key, a getter, a Proxy or a custom iterator is the caller's to rule out: no persona builds one. Goal +9's size counts ADF as JSON, so a shared object costs once per place it is held. ## Nothing spreads an unbounded array diff --git a/todo.md b/todo.md index 348e975..f2aa13a 100644 --- a/todo.md +++ b/todo.md @@ -30,7 +30,7 @@ | 67 | 0.2.0 | defect | **Push an expand title's leaves one at a time, so a title carrying many text nodes returns a result.** | 1 | 1 | 4 | 9 | 1 | 24.8 | | 6 | 0.2.0 | decision | **Specify the HTML dialect.** | 2 | 6 | 7 | 8 | 2, 4 | 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, 8 | 23.0 | -| 77 | 0.2.0 | decision | **Read the input once into a plain copy, so a getter or Proxy yields `not-an-adf-document` and every call returns a result.** | 4 | 4 | 5 | 9 | 1 | 23.0 | +| 77 | 0.2.0 | decision | **Read the input once into a plain copy, so an accessor property or a throwing Proxy yields `not-an-adf-document` and every call returns a result.** | 4 | 4 | 5 | 9 | 1 | 23.0 | | 66 | 0.2.0 | defect | **Refuse an attribute value that is not a plain object, array or JSON primitive.** | 3 | 2 | 5 | 8 | 1 | 22.5 | | 71 | 0.2.0 | | **Add a README table comparing the package with the other ADF converters, each cell checked against that package's own docs or behaviour.** | 1 | 3 | 6 | 7 | 3 | 21.2 | | 43 | 0.2.0 | decision | **Give each markdown input its own reader, strict to its own standard.** | 6 | 7 | 8 | 9 | 4, 5 | 20.3 | @@ -81,7 +81,7 @@ Lands after items 6, 59, 60, 61 and 62. The CommonMark spec suite also runs agai ### 45. Replace `isAdfDocument` with a reader returning `Result`. -Lands with item 77, whose copy the reader returns. Goal 1 has every call return a result; the +Lands with item 77: the reader returns item 77's copy. Goal 1 has every call return a result; the boolean guard is the one export that does not, and it cannot say which branch refused, where `not-an-adf-document`'s message already does. Breaking: `MIGRATION.md` shows the guard's replacement. @@ -108,17 +108,19 @@ 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. -### 77. Read the input once into a plain copy, so a getter or Proxy yields `not-an-adf-document` and every call returns a result. +### 77. Read the input once into a plain copy, so an accessor property or a throwing Proxy yields `not-an-adf-document` and every call returns a result. -Lands with item 45, in one chunk: its reader returns the copy. The maintainer's call, 2026-10-04: -Goal 1 promises a result for any value, getters and Proxies included. Today the guards and the -conversions read the caller's object many times, so a throwing getter, a revoked Proxy or a getter -minting a fresh child per access throws or walks forever. The entry check copies the document once -inside one tight `try/catch`, reading property descriptors so no getter runs: an accessor property, -or a Proxy trap that throws, is `not-an-adf-document`. Every later step works on the copy. A Proxy -can still claim unbounded width, which the 500-level limit does not cover, so the copy needs a cap -on the values it reads. No standard sets that number: the chunk asks the maintainer for it first. -Found by the technical-principles audit, 2026-10-04. +Lands with item 45, in one chunk: item 45's reader returns the copy. The maintainer's call, +2026-10-04: Goal 1 promises a result for any value, getters and Proxies included. Today the guards +and the conversions read the caller's object many times, so a throwing getter, a revoked Proxy or a +getter minting a fresh child per access throws or walks forever. Item 45's reader copies the +document once inside one tight `try/catch`, reading property descriptors so no getter runs: an +accessor property, or a Proxy trap that throws, is `not-an-adf-document`. The copy keeps own +enumerable keys, as `JSON.stringify` does, so an inherited or non-enumerable key drops, and it reads +arrays by index, so no custom iterator runs. Every later step works on the copy. A Proxy can still +claim unbounded width, which the 500-level limit does not cover, so the copy needs a cap on the +values it reads. No standard sets that number: the chunk asks the maintainer for it first. Found by +the technical-principles audit, 2026-10-04. ### 66. Refuse an attribute value that is not a plain object, array or JSON primitive.