Skip to content

fix(link): keep Windows containment refusal at 126; correct the #8100 fan-out test fixture - #8106

Merged
lidge-jun merged 7 commits into
devfrom
goat/fix-dev-batch-8100-windows
Nov 2, 2026
Merged

lidge-jun merged 7 commits into
devfrom
goat/fix-dev-batch-8100-windows

Conversation

@lidge-jun

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

Copy link
Copy Markdown
Owner

Summary

Fixes the two Windows shards that turned the dev batch red at 09b558580 (run 41462914814). Both come from #8100 (4948c04d9). The last tree before it (be51cb817, run 41455278872) was green on every platform.

windows 10/11: an uncontainable Windows ocx exited 1 instead of 126 (product fix). #8100 sent every Windows remote command deflated and inflated it on the Child ([IO.MemoryStream]::new, DeflateStream, then Invoke-Expression) before the containment helper and its Fail → exit 126 existed, outside any try. Constrained Language Mode, the AppLocker/WDAC case structure/remote-link.md names, blocks those types, so the session ended with 1. The Home reads 1 as an ordinary ocx failure; 126 is what classifySyncResult maps to child-ocx-not-contained. Nothing ran uncontained, but the refusal was misreported. packedPowerShellArgv now guards the inflate alone with $ErrorActionPreference='Stop'; try{…}catch{…; exit 126}. Invoke-Expression stays outside the guard, so the inflated script's own errors and exit codes pass through unchanged. The encoded commands grow by 416–420 characters (native 5,320 → 5,736, discovery 5,820 → 6,240, pinned sync 6,924 → 7,344, all under the 8,000 limit).

windows 2/11: the new fan-out test's fixture was wrong on Windows (test fix, no product change). tests/cli/sync-command-fanout.test.ts "local-only JSON does not invoke ssh" was added by #8100 and timed out at 15 s with empty stdout. Evidence that the fixture is at fault:

The log discarded the child's stderr, so the exact blocking operation was not observed. The Windows dispatch on this head is the check. CLI children in this file now get the inherited environment with temp homes, the owned-service-home fixture, a delimiter-correct PATH, a 12 s spawn timeout under the 15 s case budget, and the child's stderr in the failure message. "No ssh" is now proven on every platform: a new test-only preload (tests/helpers/ssh-spawn-sentinel-preload.ts) stops Bun.spawn/Bun.spawnSync of ssh/ssh.exe and records the attempt. Positive controls check both APIs, pass-through, and that the Windows service fixture still answers beside it. A new in-process case shows --local-only never reaches link status, the SSH runner or a Child process, even with a committed catalog and a connected link. Its positive half shows the same spies are reached without the flag. The subprocess case also pins the Home outcome its fixture is built for ({state: "failed", exit: 1} with the Codex-home refusal on stderr). No assertion was removed and no timeout was raised.

CI shard balance (requested after PR test 4/4 at 7f4924ec4 hit the 15-minute cap with no failing test). The cancelled shard's merge with dev ran tests/update/update-orchestrated-entry.test.ts (#8103) for 98 s. Like every other file #8099, #8100, #8103 and #8104 added, it had no recorded duration and weighed the 176 ms median, so the shard predicted 728 s and ran 852 s of tests. Both tables are refreshed with scripts/ci/test-durations.ts, as #8102 did. Linux/macOS: batch run 41462914814 (Linux and macOS shards) plus the Linux shards of PR runs 41485932590, 41482553737 (#8103) and 41483744349 (#8104). Every test file now has a row, and the four Linux shards predict 716 s each. Windows: run 41462914814's eleven shards. The #8103/#8104 files and three files from the two stopped shards have never run on Windows, so they still weigh the median there. The branch merges origin/dev (e4ced1838) so those rows exist. One #8100 case waited out the production ten-second watchdog ("a version writer ignoring signals is killed…"). It now runs the same script with a one-second watchdog and asserts the shipped script keeps sleep 10, so it takes 1.4 s instead of about 10.4 s.

