row 283 (#1788): BUILD.md: drift check, N3 grep, mos-1330 :73 old and new text, Q2 tradeoff, Q4 handoff to row 288 via #1793 c30738, mutants M1-M8 exact strings, gate plan; doc only
This commit is contained in:
1 parent
28918824ca
commit
bd2c1c4ea1
1 file changed
+111
@@ -0,0 +1,111 @@
|
||||
# Row 283 (#1788) C2-01d build notes (Honker)
|
||||
|
||||
Append-only. Design: DESIGN.md d2 16e809457, APPROVE webby-0172. Gate owner Sage, reviewer Webby.
|
||||
|
||||
## 2026-10-23 build on 45dca69f6 (sage-3577)
|
||||
|
||||
Branch honker/row283-build from origin/refactor 45dca69f6e4bce52834587f66f2ff33ba839ab8a. The old branch
|
||||
honker/row283 (16e809457) held only the design, so its two commits were cherry-picked as 398314cf4
|
||||
(d1) and 4f66dccde (d2). The DESIGN.md blob equals 16e809457's.
|
||||
|
||||
Commits:
|
||||
- 331653b38: code, README and tests T1-T8.
|
||||
- 28918824c: the survey.test:73 re-pin, alone (mos-1330 item 4).
|
||||
- this file.
|
||||
|
||||
Nothing has run. No node, test or mutant ran during the build: Darkwing held the slot. Every count
|
||||
below is a plan until Sage's CLEAR.
|
||||
|
||||
### Drift check (sage-3577)
|
||||
|
||||
`git diff --stat 94c33a43c 45dca69f6` (design base to build base) over the paths the tests read or
|
||||
hash-pin:
|
||||
- No change in packages/library, packages/business/src/business.mjs or
|
||||
packages/business/tests/business.test.mjs.
|
||||
- No test hash-pins a library file. bus library.test and library-sync.test import index.mjs, and
|
||||
stack-copy.test only checks that index.mjs exists.
|
||||
- webui library-cli.test changed one line and doesn't read scope. The `classify` in webui reads.mjs is
|
||||
the business one, not the library's.
|
||||
|
||||
I redo the drift check on BASE..refactor before the in-review move.
|
||||
|
||||
### N3 (webby-0169): deepEquals of the mapping output outside packages/library
|
||||
|
||||
`git grep -n playground -- 'packages/*/tests/*' ':!packages/library/*'` and the files naming
|
||||
`universes` give two files:
|
||||
- business.test.mjs:20 compares `validateBusinessDocument(...).projects.books` with
|
||||
`checkMapping(mappingEntry())`. That is output against output, so `supporting: []` shows up on both
|
||||
sides. :27 compares only `.playground`.
|
||||
- library-projects-protected.test.mjs compares file bytes (:31, :32) and change paths (:58), never the
|
||||
mapping output.
|
||||
|
||||
No re-pin is needed outside library. Inside library, only the draft deepEqual at mapping.test:48 gains
|
||||
`supporting: []`, as the design says.
|
||||
|
||||
### Q1 departure (sage-2923) and the :73 re-pin (mos-1330 item 4)
|
||||
|
||||
survey.mjs:65 counts `supporting: 0` and formatSurvey prints it. T8 is the only added test
|
||||
(survey.test "C2-01d: with --mapping the survey counts supporting files").
|
||||
|
||||
mos-1330 item 4, packages/library/tests/survey.test.mjs:73, commit 28918824c:
|
||||
- old: `'scopes canon 5, playground 1, unmapped 3; indexed 6',`
|
||||
- new: `'scopes canon 5, playground 1, supporting 0, unmapped 3; indexed 6',`
|
||||
|
||||
N2: the pin gains only `supporting 0`. No other text on the line or in that test moved.
|
||||
|
||||
### Q2 tradeoff (webby-0169)
|
||||
|
||||
A supporting prefix that holds a playground prefix refuses `library-mapping-invalid`. That goes past
|
||||
the brief, but it is the fail-closed reading, and it uses an existing code: classify checks supporting
|
||||
first, so that playground prefix could never match. The cost is that she can't nest a playground under
|
||||
a supporting folder, though she can nest the other way (a playground holding a supporting folder).
|
||||
|
||||
### Handoffs
|
||||
|
||||
- Q4 (webby-0169, sage-2930): the M12 delete rule ("A delete also needs the path to exist at the tip as
|
||||
a 100644 blob", case2 DESIGN.md :308) is not in supportingPath. It binds row 288 (C2-02) via Gitea
|
||||
#1793 comment 30738, with tests for a missing path and a non-100644 entry.
|
||||
- A save with no `editor` refusing is C2-02's (DESIGN.md section 1).
|
||||
|
||||
### Choices the design left open
|
||||
|
||||
- The book loop is now `againstBooks(owners, list, code)` in mapping.mjs, called once per list. The
|
||||
playground's messages and codes are byte-equal to before.
|
||||
- A non-string path refuses `library-write-story-path` ("the path must be a string") as part of
|
||||
check 1. A non-array `tree` is a TypeError (DESIGN.md section 3).
|
||||
- Check 8 builds the tree's names as every path and every folder above it, keyed by
|
||||
`normalize('NFC').toLowerCase()`. A name on the way refuses if its key holds any name other than
|
||||
itself, so a tree that already holds case twins refuses a write to either (R7).
|
||||
|
||||
### Mutants (exact strings)
|
||||
|
||||
Each applies one replacement to the build tip. Run one at a time, and restore with `git checkout --`
|
||||
on the one file before the next.
|
||||
|
||||
| Mutant | File | Replace | With | Killed by |
|
||||
|---|---|---|---|---|
|
||||
| M1 | src/scope.mjs | `const prefix = entry.supporting.find(p => inside(p, path));` | `const prefix = entry.supporting.find(p => inside(p, path) && !entry.playground.some(q => inside(q, path)));` | scope.test "supporting comes before playground", supporting.test "passes at book level" (both-lists path) |
|
||||
| M2 | src/mapping.mjs | `if ((inside \|\| holding) && owner !== id)` | `if ((inside \|\| holding) && owner !== id && list !== 'supporting')` | mapping.test "each supporting prefix rule", business.test C2-04 |
|
||||
| M3 | src/supporting.mjs | `for (const p of own) if (LINKS.has(modes.get(p)))` | `for (const p of own) if (false && LINKS.has(modes.get(p)))` | supporting.test "symlink or gitlink" |
|
||||
| M4 | src/supporting.mjs | `const fold = name => name.normalize('NFC').toLowerCase();` | `const fold = name => name.normalize('NFC');` | supporting.test "case or Unicode form" |
|
||||
| M4b | src/supporting.mjs | `const fold = name => name.normalize('NFC').toLowerCase();` | `const fold = name => name.toLowerCase();` | supporting.test "case or Unicode form" (NFD case) |
|
||||
| M5 | src/supporting.mjs | `Buffer.byteLength(path, 'utf8') > MAX_BYTES` | `path.length > MAX_BYTES` | supporting.test "1025 bytes" |
|
||||
| M6 | src/mapping.mjs | `const IDENT_BAD = /[\u0000-\u001f\u007f-\u009f<>]/;` | `const IDENT_BAD = /[<>]/;` | mapping.test "editor is optional" |
|
||||
| M6b | src/mapping.mjs | `const IDENT_BAD = /[\u0000-\u001f\u007f-\u009f<>]/;` | `const IDENT_BAD = /[\u0000-\u001f\u007f-\u009f]/;` | mapping.test "editor is optional" |
|
||||
| M7 | src/supporting.mjs | `if (place.scope !== 'supporting' \|\| place.universe !== universe)` | `if (place.scope !== 'supporting')` | supporting.test "outside the universe's supporting folders" |
|
||||
| M8 | src/mapping.mjs | `if (sid === pid && s !== p && holds(s, p))` | `if (false && sid === pid && s !== p && holds(s, p))` | mapping.test "each supporting prefix rule" (Workshop case) |
|
||||
|
||||
(The `\|` in the table is an escaped `|` in the source text.) Each mutant runs the one test file named,
|
||||
plus business.test for M2, under `timeout -k 10 600`. A mutant passes the gate only when its run is red
|
||||
on the named test and the restored file's sha256 equals the build tip's.
|
||||
|
||||
### Gate plan (on Sage's CLEAR)
|
||||
|
||||
1. The touched files whole, each under `timeout -k 10 600`: library mapping, scope, supporting and
|
||||
survey tests, and business.test.mjs. Counts go below.
|
||||
2. M1-M8 as above.
|
||||
3. The full gate, under mos-1275 timeouts: `node --test packages/library/tests/` and
|
||||
`node --test packages/business/tests/` each under `timeout -k 10 1800`, and every scripts/test-*.sh
|
||||
under `timeout -k 10 300`. pipefail and tee, with skips named (test-task Docker groups).
|
||||
4. Before in-review: grep packages/*/tests for a 64-hex pin on any changed file and for the changed
|
||||
message text, then the drift check on BASE..refactor.
|
||||
Reference in new issue
Block a user