Files
2026-10-23 18:15:16 -05:00

8.3 KiB

Row 322 / #1818 — F8 and F9

Goldie, 2026-10-23. Branch goldie/row322, base 833ec1cc8d. Brief: docs/plans/2026-10-23_host-fixes-1816-brief.md, F8/F9 section at 7333f94ba9. Issue #1818 is supplied by Sage; no new issue is needed. Reviewer Morgana; Sage owns landing/full gate.

Implementation and authority

F8 runs the importer from $COPIES/$COMMIT/scripts/case2-persona-import.mjs. This uses Node's normal ESM resolution, finding yaml beside the copy and the relative harness module in that same commit. It avoids a custom loader or ambient resolution setting. The copy closure already includes harness/src and business/src, but omitted the importer itself; COPY_PATHS now includes that one script. No new dependency or dependency version change.

F9 selects the first line beginning with an Error type (including TypeError etc.) or ERR_, falling back to the last line for the importer's handled refusal. awk exits after the first matching line and emits exactly one line, keeping the stack and version banner out of the install refusal. Anchoring avoids selecting Node's earlier throw new ERR_MODULE_NOT_FOUND(...) source excerpt instead of the actual Error line.

Mos-1550 authorizes the copy-path addition, setup-only additions to world(t), and adding the single new filename to any existing copy-file pin. Existing test edits outside the appended row-322 block:

  • case2-install.test.mjs: the fake stack-copy setup gains a loop copying the importer, harness bundle.mjs/tools.mjs, and business vocabulary.mjs; it copies yaml into the fake copy's node_modules. The existing last template-string line is extended to add those setup commands. No existing assertion changes.
  • packages/webui/tests/pinned-copy.test.mjs:76: the scripts file-list assertion gains only case2-persona-import.mjs, in sorted order. No other change in this test.

The new append-only block builds a scratch clone outside the repository with no node_modules, real installer and importer, stubbed bootstrap/business validation, and a copy with the real importer, relative module closure and yaml. F8 checks installed persona bytes/mode; F9 removes yaml from that copy to produce a real uncaught Node missing-package error, then checks one refusal line carries the cause and no stack/banner. Existing tests missed F8 because the real importer ran from the development checkout, which has yaml installed; the fake copy held only scripts/mosaic. The old fixtures thus never exercised the dependency boundary or an uncaught importer load error.

Class check and copy-test audit

Before change:

grep -n 'node "$REPO/' scripts/case2-install.sh scripts/case2-precheck.sh scripts/stack-copy.sh
scripts/case2-install.sh:185:        out="$(node "$REPO/scripts/case2-persona-import.mjs" ...

After change: same grep has no hits (exit 1). Direct clone-side .mjs entry points in the three scripts with a bare package import: scripts/case2-persona-import.mjs → yaml, moved to the copy by F8. No other direct entry point imports a bare package. Precheck's inline Node programs dynamically import cli/src/config.mjs, business/src/index.mjs, library/src/index.mjs and cli/src/cli.mjs; those entry files import builtins/relative modules only. Library reader.mjs uses its own front-matter parser and has no yaml import. stack-copy sources instance.sh, whose mosaic-config.mjs imports builtins only. Installer bootstrap likewise runs mosaic-config.mjs, and business validation runs business/src/cli.mjs, also no direct bare imports. No other product fix made.

Audit commands (read-only):