structure/remote-link.md now describes whole-script packing and when 126 happens, which is also the stale comment #8100 left behind.

Plan and audit trail: devlog/_plan/261103_fix_8100_windows_batch/010_plan.md.

Verification

  • Focused, on the final head: bun test tests/cli/sync-command-fanout.test.ts tests/clients/link-ssh-argv-discovery.test.ts tests/clients/link-pinned-sync-argv.test.ts tests/ci-workflows/ci-shard-balance.test.ts tests/test-layout.test.ts: 62 pass, 14 skip (Windows-only), 0 fail. sync-command-fanout: 11 pass (macOS). Removing the localOnly short-circuit in runHomeFanout fails both the subprocess case and the new in-process case.
  • bun test tests/clients/link-ssh-argv-discovery.test.ts tests/clients/link-pinned-sync-argv.test.ts: pass on macOS. The Windows-only cases skip: two new Constrained Language Mode cases (discovery and pinned sync) and the new post-inflation error case.
  • bun run typecheck, bun run structure:check, bun run privacy:scan: pass.
  • bun scripts/test.ts --changed=dev --parallel=1: the default run hit the harness's 900 s whole-run cap with 15,746 passes and 0 failures. Rerun with OCX_TEST_MAIN_TIMEOUT_MS=3600000 (a local wall-clock cap, not a test timeout): 33,691 tests across 1,459 files, 26 failures. All are server/proxy cases that block for 5–20 s on this shared, loaded host. None is in the link or sync area. They flake either way: an A/B rerun of combo-replay-refusal-attribution with dev's remote-windows.ts failed once and passed once, and so did this branch, and server-search fails the same two cases on dev's file. The four full Ubuntu shards (ci:full) ran the same suites and passed on this PR.
  • Windows dispatch, the one authorized run, on 1800b4d7f: run 41491122166. Every case this PR targets passed: "a Windows ocx that cannot be contained in a kill-on-close job is refused before it runs" (184 ms), both new Constrained Language Mode cases, the post-inflation error case, the exit-23/stdin, Desktop-first discovery, kill-on-close and pinned-sync success paths (windows 1/11, 4/11), and "local-only JSON does not invoke ssh" (711 ms, was a 15 s timeout), together with the sentinel controls (windows 3/11). Linux test 1/4–4/4 passed in 710–812 s and macOS 1/4–4/4 in 660–928 s. Four Windows shards are red, none in code this PR changes:
    • windows 7/11: tests/update/update-bun-ownership-lease.test.ts "… replaces only the package and releases its lease" (Installer termination was not confirmed).
    • windows 10/11: tests/update/update-orchestrated-identity.test.ts "identity requires a stable, attested runtime record" (POSIX fixture paths, kind: "unknown").
    • Both come from feat(update): orchestrated ocx update plan/apply contract (update.orchestrated/1) #8103, which reached dev after the last Windows batch, so this was their first Windows run. They will fail the next dev batch whether or not this PR merges.
    • windows 8/11: tests/claude-integration/claude-intercept-acl-barrier.test.ts. It sets OPENCODEX_ACL_TIMEOUT_MS=1000, and both cases ended at that budget during a runner icacls stall. It passed in 220 ms in run 41462914814.
    • windows 9/11: cancelled at the 30-minute job cap, with no failing test. The shard predicted 1,324 s, and its completed files ran 1,403 s against 1,251 s recorded. The heaviest Windows files ran slow, for example codex-cli-update-windows-apply-install at 216 s against 153 s. Eleven Windows shards at about 22 minutes of predicted tests leave little headroom under 30.
    • Per the batch policy, none of these was re-dispatched.
  • Reviews (Terra, gpt-6.1-terra high): plan audit PASS after three rounds, code review PASS, security review PASS-WITH-NITS (the documentation nit is fixed in 9ed997ac4), fresh final approval APPROVE on 7f4924ec4. CodeRabbit: two findings adopted in 7f4924ec4. The third, the containment message being silent under Constrained Language Mode, is rebutted in its thread as pre-existing and outside this fix; a specific enrollment message for 126 is a possible follow-up.

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.

