## Filbert review: row 112 round 2 (#1606): approve Candidate manifest sha256 `013c82c2fd99d23d92f6bed543a788aa04ff97b164019ccb15252ae808b4138e` (5 files), as named in comment 28382. I rebuilt it in my own worktree at BASE 96656dd21 with `build.patch` from packet fee89d52f. All 5 hashes match, `git diff --check` is clean, no manifest path has drifted from 96656dd21 to HEAD, and the patch's added lines have no dashes, bidi or control characters. ### What changed since round 1 Against the round 1 manifest, only `packages/bus/README.md` and `packages/bus/tests/broker.test.mjs` differ. `r1-to-r2.diff` is the whole change. `broker.mjs`, `tools.mjs` and `tools.test.mjs` keep their round 1 hashes, so my round 1 findings on them still hold. ### C1 and Sage's 28378 The `invalid-options` row now matches `broker.mjs` clause by clause: - "not an array, fewer than 2 or more than 9 options" is the `Array.isArray` and length check. - The key rule is `id()`: `text(x,160)` plus `^[a-zA-Z0-9][a-zA-Z0-9_.:/-]*$`. - The text rule is `text(o.text,1024)`: a string of 1 to 1024 characters with no NUL. - Duplicate keys is the `Set` check. The new line says an option that isn't an object with exactly `key` and `text` refuses `invalid-request`. That is what `keys(o,['key','text'],['key','text'])` does, and it matches my round 1 probe. The lead-in now says "each of these codes names one field", which is true of the three codes in the table. C1 is closed, and so is Sage's request. ### The new test The `shaped` assertions pin a bad key and empty text to `invalid-options`, and a missing `text`, an extra field and a bare string to `invalid-request`, which matches my probe table. To check that they catch a regression, I replaced the `keys(...)` call with `if (!object(o)) fail('invalid-options')`. With that change, `broker.test.mjs` gave 15 pass and 1 fail on the new test. I restored the file and rechecked all 5 hashes. ### What I ran (single files, no slot) bus: `broker` 16/16. harness: `tools` 11/11. I also ran the shape mutant above. I didn't rerun the full gate or m1 and m2. For those I relied on the packet: `gate-run.log` ends in `GATE_PASSED`, with bus at 148 pass and 0 fail, and `mutants-run.log` shows both m1 and m2 killed. The worktree is removed and no process is left in it. Verdict: **approve**.