Skip to content

fix(sandbox): hide Windows sandbox consoles and fail lock waits fast#6097

Merged
SivanCola merged 1 commit into
esengine:main-v2from
SivanCola:fix/winsandbox-hidden-console-lock-holder
Jul 6, 2026
Merged

fix(sandbox): hide Windows sandbox consoles and fail lock waits fast#6097
SivanCola merged 1 commit into
esengine:main-v2from
SivanCola:fix/winsandbox-hidden-console-lock-holder

Conversation

@SivanCola

@SivanCola SivanCola commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Problem

Users on the new native Windows sandbox path (1.17.x) reported two issues (with screenshots):

  1. Black console windows flashing / lingering over the desktop — one titled npm run dev, one titled C:\Windows\System32\icacls....
  2. windows sandbox: waiting for another sandboxed command on this workspace to finish (lock wait limit 10m0s; set WINDOWS_SANDBOX_LOCK_MS to adjust) — a long-running dev server holds the per-root lock for its whole lifetime, so every later sandboxed command silently queues for 10 minutes and then fails with a message that suggests the wrong fix (raising the cap only makes later commands wait longer).

Changes

Hide sandbox child consoles. The Win32 CreateProcess* launch paths (restricted token + AppContainer) and the internal icacls.exe/taskkill.exe invocations now start with CREATE_NO_WINDOW + STARTF_USESHOWWINDOW/SW_HIDE, matching what proc.HideWindow already does for ordinary exec.Cmd. Startup-info and creation-flag construction is factored into shared helpers so the two launch paths cannot drift.

Name the lock holder. Each acquired root lock records its holder (pid, start time, command preview) in a best-effort sidecar file keyed by the same root digest as the mutex. The 2-second queue notice and the timeout error now say e.g. held by "npm run dev", pid 1234, running 25m; stop that command or set WINDOWS_SANDBOX_LOCK_MS to adjust. Records are validated against a live PID on read, so crash leftovers are ignored (the OS already releases the abandoned mutex).

Fail fast in the foreground. The interactive lock-wait default drops from 10 minutes to 1 minute — a blocked foreground command now surfaces the holder-named error quickly and flows into the existing sandbox escape-approval path instead of hanging the turn. Background bash jobs (which nobody is blocked on) keep the patient 10-minute wait via a new Spec.LockWait budget threaded through the helper payload. WINDOWS_SANDBOX_LOCK_MS still overrides both. The security model is unchanged: no automatic escape, whole-run serialization stays.

Docs (EN/zh-CN guides, winsandbox README) updated to match.

Tests

  • New portable tests for holder-record round-trip/rejection, label sanitizing, holder description, and wait-budget precedence (run on any host).
  • New Windows-only tests: hidden-window creation flags/startup info, hidden system commands, holder record lifecycle + holder-named queue notice.
  • bash tool test asserting foreground uses the short default and run_in_background opts into the 10-minute budget.

Verification

  • go test ./internal/winsandbox ./internal/sandbox ./internal/tool/builtin ./internal/proc
  • GOOS=windows GOARCH=amd64 go test -c for winsandbox / sandbox / builtin ✅
  • go build ./..., cd desktop && go test ., git diff --check
  • Windows-only tests are compile-verified here (macOS dev host); they need a Windows CI run, and the black-window fix should be eyeballed once on a Windows desktop build.

Cache-impact: none - WindowsLockWait only changes internal Windows bash execution timing; tool schema/order and provider-visible prompt bytes are unchanged.
Cache-guard: go test ./internal/tool/builtin -run TestBashSandboxLockWaitForegroundVsBackground

- Launch sandboxed user commands and internal icacls/taskkill with
  CREATE_NO_WINDOW + STARTF_USESHOWWINDOW/SW_HIDE so no black console
  flashes over the desktop (npm run dev / icacls windows in the report).
- Record each root lock's holder (pid + command preview) in a sidecar
  file; the queue notice and timeout error now name the blocking command
  so users know what to stop instead of only being told to raise
  WINDOWS_SANDBOX_LOCK_MS.
- Drop the interactive lock wait default to 1 minute so a queued
  foreground command fails fast into the existing escape-approval path;
  background bash jobs keep the patient 10-minute wait via Spec.LockWait
  (WINDOWS_SANDBOX_LOCK_MS still overrides both).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skills Skill system (internal/skill, internal/tool) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant