Baseline: bca1183fcc1cd9f4820bb54139ecdaaf63adfcf6, 2026-09-07.
The user already has WSL2. The target is the same scientific workflow as the macOS download.
The branch now includes production fixes following the original investigation. The baseline observations below are historical; they are not the current branch's results. This is WSL2 x86_64 validation, not certification of every Windows configuration.
| Findings | Change | User-visible result |
|---|---|---|
| W0 | Focused WSL adapter, Windows/session mount masks, private PID namespace and AF_VSOCK filter; reuse the existing sandbox and interrupt lifecycle | Scientific code cannot use Windows interop to bypass its boundary; Python/R cancellation preserves the live analysis state |
| W1, W5 | Exclude infrastructure distributions; verify architecture, ordinary user and usable bubblewrap; offer Ubuntu prerequisite installation | First launch selects a user distribution and explains/prepares the missing isolation component |
| W2 | Windows user-scoped DPAPI backend behind SecretBroker; retain an existing usable Linux keyring | Fresh WSL can save model credentials without setting up a Linux desktop keyring or writing plaintext |
| W3, W4, W9 | Embedded runtime on CLI PATH, Linux tool lookup, explicit Bash executable | Shell commands use the selected analysis environment and support source / [[ ]] |
| W6–W8 | Digest-addressed staging and atomic current pointer, package-independent management, running-build identity | A failed update preserves the working installation; updates report a pending restart and leave active work running |
| C1, C2 | Shared macOS/Linux builder fixes for default UI and relocatable Python entry points; stronger artifact verification | The downloaded app opens its actual workbench and scientific commands keep working after installation |
| W10 — found during browser acceptance | One process-creation thread lives with the daemon instead of a short request | A completed Web Cell no longer loses its worker when its request thread ends; subsequent Cells and reloads retain variables |
| W11 — found during standalone launch | The Windows launcher retains a hidden WSL process for the foreground Linux server | No terminal needs to stay open; stopping the server also releases the background WSL process |
| C3 — found in installed-package acceptance | Bundled Linux/macOS CLIs disable Python's implicit current-directory import with -P |
A project containing openai4s.py or a source checkout cannot replace the installed application; the working directory is preserved |
The final full-suite check also reproduced an existing HTTP timeout race. The shared bounded reader now classifies a socket timeout consistently even when it precedes the watchdog. Regression tests exercise both orderings without loading unrelated TLS trust files into a 200 ms socketpair deadline.
The WSL-specific policy lives in security/wsl.py; encrypted storage lives in security/windows_dpapi.py. The existing kernel protocol, scientific services and UI remain unchanged. The two short-lived sandbox callers now pass the same required descriptors as persistent kernels. Hardlink scanning is retained for team isolation and Windows-backed workspaces, rather than scanning every Linux development checkout at startup.
Automated acceptance includes harness.smoke.wsl_sandbox, the real Python/R interrupt smoke, offline regression contracts, native PowerShell 5.1 launcher contracts and actual Windows-browser/package checks. See the follow-up verification record at the end of this report.
The existing Linux Python kernel runs in WSL. Most gaps are missing product setup or additional boundaries between Windows and Linux. macOS already gets an embedded Python/science stack, launcher environment, OS sandbox and login keychain. Having WSL2 alone does not provide equivalent conditions inside a distribution.
The first release blocker is Windows interoperability escaping the Cell sandbox. After the existing full Linux boundary smoke passed, an actual enforced Python Cell launched Windows PowerShell and changed a synthetic marker outside its workspace. The Linux smoke does not establish the WSL boundary.
OpenAI4S-Parity-Test distribution, an ordinary user, official Ubuntu 24.04.4 x86_64 and WSL2 kernel 6.18.33.2-microsoft-standard-WSL2.The official WSL image SHA-256 was 9b2f7730dc68227dd04a9f3e5eab86ad85caf556b8606ad94f1f29ff5c4fd3f5, verified against Ubuntu's checksum list.
The complete payload was also built: approximately 406 MiB compressed and 1.4 GiB installed. Its existing verifier successfully imported 38 scientific packages. After extracting the actual Windows ZIP under a path containing spaces and Chinese characters, the PowerShell 5.1 launcher installed as the ordinary user, started the daemon, reported ready and exited zero. Windows HTTP requests returned 401 without authentication and 404 for the authenticated homepage; the installed default UI is absent. Connectivity/authentication work, but artifact verification and the ready check miss the default page.
After keyring packages were installed, D-Bus ReadAlias(default) returned / and Collections contained only session. The broker's real store self-test timed out; a usable persistent default collection was not established.
The actual launcher status returned the running PID, reopening reused that daemon, stop exited zero, and subsequent status exited one with not running. The test daemon has been stopped.
Windows ZIP → distribution/user selection → prerequisites and Linux payload installation → Linux daemon → authenticated Windows browser → model credentials → upload and Python/R/Bash execution → artifacts/download → stop, reopen, upgrade and recovery.
| User action | Observation | Acceptance needed |
|---|---|---|
| Extract and launch | Selector admits docker-desktop; fresh Ubuntu stops at missing bwrap | Exclude infrastructure distributions; check architecture, user and runtime compatibility; provide a usable prerequisite setup flow |
| Open UI | The real ZIP installs and the launcher reports ready, but the authenticated homepage returns 404; the Linux verifier passes | Verify installed default HTML and referenced JS/CSS; correct the shared macOS builder too |
| Configure a model | Fresh WSL has no available secure backend; installing keyring packages alone does not create one | Secure save/read, unlock, reopen and WSL-restart recovery; no implicit plaintext fallback |
| Analyze uploaded CSV | Real Python and persistent variables work; bundled CLI supplies the wrong shell PATH | Verify selected Python and shell tools, upload, dataframe/figure capture and Windows-browser download |
| Run Bash | POSIX command succeeds; source and [[ … ]] return 127 through real host.bash |
One deliberate foreground/background shell contract, correct dependency environment, retained authorization and cancellation |
| Run R or specialist tools | Neither base desktop bundle includes R/Conda or every domain CLI | Capability-specific environment provisioning, real binaries, R fd transport and post-interrupt recovery |
| Isolate a Cell | Ordinary Linux boundary smoke passes; Windows marker can still be changed | Cover Windows processes/IPC, filesystem aliases, credentials and networking as part of WSL enforcement |
| Stop/reopen | 199 existing tests passed; the real ZIP's status, reuse, stop and post-stop status passed | Add conflicting ports, active-work cancellation, complete subsequent scientific execution and restart recovery |
| Upgrade/recover | Bad same-version archive removes previous CLI; management commands require/install the new payload; running version is not compared | Preserve a working install on failure, diagnose/stop without a good new ZIP, report real running version and protect active work |
| Restart WSL/Windows | Full product recovery not yet certified | Stable distribution/user selection, persistent credentials/data/environments and updated addressing |
Uploads, downloads and WebSockets already use HTTP. Validate these flows before inventing cross-filesystem mapping. Proxy, Fake-IP and localhost fallback implementations already exist, but multiple network modes were not tested by changing global machine settings.
| ID | Evidence and impact | Entry point / required change |
|---|---|---|
| W0 — release blocker | An enforced Python Cell executes Windows PowerShell and changes its own out-of-workspace marker even with the ordinary Linux smoke green | kernel/manager.py → security/sandbox.py:wrap_bwrap_command. Account for WSL executable/IPC/mount/proc boundaries; stripping WSL_INTEROP from the worker environment did not prevent this reproduction |
| W1 — first run | Fresh Ubuntu bootstrap.sh preflight exits 1 because bwrap is missing; it prints apt instructions |
scripts/windows/bootstrap.sh:run_preflight. Provide prerequisite setup and actual enforced self-tests |
| W2 — credentials | SecretBroker fails closed without a system store; secret-tool alone does not imply a user session and unlocked Secret Service | security/secret_broker.py. Define ownership, service lifetime, unlock and restart behavior before implementing a backend; a Windows secure-store bridge also depends on W0 being closed |
| W3 — execution | The bundled CLI does not prepend runtime/bin. The fixture resolves python3 to /usr/bin/python3 and cannot find python |
Linux builder CLI → bootstrap serve → kernel environment. macOS desktop LAUNCHER sets PATH; both CLI wrappers lack it. Unify launch environment while keeping selected Conda environments authoritative |
| W4 — execution | shell=True uses Ubuntu /bin/sh; source and [[ ]] fail. Jobs explicitly uses Bash |
sdk/bash.py:BashExecutor, jobs.py. Preserve authorization, timeout, process groups and audit when unifying the contract. R's POSIX fd redirection through sh is valid and need not be mechanically changed |
| W5 — distribution | The real selection function with a synthetic list chooses docker-desktop if it is the only WSL2 distribution; nothing was run inside Docker | openai4s.ps1:Select-Distro. Filter infrastructure, probe capability, preserve data ownership and explicit selection |
| W6 — upgrade | TCP plus CLI status reuses an existing daemon without comparing the running build to the newly installed build | PowerShell main flow and Test-OpenAI4SServing. Separate installed/running versions and active work; offer safe restart or pending-restart state |
| W7 — recovery | status/stop/doctor skip sandbox preflight but still call Get-PackageFacts → install → cli | PowerShell Arguments flow. Management of an existing installation must work without an intact new payload and without reinstalling to answer a query |
| W8 — recovery | A matching checksum over invalid archive bytes passes digest verification, tar fails, and the old same-version CLI is gone | bootstrap.sh install removes before extraction. Stage, verify and switch with concurrency/recovery rules. Different versions already have distinct directories; this does not prove session loss on every upgrade |
| W9 — tool discovery/latency | This WSL PATH had 43 entries, 34 under /mnt. Five missing-command lookups had a median of 209 ms versus 0.034 ms with Linux-only PATH. Windows npx was found without Linux node | Inherited CLI/daemon PATH and which callers such as cli/main.py:_find_conda_tool. Define Linux tool resolution, verify executability and invalidate caches on environment changes; do not change global WSL settings. This local measurement is not a full attribution of suite runtime |
| C1 — shared release blocker | Real rsync omits webui/dist/index.html; shared source verifier still passes and counts 604 Skills |
Both bundle builders exclude every dist; REQUIRED_SOURCES only checks the legacy UI. Include default UI and referenced assets, then verify all desktop artifacts, not only wheels |
| C2 — scientific CLI relocation | 22 console scripts in this actual payload embed the builder's interpreter path. Hiding the build directory only in a temporary mount namespace makes installed f2py fail, while the same installation's python3 -m numpy.f2py -v and pip succeed |
Linux builder pip installation/runtime/bin; the macOS builder uses the same installation strategy and needs comparison. Relocate console scripts and execute them without builder paths visible; the current verifier misses these entry points |
The POSIX default of shell=True is documented by Python subprocess. These observations have concrete environment and lifecycle causes; they do not establish general incompatibility with Linux syscalls.
The inventory records all 226 tracked .sh / .command / .ps1 / .cmd files at the baseline, six generated shell heredocs and 25 directly recognizable Python subprocess / host.bash call sites. Two remote .sh.tmpl templates are additional rendered-shell boundaries. All 224 .sh / .command files passed real Ubuntu bash -n. Syntax acceptance is not dependency or workflow certification. AST discovery cannot guarantee coverage of dynamic aliases, generated code or arbitrary configuration commands.
A targeted search of domain shell scripts found no brew, osascript, pbcopy/pbpaste, /Applications, /Users or /opt/homebrew matches. That rules out those specific indicators, not all possible workflow incompatibilities.
| Layer | Files / modules | Review boundary |
|---|---|---|
| Build/distribution | Linux/macOS/Windows builders, notarization and tag scripts | Payload/architecture, UI resources, dependencies, permissions/symlinks and line endings; signing runs on macOS builders |
| Desktop entry | Three Windows entry files; CLI/LAUNCHER/INSTALL/UNINSTALL heredocs | Windows args → wsl.exe argv → Linux shell, identity, environment, versions and lifetime |
| Development entry | setup.sh, start.sh, setup_envs.sh | uv, venv and Conda prerequisites; a configured checkout is not a clean downloaded package |
| Execution | Kernel transport, R, SDK Bash, Jobs, dynamic tools, preinstall | Identity/environment, shell semantics, permissions, process groups, cancellation, streams and persistent state |
| Environments | CLI setup, env_generations, preinstall, environment definitions | Bundled base differs from named python/r; Python, pip and domain tools must belong to the selected environment |
| External programs | MCP, Ark CLI, git, scientific services | Execute under the actual Linux daemon environment. A discoverable Windows shim is not proof of a Linux tool: fresh WSL found Windows npx with no Linux node |
| Remote work | Compute/Slurm/local worker, fold_remote, run/wrapper templates | Remote Linux, SSH, GNU timeout/setsid and specialist dependencies; no real remote-server certification |
| Domain recipes | 213 scripts under skills | Delivered recipes do not imply installed binaries; provision capabilities such as STAR/samtools/mafft as needed |
| Supporting tools | Container smoke, benchmark, review scratch, BYOC confinement | Separate deployment/research capabilities, not implicit ordinary desktop startup dependencies |
R, Conda and the complete domain CLI stack are absent from the macOS base download too. The Stage 1 standard-profile gate is off by default; its requirement for named python/r environments when enabled does not establish failure of default Python execution.
The existing CI/release windows-launcher jobs cover PowerShell parsing and refusal on a machine without WSL, not successful installation on WSL2. The Linux runner's sandbox smoke also lacks Windows interoperability. A separate real WSL2 acceptance gate is needed after fixes; neither existing green check establishes it.
| Check | Result and limits |
|---|---|
| Existing kernel/Bash/platform/release tests | 199 passed as an ordinary WSL user |
| Shell syntax | 224 files passed; not all domain workflows executed |
| Full Linux boundary smoke | Enforced filesystem, network and child-secret checks passed; Windows channel W0 remains outside its coverage |
| Complete Linux payload verifier | Passed, executing embedded Python and importing 38 scientific packages; C1/C2 remain undetected |
| Actual Windows ZIP | Spaces/Chinese path installation, authentication, reopen and status/stop passed; default homepage returns 404 |
| All-file pre-commit / type checking | Passed |
| Bilingual directory coverage / source secret scan | 160 directories and 1476 direct files covered; 3787 files scanned successfully |
| Complete offline suite | Completed: 8303 passed, 136 skipped, 2 failed, 1 warning in 852.74 s. uv run --locked pytest -n auto --maxprocesses=4 --dist loadfile, explicit Linux PATH, private tmpfs temporary data and tmp_path_retention_policy=failed |
| Failed-test recheck | Both passed in 17.92 s using uv run --locked pytest -n 0 and ordinary disk temporary directories; this does not turn the full-suite result into a pass |
Conditions matter: the first direct .venv/bin/pytest invocation lacked uv on PATH and produced one release-build-command assertion failure; interruption recorded another 5172 passed / 103 skipped. With the corrected PATH and uv run, that test passed individually. A subsequent disk-backed attempt was interrupted during I/O waits at 1951 passed / 38 skipped and is not counted as a complete pass. The final ordinary-user offline run uses private memory-backed temporary data, retaining failed-test data. Actual installation, credentials, sandbox and relocation probes used the real Windows/WSL filesystems.
The completed suite failed tests/test_mcp_client.py::test_streamable_http_body_watchdog_interrupts_a_chunked_slow_drip with a raw TimeoutError instead of the expected MCPTimeout, and tests/test_skill_product_surface.py::test_team_member_cannot_reactivate_legacy_host_skill_poison_over_http because the HTTP helper received no status line. Both passed in the separate recheck. Their causes remain unconfirmed; neither is attributed to WSL, tmpfs or this documentation/probe change. The warning comes from the test that intentionally simulates unsupported native win32 sandboxing.
Unverified scope remains explicit: real macOS execution, Windows on ARM, multiple distributions/network modes, real provider authentication/inference, every science recipe, and complete recovery after WSL/Windows restart.
Run as an ordinary WSL user in a clean checkout with Bash/rsync. The sandbox probe requires bubblewrap. Supply an existing Windows scratch directory; the script creates and cleans up only its own random subdirectory there.
python3 scripts/probe_wsl_parity.py \
--windows-scratch /mnt/c/path/to/audit-temp \
--output /tmp/wsl-parity.json
OPENAI4S_KERNEL_SANDBOX=enforce python3 -m harness.smoke.linux_sandbox
Exit zero from the first command means collection finished, not parity achieved: inspect windows_marker_changed and the other observations. The second command passes at this baseline while missing the Windows interoperability issue demonstrated by the first.
For an actual installed artifact, substitute its install path and the original build root below. The tmpfs hides the build root only in the child mount namespace; it does not remove or move the real directory. In this run f2py failed while the module and pip invocations succeeded. Another 21 commands had the same absolute-shebang pattern; they were not all executed individually.
PARITY_APP=/path/to/installed/OpenAI4S-0.2.0-linux-x86_64
PARITY_BUILD_ROOT=/path/to/checkout/.build
bwrap --unshare-net --ro-bind / / --tmpfs "$PARITY_BUILD_ROOT" \
--dev /dev --proc /proc -- "$PARITY_APP/runtime/bin/f2py" -v
bwrap --unshare-net --ro-bind / / --tmpfs "$PARITY_BUILD_ROOT" \
--dev /dev --proc /proc -- "$PARITY_APP/runtime/bin/python3" -m numpy.f2py -v
bwrap --unshare-net --ro-bind / / --tmpfs "$PARITY_BUILD_ROOT" \
--dev /dev --proc /proc -- "$PARITY_APP/runtime/bin/pip" --version
Concurrent build/install/full-suite work also saw WSL service connection timeouts (0x8007274c). One launcher attempt reported an unreachable folder after the same spaces/Chinese path had installed successfully. The service timeout's root cause was not established, and this does not demonstrate Unicode path incompatibility. Separately test service timeout, retry and diagnostic behavior.
These results supersede the baseline failures above. The environment remains an ordinary user in the isolated Ubuntu 24.04 WSL2 x86_64 distribution; the Windows browser is Chromium and the launcher runs under Windows PowerShell 5.1. The core still uses only the Python standard library.
OPENAI4S_NOTEBOOK_REPL=1; no live model provider was called.Archive digests and final-run receipts are recorded in the evidence JSON's fix_verification section. Build validation reused the previously assembled science runtime and repeated the builder's source-copy, CLI generation, bytecode compilation, full Linux verification and Windows packaging steps with the production changes.
This is WSL2 x86_64 acceptance evidence. It does not certify macOS execution, ARM, arbitrary distributions/network modes, real provider login/inference, Windows reboot, Conda provisioning or all domain recipes.