Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
6.7 KiB
Filbert review, row 154 round 1: changes
Candidate manifest ecaec3293be94ed968588eeb3332b6b7e23289dedbf935d06106a494495f04cb (195 paths), base 0f715a054. I reviewed and ran on 0f715a054 plus Researcher's candidate.patch. All 195 hashes match before and after every run. The packages/webui/src/public/ diff and the imported source still need Mos's decision 123 go on the candidate.
One change is requested, a single test. Everything else checks out, including the byte-for-byte rebuild.
1. Byte-for-byte rebuild: confirmed
In packages/webui, I ran:
npm ci --ignore-scripts --no-audit --no-fundfrom the package-local lock. The lock sha256 iseb60a494...f63f. It installed esbuild0.28.2, and the linux-x64 binary sha256 ise1698a3d...4100, aseditor/toolchain.mjspins.MOSAIC_REQUIRE_EDITOR_BUILD=1 node editor/toolchain.mjs, which exited 0.node editor/build.mjs --outinto my scratch.editor.jsisc601f6c3f75b7cf9898a9a52abfdab3e50badbcb5f66e57e6df57641878e6565, 757137 B;editor.cssis8654ac57d1e7a561110138ecd7f701c34a074017ff8c4cd2768d8083908ee61f.cmpshowseditor.js,editor.cssandBUILD.jsonidentical to the shipped files.- The literal
node editor/build.mjsin place. All 195 manifest hashes were unchanged afterwards.
Because the build ran from my own path, this also confirms the README's claim that builds from different absolute paths give identical bytes. esbuild printed one [ignored-bare-import] warning for import "./mark" in prosemirror-transform/src/index.ts. BUILD.md:198 discloses it, and it is harmless: mark.ts only exports functions, and transform.ts imports them directly. editor-provenance.test.mjs:159 ran rather than skipped under MOSAIC_REQUIRE_EDITOR_BUILD=1 (6/6, 0 skipped).
2. Round-trip and save tests
editor.test.mjs:32round-trips the goals review andEVERYexactly.:40asserts that every.mdunderdocs/andspec/round-trips, with CRLF normalised to LF as row 148 saves.editor-browser.test.mjs:323types into one paragraph and asserts the whole savedcontentstring. Only that block is rewritten, with the typed**escaped; the table, heading and last paragraph come back byte for byte. The body keys are row 148's{base, content, path, project}, and the second save is based on the first save's commit.:246checks that pasted image spans survive into a save only for targets the gate accepts.:154checks that pasted links and the link bar refusejavascript:,data:,vbscript:, protocol-relative and bad-host targets.- Row 148's save tests in
docs-browser.test.mjspass (1/1). Their assertions are unchanged. Theopenhelper and three waits now go through a newsource()helper that clicks Source first, which the README discloses.
3. The mode switch reuseDraft fix: correct and pinned
docView(get, project, file, { reuseDraft = false } = {}) rereads only when !s || (!dirty(s) && !reuseDraft) (bus.js:690). The mode click passes { reuseDraft: true } explicitly through render, view and docView (bus.js:744); it is not a module flag that later navigation could inherit. editor-browser.test.mjs:283 counts the reads:
- two Visual/Source round trips read nothing;
- Reload reads once;
- a switch after Reload reads nothing;
- going away and back reads once.
My m1 (drop && !reuseDraft) and m2 (click without { reuseDraft: true }) are both killed by :283 and :323.
4. The browser.test.mjs script-list pin
browser.test.mjs:22 deep-equals the page's script src list against ['/editor.js', '/brand.js', '/app.js', '/markdown-preview.js', '/bus.js'], which is order and count, not a bare count. My m4 (moving editor.js after brand.js in index.html) is killed by it. serve.mjs changes only by the two static entries (serve.mjs:26-27), and serve.test.mjs:36 serves both.
Row 129 overlap
BUILD.md's "Row 129 overlap" section matches what I expect: browser.test.mjs:22, index.html and the serve.test.mjs path list conflict textually, not semantically. Row 129 landed first, so the r2 rebase must pin all six scripts in page order and keep row 129's named /chat.js check. I'll review that delta when it comes.
Change requested
Test the Source fallback when the round trip fails. The visual editor opens only if window.MosaicEditor.roundTrip(s.text) === s.text (bus.js:703). Otherwise the file opens in Source with the note "The visual editor is not available for this file, so it is open as source." (bus.js:704). This gate is what keeps brief item 5 ("A file opened and saved with no edits saves the same bytes") true for a file nobody has tried yet. The README states the behaviour at README.md:515.
My m3 replaced the gate with visualOk = true; and survived editor-browser.test.mjs. No test opens a file that fails the round trip, because every repository doc passes it. A browser test can still reach the gate: replace window.MosaicEditor before the page opens the file, with a roundTrip that returns different text and the real mount. Then assert that #doc-text is shown, that the note is present, that no .ProseMirror exists, and that Save stays off with no edit. Covering the !window.MosaicEditor branch (editor.js failed to load) in the same test would be cheap.
Non-blocking notes
bus.js:743: when a file falls back to Source,docModestays'visual'. Clicking Visual then returns early (mode === docMode), so the button does nothing; Source still works. The behaviour is harmless, but thearia-pressedVisual button is a dead control here. The new test could pin whichever behaviour you choose.docs-browser.test.mjs: the third replaced wait dropped#doc-commit textContent !== "";source()waits only for#doc-committo exist. The#doc-committext assertion follows right after it, so a slow render could fail that test intermittently. It is not a weakened assertion.
Ran by me
Slot from sage-0792. The busy check was CLEAR before each step, the manifest was checked before and after, TMPDIR was in my own scratch, and DOCKER_HOST was a dead socket.
- Rebuild: 17:16:38Z to 17:16:39Z, as in section 1.
- Singles, 17:16:49Z to 17:17:09Z, with
MOSAIC_REQUIRE_EDITOR_BUILD=1: editor 5/5, editor-provenance 6/6, editor-browser 5/5, docs-browser 1/1, browser 1/1, serve 4/4, project-file 10/10, markdown-preview 19/19. The awk sum is 51/51, 0 skipped. - Mutants, 17:17:14Z to 17:17:42Z. The controls for editor-browser and browser passed first. m1, m2 and m4 were killed as described above. m3 (the round-trip gate) survived.
Not mine
Researcher's slot run (BUILD.md "Results"), 16:48:49Z to 16:51:57Z: webui 162/162 with MOSAIC_REQUIRE_EDITOR_BUILD=1, and Researcher's own rebuild check at 16:52Z.