rg -n 'COPY_PATHS|copy carries|copy.*(hash|sha256|files|file set)|sha256.*copy' packages/*/tests/* scripts/test-*.sh
rg -n 'COPY_PATHS|stack-copy\.sh|readdirSync|sha256|deepEqual' packages/webui/tests/pinned-copy.test.mjs packages/cli/tests/stack-copy.test.mjs

Relevant hits: cli/tests/stack-copy.test.mjs:35-47 checks harness file closure (positive control: COPY_PATHS at :36), :52 asserts a required-file subset, :248-264 computes hashes/modes and compares bundle/check-out copy trees dynamically, :274 compares another bundle tree. None freezes a complete path list/hash. webui/tests/pinned-copy.test.mjs:75 pins top-level entries (unchanged), :76 pins scripts' exact file set (approved one-path update). Other readdir hits in those files check cleanup/existing-target behavior, not COPY_PATHS identity. Broad initial grep also hits business/tests/helpers.mjs:33, cli/tests/stack-upgrade.test.mjs:295, webui/tests/views.test.mjs:172, cli/tests/stack-release.test.mjs:1751 and :1987; inspected contexts are unrelated comments/UI copy or different fixture copies. No scripts/test-*.sh hit for these path/hash patterns.

Verification plan

Pending Sage CLEAR before any test: run new tests on fixed build first, then whole case2-install.test.mjs, whole stack-copy.test.mjs and webui pinned-copy.test.mjs. Demonstrate expected failure at 094124b4e with new block applied (baseline importer path), and kill the $REPO reversion mutant. Record all outcomes. First unexpected new-test red is recorded/reported under mos-1272; existing-test edits outside mos-1550 or a second unexpected red stop for Sage.

No tests run yet. No commit/push yet. No host changes, live state, secrets, deploy or release actions.

Verified results — sage-3808 CLEAR, 2026-10-23T22:47Z

All runs were serialized with TMPDIR=/mnt/storage/scratch/tmp/goldieuQ2664 (created by mktemp -d /mnt/storage/scratch/tmp/goldieXXXXXX), using timeout -k 10 90 for focused tests and timeout -k 10 180 for whole files/negative-proof driver. Node v26.8.1. Dependencies were read through the ignored, uncommitted node_modules symlink approved by sage-3804; each scratch clone had no node_modules. No /tmp fixture was used.

Run Result Evidence
New tests, first run 2/2 pass, exit 0 test-new.log
Whole case2-install.test.mjs 26/26 pass, exit 0 test-install.log
Whole stack-copy.test.mjs 18/18 pass, exit 0 test-copy.log
Whole webui pinned-copy.test.mjs 10/10 pass, exit 0 test-pinned-copy.log
Installer from 094124b4e, new tests 0/2 pass, exit 1, expected red baseline-094124b4e.log
F8 mutant: restore $REPO importer path only 0/1 pass, exit 1, killed mutant-F8.log
F9 mutant: restore tail-only refusal only 0/1 pass, exit 1, killed mutant-F9.log
Fixed installer restored, new tests rerun 2/2 pass, exit 0 test-restored.log

The baseline proof temporarily installs the exact installer bytes from git show 094124b4e:scripts/case2-install.sh, retaining the newly appended tests and approved fixture setup. Relevant installer/importer/copy/test source paths have no changes between N and the branch base 833ec1cc8 (git diff 094124b4e 833ec1cc8 -- those paths is empty). It is a targeted baseline proof, not a full checkout/suite run at N. Baseline failures show persona-import: Node.js v26.8.1; the F8-only mutant exposes the underlying Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'yaml' from the scratch clone. F9-only mutant again prints the banner. All expected failures are deliberate acceptance checks; no unexpected first-run red occurred.

negative-proof.py records each run, checks the expected failure count/exit, restores in a finally block, and verifies fixed installer bytes after each run. Restored SHA-256 each time: c23a08324528cc29895014093c661948a5c8eb40316c7b2e21c6f833cf5d6462. Final focused green confirms restoration. git diff --check passed.

git diff --numstat -- packages/cli/tests/case2-install.test.mjs: 57 additions, 1 deletion. Outside the new appended block, original line 70's template-string close moves after four new setup lines: the existing mkdir/empty mosaic/echo command is unchanged, followed by the for file ... line, mkdir/cp loop body, done, and mkdir/cp yaml line. All pre-existing assertions remain byte-for-byte unchanged. The only pre-existing assertion edit anywhere is the expressly approved one-filename addition at packages/webui/tests/pinned-copy.test.mjs:76.

Sage's full package/script gate and Morgana's review remain pending. This builder ran only the approved three whole test files and targeted acceptance checks. Sage retains queue transition/review posting and integration authority; no PR was created by Goldie.

Evidence log lines have trailing whitespace removed for git diff --check; test content and outcomes are unchanged.