# PRODUCT.md ## Purpose Herdr Sandbox exposes the `sandbox` Windows command for running development and agent workloads inside disposable Windows Sandbox instances. A persistent Herdr server runs in the guest and the Herdr thin client remains on the host, attaching to that server over SSH. ## Product at a glance The current product contract is: - The host `sandbox` command starts, provisions, inspects, and stops an app-owned Windows Sandbox while Herdr keeps the interactive terminal on the host. - Selected projects and explicit cache, mount, worktree, and model roots can persist on the host. Unselected host data is not mapped, and guest tools and processes remain disposable. - `sandbox up` reports whether it will create a guest or reprovision a compatible ready app-owned guest whose mappings still match exactly before starting that work. It never replaces a ready guest automatically. - Windows PowerShell 5.1 provisions selected tools and verifies their integrity, ownership, and real capabilities. Omitted external-tool versions resolve to current stable releases; explicit project versions remain exact. - Herdr Sandbox is pre-1.0. Only the latest published release is supported, breaking changes may occur, and no backward-compatibility promise applies. ## Terminology - **Windows Sandbox**: Microsoft's disposable Windows guest environment. - **Herdr**: the agent-aware terminal multiplexer at `herdr.dev`; its CLI and executable remain `herdr` and `herdr.exe`. Sandbox requires the maintained [`herdr-win`](https://github.com/hdosys/herdr-win) Windows distribution because upstream Herdr does not yet support running the Herdr server on Windows or provide the remote-provisioning behavior this workflow needs. The host command must identify itself with the exact `herdr-win` marker and prove unattended `--remote --provision --yes --json` behavior. Herdr-Win remains an independent distribution that Sandbox never installs or updates on the host. - **Host**: the user's normal Windows machine. - **Guest**: the disposable Windows Sandbox instance. ## Core Behavior ### Commands and lifecycle - `sandbox config` reports whether it created the default configuration or opened an existing file, then points to `sandbox plan` as the next validation step. - `sandbox config`, setup, and portable first-use seeding refresh the app-owned adjacent `config.sample.json` and `config.schema.json`; they never rewrite an existing user-owned `config.json`. The optional `$schema` field accepts only `./config.schema.json`, gives editors local structural guidance, and never replaces runtime validation. - After successful provisioning and before optional attach, `sandbox up` prints preparation, provisioning, and total elapsed time in one line. - `sandbox config` creates only the user-owned `%APPDATA%\herdr-sandbox\config.json` when absent, never replaces an existing file, and asks the Windows Shell to open it with the application registered for `.json` files. It does not open a hard-coded editor or mutate Sandbox lifecycle state. `sandbox version` prints the build-owned release identity and abbreviated source revision without inspecting or mutating Sandbox state. `sandbox plan` validates and prints the effective configuration, generic folder mounts, workspaces, stacks, packages, resolved project-stack tool selections with every owner, and any exact ready-guest launch-plan differences without seeding configuration or changing app, host-tool, or Sandbox state. `sandbox init --stack ` creates one direct-call project profile at the current project root and never replaces an existing or ancestor-owned profile. `sandbox init --stack all` selects every generic technology, tool, and composition exactly once, including `audio`, `hyperframes`, and `python-ai`; checkout-specific `handy` and `herdr` shortcuts remain separate and `all` cannot be combined with another selection. The explicit virtual `herdr` selection makes an upstream Herdr checkout directly provisionable without repository guessing; it cannot be combined with an included `python`, `rust`, or `zig` selection. Generic stack profiles can initialize and provision an otherwise empty mapped project without requiring a repository manifest or dependency state. `sandbox up` launches and provisions a fresh Sandbox when none exists. When the exact app-owned Sandbox is already ready with the same fixed mapping set, running `up` again re-runs the current Base/project provisioning inside that guest and then reattaches instead of recreating it. `sandbox attach` verifies and attaches to that exact ready guest without reprovisioning, `status` inspects it, `mobile` prints the ready secret-free mobile connection profile and QR code, `down` stops it, and `clean` explicitly removes inactive app-owned run workspaces. - The build-owned identity printed by `sandbox version` includes one lexically sortable UTC freshness label as `YYYY.MM.DD.HHMMZ` before the abbreviated source revision. ### Project selections and models - The virtual `python-ai` init selection supplies current stable Python plus uv for CPU/API AI projects and cannot be combined with the overlapping `python` or `herdr` selections. It writes one direct `Install-PythonAIStack` call; repository contents are never guessed. - The virtual `audio` init selection writes one direct `Install-AudioStack` call that makes Windows Sandbox the AudioGridder VST execution server. It resolves the current stable REAPER and AudioGridder releases, disables REAPER's in-app update checks before first launch, and binds the selected payloads to WinGet metadata, a published digest, or the exact release payload downloaded in that provisioning operation. It excludes AAX, configures server ID 0 to scan the canonical guest VST folders, and allows only the host gateway through the guest firewall on TCP 55056 and 55088 through 56088. Project or user provisioning installs the production VST set in the guest. The production host DAW and matching AudioGridder client remain manually installed and target the current guest IP reported by `sandbox status`. Guest REAPER and the local client endpoint `127.0.0.1:0` exist primarily to prove a real connection to the same server during native acceptance. Provisioning never launches or terminates REAPER or AudioGridder Server. Global config `audio: true` remains the separate opt-in for hearing guest-local playback. - The virtual `handy` init selection makes the current Handy Windows checkout directly provisionable. It writes one `Install-HandyStack` call and cannot be combined with the overlapping `rust` or `herdr` selections. The stack validates Handy's project identity, reuses Bun and Rust/MSVC, resolves current stable CMake, Vulkan SDK, and WebView2 releases, and supplies the corrected SPIRV-Headers CMake target required by its native dependency build. Application dependencies, models, signing, and project files remain owned by Handy. - The virtual `hyperframes` init selection writes one direct `Install-HyperFramesStack` call and requires no project identity or dependency file. Omitted versions resolve the latest stable Node.js LTS, WinGet `Gyan.FFmpeg` full build, and npm `hyperframes` release; explicit profile values remain exact. The stack requires Node.js 22 or newer, exposes `hyperframes.cmd`, installs HyperFrames' managed Chrome Headless Shell, and stages every current HyperFrames skill outside all agent discovery roots. Ordinary OpenCode sessions therefore load no HyperFrames skill metadata. The explicit `hyperframes-opencode` command starts a separate OpenCode process for the current directory, forwards its arguments, and exposes the staged skills to that child only through process-scoped inline configuration. Provisioning requires Git for the official skills installer, runs machine-readable doctor checks for Node.js, FFmpeg, FFprobe, and Chrome, then proves a `libx264` software encode with FFprobe. Windows Sandbox vGPU may accelerate the browser, but it does not establish an FFmpeg hardware encoder and the stack makes no such promise. - An explicit nonempty `modelsDirectory` maps one shared host root read/write at `C:\Models` for persistent AI models. Host preparation uses that root for the latest stable `hdosys/hyperframes-voxcpm2` release and its exact model identities. The existing HyperFrames stack rehashes the selected VoxCPM2 files before use, accepts only the CPU runtime, launches it with GPU layers disabled, and uses the release's selected German Herdr narrator reference as the stable default voice across segments. A project's `voice_design` request field or the audio engine's `--voice-design` flag selects Voice Design for one request instead, while an explicit `--voice` WAV selects another reference voice. The guest-wide `tts.ps1` command exposes the same choices through `--design` and `--voice`. The stack fails when the release omits the selected narrator, contains another runtime, or omits the CLI. The provider's recorded HyperFrames version is build provenance only and never blocks provisioning with the selected current HyperFrames release; actual runtime behavior owns compatibility failures. Empty or omitted disables the shared mapping and VoxCPM2 preparation. ### Output, bootstrap, and attachment - Public host commands use plain, redirect-safe text with descriptive sections, indented fields, deterministic ordering, and one item per line for multi-value results. They do not require color, terminal-width detection, or a TUI framework; errors remain on stderr and command results remain on stdout. - While provisioning is active, the guest displays the same PowerShell bootstrap in a visible console so progress is observable inside the Sandbox; interacting with that window is not required. - The guest resolves and installs current stable Microsoft WinGet, VC++ runtime, and PowerShell 7 releases. OpenSSH prefers the newest usable stable server MSI and permits only a strictly named official `Preview` MSI when no usable stable server release exists. Every selected bootstrap payload remains bound to official metadata, digest, package hash, and applicable signature checks. After SSH and final guest configuration are ready, the existing host Herdr command provisions its matching complete Windows runtime and persistent server through `herdr --remote sandbox --provision --yes --json`. Sandbox never copies a host executable through bootstrap input or installs Herdr through WinGet. - Installed version strings and duplicated package, manifest, or executable version metadata are diagnostics. Missing, unfamiliar, or mismatched version read-back emits a warning and does not discard a successful installation. Required commands and capabilities, process success, payload hashes, signatures, publisher identity, and safe paths remain mandatory. - The host management connection authenticates with an app-owned SSH key. Its private key stays on the host; only the public key enters the guest. Optional mobile access uses separate device-owned Ed25519 credentials and never copies a device private key into host configuration, run state, QR output, or the guest. - Normal interactive `up` success means the host `herdr` client has attached to the guest Herdr server through `herdr --remote`, detached, and verified that the guest server remains running. After detach, the CLI labels that bounded verification and confirms its result instead of pausing silently. Installation success or plain SSH alone is insufficient. Explicit `up --no-attach` instead succeeds at the same terminal-ready boundary and leaves the verified guest available for a later `sandbox attach` or `herdr --remote sandbox`. - The automatic TUI attach requires real interactive console input, output, and error streams. Without `--no-attach`, a redirected or headless caller fails before cleanup, provisioning, download, or host-tool mutation and points to the intentional headless option; it must never send a live TUI into log files or present a blank terminal as success. - Fresh guest readiness includes one focused initial guest workspace with a root terminal pane, so remote attach never opens an empty client surface. - The Sandbox tool never installs, updates, or replaces host Herdr. It resolves the existing standard `herdr.exe` command, requires bounded `--version` and exact current `status client --json` identities, proves unattended remote provisioning, and fingerprints the selected command plus active physical runtime. - After publishing the final guest Herdr configuration atomically, Sandbox invokes exact `herdr --remote sandbox --provision --yes --json` for fresh and retained `up`. It strictly validates the returned target, Windows platform, canonical local executable path, binary outcome, server start/reload/restart outcome, distribution version, and protocol. It then independently verifies that the running detached server reports the same runtime, protocol, and binary. Herdr owns that guest executable's storage layout; Sandbox verifies its existing non-reparse file and parent without prescribing a directory. - A retained retry may provision over stale ready metadata, then republishes the verified current identity before later mobile and unchanged-host checks. Immediately before reporting success, Sandbox revalidates that the host command and runtime did not change. It installs or updates only the `sandbox` alias through the user's standard SSH configuration. - In the guest, the exact verified runtime directory becomes the unique first machine `PATH` entry. The same PATH plus `HERDR_SANDBOX_HERDR_EXE` are the explicit launch environment for every initial mapped-project workspace, without copying or wrapping the binary. The printed `herdr --remote sandbox` command therefore reattaches without a Sandbox-owned guest runtime or second server lifecycle path. - The CLI does not create a host-side Herdr workspace or pane as a substitute for remote attach. ### Failure, retention, and cleanup - Failure names the failed phase and points to bounded, terminal-safe diagnostics. `up` has a four-hour launch-to-ready deadline by default; an explicit positive `--timeout` replaces it for that run, while caller cancellation and narrower external-operation timeouts remain enforced. Ctrl+C cancels retained provisioning, skips the terminal Explorer-restart wait, performs only bounded task cleanup, preserves Sandbox state, and exits with status 130; a second Ctrl+C restores the operating system's immediate termination behavior. Retained reprovisioning publishes live progress and one host-owned bounded current/latest operation result separately from guest readiness, so a failed refresh never erases or falsely downgrades an otherwise ready guest. If a retained operation exits without a terminal result, the next lifecycle-lock owner records it as interrupted before any close, replacement, or cleanup mutation; another operation cannot silently overwrite a still-running record. - A cancelled pre-launch preparation states that no Sandbox was launched. A cancelled retained reprovision states that the ready guest was preserved. Cancelling the host wait after a fresh launch states that guest bootstrap may continue. Both guest cases point to `sandbox status`. - `up` never closes an existing Sandbox automatically. It reuses only an exact ready app-owned guest whose immutable mappings still equal the currently selected folder-mount and workspace set. Starting, failed, changed-mapping, unmanaged, or ownership-uncertain stale state is refused with an explicit next action, while automatic cleanup handles a provably gone stale session. Windows-equivalent mapped-path letter casing and ordering of the same mapping set do not force replacement. - Current package additions, removals, and version selections are applied by retained reprovisioning. Changed retained plans still name the exact differing audio input, audio output, memory, cache, folder mounts, workspace, Tailscale, mobile SSH authorized keys, or residual launch-contract fields. - `status` reports app-owned guest health separately from the current or latest retained operation, including start time, versions and protocol, safe guest workspace identities, bounded recent timings, diagnostics path, warnings, and the next action. It waits only boundedly for the lifecycle lock and may return a stable read-only snapshot while retained reprovisioning owns that lock. Exit status is zero only for `ready`; every printed non-ready state returns one so scripts cannot mistake starting, stopped, stale, unmanaged, or failed state for readiness. - `down` bounds lifecycle-lock and Windows process inspection and termination waits, and returns an actionable status command when another lifecycle operation remains active. It is idempotent and terminates that process tree without opening the Windows close-confirmation dialog only after retaining handles and revalidating the exact app-owned launcher and client relationship. It refuses to stop an unowned or changed process. - When stable Tailscale identity is enabled for a ready guest, `down` stops the service, protects local state against the already verified identity, and terminates the guest without control-plane readiness or a successful-path service restart. A failed persistence or termination attempt restarts Tailscale before returning. - After command syntax is validated, `up`, `attach`, `status`, `mobile`, and `down` run the lifecycle-locked automatic cleanup through the applicable shared inspector; `clean` invokes that cleanup owner directly. It preserves an exact running app-owned Sandbox and deletes only strictly validated inactive run directories. When process evidence proves that no Windows Sandbox launcher or client remains, it also removes stale active and SSH target state. Unmanaged, changed, unsafe, or uncertain state remains intact and is reported. Help, `plan`, and invalid command lines remain nonmutating. ## Product Direction This project is a standalone Windows Sandbox workflow with no external compatibility target. Prefer the happy path and fast real feedback over broad configuration, compatibility variants, or speculative abstractions. ### Compatibility and development releases Herdr Sandbox is pre-1.0 and makes no backward-compatibility promise. - Development release tags are monotonic `v0.0.N` identifiers, beginning with `v0.0.0`. Every tag attempt consumes its `N`; identifiers are never reused, so failed attempts may leave gaps between published releases. - Only the latest published release is supported. Breaking changes may occur and are documented in [`CHANGELOG.md`](CHANGELOG.md). ### Release formats and installer ownership - Every release offers both a per-user Windows installer and a ZIP download. Both share exactly `sandbox.exe`, `base.ps1`, `stacks.ps1`, and `LICENSE.txt`; setup additionally owns `uninstall.exe` and its `uninstall.ps1` quiet runner. - The ZIP contains the same four application files at its root and remains a permanent portable release artifact. Neither release format contains Herdr or becomes an input to a combined package. - The current product-GUID uninstall key, product-bound repair intent, and fixed registered `%LOCALAPPDATA%\Programs\Herdr Sandbox` location establish ownership. That entire fixed directory is an installer-owned binary root. - Setup refuses a nonempty unregistered root, snapshots registration values before preparation, stages and backs up the supported payload, replaces the complete owned root on upgrade, and restores the previous supported payload plus exact registration state when replacement fails. - Setup refreshes app-owned `%APPDATA%\herdr-sandbox\config.sample.json` and `config.schema.json` on every install or upgrade; neither reference is user-owned. - Setup has no marker file, installer-state schema, mixed-directory ownership, junction, versioned directory, persistent transaction journal, generic manifest engine, or PowerShell installer engine. Rerunning setup rewrites the complete payload and repairs recognized incomplete state; power-loss rollback is not promised. - One installer-only mutex serializes setup and uninstall, so ordinary `sandbox` commands never produce the installer-busy message. - Setup accepts only its current product registration, payload names, and direct application protocol. It does not parse, migrate, alias, delete, or otherwise adopt historical installer formats or executable names. Remove an older-format installation with its matching uninstaller before installing the current release. ### Setup and uninstall lifecycle - Setup converges user `PATH` by preserving its registry kind and first unique unrelated entries, removing empty and duplicate effective entries, and retaining one canonical product entry. Successful setup records only that it manages that entry. - Uninstall removes every effective product entry, including literal, quoted, slash, duplicate, and expanded-variable forms, while preserving distinct Unicode spellings and unique unrelated entries. - Before the repair, upgrade, or uninstall path acquires the application lifecycle gate, the installer invokes the hidden `--installer-stop-processes` command through the installed executable. Discovery, exact full-image-path validation, force termination, and exit confirmation share one five-second total deadline. The command targets only other processes running that exact installed `sandbox.exe`, and never targets a process tree or `WindowsSandbox.exe`. A failure stops before installed-file mutation and asks the user to close the named command manually. - Uninstall holds the lifecycle mutex continuously across its strict hidden cleanup command, cleanup commit, and recursive deletion of the registered binary root. The child receives exact ordered `--installer-lifecycle-lock-held` and optional `--delete-configuration` flags and never reacquires that mutex. - Cleanup always removes app-owned `config.sample.json` and `config.schema.json`, preserves a running Sandbox as unmanaged, and treats locked cache or state files as nonblocking residuals. - A late binary-root removal failure restores an exact resumable uninstall registration, so another uninstall continues after the lock clears without requiring setup. - Quiet uninstall has a 30-second total bound, returns the real terminal status, and terminates only its owned process tree on timeout. - **Also delete config.json and user.ps1**, and exact silent `/DELETE_CONFIG`, remain the only authorization to remove user-owned configuration outside the binary root. ### Installer experience and artwork - Welcome and Finish headings show only the short release version. Build freshness and source revision remain available in executable and installer metadata and never appear in those user-facing headings. - Interactive setup follows Welcome/License/Files/Finish. Installation and uninstall both show their real progress details by default. The license page displays Apache License 2.0 before installation. Successful setup ends on a finish page that explains the terminal-first next steps and offers one optional link to the product's setup and usage guide. A fresh interactive install also shows a checked **Open Herdr Sandbox configuration** option. Selecting Finish while it remains checked runs the canonical configuration-open path so `%APPDATA%\herdr-sandbox\config.json` opens with the application registered for `.json` files. Repair, upgrade, and silent setup, including standard WinGet installation, do not show the option or open it. Setup launches no product GUI or browser. - A terminal interactive failure shows one actionable explanation before setup closes completely; it never leaves an aborted Files page open. Silent setup/uninstall shows no blocking dialog and reports the same terminal outcome through a stable exit code. - Welcome and Finish share artwork whose sole editable source is `packaging/windows/assets/installer-welcome-finish-source.png`. Five linear-light Lanczos3 renders cover 96/120/144/168/192 DPI at exactly 164x314, 205x393, 246x471, 287x550, and 328x628 pixels. Setup selects the nearest listed scale from its effective system DPI at GUI initialization and displays that bitmap at native size without NSIS stretching, cropping, or alignment scaling. ## Productive Development Guest ### Persistent paths and workspace selection - Guest-only worktree routing must never become host workflow state. When a selected agent configuration root is Git-backed, configuration sync registers a required guest-local clean filter that removes only the managed routing block from check-in content while preserving ordinary edits. An instruction file created solely for guest routing is also excluded from normal staging. These controls live only in guest Git metadata, so a later guest push and host pull cannot carry the `C:\Worktrees` block. - `%APPDATA%\herdr-sandbox\config.json` may declare up to 16 named `mounts` whose strict entries contain only an absolute existing host `path` and an explicit `readOnly` boolean. Each folder appears deterministically at `C:\Mounts\`; `true` exposes it read-only and `false` allows persistent host writes from the guest. A generic mount is never a project workspace: it does not select an active directory, run a project profile, enter the workspace manifest, or create a Herdr workspace. Names and host paths are unique case-insensitively, volume roots and reparse-bearing paths are rejected, and mounts may not overlap another mount, workspace, cache, private run state, protected host root, or app-owned root selected for recursive uninstall removal. Ordinary selected profile descendants remain valid, but known SSH/GPG, cloud/container, coding-agent authentication, GitHub CLI, and Windows credential roots reject both an enclosing mapping and any descendant mapping. Any mount or access change requires `down` before the next `up`. - The same config may set one optional absolute `worktreeDirectory`. Empty or omitted disables persistent linked worktrees. A selected existing physical non-reparse host root maps read/write only at `C:\Worktrees`; configuration sync sets guest Herdr's native `[worktrees].directory` to that root and adds only `C:/Worktrees/*` to guest Git trust. `Git.Git` must remain selected. The directory must not overlap configuration, cache, private run state, workspaces, folder mounts, protected roots, or sensitive credential locations, and any change requires a fresh Sandbox. Herdr and Git remain the only worktree create/list/open/remove owners; Sandbox adds no parallel lifecycle, leases, pruning, or deletion. When enabled, configuration sync projects one guest-only managed block into each selected agent's native global instructions. That block routes lifecycle mechanics through `herdr worktree` while leaving the user's existing instructions authoritative over whether and when worktrees are created or removed; host instructions remain unchanged. `sandbox clean` and uninstall preserve the root. These linked worktrees are guest-native because Git records their guest paths in the mapped main repository, so the same main workspace must return at the same guest path and host-side portability is not promised. - The same config may set one optional absolute `modelsDirectory`. Empty or omitted creates no model mapping and does not contact the VoxCPM2 release or model sources. A selected existing physical non-reparse host root must not overlap configuration, cache, run state, worktrees, mounts, or workspaces and maps read/write only at `C:\Models`; changing it requires a fresh Sandbox. Guest administrators and tools may create or replace any content there, so the folder must contain no unrelated private data. Every `up` resolves the current stable GitHub Latest release before provisioning. The host verifies release metadata and every downloaded artifact before publishing one completion record; the HyperFrames stack rehashes every selected VoxCPM2 artifact immediately before activation. `sandbox clean` and uninstall preserve the shared model root. - `%APPDATA%\herdr-sandbox\config.json` may declare a name-to-path map of additional project workspaces and an optional `workspaceDiscovery` object whose nonempty absolute `root` contributes each nonexcluded direct child directory as a project. Its `exclude` array contains Go/RE2 regular expressions matched against each child directory name; any match excludes that child. Discovery never recurses or maps the parent itself. Selected and explicit workspaces are mounted without requiring `.herdr-sandbox\provision.ps1`; when that optional script exists it is strictly validated and run. An explicit workspace at the same path keeps its configured name. Independent workspace-validation errors are reported together. The user runs `sandbox up` anywhere: the nearest ancestor containing `.herdr-sandbox\provision.ps1` becomes the active project and is added or deduplicated; without one, only globally selected workspaces are used. `memoryMB` defaults to 32768 and must be at least 2048; `--memory-mb` overrides it for one run without rewriting the config. Exact booleans `audio` and `audioInput` independently control guest output and host-microphone sharing, and both default false. With both off, playback is muted and the shared audio services are disabled; input opt-in retains those services so microphone applications can work while output remains initially muted. Changing either audio selection requires `down` before the next `up`. - Project provisioning validation failures identify each failing workspace name, host directory, and source profile path, so a copied inspection filename is never the only diagnostic identity. - The same config may contain `mobileSSHAuthorizedKeys`, an array of at most eight unique canonical Ed25519 public keys generated and retained by the connecting devices. A nonempty array requires exact `"tailscale": true` and creates one dedicated key-only Win32-OpenSSH endpoint on the stable MagicDNS name at TCP 2222; tailnet access to the management endpoint on TCP 22 is blocked. A successful login starts the existing guest Herdr client directly. The mobile server host key persists as current-user DPAPI ciphertext so its displayed SHA-256 fingerprint survives fresh Sandboxes. Bootstrap and `sandbox mobile` show a QR containing only the `ssh://` URI plus a manual address/fingerprint fallback. Changing the authorized-key set requires `down` and a fresh `up` rather than mutating a live listener. - The same config may set `cacheDirectory` to an absolute, dedicated Herdr Sandbox cache directory on any available drive; it must not be a shared data directory because uninstall treats it as disposable and attempts recursive removal. Files still locked by an active compiler, test, agent, or tool are preserved without blocking application removal. When omitted or empty, the cache defaults beneath the system-selected temporary directory (`\herdr-sandbox\cache`, normally `%TEMP%\herdr-sandbox\cache`); the guest always sees the selected directory at `C:\HerdrSandbox\cache`. Caching is strictly demand-driven: a normal provisioning run stores only payloads it actually needs, and later normal runs reuse them without downloading those payloads again; no separate warm, prefetch, or scheduled mode exists. The guest caches the immutable WinGet bundle/dependencies, VC++ runtime, OpenSSH MSI, supported WinGet installer payloads, and each concretely resolved Rust distribution by verified digest, then copies executable bootstrap inputs guest-local before use. Herdr's matching runtime travels through its managed remote SSH provisioning path and never enters the Sandbox package cache or read-only bootstrap input. Because Microsoft's layout bootstrapper cannot create a complete layout inside a Windows 10 Sandbox, `sandbox up` creates or updates the required Visual Studio Build Tools layout automatically on the host only when the selected project needs it and no valid Current layout exists; the guest then revalidates, materializes, and installs that layout offline. Provisioning time is evaluated against the selected project plan and cache state rather than one universal wall-clock target: the maximal `native-all-stacks` fixture deliberately installs every supported stack as a breadth and compatibility gate and is not representative of normal project startup. Performance work requires a measured regression or concrete critical-path owner in a realistic project plan; adding supported stacks does not block unrelated feature work. - When Current Visual Studio layout preparation fails, provisioning may continue with an existing cached A/B layout only after its signed channel, artifact hashes, selected components, bootstrapper, and safe paths all revalidate. The cached build is reported as a warning. An unavailable or unverifiable layout remains a failure. - The optional `wingetPackages` object in `%APPDATA%\herdr-sandbox\config.json` customizes the global Base package set through `remove`, `add`, and `versions`: `remove` may name only known non-core defaults, `add` contains exact WinGet package IDs, and `versions` assigns an exact version to a retained or added package. PowerShell 7 remains protected Core tooling. Invalid/conflicting entries, unavailable versions, and failed installation commands fail without silently falling back; omitted versions retain latest-stable behavior. A current ready guest applies package-plan changes through retained reprovisioning without replacement. When installation succeeds but WinGet cannot confirm the exact installed ID/version, provisioning emits a clear warning and continues so WinGet correlation defects do not discard an otherwise usable guest. Package-specific functional verification remains strict. Adding `KhronosGroup.VulkanRT` is the disabled-by-default experimental Vulkan opt-in: provisioning succeeds only when `vulkaninfo` discovers at least one physical device through the already enabled vGPU. It installs no SDK, compatibility mapping package, host driver, or vendor-extension mode. Package selection owns installation, not personal configuration copying. ### Configuration and credential sync - After guest verification, `up` reports each enabled credential provider as transferred and verified or skipped with a non-secret reason; it never prints credential paths or values. - When no credential provider is enabled, `sandbox plan` identifies this as the secure default and names the `credentialSync` owner for explicit opt-in. - The optional strict `configurationSync` object has exact booleans `pullHostGitRepositoriesOnUp` and `pullHostGitRepositoriesOnDown`, both defaulting false when omitted or newly introduced. Before `up` transfers configuration, and only after `down` has terminally stopped the owned Sandbox, the corresponding enabled action updates every explicitly registered transferred configuration root that is itself one physical Git repository. The Herdr Sandbox configuration root is updated first and `config.json` is reloaded before remaining roots are selected. The explicit host-only `sandbox pull-host-config` command performs the same update regardless of both automation flags and never starts, stops, or copies from a Sandbox. No path searches an ancestor repository. Pulls are promptless, hook-free, and fast-forward-only; compatible local edits remain, while divergence, overlapping edits, detached `HEAD`, a remote-backed branch without upstream, authentication/network failure, or timeout fails without rebase, merge commit, stash, conflict resolution, or guest-to-host copying. A post-stop pull failure leaves the shutdown successful but returns a clear command failure. `sandbox plan` reports both flags and never pulls. - The optional strict `codingAgentSync` object has exact boolean fields `opencode`, `claudeCode`, `codex`, `githubCopilot`, and `pi`. Every field defaults to `true`, including when the object or a newly introduced field is absent from an existing config; setting one agent field false prevents discovery and configuration transfer for that agent. Missing host configuration is a clean no-op. The feature copies approved user-authored configuration, never conversations, runtime history, logs, caches, project trust, arbitrary home content, or machine-bound keyring state. When an enabled agent root or the shared skills root is itself one standard physical Git worktree using files-based refs, tracked files and bounded repository metadata are copied so branch, remote, upstream, index, refs, objects, retained local edits, and tracked deletions remain usable in the guest. Hooks, reflogs, linked-worktree state, active operations, external object stores, other ref storage, and known credential/runtime paths fail closed or remain excluded. - The separate optional strict `credentialSync` object has exact boolean fields `opencode`, `claudeCode`, `codex`, `githubCLI`, `pi`, and `tradingView`. Every field defaults to `false`; unknown fields, aliases, duplicates, nulls, and non-booleans fail. Each enabled field discovers and transfers only that provider's documented portable credential owner, independently of coding-agent configuration selection. Missing host credentials are a clean no-op. When the retained package plan is unchanged, `sandbox up` applies selected credentials immediately after SSH verification and before the longer idempotent Base and project reprovision, then runs the normal final configuration verification. A changed package plan retains package-first ordering. Turning a field off during retained reprovisioning stops later discovery and transfer but never deletes or revokes credentials already present in the ready guest. Closing the Sandbox remains the credential cleanup boundary. `sandbox plan` reports credential transfers separately and displays `(none)` for the default selection. - Host Git configuration, GitHub CLI `config.yml`, and successful authenticated accounts are separate optional configuration-sync inputs. GitHub `hosts.yml`, `gh` account discovery, login, HTTPS credential-helper setup, and status verification require `credentialSync.githubCLI`; missing selected credentials produce an empty transfer while guest Git still receives only the selected workspace trust entries. Windows Terminal `light` and `dark` themes select their matching guest prompt preset; its supported dynamic `system` theme uses the deterministic dark guest baseline rather than blocking startup. - Imported GitHub CLI tokens use the CLI's plain-file storage only inside the disposable guest, never its Windows credential store. An authenticated import requires selected Git. For every imported host, configuration sync makes the exact resolved `gh auth git-credential` command the host-specific HTTPS Git helper so an inherited Git Credential Manager cannot open an account dialog; the token source, empty helper-chain reset, and helper are all read back before ready. ### Project stacks and tool resolution - A project `.herdr-sandbox\provision.ps1` may directly call the built-in `Install-HerdrStack`, `Install-BunStack`, `Install-DotNetStack`, `Install-GoStack`, `Install-NodeStack`, `Install-PythonStack`, `Install-Uv`, `Install-PythonAIStack`, `Install-ZigStack`, `Install-RustMSVCStack`, `Install-CargoNextest`, and `Install-Just` functions before or alongside project-specific PowerShell. `Install-HerdrStack` is the repository-specific virtual composition: it validates `Cargo.toml`, reuses the standard Python, Zig, Rust/MSVC, Bun, Cargo Nextest, and Just stacks, resolves current stable Python and Zig unless the project supplies an exact selection, and lets the standard Rust/MSVC stack use the checkout's optional `rust-toolchain.toml` only when no explicit toolchain or stack constraint wins. The standard Python stack owns the compatible `python3` command, while conditional Base Git for Windows owns validation and PATH exposure of its shipped `sh.exe`; the Herdr composition only requires those capabilities and places libghostty Zig output below guest-local Cargo build state. The nonexecuting plan adapter expands that call into its existing concrete package identities, including latest-stable Bun and Base `Git.Git`. `Install-DotNetStack` owns only the highest stable numeric `Microsoft.DotNet.SDK.` family and latest SDK, which includes its modern runtimes; it never installs .NET Framework, preview SDKs, Visual Studio, or a compatibility path. An omitted version resolves the latest available stable version through the stack's existing package/channel owner and is concretized before cache/install; every explicit version remains exact and fails without fallback. `Install-NodeStack` always installs Node.js LTS, resolves npm's current stable Playwright `latest` dist-tag, and installs that version's matching full Chromium/headless-shell payload; only an explicit `PlaywrightVersion` pins a different exact version. Tooling, npm cache, and browsers stay guest-local below `C:\HerdrSandbox\tools`, later shells receive `PLAYWRIGHT_BROWSERS_PATH`, and provisioning requires a successful headless Chromium launch. It never runs npm dependency installation in a mapped project; TypeScript, Playwright test packages, other npm dependencies, and .NET target frameworks remain project state owned by their project files. - A custom project-profile failure names its workspace and `.herdr-sandbox\provision.ps1` owner before preserving the original PowerShell cause. - `Install-PythonStack` resolves the highest stable numeric `Python.Python.` family and its latest patch when no series or version is supplied. A requested series or version remains exact. Base and additional online WinGet packages inspect their already known installed IDs first and leave an installed unpinned package untouched during idempotent reprovisioning. A missing package is installed directly by exact ID, with an omitted version selecting WinGet's latest available version. - Before fresh or retained guest mutation, the nonexecuting planner merges every selected built-in tool requirement across `user.ps1` and all selected project profiles and prints the winning selection, source, and every owner. An explicit provisioning value, including an explicitly selected project version source, wins over an automatically discovered optional project version file; that optional file wins over the stack default or latest-stable resolver. Equal winning values are shared. Conflicting explicit values, conflicting selected project sources, and incompatible stack constraints fail before mutation. Missing optional version files never fail. The project-local `$projectPlaywrightVersion` selector explicitly chooses bounded non-reparse `frontend\package-lock.json` v3 state and requires matching exact `@playwright/test`, `playwright`, and `playwright-core` versions. Rust considers an exact `rust-toolchain.toml` channel only when no provisioning value or stack constraint already owns `rust-toolchain`; it remains separate from the `Rustlang.Rustup` package version. Generic stacks require no project manifest or dependency state, while project-specific shortcuts retain only their documented identity inputs. - The directly callable `Install-CppStack` reuses the current stable Visual Studio Build Tools layout with only the x64 MSVC tools and the highest stable Windows 11 SDK component in its catalog, and installs the current stable CMake release through the shared verified package owner. It persists the official x64 Developer PowerShell environment required by new SSH and Herdr shells, exposes `cl`, `link`, `lib`, `nmake`, `msbuild`, `rc`, and `cmake`, and proves both C and C++ compile/run paths. It adds no LLVM, MinGW, MSYS2, project dependency, or second compiler or Visual Studio owner. - The directly callable `Install-JavaStack` resolves the highest stable numeric `Microsoft.OpenJDK.` family and latest update through the existing hash-verified cached MSI path. The package family remains project-stack-owned and cannot also be configured as a global Base addition. A matching update is retained; otherwise the publisher-required uninstall-previous path runs before installing the target, while inconclusive remaining-version output is only a warning. The stack persists and verifies `JAVA_HOME`, exposes the exact publisher-owned `java` and `javac` commands, and proves a compile/run path. It adds no alternate JDK vendor, JRE-only path, build tool, framework, or project dependency. - The directly callable `Install-AndroidStack` resolves Google's current stable Windows command-line tools and published SHA-256, installs latest stable Platform Tools when absent, exposes `android.exe` and `adb.exe`, and persists `ANDROID_HOME` plus disposable `ANDROID_USER_HOME` state. Retained provisioning keeps an existing Platform Tools payload after its safe tree and wireless `pair`/`connect` commands pass; source and ADB version strings remain warning-only diagnostics. Android reuses the current stable Microsoft OpenJDK stack and publishes that same verified `JAVA_HOME` as `ANDROID_JAVA_HOME`. Android 11+ devices connect through standard wireless `adb pair` and `adb connect`. The stack adds no Android Studio, emulator, SDK platform/build-tools default, Gradle distribution, project dependency, USB passthrough, host ADB daemon, or device credentials. - Also directly callable, `Install-NSISStack` reserves `NSIS.NSIS` from global Base additions, resolves the latest stable x86 Nullsoft installer by default, and reuses the hash-verified package cache plus the publisher's silent `/S` contract. It exposes only the installed `makensis.exe` from the verified publisher path and compiles a minimal Windows installer with warnings treated as errors. It does not run the generated installer, mutate project files, introduce another packaging path, or pin a version unless a project explicitly requests one. This repository's profile and package task use the same dynamically resolved compiler. - The directly callable built-in `Install-PlaywrightCLIStack` is separate from `Install-NodeStack`: both reuse the same Node.js LTS runtime owner, but only Node installs Playwright-managed Chromium. The CLI stack resolves npm's current stable `@playwright/cli` release unless a profile supplies an exact version, disables update query/state through the supported `NO_UPDATE_NOTIFIER` environment, exposes `playwright-cli.cmd`, downloads no browser, registers Microsoft's official Playwright Extension for Edge from the Chrome Web Store, and never launches or creates a browser/profile. Because the official extension generates its token inside each fresh Edge profile, the user currently enables/installs it and places its displayed `PLAYWRIGHT_MCP_EXTENSION_TOKEN` value in the disposable guest environment once per fresh Sandbox. Agent automation then uses only `playwright-cli.cmd -s=edge-main attach --extension=msedge` and `detach`; it never uses `open`, `install-browser`, a persistent/alternate profile, or a custom extension. - The same built-in stack owner exposes `Install-HandyStack` for the current Handy checkout. Its nonexecuting plan identity expands to Bun, Rust/MSVC, and the current stable CMake, Vulkan SDK, and WebView2 package group; Rust/MSVC triggers the existing host Visual Studio layout owner. Provisioning verifies CMake and Vulkan with a compiled C++ probe and keeps the corrected SPIRV-Headers package under guest-local tools. The separate experimental global `KhronosGroup.VulkanRT` addition is not used by this project stack. - The directly callable built-in `Install-TradingViewStack` reuses Node.js LTS, resolves current stable TVControl once and downloads TradingView Desktop from its official `stable/latest` endpoint, installs them in the stable guest-local `C:\HerdrSandbox\tools\tvcontrol` and `C:\HerdrSandbox\tools\TradingView.TradingViewDesktop` roots, and exposes `tv.cmd`, `tvcontrol.cmd`, and `TradingView.exe`. Desktop verifies the unchanged signed MSIX and derives its version from the embedded Appx identity, but does not register AppX, whose manifest requires build 19042. Native build-19041 acceptance proved visible Desktop launch, CDP, exact TVControl launch selection, healthy API/datafeed state, and compatibility. When `credentialSync.tradingView` is true, selecting this stack also transfers an available account session from the installed host MSIX package family `TradingView.Desktop_n534cwy3pjxzj` through the verified configuration-sync SSH path. Only the signed `sessionid` and `sessionid_sign` cookie pair for TradingView domains enters the disposable guest; missing host profile/login state is a clean no-op, unrelated guest cookies survive, and a running guest Desktop blocks refresh rather than being terminated. Before the first guest launch, the same profile owner records an essential-only privacy choice that rejects TradingView analytics and advertising cookies and suppresses the consent prompt. These two non-secret settings are created in the guest and are never copied from the host. With credential transfer disabled, this privacy update preserves existing guest session rows. When OpenCode is available, configuration sync also manages one disabled-by-default local `tvcontrol` MCP definition using the verified absolute Node.js and TVControl server paths, loopback CDP port 9222, advanced tools disabled, and telemetry disabled. Enter `/mcps` in OpenCode to enable it for the current session only; every new session starts without its tools in model context. Provisioning and configuration sync never launch Desktop, sign in interactively, read charts/accounts, or edit a mapped project's package files. The stack leaves the installed upstream TVControl package unmodified, and `TradingView.exe` is already verified and exposed through guest `PATH`. The managed Start-menu and taskbar shortcut remains the explicit manual launch path and passes only `--remote-debugging-port=9222`. TVControl has one direct upstream launch path. Because TVControl and the guest agent run in the same interactive Session 1 context, its `launch` command and `tv_launch` tool directly spawn the visible Desktop with CDP. Either launch path exposes CDP to guest processes until Desktop exits. - The directly callable built-in `Install-NushellStack` reserves `Nushell.Nushell` from global Base additions, resolves latest stable unless a project supplies an exact version, and reuses the hash-verified cached x64 machine-scope MSI path. It exposes the publisher's exact `%ProgramFiles%\nu\bin\nu.exe`, requires that command to start successfully, and writes one provisioner-owned vendor autoload file that suppresses Nushell's welcome banner and initializes the selected Starship prompt without replacing user `config.nu`. It adds no plugins, Rust toolchain, or alternate shell owner. - For every selected Python 3 runtime, `Install-PythonStack` copies the verified Windows launcher to app-owned `C:\HerdrSandbox\tools\python\bin\python.exe` and `python3.exe`, verifies identical bytes and exact command paths, and exposes that directory through guest `PATH`. The adjacent names preserve Python's normal Windows virtual-environment base-executable contract without installing another distribution. Conditional Base `Git.Git` similarly validates and exposes its shipped `bin\sh.exe`. Because maintained Herdr recipes require `python3` and `sh`, a Herdr plan fails before launch when `Git.Git` was removed. - `Install-PythonAIStack` is a virtual composition over current stable Python and latest-stable `astral-sh.uv`. uv is reserved to the project-stack package owner, its concurrency-safe dependency cache persists at `C:\HerdrSandbox\cache\uv`, and uv-managed Python downloads are disabled so the standard Python stack remains the only runtime owner. The nonexecuting plan expands the composition to `python` and `uv`. Frameworks, notebooks, provider SDKs, project environments, and lockfiles remain project-owned; CUDA requires a separately accepted and natively verified hardware path. ### Release-owned guest environment - Release-owned `base.ps1` and `stacks.ps1` supply every built-in provider/adapter and update with the application. `%APPDATA%\herdr-sandbox\user.ps1` is the one seeded-once user-owned global PowerShell extension; the installer seeds it and `config.json` when absent, while portable use retains the same first-mutating-command fallback. Both paths refresh the app-owned configuration sample and adjacent editor schema. Config owns global package selection and project profiles own project-specific behavior. - Release-owned `base.ps1` applies the pinned Just the Browser Edge policies plus the complete reviewed, nonvolatile registry delta produced by the privacy/debloat tool and deliberate Windows UI changes, including Explorer Folder Options and taskbar visibility settings that hide Search, Task View, Windows Widgets, News and Interests, and Weather. Review starts from the complete delta and removes only entries proven volatile, runtime-generated, duplicated, or unrelated to the intended user state; it does not sample a short allowlist. The selected disposable-guest profile intentionally includes the explicitly requested ShutUp10++ switches even when the tool marks them not recommended, including restrictions on Defender cloud/security features, SmartScreen, automatic Windows and driver updates, application inventory, KMS online activation, NCSI, telemetry, DRM, and the named Chromium/legacy Edge services. This registry phase is the first guest mutation after bootstrap input validation: it runs before WinGet download and every package/tool installation, reads back every value, and immediately performs one bounded Explorer restart only when an exact value changed. - Base Development uses the dynamically resolved current WinGet bootstrap to install and verify latest available PowerShell 7, Git, GitHub CLI, Tailscale, Starship, fzf, ripgrep (`BurntSushi.ripgrep.MSVC`), actionlint (`rhysd.actionlint`), WinDirStat (`WinDirStat.WinDirStat`), File Pilot (`Voidstar.FilePilot`), matching Windows Terminal edition, and explicitly selected additions before user/project scripts run. It also resolves the current stable native `opensrc` Windows x64 release, verifies its official digest and exact version output, exposes `opensrc.exe`, and persists fetched sources only below `C:\HerdrSandbox\cache\opensrc` through `OPENSRC_HOME`; it does not install Node.js for this tool. Coding agents remain removable additions rather than protected Base packages: fresh configs and in-memory defaults select OpenCode, Claude Code, Codex, and GitHub Copilot, while an explicit `add` array remains authoritative. Base publishes and verifies guest machine and provisioning-process `OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT=false` before any coding agent can start. Every provisioning phase continues to run exclusively under inbox Windows PowerShell 5.1. PowerShell 7 is Core/Base-owned interactive guest tooling after provisioning. Base also resolves, verifies, and loads the current stable GeistMono Nerd Font for the disposable guest session. User/project scripts pin a development-tool version only when they define that exact constraint. - The explicitly selected ShutUp10++ Chromium Edge controls are written from one table to both `HKCU\SOFTWARE\Policies\Microsoft\Edge` and `HKLM\SOFTWARE\Policies\Microsoft\Edge`, matching the complete user-and-machine state observed in ShutUp10++. The remaining pinned Just the Browser controls stay machine-wide only. Device-location denial owns both the supported App Privacy policy and the machine/user ConsentStore values confirmed by the reviewed delta. - Windows application background execution remains enabled because installed-application refresh and the supported taskbar materialization path are functional behavior; provisioning must not write `BackgroundAccessApplications\GlobalUserDisabled`. The selected privacy profile does disable the separate application-inventory collector through `AppCompat\DisableInventory`. ### Guest identity and workspace startup - The latest stable Tailscale Windows client is installed and version-verified through the existing WinGet MSI cache path. Exact boolean `"tailscale": true` in the global config opts into one stable tagged tailnet host named `herdr-sandbox`; Tailscale must remain in the selected Base package plan. The first enabled `up` requires a one-off preapproved tagged auth key in `HERDR_SANDBOX_TAILSCALE_AUTH_KEY`, consumes it without printing or persisting it, and captures the enrolled identity. Every later fresh Sandbox restores that same device identity, node key, Tailscale IP, and MagicDNS name without user interaction or another auth key. Ready requires exact identity and local-user ownership verification; an unexpected identity or Windows user SID fails closed. With the option omitted or false, Tailscale remains install-only. No Tailscale credential or state is exposed through a Sandbox mapping. - Sandbox-owned guest-local state lives beneath one understandable `C:\HerdrSandbox` root: `cache`, `tools`, `toolchains`, `build`, `staging`, and `visual-studio`. Herdr separately owns the storage location, complete Windows payload, and lifecycle state of its remote runtime. Sandbox records and publishes only the executable returned by Herdr for bootstrap workspace creation and mobile SSH routing. Initial workspaces receive the published environment directly, and new PowerShell 7 shells refresh their process `PATH` from current machine and user values, without copying or wrapping the binary. The only persistent host mapping inside `C:\HerdrSandbox` is `cache`; app-owned sibling roots must not be created. - Only after all selected guest configuration has been transferred and verified does bootstrap create exactly one Herdr workspace and root pane for every selected/mounted project root, using that project's `C:\Workspaces\` root as `cwd`; the active project workspace is focused. Guest Git trusts exactly those manifested roots so mapped host ownership does not break normal repository commands, and wildcard safe-directory trust is forbidden. - Herdr preserves an exact host Nushell default as guest `nu.exe` when the inspected guest provisioning plan includes the Nushell stack. PowerShell 7 remains Herdr's default when Nushell is not both selected by the host and available in the guest. - Selected host Git configuration, available GitHub CLI configuration and selected successful authenticated accounts, enabled coding-agent configuration and separately selected portable credentials, an available Herdr `config.toml`, and Windows Terminal settings/schemes are transferred together after project provisioning and SSH host verification but before any interactive workspace or shell pane is created. GitHub CLI credentials stored in the host keyring are exported only when `credentialSync.githubCLI` is true, through the installed `gh` boundary into memory and then guest `gh` standard input; tokens are never printed or persisted in host run state. The guest copies preserve the remaining host configuration but make installed PowerShell 7 (`pwsh.exe`) the default for Herdr, OpenSSH, and Windows Terminal, normalize every configured Terminal font to the verified `GeistMono Nerd Font`, and replace every synced Terminal profile's starting directory with the active mapped `C:\Workspaces\` root, so host-only shells, fonts, and physical paths cannot break guest startup; when no host Herdr config exists, the guest receives only that required default-shell setting. The legacy Windows PowerShell 5.1 Terminal profile remains visible and host files remain unchanged. The guest's PowerShell all-host profile initializes Starship. An explicitly dark host Terminal application theme selects Starship's upstream Pastel Powerline preset; an explicitly light theme selects upstream Catppuccin Powerline with its palette changed from the dark default to `catppuccin_latte`. Every copied destination and generated Starship configuration is verified at its standard guest path and selected imported GitHub CLI accounts are status-verified. The host Herdr provision command then validates that final configuration and starts, reloads, or restarts the matching server before pane creation and attach; private SSH/GPG keys, unrelated Windows Credential Manager state, logs, runtime sockets, and unrelated home/AppData content remain excluded. The first attached viewport must therefore show the final selected prompt immediately, without `Ctrl+L`, shell restart, or another manual redraw. - OpenCode, Claude Code, OpenAI Codex CLI, GitHub Copilot CLI, and Pi have fixed out-of-the-box configuration-sync contracts. When selected separately through `credentialSync`, OpenCode, Claude Code, Codex file-mode credentials, and Pi copy their documented portable credential files; Copilot reuses selected GitHub CLI authentication. Codex encrypted/keyring credentials and Copilot-native Windows Credential Manager tokens remain machine-bound and require one-time guest authentication. This copy-only support installs no agent CLI; package selection and project profiles remain the installation owners. Whenever OpenCode configuration is synchronized, its package is selected, or `opencode.exe` is already available, configuration sync reapplies one guest-managed policy after the host copy and replaces every top-level and per-agent permission with `allow`; host permission rules never govern the guest. A selected TradingView stack additionally registers the managed `tvcontrol` MCP server disabled by default for explicit session-only opt-in through `/mcps`. No permission or MCP policy is invented for the other agents. - The same selected-agent sync preserves official Herdr integration assets already installed on the host. Copied Claude Code, Codex, and GitHub Copilot hook registrations replace only their absolute host hook path with the corresponding guest path; the synchronized integration bytes and unrelated settings remain unchanged. After the matching guest Herdr runtime is active, fresh and retained `up` install an integration only when Herdr reports that selected target as not installed and its agent command is available. Current, outdated, and repair-needed integrations are never replaced automatically, and targets Herdr does not offer are skipped. - After installing the selected defaults and project stacks, provisioning applies one complete taskbar pin list through the supported Start Policy CSP in this exact order: Microsoft Edge, File Explorer, File Pilot, selected TradingView Desktop, Windows Terminal, then WinDirStat. The portable TradingView stack creates and verifies its Start-menu shortcut from the installed executable with the fixed `--remote-debugging-port=9222` argument before that conditional pin is added. Full-list ownership is required because appended policy pins do not reorder existing/default pins reliably. A matching existing layout is left untouched. Every change is read back exactly, then triggers a second Explorer restart after the independent early Registry-phase restart; failed or matching policy state never triggers that taskbar-owned restart. ### Isolation and acceptance - Only explicitly configured project roots under `C:\Workspaces\`, named folder mounts with `readOnly: false` under `C:\Mounts\`, an explicitly selected `worktreeDirectory` at `C:\Worktrees`, and an explicitly selected `modelsDirectory` at `C:\Models` expose writable user data. The host home root, AppData roots, credentials, unselected repositories, and broader parents are not mapped; changing any mapping list or a mount's access requires a fresh Sandbox launch. The generated Sandbox contract explicitly enables Windows clipboard redirection so text and files can be copied between the host and guest without introducing another host mapping, and enables virtualized GPU acceleration when the Windows Sandbox host can provide it. - Windows Sandbox has no supported per-instance CPU-priority control, and Windows client Hyper-V does not support per-VM weights, caps, or reserves under its root scheduler. The product therefore has no idle/low-priority mode and does not pretend that changing the launcher process priority controls guest vCPU scheduling. - The Sandbox project profile installs and verifies Go plus the current stable NSIS compiler required by this repository's build and installer package tasks. Routine provisioning does not rerun repository test, lint, build, or package suites; acceptance runs representative commands explicitly through the ready Herdr session while project edits persist on the host workspace. - Provisioning aborts when installation fails or when required package identity, integrity, command ownership, execution, or a real capability cannot be proven. Unrelated warning text and duplicate version presentation are not failures after stronger evidence already proves the installed result.