diff --git a/agents/honker/work/queue-283/BUILD.md b/agents/honker/work/queue-283/BUILD.md index 01a73db35..052f377ab 100644 --- a/agents/honker/work/queue-283/BUILD.md +++ b/agents/honker/work/queue-283/BUILD.md @@ -109,3 +109,15 @@ on the named test and the restored file's sha256 equals the build tip's. 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. + +## 2026-10-23 Webby early look (webby-0227, static, not a verdict) + +- E1: business.test.mjs is an existing test file with a 4-line addition after the playground refusal. + The in-review request lists it next to survey.test:73. +- E3 fixed: supportingPath now runs the string check before `JSON.stringify`, so a BigInt (or any + non-string) path refuses `library-write-story-path` instead of throwing a TypeError. + supporting.test's string case now covers 7, null, undefined, 1n and an array. +- E2 open: `editor` takes surrounding whitespace, and git trims it at commit, so the saved ident and + the commit ident can differ. DESIGN.md section 1 says "non-empty after trim". Refusing + `value.trim() !== value` would change that approved rule, so it went to Sage instead of into the + build. diff --git a/packages/library/src/supporting.mjs b/packages/library/src/supporting.mjs index 246b564c2..8020899b3 100644 --- a/packages/library/src/supporting.mjs +++ b/packages/library/src/supporting.mjs @@ -16,8 +16,8 @@ const fold = name => name.normalize('NFC').toLowerCase(); export function supportingPath(mapping, universe, path, tree) { if (!Array.isArray(tree)) throw new TypeError('supportingPath needs the listTree array'); const refuse = message => { throw new LibraryError('library-write-story-path', message); }; - const at = JSON.stringify(path); if (typeof path !== 'string') refuse('the path must be a string'); + const at = JSON.stringify(path); if (Buffer.byteLength(path, 'utf8') > MAX_BYTES) refuse(`${at} is longer than ${MAX_BYTES} bytes`); if (CONTROL.test(path)) refuse('the path holds a control character'); if (path.includes('\\')) refuse(`${at} holds a backslash`); diff --git a/packages/library/tests/supporting.test.mjs b/packages/library/tests/supporting.test.mjs index 5575c42f6..a6db94241 100644 --- a/packages/library/tests/supporting.test.mjs +++ b/packages/library/tests/supporting.test.mjs @@ -64,7 +64,7 @@ test('C2-01d: malformed paths refuse by class, in order', () => { for (const c of ['\u0000', '\u0001', '\n', '\u001f', '\u007f', '\u0085', '\u009f']) assert.throws(() => supportingPath(m, 'harbor', `Book One/Notes/A${c}.md`, tree), e => e.code === 'library-write-story-path' && e.message === 'library-write-story-path: the path holds a control character'); - refuses('harbor', 7, /the path must be a string/); + for (const path of [7, null, undefined, 1n, ['Book One/Notes/A.md']]) refuses('harbor', path, /the path must be a string/); // A backslash in a path that is also absolute names the backslash: the order is fixed. refuses('harbor', '/a\\b.md', /holds a backslash/); assert.throws(() => supportingPath(m, 'harbor', 'Book One/Notes/A.md', { 'Book One/Notes/A.md': '100644' }), TypeError);