From 16e809457e87da21d0e3a4a1ce88924c2c8fd3eb Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 22 Oct 2026 13:48:12 -0500 Subject: [PATCH] row 283 (#1788): design draft 2 folds webby-0169 R1 (editor refuses < and >, T3, M6b) and N1 (check 8 compares NFC and case, NFD case in T6, M4b); Q2-Q4 accepted, Q4 handoff to C2-02 in BUILD.md; doc only --- agents/honker/work/queue-283/DESIGN.md | 35 ++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/agents/honker/work/queue-283/DESIGN.md b/agents/honker/work/queue-283/DESIGN.md index f4cf2a4d6..3468b1454 100644 --- a/agents/honker/work/queue-283/DESIGN.md +++ b/agents/honker/work/queue-283/DESIGN.md @@ -1,4 +1,4 @@ -# Row 283 (#1788) C2-01d design, draft 1 (Honker) +# Row 283 (#1788) C2-01d design, draft 2 (Honker) Brief: docs/plans/2026-10-20_case2-rows.md "C2-01d" at refactor 94c33a43c. Sources: the design at agents/gosalyn/work/case2/DESIGN.md b68d79663, the ruling after r11 (:207), the M12 paragraph (:300), @@ -35,7 +35,9 @@ build waits for 282 to land (sage-2906). `editor`: - The entry takes an optional `editor`. When present, it is an object with exactly the keys `name` and `email` (via `only()`). Each value is a string that is non-empty after trim and has no control - character (`[\u0000-\u001f\u007f-\u009f]`). Anything else refuses `library-mapping-invalid`. + character (`[\u0000-\u001f\u007f-\u009f]`), `<` or `>` (webby-0169 R1: git drops them from an ident + and commits under a different name, so C2-02 would never see a failure). Anything else refuses + `library-mapping-invalid`. - The output carries `editor: { name, email }` only when present, as `user` and `vaultPrefix` do. A save with no `editor` refusing is C2-02's job. @@ -58,7 +60,7 @@ build waits for 282 to land (sage-2906). a caller bug, not a path class. - The checks run in this order, each with its own message naming the class: 1. The path must be a string of at most 1,024 UTF-8 bytes (`Buffer.byteLength`). - 2. It must have no control character, using the same class as `editor`. + 2. It must have no control character, using the same control class as `editor` (not `<` or `>`). 3. It must have no backslash. 4. It must not be absolute (a leading `/`). 5. It must have no empty, `.` or `..` segment. That also catches `//` and a trailing `/`. @@ -69,13 +71,17 @@ build waits for 282 to land (sage-2906). 7. Every proper prefix of the path (`a`, `a/b`, ...) and the path itself must not be in `tree` with mode `120000` (symlink) or `160000` (gitlink). 8. No prefix of the path, and not the path itself, may equal a tree path or a tree directory - (derived from the entries' paths) when lowercased, unless it equals that tree path exactly. + (derived from the entries' paths) after `normalize('NFC').toLowerCase()` on both sides, unless + it equals that tree path exactly. NFC as well as case, because APFS treats NFC and NFD forms of + a name as one file (webby-0169 N1). Directories are checked too, because the folders under a supporting prefix are hers to name. A path in a tree that holds both `a.md` and `A.md` refuses, which matches R7. - The refusal messages quote the path with JSON, except for the control-character class, whose message leaves the path out. - The delete rule ("A delete also needs the path to exist at the tip as a 100644 blob", M12) isn't in the brief's supportingPath list. It stays with C2-02's delete (Q4). + The C2-02 brief doesn't name it (only design :308), so BUILD.md carries it to C2-02 under Handoffs + (webby-0169 Q4). - index.mjs exports `supportingPath`. ## 4. README (packages/library/README.md) @@ -117,8 +123,8 @@ build waits for 282 to land (sage-2906). holding another universe's book. - An equal same-entry playground passes. - T3: `editor` passes, and absent passes. It refuses `library-mapping-invalid` for a non-object, an - array, an extra key, a missing key, an empty or blank value, a non-string, and a control character - in either value. + array, an extra key, a missing key, an empty or blank value, a non-string, and a control character, + `<` or `>` in either value. - scope.test, T4: - Supporting at book level, universe level and in a draft each give their universe and book. - A folder in both lists is `supporting`, and a playground-only folder is `playground`. @@ -131,7 +137,7 @@ build waits for 282 to land (sage-2906). supporting prefix, and an unknown universe; - absolute, `..`, `.`, `//`, a trailing `/`, a backslash, a C0 control and DEL; - a symlink folder, a gitlink folder, and a symlink at the path itself; - - a case-variant file and a case-variant folder; + - a case-variant file, a case-variant folder, and an NFD-form variant of an NFC tree name; - 1,025 bytes made with a multi-byte character, so bytes and characters differ. - Each asserts the code `library-write-story-path`. - business.test: T7 adds one assertion that `validateBusinessDocument` refuses @@ -146,8 +152,10 @@ build waits for 282 to land (sage-2906). | M2 | the other-universe fail for supporting is dropped | T2 | | M3 | the symlink and gitlink check is dropped | T6 | | M4 | the case check is dropped | T6 | +| M4b | check 8 drops `normalize('NFC')` | T6 NFD variant | | M5 | the byte length uses `path.length` | T6 1,025 bytes | | M6 | the `editor` control-character check is dropped | T3 | +| M6b | the `editor` `<` and `>` check is dropped | T3 | | M7 | supportingPath skips the universe match | T6 other universe | | M8 | the supporting-holds-playground check is dropped | T2 | @@ -168,3 +176,16 @@ build waits for 282 to land (sage-2906). - Q4 (Webby): the delete's 100644 check stays with C2-02? - Q5 (Webby): `editor` refuses only blank values and control characters, as the brief says. `<` and `>` would break a git ident. I'd leave them to C2-02's commit step unless you want them refused here. + +## 10. Draft 2 (webby-0169) + +- R1 folded: `editor` refuses `<` and `>` too, with T3 cases and mutant M6b. +- Q2 accepted. BUILD.md records the tradeoff: refusing a supporting prefix that holds a playground + prefix goes past the brief, but it is the fail-closed reading and uses an existing code. The cost + is that she can't nest a playground under a supporting folder, though she can nest the other way. +- Q3 accepted. Q4: carried to C2-02 under Handoffs in BUILD.md, and Sage was asked to add it to C2-02's brief. +- N1 folded into check 8 (NFC and case), with an NFD case in T6 and mutant M4b. +- N2: the survey.test:73 pin gains only `supporting`, and the count test is the only addition + (mos-1330, its own commit). +- N3: before the build, re-grep tests outside packages/library for a `deepEqual` of the mapping output + on the build base.