…n-out test fixture

#8100 packed every Windows remote command and inflated it before the
containment helper existed, outside any try. A Child whose PowerShell
runs in Constrained Language Mode could not inflate it and exited 1,
which the Home reads as an ordinary ocx failure. Guard only the inflate
so it exits 126; Invoke-Expression stays outside the guard so the
inflated script's own errors and exit codes pass through.

The new local-only fan-out test spawned the CLI with a stripped POSIX
environment (no SystemRoot, a ':' PATH, a sh-script ssh) and without the
owned-service-home preload that keeps Codex write admission away from the
runner's real Task Scheduler. It timed out on Windows and could not prove
"no ssh" there at all. Give CLI children the inherited environment and
the owned-service-home fixture, add a Bun-spawn ssh sentinel with
positive controls, and prove local-only in process as well.
@lidge-jun lidge-jun added the ci:full Run the four full Ubuntu test shards on this pull request label Nov 2, 2026
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner November 2, 2026 15:50
@chatgpt-codex-connector

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

Copy link
Copy Markdown

Codex Review Summary

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

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-02T15:52:40.437177Z 9ed997a 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 github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • empty_catch — An empty catch block was added. Handle, report, or deliberately propagate the error. Paths: devlog/_plan/261103_fix_8100_windows_batch/010_plan.md.

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

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 7f4924e and 1800b4d.

Files ignored due to path filters: 2
  • scripts/ci/test-durations.tsv is excluded by !**/*.tsv
  • scripts/ci/test-durations.windows.tsv is excluded by !**/*.tsv
Files selected for processing: 1
  • tests/clients/link-pinned-sync-argv.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Walkthrough

The Windows packed PowerShell command now treats inflation failures as containment refusals with exit status 126, while leaving script execution outside the catch. Sync fan-out tests now use a controlled child-process environment and SSH spawn sentinel, and check --local-only behavior in-process.

Changes: Windows packed-script containment

Layer / File(s) Summary
Inflation error handling and coverage
src/link/remote-windows.ts, structure/remote-link.md, tests/clients/link-ssh-argv-discovery.test.ts, tests/clients/link-pinned-sync-argv.test.ts, devlog/_plan/261103_fix_8100_windows_batch/010_plan.md
packedPowerShellArgv catches failures while decoding and reading the inflated script, then exits with status 126. Invoke-Expression remains outside the catch. The documentation describes the Windows command behavior. Windows tests cover containment refusal, script errors, and the pinned-sync watchdog. The plan records regression cases and verification steps.

Sync fan-out test isolation

Layer / File(s) Summary
Child-process harness and SSH sentinel
tests/cli/sync-command-fanout.test.ts, tests/helpers/ssh-spawn-sentinel-preload.ts, devlog/_plan/261103_fix_8100_windows_batch/010_plan.md
Subprocess tests use an inherited environment, an owned service-home preload, and a 12-second timeout. The sentinel records and rejects SSH launches through Bun.spawn and Bun.spawnSync. The local-only and damaged-link-store tests use the shared runner. The plan records the fixture changes and verification steps.
Local-only fan-out assertions
tests/cli/sync-command-fanout.test.ts
An in-process test compares behavior with and without --local-only. Without the flag, status lookup, the SSH runner, and a child process are reached. With the flag, only Home sync runs and JSON reports fan-out disabled.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Possibly related issues

  • lidge-jun/opencodex#7297: The issue requests durable diagnostics for Remote Link failures. This change assigns a distinct exit code to Windows containment refusals but does not add durable logging.

Possibly related PRs

Merge Risk: Low · up to 1800b

Windows constrained-language failures can still lack the documented refusal explanation, but the core containment exit code and fan-out test behavior are otherwise preserved.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies both primary changes: preserving Windows containment refusal exit code 126 and correcting the #8100 fan-out test fixture.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 5 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • 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

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed.

