Skip to content

fix(update): repair the Windows installer tests broken by #8534 - #8548

Merged
lidge-jun merged 1 commit into
devfrom
fix/windows-installer-test-loader
Nov 11, 2026
Merged

lidge-jun merged 1 commit into
devfrom
fix/windows-installer-test-loader

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Nov 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

The dev Windows batch went red on shards 1, 3, 6 and 8 (run https://github.com/lidge-jun/opencodex/actions/runs/43000940642, head 0873b5c). #8534 caused it in two ways.

  1. The data: URL loader. update-npm-timeout and update-npm-supervisor-exit run a private, instrumented copy of src/update/npm-install.mjs from a data: URL. They rewrote only "./mutation-guard.mjs" to a file: URL. fix(update): release an interrupted Windows update marker once its supervisor is gone #8534 added "./windows-installer-marker.mjs" and "./test-home-guard.mjs" to that module, and a data: URL cannot resolve them, so every Windows supervisor case failed with Cannot find module './windows-installer-marker.mjs' from 'data:text/javascript;base64,…'.
    • The new tests/helpers/update-module-data-url.ts pins every relative ./*.mjs import to the shipped file's file: URL. It refuses a copy that still has an unpinned relative import.
    • Both test files use it.
    • A new case loads the copy on every host, so this class of break fails on Linux and macOS CI instead of only on the Windows lane.
    • Production code is unchanged: absolute system paths, no PATH search, guardedSpawn untouched.
  2. The win32 installerPid rule. fix(update): release an interrupted Windows update marker once its supervisor is gone #8534 stopped probing a recorded installerPid on win32 unless terminationUnconfirmed was set, so a marker with a live installer read free on Windows. This broke "a failed marker retains the update fence while its installer remains alive" and "prior installer marker refuses and remains untouched". confirmInstallerExit already drops the Windows supervisor pid, so a finished update leaves none for a reused pid to hold, and the rule was unnecessary.
    • The pid is probed again whenever it is present, on every platform.
    • The witness test that encoded the rule now checks the real guarantee: a finished session leaves no supervisor pid.
    • A new injected-win32 case checks that a live recorded installer keeps the marker fenced.

Refs #8524

Verification

  • Fail-first on this Mac:
    • the old mutation-guard-only loader reproduces the exact Windows error, Cannot find module './windows-installer-marker.mjs' from 'data:…';
    • with origin/dev's sync-update-mutex.mjs, "win32: a recorded live installer keeps a marker fenced" fails (free where active is expected). Both pass on this head.
  • bun test tests/update: 1046 pass, 317 skip, 0 fail. The skips are Windows-only cases and the parser-backed lint.
  • bun run typecheck, bun run privacy:scan, bun run structure:check, test-layout, the file-size ratchet and the Lab boundary all pass.

NOT RUN: the Windows shards themselves. The coordinator re-runs the dev batch after merge; this PR does not dispatch lane=all.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • Bug Fixes
    • Improved update-marker handling on Windows: a live installer process keeps a failed update marked as active, while a confirmed installer exit prevents a reused process ID from keeping the marker active.
    • Recorded installer processes are now checked across platforms.
  • Documentation
    • Clarified how installer process checks affect update markers.

The dev batch went red on four Windows shards (run 43000940642). Two causes:

- The Windows supervisor tests run a private copy of npm-install.mjs from a
  data: URL and rewrote only "./mutation-guard.mjs" to a file URL. #8534 added
  "./windows-installer-marker.mjs" and "./test-home-guard.mjs", which a data:
  URL cannot resolve. A shared test loader now pins every relative ./*.mjs
  import and refuses a copy with an unpinned one, and a new case loads the copy
  on every host so CI catches this without the Windows lane.
- #8534 stopped probing a recorded installerPid on win32 unless
  terminationUnconfirmed was set, so a marker with a live installer read free
  on Windows. confirmInstallerExit already drops the Windows witness, so the
  rule was unnecessary: the pid is probed again on every platform.

Refs #8524
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner November 11, 2026 11:44
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-11T11:45:29.846473Z 74ce592 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Nov 11, 2026
@coderabbitai

coderabbitai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Caution

Review failed

The pull request is closed.

Walkthrough

The updater now probes every recorded installer PID, including on Windows, when inspecting a marker. Tests cover confirmed installer exit, PID reuse, live installer witnesses, and private module loading through a shared test helper. The documentation reflects the Windows PID-witness rule.

Changes: Installer PID witness

Layer / File(s) Summary
Marker inspection and documented PID rule
src/update/sync-update-mutex.mjs, structure/ops/service-and-sidecars.md
At sync-update-mutex.mjs:180–182, marker inspection now probes a recorded installer PID on Windows, including when termination is confirmed. The documentation at service-and-sidecars.md:419 describes the Windows PID-witness rule.
Installer witness tests and module loading
tests/helpers/update-module-data-url.ts, tests/update/update-windows-installer-witness.test.ts, tests/update/update-npm-supervisor-exit.test.ts, tests/update/update-npm-timeout.test.ts
The Windows tests cover confirmed installer exit, PID reuse, and a live recorded installer. The shared helper loads private module copies through data URLs after rewriting relative .mjs imports; the supervisor-exit and timeout tests use it.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

  • lidge-jun/opencodex#8524 — Describes the Windows installerPid failure that this change addresses by probing recorded PIDs on every platform.

Possibly related PRs

Suggested labels: bug

Suggested reviewers: luvs01

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer judgment (bundle lane: urgent fix for the dev Windows batch)

Value. This turns the dev Windows batch green again (run 43000940642: shards 1, 3, 6 and 8 failed after #8534). It also stops this class of break from hiding behind the Windows lane.

Causes and fixes.

  1. Data: URL loader. The supervisor tests load a private data: URL copy of npm-install.mjs, and they pinned only ./mutation-guard.mjs. fix(update): release an interrupted Windows update marker once its supervisor is gone #8534 added ./windows-installer-marker.mjs and ./test-home-guard.mjs. A shared loader now pins every relative ./*.mjs import and refuses a copy with an unpinned one, and a cross-platform case loads the copy on every host.
  2. Win32 skip rule. fix(update): release an interrupted Windows update marker once its supervisor is gone #8534's rule stopped probing installerPid on win32 unless terminationUnconfirmed was set, so a marker with a live installer read free. The rule is reverted. confirmInstallerExit already drops the Windows witness, so a finished update leaves no pid for a reused number to hold.

UX change. None. Production code changes only in sync-update-mutex.mjs, where the fence gets stricter: a recorded live installer keeps it on every platform. npm-install.mjs is byte-identical.

Existing users. POSIX is unchanged. On Windows, no marker that production writes carries the reverted shape: publishWindowsInstallerPid requires terminationUnconfirmed, and confirmation drops the pid. The #8534 behavior stays: an interrupted marker frees after the fence once the supervisor is gone.

Verification.

  • Fail-first on macOS:
    • the old loader reproduces the exact Windows Cannot find module './windows-installer-marker.mjs' from 'data:…';
    • origin/dev's mutex fails the new injected-win32 live-installer case.
  • bun test tests/update: 1046 pass, 0 fail. The reviewer ran tests/update plus the layout tests and saw 1075 pass.
  • Typecheck, privacy:scan, structure:check, test-layout, the file-size ratchet and the Lab boundary pass.
  • Independent review: APPROVE, mapping each failing shard to its fix. Security review: SECURITY APPROVE; the fence only gets stricter, and the test loader cannot reach production.

NOT RUN. The Windows-only cases themselves (cmd-wrapped joins, supervisor exit, process attributes). The coordinator re-runs the dev batch after merge; this PR dispatches no lane=all.

Residual (noted). The loader's refusal regex misses a bare side-effect import "./x.mjs". Bun still fails such an import loudly on every host, so only the error message differs.

Refs #8524

@lidge-jun
lidge-jun merged commit 03a469c into dev Nov 11, 2026
28 of 30 checks passed
@lidge-jun
lidge-jun deleted the fix/windows-installer-test-loader branch November 11, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant