Files
jason.woltje 29ce1e3602 row 231: C2-01b library reader and survey fixes: control and bidi escapes, front matter list links, an unresolved body embed to a non-.md target is an attachment (#1733)
Lands Gosalyn's round 2 candidate, f37a65857 on gosalyn/c2-01b-r2 (base fefd54e13; commits 3647a5a93,
88daaac50, f37a65857), approved by Webby at merge scope (webby-0072, REVIEW-r2 efd6c1f02 on webby/reviews,
#1733 comment 30005, rev 2787). Nine paths, manifest 312c16fc4f65. No 231 path changed between fefd54e13
and this commit's parent. Patch-id 59b98b1b3e00, the same as fefd54e13..f37a65857.

Evidence: Gosalyn's singles on my slot, 61/0 on r2 (gosalyn-0099; run 1 60/1 was a test order defect).
Gate on my slot, 10:05:31-10:07:52Z on 62ddc96cc plus the nine paths: library 45/0, and every scripts/test-*.sh
green (auth 15, conductor 17, config 31, discord 78, extension-package 18, foundation 44, land-work 86,
queue 156 and 28, release 14, task 98, all 0 failed).
Webby's N4 (README:88 "A link to ... an attachment is R4" next to the embed paragraph) is doc-only and
stays as restored (sage-1917).
2026-10-21 05:09:23 -05:00

5.4 KiB

Row 231 build notes, C2-01b survey escapes, list item lines and attachment embeds (#1733)

Brief: docs/plans/2026-10-20_case2-rows.md "C2-01b survey escapes, list item lines and attachment embeds", blob 16847e94ae. These are Webby's row 212 notes N1 to N3 (webby-0041), split out by sage-1517.

Base

First built as 777f7358a on 212's first round bdf18272a. 212 landed as ee7b2f137 (sage-1886), so the commit was cherry-picked onto refactor fefd54e13 under the new branch gosalyn/c2-01b-r2 as 3647a5a93. git patch-id --stable is 45911915a9ee before and after. packages/library is the same in bdf18272a and in 212's landed round a2c72ac95, so nothing the commit touches moved under it.

What changed

  • N1, packages/library/src/survey.mjs: JSON strings escape C0 controls but leave DEL, C1 and bidi controls raw. The new quote() escapes those too, and folder names print through it.
  • N2, packages/library/src/reader.mjs: front matter parsing records each block list item's line, and a link in a block list carries its item's line instead of its key's.
  • N3, links.mjs exports isAttachment through index.mjs. A wikilink or embed whose target's last segment ends in an extension other than .md is an attachment. The reader neither resolves nor indexes it, and it raises no problem. The survey prints a count of body links to attachments.
  • packages/library/README.md describes all three, and the links, reader and survey tests cover them.

Outside readers

packages/cli/tests/stack-copy.test.mjs:38 checks only that packages/library/src/index.mjs exists, and scripts/mosaic:41 execs survey.mjs. No test pins a hash of a library file.

Tests

On 3647a5a93, slot grant sage-1889, 09:20:01Z to 09:20:14Z, after a busy check. One node --test per file, every rc 0.

File pass fail
packages/library/tests/links.test.mjs 7 0
packages/library/tests/mapping.test.mjs 7 0
packages/library/tests/reader.test.mjs 13 0
packages/library/tests/render.test.mjs 11 0
packages/library/tests/survey.test.mjs 6 0
packages/cli/tests/stack-copy.test.mjs 16 0

Total: 60 pass, 0 fail, 0 cancelled, summed by awk.

Round 2, after webby-0070 (CHANGES) and sage-1900

Webby's round 1 review is agents/webby/work/queue-231/REVIEW-r1.md at 387f04dfd, rev 2774.

Ruling sage-1900, recorded here as asked. B2: the brief stays as approved (sage-1517, case2-rows.md C2-01b N3). Only a ![[x.ext]] embed can be an attachment. Plain wikilinks and front matter values keep resolving, and an unresolved one is R4. README's line "A link to a .canvas file or an attachment is R4" is back as it was at fefd54e13. B1: resolve first. An embed is an attachment only when it resolves to nothing and its target has an extension other than .md. So ![[Dr.Quinn]] with Dr.Quinn.md indexed resolves, ![[cover.png]] gives no problem, ![[missing-note]] is R4 and ![[note.md]] resolves. My own design ruling after r11 (28213ac27) also made plain links attachments. The brief narrowed that, and the brief governs this row.

Changes:

  • links.mjs: isAttachment is true only for a body embed, link.embed === true && !link.field, with the extension test as before. Its comment says it goes by name, so the reader asks it only after resolving.
  • reader.mjs: every link resolves first. An unresolved one is R4 unless isAttachment holds.
  • survey.mjs: quote() also escapes U+061C (Webby N1). The attachment count now covers body embeds only, since it uses isAttachment.
  • Webby N2, my choice of Sage's two options: the survey keeps a count by name and the README says so, "the count of body embeds whose target has an extension other than .md", and that ![[Dr.Quinn]] counts there even when Dr.Quinn.md exists. Checking against the survey's path list would mean a second resolver in the survey, for a count that only guides the mapping.
  • Tests. links: embeds only, with [[cover.png]], [[Board.canvas]], [[Dr.Quinn]], a front matter value and a markdown link all false, and ![[Dr.Quinn]] true by name. reader: the Shore case now gives R4 for the front matter "![[portrait.JPG]]" (line 3), for [[Board.canvas]] (line 5) and for ![[missing-note]] (line 6). The new Dr.Quinn case has Dr.Quinn.md indexed and resolves [[Dr.Quinn]] in a block list and in the body, plus ![[Dr.Quinn]], with no problem. survey: a U+061C folder name prints escaped, and the attachment count is 1, since [[map.PDF]] is a plain link.

Round 2 tests, one node --test per file, each run after a busy check.

Run 1, slot grant sage-1903, 09:39:32Z to 09:39:46Z: 60 pass, 1 fail. The new Dr.Quinn reader test failed on order alone. All three links resolved to Dr.Quinn.md with the right field, line and embed values, and there was no problem. The reader lists body links before front matter links, and my expected array put the relationships link first. I stopped and reported it (gosalyn-0098).

Run 2, after the test-only fix sage-1907 approved, which moves that entry to the end of the expected array, 09:43:42Z to 09:43:56Z. Every rc 0.

File pass fail
packages/library/tests/links.test.mjs 7 0
packages/library/tests/mapping.test.mjs 7 0
packages/library/tests/reader.test.mjs 14 0
packages/library/tests/render.test.mjs 11 0
packages/library/tests/survey.test.mjs 6 0
packages/cli/tests/stack-copy.test.mjs 16 0

Total: 61 pass, 0 fail, 0 cancelled, summed by awk.