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

This commit is contained in:
jason.woltje committed 2026-10-23 13:52:54 -05:00
1 parent 398314cf4d
commit 4f66dccdec
1 file changed
+28 -7
+28 -7
View File
@@ -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 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), 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`: `editor`:
- The entry takes an optional `editor`. When present, it is an object with exactly the keys `name` and - 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 `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 - 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. 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. a caller bug, not a path class.
- The checks run in this order, each with its own message naming the 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`). 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. 3. It must have no backslash.
4. It must not be absolute (a leading `/`). 4. It must not be absolute (a leading `/`).
5. It must have no empty, `.` or `..` segment. That also catches `//` and a trailing `/`. 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 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). 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 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 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. 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 - The refusal messages quote the path with JSON, except for the control-character class, whose message
leaves the path out. 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 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 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`. - index.mjs exports `supportingPath`.
## 4. README (packages/library/README.md) ## 4. README (packages/library/README.md)
@@ -117,8 +123,8 @@ build waits for 282 to land (sage-2906).
holding another universe's book. holding another universe's book.
- An equal same-entry playground passes. - An equal same-entry playground passes.
- T3: `editor` passes, and absent passes. It refuses `library-mapping-invalid` for a non-object, an - 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 array, an extra key, a missing key, an empty or blank value, a non-string, and a control character,
in either value. `<` or `>` in either value.
- scope.test, T4: - scope.test, T4:
- Supporting at book level, universe level and in a draft each give their universe and book. - 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`. - 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; supporting prefix, and an unknown universe;
- absolute, `..`, `.`, `//`, a trailing `/`, a backslash, a C0 control and DEL; - absolute, `..`, `.`, `//`, a trailing `/`, a backslash, a C0 control and DEL;
- a symlink folder, a gitlink folder, and a symlink at the path itself; - 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. - 1,025 bytes made with a multi-byte character, so bytes and characters differ.
- Each asserts the code `library-write-story-path`. - Each asserts the code `library-write-story-path`.
- business.test: T7 adds one assertion that `validateBusinessDocument` refuses - 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 | | M2 | the other-universe fail for supporting is dropped | T2 |
| M3 | the symlink and gitlink check is dropped | T6 | | M3 | the symlink and gitlink check is dropped | T6 |
| M4 | the case 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 | | M5 | the byte length uses `path.length` | T6 1,025 bytes |
| M6 | the `editor` control-character check is dropped | T3 | | 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 | | M7 | supportingPath skips the universe match | T6 other universe |
| M8 | the supporting-holds-playground check is dropped | T2 | | 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? - 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 `>` - 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. 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.