Skip to content

fix(odb): repair LF-corrupted webBrowser.openURL + string.isValidUrl (#881) - #892

Merged
jsavin merged 1 commit into
developfrom
unit-855-firstrun
Aug 11, 2026
Merged

jsavin merged 1 commit into
developfrom
unit-855-firstrun

Conversation

@jsavin

@jsavin jsavin commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Repair LF-single-node corruption: webBrowser.openURL + string.isValidUrl (#881)

Both scripts shipped in Virgin.root stored as a SINGLE outline node with embedded LF (0x0A) bytes and zero CR -- the signature of a .ut import path that skipped LF->CR normalization (full provenance: #881, #879). string.isValidUrl was hard-broken (raised a script error instead of returning a value); webBrowser.openURL failed to compile, which had transitively disabled the first-run setup-page open.

The fix

Reinstall-once through script.newScriptObject, whose first operations normalize CRLF/LF to CR and re-split the body into proper outline nodes. Because newScriptObject wraps its own compile in try{} and returns true unconditionally, each install is followed by a separate script.compile(@adr) gate that must return true -- validated against an installer-unrepairable negative control (unbalanced paren).

Verified

  • openURL: compiles, 26 nodes (was 1), zero embedded LF.
  • isValidUrl: returns true for http/file, false for javascript/non-URL (was hard-broken).
  • Scope: exactly 2 of 3061 scripts changed vs develop (mirror-drift confirmed); firstRootRun untouched (still false); no stray table/pref/script mutation.
  • .ut mirrors re-synced (verify_virgin_root_sync.sh --full: 3061/3061).
  • Full integration suite: 2488 total / 0 failed. Gate: bar-raiser CLEAN (no findings; compile-gate negative control reproduced independently).

Scope note

This is the LAST sanctioned direct binary edit of Virgin.root. Subsequent shipped-root changes move to the source-tree build pipeline (planning/ROOT_BUILD_FROM_SOURCE_PLAN.md).

Follow-up (NOT in this PR)

The firstRootRun=true flag flip is deferred to a separate unit that must carry the #891 browser-suppression shim -- a live openURL now executes the setup-page browser open, which must not launch a host GUI browser in headless/test contexts.

Fixes #881. Unblocks the #865 setup-page-open path. Related: #855, #879, #891.

https://claude.ai/code/session_01SEFFEgkaQJayd48Y2iuNkx

… and string.isValidUrl

Both scripts were stored as a single outline node with embedded LF (0x0A)
bytes and zero CR -- the signature of a .ut import path that skipped LF->CR
normalization. string.isValidUrl was hard-broken: calling it raised a script
error rather than returning a value.

Repair is a reinstall-once through script.newScriptObject, whose first
operations normalize CRLF and LF to CR, re-splitting the body into proper
outline nodes.

Compile gate: script.newScriptObject wraps its own compile in try{} and
returns true unconditionally, so its return value cannot verify a repair.
Each install is therefore followed by a separate script.compile(@adr) call
that must return true. The gate was validated against an
installer-unrepairable negative control (unbalanced open paren, which
auto-close-braces cannot fix): newScriptObject returned true while the
independent script.compile correctly failed.

Verification, both scripts, in a fresh process after save:
  - zero LF bytes; CR counts 15 (isValidUrl) and 26 (openURL)
  - script.compile returns true
  - isValidUrl("http://example.com") -> true
  - isValidUrl("file:///tmp/x.html") -> true
  - isValidUrl("javascript:alert(1)") -> false
  - isValidUrl("notaurl") -> false
Before the repair the first of these was a script error, not false.

The .ut mirror was re-synced from the repaired ODB via
verify_virgin_root_sync.sh --rewrite. The resulting diff is one line per
file: the first comment node moves from depth 2 to depth 1. The .ut files
carried an illegal +2 indentation jump directly under a depth-0 handler;
re-splitting produced the well-formed structure. No code lines changed and
both files remain pure ASCII (no MacRoman round-trip damage, per #880).
verify_virgin_root_sync.sh --full: all 3061 files match.

user.prefs.firstRootRun is deliberately LEFT AT false. Flipping it was
tested on a scratch copy and reproduced exactly the 9 failures #855
predicts across startup_script_execution, webserver_hello_world and
webserver_inetd_e2e. Root-caused to stale pathString, not test design:
Frontier.pathString in Virgin.root still points at
.claude/worktrees/menu-port-phase-c-bridge/databases/, a worktree that no
longer exists, so Frontier.getSubFolder() fails with "Can't create folder".
That is the #859 pathString bug, which is not yet merged into this base.
The same three suites pass 23/23 with these repairs and the flag left
false, isolating the two variables cleanly. The flag flip should land as a
follow-up once #859 is merged.

Full integration suite: 2482 total, 2302 passed, 163 skipped, 0 failed
(17 baselined known-failures, all pre-existing and unrelated).

Per the maintainer decision of 2026-08-11, this is the last sanctioned
direct binary edit of Virgin.root; subsequent shipped-root changes move to
the sources/ pipeline described in planning/ROOT_BUILD_FROM_SOURCE_PLAN.md.

Virgin.root: dd491bd16ccb8b3dfb478acc77375387 (17011793 bytes)
         -> d9dbf48121c452b31b2c41ace188e679 (18219590 bytes)
Growth is ODB append-on-save; no db.compactDatabase was run (#854).

Refs #881, #865, #855, #859
@jsavin

jsavin commented Aug 11, 2026

Copy link
Copy Markdown
Owner Author

Gate: CLEAN (bar-raiser, repairs-only)

Single-reviewer gate appropriate: data repair, no C/logic/network/threading surface. Full suite 2488/0 failed at rebased HEAD.

Bar-raiser verified independently (read-only): scripts match pre-corruption intent (parent-commit mirrors byte-identical on every code line; only the illegal comment-node depth 2->1 corrected); compile-gate soundness reproduced (negative control surfaces hard failure while newScriptObject reports true unconditionally); scope decisive (exactly 2 of 3061 scripts drift vs develop, firstRootRun untouched, no stray mutation); deref-read false-zero trap confirmed real, indexed-read used throughout.

Verdict: approve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LF-single-node script corruption in Virgin.root (embedded LF, zero CR); webBrowser.openURL root cause, #855 unblocker

1 participant