Hygiene

✅ Deterministic PR hygiene checks passed.

@github-actions
github-actions Bot marked this pull request as draft November 2, 2026 15:51
@github-actions github-actions Bot removed the intake: hygiene-blocked Deterministic PR hygiene checks failed label Nov 2, 2026
@github-actions
github-actions Bot marked this pull request as ready for review November 2, 2026 16:02

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/link/remote-windows.ts Resolved
Comment thread tests/cli/sync-command-fanout.test.ts Resolved
…ors out of 126

Address review: the local-only subprocess case now asserts the Home outcome its fixture is built for, and a Windows case shows an error raised by an inflated script keeps its own exit instead of the containment refusal (packedPowerShellArgv is exported for it).
… and shorten the pinned-sync watchdog case

PR test 4/4 at 7f4924e hit the 15-minute job timeout (job 125416446261) with no failing test. Its
merge with dev ran tests/update/update-orchestrated-entry.test.ts (#8103) for 98 s, and like the
other files #8099, #8100, #8103 and #8104 added it had no recorded duration and weighed the 176 ms
median: the shard predicted 728 s and ran 852 s of tests.

Both tables are refreshed with scripts/ci/test-durations.ts. Linux/macOS: run 41462914814 (dev
09b5585, Linux and macOS shards) plus the Linux shards of pull_request runs 41485932590,
41482553737 (#8103) and 41483744349 (#8104); every test file now has a row and the four Linux
shards predict 716 s each. Windows: run 41462914814's eleven shards; the #8103/#8104 files and
three files of the two stopped shards have no Windows measurement yet and still weigh the median.

The POSIX "version writer ignoring signals" case waited out the production ten-second watchdog. It
now runs the same script with a one-second watchdog and asserts the shipped script keeps
"sleep 10": the case drops from about 10.4 s to 1.4 s.
@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer integration into dev (MAINTAINERS.md maintainer-integration exception), requested by @lidge-jun. This fixes #8100's two failures in the batch run 41462914814. This is integration, not a self-approval or an independent review.

Exact-head verification for 1800b4d7f13067cf07dd3ab651372f04be7ab990:

  • PR CI with ci:full: every reported check passed (19), including the four Ubuntu shards. With the refreshed duration tables, those shards now predict about 716 s each.
  • Windows dispatch on this exact head, the one authorized run: 41491122166. Every case this PR targets passed natively. The uncontainable-ocx refusal exits 126 (184 ms), and both new Constrained Language Mode cases pass. "local-only JSON does not invoke ssh" now passes in 711 ms; it used to time out at 15 s.
  • The Windows shards still red in that run are outside this diff. Two #8103 update tests fail on Windows (7/11, 10/11). A Claude ACL test hit its 1 s icacls budget during a runner stall (8/11). Shard 9/11 hit the 30-minute job cap with no failing test. A follow-up lane will fix these before the next batch.
  • Reviews (Terra): plan audit PASS, code review PASS, security review PASS-WITH-NITS (nit fixed in 9ed997ac4), fresh final APPROVE on 7f4924ec4. Since then the branch only merged dev (feat(update): orchestrated ocx update plan/apply contract (update.orchestrated/1) #8103, Normalize upstream error details in request logs and Retry-After advice #8104) and added 1800b4d7f, which changes only duration tables plus a watchdog test speedup that still pins the shipped 10 s budget. Coordinator-reviewed. All review threads are resolved.
  • The test-fixture change in sync-command-fanout.test.ts is justified in the description: the same scenario, written to the repository's CLI-spawn convention, passed on Windows in about 700 ms, and the product's localOnly short-circuit still has a test that fails if it is removed.

@lidge-jun
lidge-jun merged commit 43e2e4e into dev Nov 2, 2026
71 of 75 checks passed
@lidge-jun
lidge-jun deleted the goat/fix-dev-batch-8100-windows branch November 2, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ci:full Run the four full Ubuntu test shards on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant