# ARCHITECTURE.md ## Purpose And Authority This file owns stable technical design: command ownership, host/guest boundaries, runtime state, external CLI integration, and verification architecture. Code and tests remain the detailed truth. `PRODUCT.md` owns user-visible behavior. ## Architecture At A Glance - **Product path:** `cmd/sandbox` owns OS process wiring and exit status, `internal/cli` owns command flow and dependency composition, and `internal/sandbox` owns Windows Sandbox planning and the concrete native workflow. - **Host and guest split:** Go owns host contracts and direct process control. Windows PowerShell 5.1 is the exclusive provisioning interpreter. Installed PowerShell 7 is interactive guest tooling. - **Data boundary:** Host mappings are explicit and narrow. Personal configuration and credentials cross only the verified SSH transfer path; host and mobile private keys are never mapped. - **State boundary:** Per-run state is ephemeral and app-owned. Only the optional Tailscale and mobile SSH identities are durable credential state, encrypted for the current host user with Windows DPAPI. - **Provisioning boundary:** Built-in Base and stack scripts, one global `user.ps1`, and the nearest project `.herdr-sandbox\provision.ps1` are the direct provisioning surfaces. No generic provider or plugin system exists. - **Delivery and evidence:** `cmd/task` owns recurring build and verification commands, `packaging/windows/installer.nsi` owns installer lifecycle, and native Windows Sandbox gates own environment-sensitive acceptance. ## System Shape - `cmd/sandbox` is the thin product executable. It owns OS process wiring and exit status only. - `internal/cli` owns argument parsing, help, user-facing command flow, and dependency composition. - `internal/sandbox` owns Windows Sandbox planning, generated configuration, guest bootstrap assets, terminal status handling, Herdr/SSH connection material, and the concrete native workflow. - Read-only effective planning and exclusive project-profile initialization reuse those same configuration, workspace, package, and direct-stack owners. They do not introduce another config model, profile DSL, or host provisioner. - `cmd/task` is a small Go-only repository task runner for recurring test, verification, and build commands. - There is one concrete Windows happy path. No provider/plugin framework, compatibility adapter, persistence service, daemon, frontend, or alternate provisioner exists in the current product. ### Go And PowerShell Ownership - Go owns the host product: CLI parsing, configuration, path/mapping validation, run/status contracts, `.wsb` generation, SSH/Herdr lifecycle, configuration sync, cache-policy decisions, subprocess bounds, and final error reporting. - Every noninteractive host subprocess, including repository task/test adapters, uses one shared Windows hidden process-tree console with captured output so compiler/test/installer descendants inherit that invisible console instead of allocating visible windows; noninteractive guest PowerShell launched through SSH also uses `-WindowStyle Hidden`. - Only the user-facing Herdr attach, a real interactive terminal check, and the Windows Sandbox application/bootstrap console remain intentionally visible. - PowerShell never selects an alternate product path or silently changes these contracts. - Repository-owned Windows PowerShell 5.1 scripts are narrow Windows adapters invoked by Go or by the Sandbox logon command: `assets/visual-studio-layout.ps1` prepares and atomically publishes the host A/B Visual Studio layout; `assets/bootstrap.ps1` initializes the guest and emits terminal status; `assets/configuration-sync.ps1` applies the verified development-configuration archive; `assets/mobile-ssh.ps1` prepares, activates, and verifies the dedicated tailnet listener; app-owned `provisioning/base.ps1` applies reviewed registry state, global packages, and the port-specific Herdr shell profile; app-owned `provisioning/stacks.ps1` supplies concrete development-tool adapters; the user extension adds global customization; and each `.herdr-sandbox/provision.ps1` installs only its project's guest toolchain. Their outputs are verified by Go or explicit read-back checks, and no CMD/batch or generic script-plugin system exists. - Windows PowerShell 5.1 is the exclusive interpreter for every host/guest provisioning action throughout the run, including bootstrap, Base, project/stack scripts, configuration sync, AST inspection, and verification, even after PowerShell 7 is installed. - Installed PowerShell 7 is a separate post-provisioning runtime used as the interactive shell for Herdr panes, OpenSSH, and Windows Terminal; the unavoidable OpenSSH default-shell process may only receive a bounded byte stream into app-owned staging before launching hidden Windows PowerShell 5.1, and no provisioning owner invokes a second `pwsh.exe` or runs provisioning logic in that transport shell. - Sandbox-owned guest-local paths share one fixed `C:\HerdrSandbox` namespace. - Go maps only the persistent cache at `C:\HerdrSandbox\cache`; Base owns global `tools` and package `staging`, and project profiles own `toolchains`, `build`, project staging, and `visual-studio`. - Herdr separately owns the guest-local storage location of its remote payload and returns the active executable through its provision contract; Sandbox assumes no Herdr directory layout. - Fresh guests require no path aliases, junctions, or migration fallback from former root-level `C:\Herdr*` directories. ## Host And Guest Boundary ### Workspace, Mapping, And Network Boundaries - The host creates a unique per-run workspace below an app-owned local data directory. Runtime workspaces and connection material are never repository files. - After strict project/cache resolution and before Sandbox launch, the host prepares a Visual Studio Build Tools layout only when an explicit project requirement is present and the app-owned cache lacks a valid Current layout; this is part of the normal `up` path, not a separate warming mode, and it never installs Visual Studio on the host. - A generated `.wsb` configuration is the launch contract because it works on supported Windows 10 and Windows 11 hosts without requiring the newer Windows 11 `wsb.exe` CLI. - The guest receives one read-only mapping containing the trusted bootstrap, selected external provisioning scripts, host public SSH key, and configured mobile-device public keys. - Herdr runtime bytes never enter mapped bootstrap input; the verified host Herdr CLI transfers its matching complete Windows payload over the managed SSH boundary after final configuration publication. - Personal configuration and secret credentials use only the separate verified SSH transfer path. - The guest receives one writable mapping for bounded status, one app-owned cache mapping, one optional shared writable models root at `C:\Models`, one writable mapping per explicitly selected project root under `C:\Workspaces\`, each explicitly configured generic folder under `C:\Mounts\` with its exact read-only selection, and at most one explicitly selected persistent worktree root at `C:\Worktrees`. - No home root, AppData root, credential store, unselected repository, or broader parent is mapped. - Mapping validation allows ordinary explicitly selected profile descendants but rejects physical overlap in either direction with existing known-sensitive roots: SSH/GPG, cloud/container and Kubernetes credentials, supported coding-agent authentication roots and overrides, GitHub CLI state, and Windows credential stores. - This prevents selecting a credential directory itself, one of its descendants, or a broader folder that would expose it without banning normal profile-hosted projects and tool folders. - The host management SSH private key remains in host-owned local state and is never mapped into the guest. Mobile private keys remain exclusively on their originating devices; only their public keys enter configuration and immutable run input. - Networking is enabled because WinGet, SSH, and Herdr remote attach require it. - Sandbox never downloads Herdr through guest HTTP or WinGet; the host Herdr remote owner may transfer its exact local portable payload over SSH. - Clipboard redirection and vGPU are explicitly enabled for host/guest transfer and available graphics acceleration; video, printers, and broad host mappings remain disabled or absent. - Audio output and host-microphone input are separate explicit config boundaries, both disabled by default and retained only when their exact boolean is true. - The tool refuses or clearly fails when Windows Sandbox is unavailable. - Enabling optional Windows features and rebooting remain explicit host-administrator actions rather than silent CLI side effects. - The current `.wsb` contract exposes `AudioInput`, which is emitted as exact `Enable` or `Disable` from `audioInput`, but no playback or VM-priority element. - Output policy therefore remains guest-owned. - Windows client Hyper-V uses the root scheduler, where per-VM weights, caps, and reserves are unsupported; `WindowsSandbox.exe` process priority does not control utility-VM vCPU scheduling. - No launcher-priority approximation or host-global scheduler mutation is added. ### Lifecycle, Cleanup, And Retained Reprovision - `up` never kills an already running Sandbox. - One app-local Windows lifecycle mutex serializes app-owned launch preparation, a pre- and post-preparation no-running check, launch/publication, and every `down` or cleanup mutation; concurrent operations therefore cannot collide in the shared host cache, lifecycle identity, or run deletion. - Immediately after launching its concrete `WindowsSandbox.exe`, Go atomically records one strict active-session contract containing the run/config identity, the stable-Tailscale opt-in bit, and the observed PID, executable, creation time, and exact command line. - The launching command retains and waits on that exact process until provisioning completes; early launcher exit cancels provisioning immediately so the command releases lifecycle ownership instead of hanging. - After bounded startup cleanup, `status`'s separately locked inspector combines that identity with existing progress/ready/failure files without further mutation. - `down` retains the exact launcher and child-client process handles across revalidation; for a ready opted-in guest it stops Tailscale and captures current local state over the verified per-run SSH connection without restarting the service on success. - It then force-terminates the exact child client followed by its exact launcher and waits boundedly for both, bypassing the Windows close-confirmation dialog without targeting any unowned process. - Capture, host persistence, refusal, or termination failure restarts Tailscale when the guest remains reachable and preserves ownership for diagnosis. - A missing-process stale record is cleared only when no unmanaged Sandbox remains. - After CLI syntax validation, `internal/cli` invokes the single lifecycle cleanup owner before mutating `up` and `down`; `clean` invokes that owner directly and exactly once. `InspectSession` owns status-time cleanup and inspection under one lock acquisition so status does not run two separately locked passes. It waits only one second for the lifecycle mutex; when a strict host-owned running reprovision operation explains the busy lock, it skips cleanup and double-reads unchanged active/operation identity around one read-only status snapshot. Help, plan, and invalid input do not cross the native or destructive boundary. Cleanup reads the strict active identity, enumerates the launcher/client set, and revalidates the same process evidence before deletion. Process inspection pins the exact `Get-Process` handle before reading its canonical creation time and confirms a disappearing process through CIM instead of dereferencing a missing object. It pins non-reparse data, run, and SSH directories with Go 1.26 `os.Root` handles and owns only the exact `active.json`, `ssh\config`, and run-ID child names relative to those roots. A replacement at one of those exact app-owned rooted names may itself be removed, but no rename or reparse race may redirect deletion outside the pinned root. An exact running app-owned tree protects its run; only a missing active process together with an empty global Sandbox process set proves the Sandbox gone and permits removal of the former active run, stale active identity, and app-owned SSH target. If that exact owned process changes from running to proven gone between cleanup preflights, cleanup replans once from the unchanged active identity; every other identity change remains fail-closed. Unmanaged, changed-root, malformed, reparse-bearing, or inspection-failed state remains intact and returns a diagnosable incomplete-cleanup error; `status` reports that warning and continues to show preserved stale/unmanaged state, while mutating commands fail closed. - A repeated `up` under the same lifecycle mutex may reuse only the exact running session already classified ready. - Go canonicalizes the current selected folder-mount/workspace/cache paths, regenerates the complete WSB launch contract with current memory, accepts canonical contracts whose complete mapping sets differ only by Windows-equivalent letter casing or element order, and names exact audio input, audio output, memory, cache, folder-mount, workspace, Tailscale, or residual contract differences before refusing mutation. - Canonical round-trip validation keeps unknown XML or formatting drift fail-closed. - It snapshots current app-owned Base/Stacks, the user extension, each current project profile, and the current resolved package plan without changing the initial run input, reuses provisioning-plan inspection and host Visual Studio preparation, then streams one length/digest-bounded archive over the verified SSH connection. - Guest PowerShell extracts it to app-owned staging, rejects reparse points, runs the same Base Development owner with mapped status progress so package additions/removals/version changes apply in place, removes staging, and returns one strict result. - A concurrent host observer prints changed mapped progress and atomically updates the host operation record; observer persistence failure cancels the SSH operation. - The existing configuration-sync/read-back path runs again before attach. - Any changed fixed plan or non-ready/unmanaged state is refused rather than approximated. ### Attach And Read-only Inspection - `sandbox attach` acquires the same lock, runs canonical cleanup, requires exact ready process and status identity, reconstructs per-run SSH material from the app-owned private key and ready host key, verifies pinned host/guest Herdr identity plus SSH, revalidates unchanged active/ready identity, and only then publishes the stable alias. - The lock is released before the interactive TUI starts. - `up --no-attach` stops at terminal ready; normal `up` validates all three console streams before cleanup or provisioning. - `sandbox mobile` reuses the same `InspectSession` cleanup and inspection owner as `status` before rendering the ready connection profile. ## Guest Bootstrap ### Ordered Windows Setup - One Windows PowerShell 5.1-compatible script owns the ordered guest setup. - No CMD/batch script or mixed shell pipeline is generated. - After validating mapped bootstrap inputs, bootstrap invokes the global Base's strict `Registry` phase as the first guest mutation. - Unless output was explicitly enabled in the fixed launch plan, that phase selects the No Sounds scheme and uses the inspected Core Audio COM contract to mute the default render endpoint at scalar zero with read-back. - When microphone input is also off, it then disables/stops `Audiosrv` and `AudioEndpointBuilder` and verifies both service contracts; when input is on, it retains those shared services because capture depends on them. - An absent render endpoint is acceptable. - The service-disabled path blocks ordinary application playback, while the input-enabled path starts muted but permits guest applications to unmute output; neither is an adversarial security boundary against administrator code in the guest. - The phase then performs and reads back all reviewed registry writes before any WinGet download, AppX registration, package installation, or tool provisioning and performs one Explorer stop-empty-start cycle only when state changed. - Bootstrap later invokes the same script's `Development` phase; a changed and verified taskbar policy triggers its separate final Explorer restart, while no second registry owner, duplicated settings table, or deferred registry refresh state exists. - WinGet bootstrap follows Microsoft's documented direct-package Windows Sandbox path. - It resolves the current stable `microsoft/winget-cli` release, binds the Microsoft App Installer bundle and dependency ZIP to that release's exact SHA-256 values, installs the x64 dependencies and bundle with `Add-AppxPackage`, and runs the installed `winget --version`; an unexpected rendering is diagnostic only. - The fresh guest lacks `VCRUNTIME140.dll`, which the released `herdr.exe` imports. - Bootstrap therefore resolves the current stable Microsoft x64 VC++ v14 redistributable through exact WinGet metadata and installs that version silently. - An inconclusive installed-version listing warns and continues because later executable startup owns the required capability. - Windows 10 Sandbox cannot reliably install the OpenSSH optional capability. - Bootstrap instead inventories official Win32-OpenSSH releases, prefers the newest published stable release with one digest-backed Win64 server MSI, and uses only a strictly named `Preview` MSI when no usable stable server release exists. - It binds the selected MSI to its published SHA-256, installs only the server feature, checks executable file versions plus the `sshd` banner as warning-only diagnostics, and then requires the project's key, shell, service, and firewall configuration to succeed for that signed installation. - The management OpenSSH service remains on TCP 22 for app-owned host automation. - When mobile keys are selected, a second independently configured `sshd.exe` binds only the verified Tailscale IPv4 on TCP 2222, permits only the fixed Sandbox user with public-key authentication, disables forwarding, and is protected by an exact tailnet-source firewall allow rule. - A higher-priority firewall block prevents tailnet clients from reaching management TCP 22. - The listener is absent when no mobile key is configured. ### Herdr Runtime And SSH - `herdr-win` is the required maintained Windows distribution because official upstream does not yet support running the Herdr server on Windows or provide the remote-provisioning behavior this workflow depends on. - It supplies both support for the Herdr server on Windows and the exact unattended `--remote --provision --yes --json` contract; the CLI and executable remain `herdr` and `herdr.exe`, while bounded `herdr --version` output must contain the exact case-sensitive `herdr-win` marker. - Its installer, release channel, and managed-install layout remain outside Sandbox ownership. - This repository publishes only Sandbox-owned files and never bundles or declares a package dependency on Herdr-Win. - Before CLI-owned cleanup or lifecycle mutation, `up` and `attach` resolve the standard host `herdr.exe` command, run bounded hidden `--version`, `--remote`, and `status client --json` probes, and resolve the active physical runtime reported by that public status contract. - The version probe rejects every identity without the exact case-sensitive `herdr-win` marker before capability inspection. - Client status must match the exact current `version|herdr_version|build_id|protocol|binary|session` schema, including a build ID consistent with the runtime identity; its independently formatted runtime version remains bounded status data and is not compared with `--version`, while it owns protocol and active physical-runtime discovery. - The remote probe first verifies target parsing, then removes `PATH` and invokes an invalid target with exact `--provision --yes --json` so only a compatible implementation can reach its first `ssh.exe` lookup without starting SSH or network activity. - Success, timeout, empty output, crashes, unrelated failures, `unsupported`, a missing command, or an invalid identity fails closed. - Sandbox never invokes a host package manager for Herdr or assumes how the host command reaches its physical executable. - Fresh run input contains no Herdr executable, ConPTY bundle, or runtime manifest. - Go fingerprints the selected host command, physical runtime, and complete adjacent ConPTY file set so a mid-operation host update fails closed, while deployment belongs exclusively to the host Herdr remote provision command. - The administrator authorized-key file is restricted to SYSTEM and the built-in Administrators SID. - Password authentication is disabled for the automated endpoint. - Guest bootstrap configures OpenSSH's default shell to verified PowerShell 7 and publishes a connectable schema containing only IP, SSH identity/host key, and WinGet version. - Go transfers development configuration, atomically replaces `%APPDATA%\herdr\config.toml`, installs the reusable `sandbox` SSH alias, and invokes exact `herdr --remote sandbox --provision --yes --json` under a five-minute context with inherited Herdr routing variables removed. - The strict result accepts only target `sandbox`, platform `windows-x86_64` or `windows-aarch64`, one canonical absolute local `herdr.exe` path returned by Herdr, `installed|already_matching`, `started|reloaded|restarted`, and the selected distribution version/protocol. - Fresh flow requires `started`; retained flow requires `reloaded` or `restarted`. - An installed binary cannot claim an unchanged-server reload. - Go publishes the accepted Herdr-owned executable path as machine-owned `HERDR_SANDBOX_HERDR_EXE` only after provision success and guest-side proof that the executable and its parent are non-reparse filesystem entries. - The same bounded publication makes its physical directory the unique first machine `PATH` entry and proves `Get-Command herdr.exe` resolves that exact file. - Because the already running server cannot inherit a later machine-environment update, bootstrap passes that resolved machine/user PATH and `HERDR_SANDBOX_HERDR_EXE` through Herdr's existing workspace launch environment for every initial mapped-project root. - Bootstrap uses the exact executable through the same bounded Job Object process owner for strict client identity and initial workspace/pane creation, Base uses it only for the TCP 2222 mobile profile, and independent SSH verification parses only bounded stdout as strict `status server --json` evidence for running, compatible, no restart needed, matching runtime/protocol/binary, and detached-server capability; PowerShell/SSH stderr remains diagnostic and cannot corrupt JSON. - Ready schema 3 records distribution and runtime versions, protocol, and the exact returned executable path. - Retained reprovision verifies SSH without rejecting stale ready Herdr metadata, provisions and verifies the current runtime, then atomically replaces ready identity before later mobile and unchanged-host checks, so a partial post-provision failure remains retryable. - No Sandbox-owned binary copy, wrapper, temporary config, direct server start, duplicate reload, alternate executable discovery, or compatibility bridge remains. - The Herdr thin client remains on the host and attaches through the untouched PATH command with `herdr --remote `. - Ready/reprovision/attach identity checks require its current distribution version, runtime version, and protocol to equal the guest; fresh and retained `up` also re-hash and compare the selected command, physical runtime, and complete file set immediately before reporting success. - A host command or runtime change after a guest becomes ready is handled by retained `up`, whose single remote provision owner reloads or restarts as required instead of forcing guest replacement. - Plain `attach` remains nonmutating and fails closed on identity drift. ### Console And Diagnostic Boundaries - Before normal `up` performs cleanup or any provisioning, and before explicit `attach` opens the ready connection, the Windows adapter requires all three inherited standard streams to be real console handles. - Redirected/headless orchestration is rejected with the intentional `up --no-attach` path; native automation reads status separately and launches interactive attach only inside a real terminal. - After the user detaches, the CLI rechecks guest server status over a fresh SSH connection. - Windows host-client, Windows target bridge, and server-persistence fixes belong in the `herdr-win` project with their own tests/releases, not in a Go compatibility shim. - The bootstrap reports explicit progress and exactly one terminal outcome. - Errors cross the guest/host boundary as bounded diagnostic text without credentials or private key material. - The shared hidden-process `CombinedOutput` owner captures at most one MiB and terminates the owned process tree on overflow. - Diagnostic rendering preserves safe line/tab layout and UTF-8 head/tail context while replacing every other nonprinting terminal control before an error reaches the CLI. - A visible guest PowerShell window mirrors the active bootstrap phase for the user. - It runs the same single bootstrap process; the mapped JSON status files remain the automation and terminal-outcome authority. ## State And Contracts ### Run State And Published Contracts - Per-run files are ephemeral operational state. - Closing Windows Sandbox discards all guest state; the next valid CLI command removes stale host run diagnostics only after the lifecycle evidence above proves that no Sandbox process remains. - The optional stable Tailscale identity and mobile SSH server identity are separate durable credential state. - Each uses one strict envelope encrypted for the current host user with Windows DPAPI and atomically stored below the existing machine-local identity root; the mobile public key supplies the stable fingerprint while its private key exists in plaintext only in bounded host memory and over the verified management SSH channel. - Automatic and explicit cleanup share one run planner/remover: they delete only child directories whose names match the exact run-ID contract and whose complete trees contain no reparse points; the runs root, unknown entries, unsafe candidates, SSH identities, Tailscale identity, user configuration/provisioning, workspaces, and package/tool cache are never followed or removed. - When no Sandbox remains, cleanup removes only the exact regular non-reparse `%LOCALAPPDATA%\herdr-sandbox\ssh\config`; the marked include in the user's SSH config remains as the stable integration point and is repopulated on the next verified run. - Publishing or removing the marked user SSH include uses an optimistic content contract: installation rereads and retries at most three times, while both install and uninstall stage atomically and compare the exact previously read bytes immediately before replacement. - This preserves edits observed before that comparison and materially narrows the prior lost-update window. - Windows has no stdlib conditional rename, so an external editor writing in the final compare-to-rename interval remains a documented residual race rather than justification for a second native in-place file writer. - A nonterminal connectable contract contains only guest IP, management SSH identity/host key, and WinGet version. - Herdr identity does not exist until host-owned remote provisioning succeeds. - The host-written completion handoff optionally adds one strictly validated secret-free mobile URI, host-key fingerprint, and QR matrix. - Bootstrap validates the published provisioned Herdr executable, creates initial workspaces, activates the prepared listener, and then publishes terminal ready; any failure remains nonattachable. - Each retained reprovision owns one strict, host-only `\operation.json` current/latest contract containing operation/run IDs, kind, running or terminal state, bounded phase/message, and ordered UTC timestamps. - The guest-writable status mapping cannot forge it. - A terminal retained failure remains separate from ready guest health; immediately after any public lifecycle path freely acquires the lock, a matching running record is atomically marked interrupted before inspection, close, replacement, or deletion. - A new operation cannot overwrite a still-running record. - Status enriches lifecycle truth from the strict guest workspace manifest and at most eight of 128 bounded timing records without exposing host workspace paths, credentials, raw command output, or terminal-control sequences. ### Installer Cleanup And Terminal Status - Installer cleanup is a separate destructive terminal owner, not an expansion of normal `clean`. - Before repair, upgrade, or uninstall takes the existing local application lifecycle mutex, NSIS invokes the installed executable's hidden `--installer-stop-processes` command. - Its five-second context enumerates only same-basename candidates, opens each candidate once with query/terminate/synchronize rights, validates the full image path against its own installed executable path, excludes itself, terminates exact peers without their descendants, and waits on each retained process handle. - It never targets `WindowsSandbox.exe`, so the guest remains available for the replacement executable to reconnect through retained AppData state. - NSIS then holds the lifecycle mutex continuously through replacement or the hidden cleanup command, `CleanupComplete` commit, registration deletion, and recursive removal of the fixed installer-owned binary root. - The exact `--installer-lifecycle-lock-held` child path skips reacquisition while every normal lifecycle command continues to acquire the same mutex. - Cleanup validates physical non-reparse roots and the exact managed SSH include, surgically removes that block, always removes the exact app-owned `config.sample.json` and `config.schema.json`, then attempts app-owned state/cache and explicitly selected user-configuration cleanup. - A locked cache/state file is a preserved nonblocking residual. - The exact `--delete-configuration` flag is supplied only after that protocol by the checked **Also delete config.json and user.ps1** option or silent `/DELETE_CONFIG`; otherwise user-owned configuration is untouched. - A running Sandbox is preserved as unmanaged. - Project profiles, persistent worktrees, unrelated SSH content, and unselected configuration remain outside the binary-root owner. - Terminal failure outranks stale progress. Host waiting is cancellable and has a four-hour default overall deadline. A positive explicit `--timeout` replaces that deadline for one run, a parent context may cancel sooner, and external-operation owners retain their narrower timeouts. ### SSH Integration And Compatibility - Per-run identity and known-hosts files remain app-owned. - The Sandbox tool updates a stable app-owned `Host sandbox` file and owns one idempotent, marked `Include` at the start of the user's standard SSH config; unrelated user content is preserved. - That first matching target explicitly disables `ControlMaster`, `ControlPath`, and `ControlPersist`: official Win32-OpenSSH design and the installed 9.5 client confirm that Windows lacks the AF_UNIX ancillary file-descriptor path required by OpenSSH multiplexing. - Reuse means reconnecting fresh SSH clients to the same ready guest and persistent Herdr server, not sharing one TCP connection. - The `herdr-win` project owns generic Windows SSH behavior matching Unix: it builds a private temporary config that includes the normal user and system SSH configs before Herdr keepalive defaults, then passes that file to `ssh.exe -F`. - It has no Sandbox-specific target knowledge or required environment-variable contract. - Superseded application and installer contracts are not supported through backward-compatibility state, schema versions, dual read/write paths, aliases, migration code, replacement filenames, historical marker parsers, or cleanup bridges. - Setup accepts only its current product GUID, registration, payload names, and direct application protocol. - Historical releases do not create an implicit compatibility contract; any future exception requires an explicit current-user decision and a matching canonical contract in the same milestone. ## Development Provisioning ### Shared Models And Worktree Projection - The strict optional `modelsDirectory` reuses the mapped-directory validation owner for one existing absolute physical non-reparse host root and maps it read/write only to `C:\Models`. - It cannot overlap configuration, cache, private run state, worktrees, workspaces, or generic mounts. - Its identity is part of the immutable `.wsb` launch contract, so drift reports `models directory` and requires a fresh guest. - Before launch or retained provisioning, one host owner resolves `hdosys/hyperframes-voxcpm2` through the fixed GitHub `releases/latest` API, accepts only a stable semantic tag and exact archive plus SHA-256 sidecar assets, and uses Windows curl with normal certificate validation, HTTPS-only origins and redirects, bounded transfer controls, no user curl configuration, and no inherited custom CA or TLS-key-log override. - GitHub's asset digest, the sidecar, archive hash, safe ZIP shape, embedded manifest, HyperFrames version, runtime commit, exact Hugging Face revision and file hashes, and exact reference audio identity all bind the result. - Model downloads use partial files plus atomic replacement. - The release archive, sidecar, current descriptor, models, and completion record share the writable model root and survive normal clean or uninstall; because guest tools may modify that root, HyperFrames provisioning rehashes every selected VoxCPM2 artifact immediately before activation. - Guest worktree instruction projection keeps its runtime overlay out of shared configuration history. For every physical Git-backed agent root, PowerShell installs one bounded filter asset below `C:\HerdrSandbox` and registers the same command for required clean and smudge directions through local `.git/config` and `.git/info/attributes`. Clean removes only the exact marked block; checkout passes ordinary indexed instructions through so linked worktrees remain usable. A routing file with no host source stays excluded through `.git/info/exclude`. Legitimate guest workflow edits remain stageable, while the filter and attributes remain guest-local metadata and never enter a commit or host configuration. ### Configuration, Mounts, And Workspace Selection - Development-provisioning PowerShell 5.1 files remain external to the Go binary. - Release-owned `base.ps1` and `stacks.ps1` beside the executable are the only built-in provider/adapter authority and are refreshed by installing a new application release; Go validates and snapshots both for each run. - The same Go seeding owner creates `%APPDATA%\herdr-sandbox\config.json` and the single user-owned `user.ps1` extension only when absent, then refreshes each app-owned configuration sample and embedded JSON Schema file atomically: setup invokes it after installing the executable, portable use invokes it on the first mutating provisioning path, and `sandbox config` refreshes the references before opening the user file. - Existing user files are never replaced. - The complete illustrative `config.sample.json` and adjacent `config.schema.json` are reference assets rather than runtime authorities. The strict Go decoder and semantic planning path remain authoritative; the schema is never fetched or used as a second validator. The optional `$schema` field accepts only `./config.schema.json`. - Existing legacy `%APPDATA%\herdr-sandbox\base.ps1` content is never overwritten or executed as a second Base owner; migration must preserve it and require one explicit user-owned-extension outcome. - Machine-local runs, identity, and SSH state remain below `%LOCALAPPDATA%\herdr-sandbox`. - The strict optional `mounts` object adds at most 16 named non-workspace mappings. - Each entry has exactly `path` and `readOnly`; Go resolves an existing absolute regular non-reparse directory, rejects whole-volume and protected-root exposure, derives only `C:\Mounts\`, and feeds the same physical overlap validator used by cache, run state, and workspaces. - These mappings exist before the logon command but never enter provisioning inspection, workspace manifests, configuration sync, or Herdr workspace creation. - Their host identity and access bit are part of the immutable `.wsb` launch contract, so retained reuse reports `folder mounts` drift rather than mutating a running Sandbox. - Before recursive uninstall cleanup, the same config paths are revalidated lexically and physically against cache, machine-local state, and the optionally selected configuration root so mounted user data cannot be deleted. - The strict optional `worktreeDirectory` is one existing absolute physical non-reparse host directory mapped read/write only to `C:\Worktrees`. It reuses mapped-directory sensitive-root and physical-overlap validation, must remain outside configuration, cache, private run state, workspaces, and generic mounts, and is part of the immutable `.wsb` launch contract. A changed mapping reports `worktree directory` drift rather than mutating a ready guest. Configuration sync patches the transferred guest Herdr config to `[worktrees].directory = "C:/Worktrees"` and extends the exact Git safe-directory set with `C:/Worktrees/*`; `Git.Git` is therefore required. One embedded Markdown asset owns the guest worktree-routing text and enters the configuration archive only when this mapping is enabled. Guest PowerShell idempotently prepends or replaces its exact marked block after copying each selected agent's native global instructions: OpenCode `.config\opencode\AGENTS.md`, Claude Code `.claude\CLAUDE.md`, Codex `.codex\AGENTS.md`, Pi `.pi\agent\AGENTS.md`, and a dedicated Copilot `.copilot\instructions\herdr-sandbox-worktrees.instructions.md`. Missing files are created, host files remain untouched, repeated sync is stable, and malformed or duplicate ownership markers fail closed. `%USERPROFILE%\.agents\skills` remains only the existing shared-skills owner. The block routes create/list/open/remove mechanics through native `herdr worktree` commands but explicitly defers creation and cleanup policy to applicable user/project instructions. Native Herdr delegates checkout creation and removal to Git under its existing `//` layout while opening and closing the corresponding Herdr workspace; removal does not delete the branch. Sandbox owns no worktree lifecycle state, leases, pruning, or cleanup, and normal clean plus uninstall preserve the selected root. Linked metadata remains in each mapped main repository and records guest paths, so the same main checkout must retain its guest workspace path across launches; direct host-side worktree use and portable relocation are outside the contract. - `%APPDATA%\herdr-sandbox\config.json` is a strict JSON object whose `workspaces` map assigns unique names to absolute project roots, whose optional `workspaceDiscovery` object has only `root` and `exclude`, whose optional `memoryMB` defaults to 32768 with a minimum of 2048, and whose optional exact booleans `audio`, `audioInput`, and `tailscale` all default false. `audio` controls guest playback policy; `audioInput` controls the generated `.wsb` `AudioInput` value and whether Base must retain shared audio services. An empty or omitted discovery root is disabled. A nonempty root is absolute, existing, physical, must not physically contain the host profile or AppData roots through any alias, and is never mapped; Go reads at most 4096 direct entries, ignores nondirectories, applies at most 64 bounded Go/RE2 expressions to each original directory name, and selects every remaining physical child as a workspace and strictly validates its project profile only when that optional file exists. Explicit workspaces are resolved first and retain their configured name when a discovered child resolves to the same physical path; any other case-insensitive derived-name collision fails. Discovery never recurses, follows a reparse point, or bypasses the combined 16-workspace and overlap limits. Tailscale opt-in is invalid when `Tailscale.Tailscale` is removed from the resolved package plan. A nonzero `--memory-mb` value is the one-run override; the resolved value and both audio selections are written once into the generated `.wsb` launch contract, so any change prevents retained-guest reuse. Starting at the current directory, `sandbox up` also finds the nearest `.herdr-sandbox\provision.ps1`, deduplicates it by physical path, and marks it active. Mapped roots need not own that script; they must not overlap and are fixed before launch under `C:\Workspaces\`. Immediately before `.wsb` rendering, every mapped directory must exist, resolve to the same physical path, and contain no symlink/junction/reparse alias; overlap checks run on those canonical paths. - The strict optional `mobileSSHAuthorizedKeys` config field is a non-null array of at most eight unique canonical Ed25519 public keys; a nonempty array requires Tailscale. Go removes optional one-token comments, sorts the keys into one immutable per-run input, and requires a fresh Sandbox when that canonical set changes. No password, device private key, mobile-client profile, or compatibility key type enters this owner. ### Package And Agent Sync Planning - The strict optional `wingetPackages` config object has only `remove`, `add`, and `versions`. Go validates exact package IDs and versions, protects Core PowerShell 7, rejects unknown default removals and versions outside the effective set, and resolves one case-insensitive final package plan before launch. An omitted package version means WinGet's latest/highest available version for that exact package ID; an explicit version remains exact with no fallback. That plan controls Base installation and the Git/GitHub CLI/Starship/Terminal/WinDirStat/File Pilot integration prerequisites; no guest-only skip list, package registry, or second package configuration exists. Fresh and in-memory defaults select the four coding agents with verified WinGet packages (`SST.opencode`, `Anthropic.ClaudeCode`, `OpenAI.Codex`, and `GitHub.Copilot`), while an explicit empty or alternate `add` list remains authoritative. OpenCode's existing conditional portable-package adapter is selected only when `SST.opencode` is present. `KhronosGroup.VulkanRT` remains an ordinary optional addition, but Base conditionally requires its installed `vulkaninfo --summary` boundary to enumerate at least one physical device; no second Vulkan setting, SDK, D3D mapping package, host-driver copy, or `EnableVendorExtensions` launch path exists. The separate strict `codingAgentSync` object has exactly five configuration-selection booleans (`opencode`, `claudeCode`, `codex`, `githubCopilot`, and `pi`) initialized true before strict decoding. The separate strict `credentialSync` object has exactly six credential-selection booleans (`opencode`, `claudeCode`, `codex`, `githubCLI`, `pi`, and `tradingView`) initialized false. The separate strict `configurationSync` object has exactly `pullHostGitRepositoriesOnUp` and `pullHostGitRepositoriesOnDown`, initialized false. These three selections own configuration transfer, credential transfer, and host Git updates independently. - The coding-agent archive includes the official Herdr integration files found inside each selected configuration root. Its strict manifest carries only the source hook paths needed to translate copied Claude Code, Codex, and GitHub Copilot JSON command strings from the host profile to the fixed guest configuration roots. Windows PowerShell 5.1 replaces those exact JSON-escaped path substrings after verified copy, preserves all other bytes, and fails closed when an archived hook has no matching registration. OpenCode uses its relative TUI plugin specification and Pi loads its extension directly, so neither needs path translation. After remote Herdr provisioning and server verification, one Go owner parses `herdr integration status`, preserves every state except exact `not installed`, checks the selected agent command through the refreshed guest PATH, invokes Herdr's own installer only for available missing targets, and requires each installed target to report current. Fresh and retained provisioning share that owner. - Credential selection is dynamic provisioning state. Fresh `runPlan` and retained reprovisioning carry it into configuration sync, but `activeSession`, `.wsb` compatibility, and immutable ready-state comparison do not. Turning a field off therefore changes the next transfer without forcing guest replacement or deleting retained guest credentials. ### Provisioning Composition And Core Stacks - App-owned Base runs one strict `Registry` phase and later one strict `Development` phase under Windows PowerShell 5.1. - Development loads app-owned stack helpers, invokes the immutable user extension once, then invokes each present mapped-project 5.1 script in deterministic name order; unprofiled workspaces remain mounted without project provisioning. - Stable PowerShell 7 installation and non-executing package/file verification are Core/Base responsibilities solely because Herdr, OpenSSH, and Windows Terminal use it interactively after provisioning; no user/project script owns or reinstalls it, and configuration sync never uses it as an interpreter. - Base may expose reusable verified package-cache and concrete installer-adapter functions to the user and project scripts; an adapter's presence does not make its tool global, because ownership is determined by the caller. - Project provisioning installs and verifies only its required toolchain and does not rerun repository test, lint, or build suites on every Sandbox start; representative commands are an explicit post-ready native acceptance gate. - No root-level same-name script, generic stack registry, or plugin framework is introduced. - The optional project customization surface is one nearest `.herdr-sandbox\provision.ps1` accepting mandatory `ProjectDirectory`; the separate global customization surface is only `user.ps1`. `init` validates every explicit selection before creating a regular `.herdr-sandbox` directory and uses exclusive file creation to write deterministic direct calls only; it never guesses from repository contents or overwrites an existing/ancestor profile. The exclusive `all` selection expands once to every generic technology, tool, and composition owner, including `audio`, `hyperframes`, and `python-ai`, while keeping only the checkout-specific `handy` and `herdr` compositions separate. Its single Python AI call owns the current stable Python and uv path instead of writing redundant direct calls. The init-only `herdr` virtual selection writes one `Install-HerdrStack` call and rejects redundant included Python, Rust, or Zig selections. `plan` resolves missing global files to in-memory defaults, copies bounded scripts only to one cleaned temporary inspection directory, and runs the same nonexecuting AST adapter even when workspaces have no project profiles so global stacks and their package owners remain visible; it creates no config, run, SSH, cache, or host-tool state. Before launch, that bounded app-owned Windows PowerShell 5.1 adapter parses but never executes each present project script, rejects parse errors, recognizes direct calls to concrete built-in stack functions, and expands `Install-HerdrStack` into its concrete Python/Rust-MSVC/Zig/Bun/Nextest/Just/`git-sh` requirement identities; the included Rust-MSVC identity triggers host Visual Studio preparation. Dynamic invocation, aliases, calls hidden in another dot-sourced file, and arbitrary requirement comments do not select stacks. Base later invokes user and present project scripts in child scope so they inherit verified Base/stack functions without a function registry, JSON/YAML profile DSL, or plugin discovery. Base, stack, and user contract markers version those surfaces; user/project scripts verify the state they own. - The single app-owned `provisioning/stacks.ps1` exposes `Install-HerdrStack`, `Install-BunStack`, `Install-DotNetStack`, `Install-GoStack`, `Install-NodeStack`, `Install-PythonStack`, `Install-ZigStack`, `Install-RustMSVCStack`, `Install-CargoNextest`, and `Install-Just`; its Node path internally reuses `Install-PlaywrightChromium`. `Install-HerdrStack` mirrors the maintained Herdr-Win Windows profile and official upstream Windows constraints without adding another installer: it requires `Cargo.toml`, resolves current stable Python and Zig unless an explicit project selection wins, lets the standard Rust/MSVC stack use `rust-toolchain.toml` only when no explicit toolchain or stack constraint wins, reuses latest-stable Bun, Nextest, and Just, and persists `LIBGHOSTTY_VT_ZIG_OUT_DIR` below `C:\HerdrSandbox\build\cargo-target` for mapped-workspace safety. Conditional Base Git for Windows remains the sole shell owner: its package integration derives and validates regular `bin\sh.exe`, adds only that directory to machine `PATH`, and requires a GNU Bash version readback; it does not add another shell package or expose Git's broad Unix-tools directory globally. Modern .NET resolves the highest stable numeric `Microsoft.DotNet.SDK.` family and latest SDK: WinGet concretizes its stable x64 Burn metadata and digest, the existing cache owner installs it with the publisher's `/install /quiet /norestart` contract, accepts only installer success or restart-required success (`0` or `3010`), and then verifies the absolute `C:\Program Files\dotnet\dotnet.exe` from its installation directory so a project `global.json` cannot redirect `--version`; both `--version` and `--list-sdks` must show the exact selected SDK under `C:\Program Files\dotnet\sdk`. No .NET Framework, preview SDK, Visual Studio workload, `dotnet-install.ps1`, compatibility alias, or migration path exists. Omitted versions resolve latest stable once. For Playwright, Node invokes its installed npm CLI through `node.exe`, resolves `playwright@latest` to one validated exact stable version unless `PlaywrightVersion` is explicitly supplied, then disables lifecycle scripts, optional packages, and bin shims while installing that exact resolved tooling under version-keyed `C:\HerdrSandbox\tools\playwright\`. It invokes only `install chromium`; Chromium remains guest-local under `C:\HerdrSandbox\tools\playwright-browsers`, the machine `PLAYWRIGHT_BROWSERS_PATH` exposes that path to later SSH/project processes, and an `about:blank` PNG smoke proves a real headless launch. No project `package.json`, lockfile, `node_modules`, host browser, mapped executable path, or agent-selected default version pin is mutated or introduced by this stack responsibility. Rust-MSVC alone owns rustup, Cargo, the verified Rust mirror, and Visual Studio installation; .NET, Zig, Python, Bun, Nextest, and Just remain independent stacks, while TypeScript, Playwright test packages, npm dependency selection, and .NET target frameworks remain project dependency state. Host Herdr remote provisioning parses only its bounded stdout as the strict JSON terminal result; stderr remains a separate diagnostic channel so successful notices cannot corrupt that result. - The Base extension boundary wraps global and project scripts only to identify their canonical profile owner; the original PowerShell failure remains the terminal cause. - Before fresh or retained guest mutation, the same bounded Windows PowerShell 5.1 AST inspection used by `plan` records direct built-in stack calls and their literal version, series, toolchain, and applicable project-directory selectors without executing project code. Generic stacks consume no project manifest or dependency state and therefore accept an otherwise empty mapped project. The shared merger records one strict source for every tool selection: an explicit provisioning value or incompatible stack constraint is considered first; an explicitly selected project source participates at that same level; only then may an automatically discovered optional project version file contribute; otherwise the stack default or latest-stable resolver owns selection. Equal winning values survive and incompatible values at the winning level fail with every owner. Missing optional files never fail. `$projectPlaywrightVersion` remains the one explicit project-file selector and requires matching stable Playwright identities in bounded `frontend\package-lock.json` v3 state. Rust reads a bounded exact `rust-toolchain.toml` channel only when no explicit value or stack constraint already selected `rust-toolchain`, separately from `Rustlang.Rustup`; Base rechecks a selected mapped file against the immutable plan in the guest. Go no longer accepts `ProjectDirectory` or inspects `go.mod`. The sorted schema-2 `tool-versions.json` carries the winning source beside version, series, and owners for fresh and retained provisioning, while `sandbox plan` prints the same selection, source, precedence, and owners. Existing WinGet, npm, Python, Rust, and direct-manifest resolvers concretize an empty slot once in memory, and every later stack call reuses that exact value without adding another resolver or persistent version state. - Only the Python, .NET SDK, and Microsoft OpenJDK stack owners use bounded WinGet ID search to select the highest stable numeric package family. Base additions and File Pilot inspect their already known installed IDs first, skip installed unpinned packages, and install a missing exact ID directly; an omitted version lets that install select WinGet's highest available version. Cached package adapters resolve only the exact ID metadata they need. - The same stack owner exposes `Install-CppStack` and `Install-JavaStack`, and the nonexecuting planner gives each one a separate concrete identity. - C/C++ selects the existing host Visual Studio layout requirement also used by Rust, installs Current only when its exact Build Tools version is absent, resolves current stable CMake through the shared hash-verified cached MSI owner, and invokes Microsoft's installed `Launch-VsDevShell.ps1` with x64 target and host architecture. - It persists only the compiler environment and exact command directories needed by fresh shells, exposes CMake through the same verified machine PATH owner, then compiles, links, and runs one C and one C++ probe through the bounded native-process owner. - Compiler-only calls use object-embedded `/Z7` information; separate verified linker calls explicitly disable PDB output. - Because current MSVC can retain its PDB server after either tool root is terminal, only these compiler and linker probes opt into terminating residual processes in their atomically assigned Job Object after preserving root exit code and output. - Each tool keeps its own deadline; installers and other child-producing paths still wait for their complete trees. - Java resolves the highest stable numeric `Microsoft.OpenJDK.` family and latest update at provisioning time, then reuses the cached signed MSI adapter with the publisher's Main, PATH, and `JAVA_HOME` features. - Before installing a nonmatching target, the exact WinGet package owner performs the manifest-required bounded silent uninstall of prior versions in that selected family and proves none remain. - It then validates the publisher root and compiles and runs one Java class. - No additional compiler or JDK provider, package registry, project mutation, compatibility family, or Java build-system stack is introduced. - The same direct stack owner exposes `Install-AndroidStack`, and the planner gives it one `android` identity. - The stack resolves Google's current stable Windows Command-line Tools plus published SHA-256 and reuses the current stable Microsoft OpenJDK family, validates exact safe archive and package identities, requires Google Authenticode on `android.exe`, and installs below app-owned tool roots. - It persists `ANDROID_HOME`, guest-local `ANDROID_USER_HOME`, and the shared verified JDK as `ANDROID_JAVA_HOME`. - The signed CLI installs latest-stable Platform Tools when absent. - Retained provisioning does not rerun that crash-prone package operation when the existing safe tree, source metadata, ADB version, and wireless `pair`/`connect` commands verify exactly; malformed or incomplete state fails closed. - Android SDK platforms, build tools, Gradle wrappers/distributions, emulators, NDKs, application dependencies, and project files remain project-owned. - Windows Sandbox has no arbitrary USB mapping in its `.wsb` contract, so no host ADB proxy, host daemon, credential bridge, or compatibility path is introduced. ### Specialized Application Stacks - The init-only `audio` selection writes one direct `Install-AudioStack` call, and the planner gives REAPER and AudioGridder separate current-release identities. - REAPER resolves the newest stable WinGet metadata and uses the shared digest, cache, silent EXE, and Authenticode path; provisioning verifies the installed Cockos executable and Start shortcut without launching it. - The same stopped-process configuration owner atomically preserves unrelated `REAPER.ini` state while setting `verchk=0` before first launch, so the selected guest build never opens its own update prompt. - The official unsigned AudioGridder ZIP resolves from the latest stable GitHub release and is bound to GitHub's digest when published or to the exact once-downloaded payload otherwise. - Its installed release manifest binds source SHA-256 and every retained file hash. - The payload is safely extracted below `C:\HerdrSandbox\tools\AudioGridder` and reduced only by removing AAX. - The server remains at the single app-owned command path, while exact tray and VST2/VST3 client copies go to `C:\Program Files\AudioGridderPluginTray`, `C:\Program Files\VstPlugins`, and `C:\Program Files\Common Files\VST3`. - Server ID 0 scans only those canonical VST2/VST3 folders, uses chain isolation, disables crash reporting, and logs connection evidence. - The local guest client config targets `127.0.0.1:0`; its accepted purpose is REAPER-based native connection proof and optional guest-local use. - Two exact inbound guest firewall rules permit the default host gateway to reach server TCP 55056 and worker TCP 55088 through 56088. - The production host DAW/client remains manually managed and targets the current guest IP, while project or user provisioning owns every production VST binary in the guest. - Running REAPER, Plugin Tray, or AudioGridder Server blocks mutation of the config or firewall state it owns. - The Herdr plan expansion's concrete identities include Bun and Git-for-Windows `sh` in addition to Python, Rust/MSVC, Zig, Nextest, and Just. `Install-PythonStack` owns verified app-local `C:\HerdrSandbox\tools\python\bin\python.exe` and `python3.exe` copies for Python 3 selections, preserving the adjacent Windows base-executable layout required by project virtual environments. Retained provisioning excludes both those app-local commands and WindowsApps aliases while resolving the installed publisher runtime, then refreshes and revalidates both copies. Conditional Base `Git.Git` owns discovery, regular-file validation, PATH exposure, and GNU Bash readback for its shipped `bin\sh.exe`, accepting either its `cmd` or already-prepended `bin` command source on retained reprovisioning. Plan and launch preparation reject Herdr's `git-sh` requirement when `Git.Git` was removed. Only the libghostty output environment remains Herdr-specific; no second Python or shell provider exists. - The directly callable built-in `Install-PlaywrightCLIStack` shares `Install-NodeRuntime` with the existing Node/Chromium stack but has its own browser contract. It resolves npm's current stable `@playwright/cli` release unless an exact version was requested, installs that version and matching dependencies below `C:\HerdrSandbox\tools\playwright-cli`, persists the CLI-supported `NO_UPDATE_NOTIFIER=1` environment so the command does not query npm or write profile-local update-check state, removes npm's PowerShell shim so the observed Windows path is always `playwright-cli.cmd`, adds no Playwright browser payload, and registers official extension ID `mmlmfjhmonkocbjadbfplnigmagldckm` through Edge's documented external-extension Chrome Web Store URL. The extension and CLI own protocol 2: `attach --extension=msedge` opens the extension connection page in the already-running headed main Edge profile, and `detach` ends only the relay/session. Edge extension activation and its random profile-local token remain a manual first-use boundary in each fresh guest; the token may enter only disposable guest environment state and is never mapped, logged, or stored in a project profile. No force-install policy, remote-debugging fallback, alternate profile, or custom extension exists. - The directly callable built-in `Install-TradingViewStack` shares `Install-NodeRuntime`, npm cache/PATH helpers, and Base's cached portable extraction owner without invoking `Install-NodeStack` or adding Playwright Chromium. `TradingView.TradingViewDesktop` remains reserved from global Base additions. TradingView is an online client that enforces its own supported release, so WinGet version metadata is not an acceptance authority. Provisioning downloads the official `https://tvd-packages.tradingview.com/stable/latest/win32/TradingView.msix`, requires a valid Authenticode signature from the exact TradingView publisher before parsing it, derives version and x64 architecture from the bounded embedded Appx identity, computes the cache SHA-256, and extracts the unchanged payload below `C:\HerdrSandbox\tools\TradingView.TradingViewDesktop`. Base's existing portable owner adds only file-version readback so a GUI binary need not be launched during provisioning. The extracted `AppxManifest.xml` identity, publisher, version, x64 architecture, regular `TradingView.exe`, and exact PATH resolution are read back. This single path replaces AppX registration, whose embedded minimum rejects build 19041, and matches TVControl's own supported local-copy strategy; no modified manifest, older package, host mapping, or dual compatibility path exists. TVControl resolves latest stable once, installs or upgrades in `C:\HerdrSandbox\tools\tvcontrol` with lifecycle scripts and optional dependencies disabled, removes PowerShell shims, verifies both distinct `.cmd` command mappings, and invokes only the `tv` CLI help boundary. The `tvcontrol` entry is the long-lived stdio MCP server, so provisioning validates its package entry and command mapping without starting it. Native build-19041 proof covered visible launch, CDP, TVControl launch selection, health, API, connected datafeed, and compatibility. The inspected stack selection from the same global/project plan also enables one extension of the existing configuration archive: Go reads only the installed `TradingView.Desktop_n534cwy3pjxzj` package's `LocalCache\Roaming\TradingView` profile, requires a physical schema-24 cookie database and exact SQLite storage classes, and emits at most four complete plaintext `sessionid` plus `sessionid_sign` pairs for exact TradingView domains. The strict schema-2 envelope and embedded PowerShell 5.1/C# adapter travel only through verified SSH; the adapter transactionally replaces those allowlisted guest rows in portable plaintext form and verifies them while preserving every unrelated cookie. It never transfers the raw cookie database or broker/site state. Missing host profile/session is a verified empty import, and a running guest Desktop fails refresh without being terminated. Provisioning never starts Electron or opens CDP 9222; later launch, MCP, diagnostics, and chart state remain explicit user operations, while mapped project dependencies and agent configuration stay untouched. - TradingView authentication export discovers at most eight sorted numeric `TVUserStorage\id-*` identities backed by bounded current-shape settings files and publishes strict schema 3. It transfers only those identifiers, never the host settings. The in-memory configuration archive carries one repository-owned credential-free initial settings file that opens `https://www.tradingview.com/chart/`; guest apply atomically creates it only for a missing authenticated identity, verifies its digest, and preserves every existing valid user settings file. The existing SQLite adapter also writes two fixed guest-owned `.tradingview.com` preferences before first launch: `cookiesSettings` rejects analytics and advertising, while `cookiePrivacyPreferenceBannerProduction=reject` records the consent decision. It replaces only those preferences and the optional imported session pair, preserves unrelated cookies, and leaves a running Desktop untouched. This gives the first Desktop start a restorable chart state without a privacy or Welcome modal blocking TVControl, while adding no host-cookie transfer, GUI automation, or second profile owner. - The init-only `python-ai` selection writes one direct `Install-PythonAIStack` call and rejects the overlapping Python and Herdr choices. The AST planner expands that virtual call to the concrete `python` and `uv` owners without executing it. `provisioning/stacks.ps1` additionally exposes `Install-Uv` and `Install-PythonAIStack`: the composition resolves the highest stable Python package family and latest-stable `astral-sh.uv` through the existing hash-verified cached adapters. The uv owner verifies its command/version and exact reported cache directory, persists `UV_CACHE_DIR=C:\HerdrSandbox\cache\uv`, and sets `UV_NO_MANAGED_PYTHON=1` so uv cannot create a second runtime path. The shared cache is uv's concurrency-safe, versioned dependency cache; project `.venv`, `pyproject.toml`, `uv.lock`, framework packages, notebooks, provider SDKs, and model data remain project-owned. The accepted path is CPU/API development; CUDA is not inferred from vGPU or experimental Vulkan and requires a separate native hardware contract. - The init-only `handy` selection writes one direct `Install-HandyStack` call and rejects overlapping Rust or Herdr choices. The AST planner expands it to Bun, Rust/MSVC, and one Handy-native package identity, so the existing Visual Studio layout owner is selected without another host requirement path. The stack validates Handy's package, Bun lock, Cargo package, and checked-in VAD model identities and resolves latest-stable CMake, Vulkan SDK, and WebView2 through WinGet metadata. Bootstrap installs the current stable Microsoft VC++ runtime before development provisioning because the selected Vulkan SDK WinGet manifest declares that runtime dependency and direct cached-installer execution does not ask WinGet to install dependencies. Base's generic EXE adapter requires caller-supplied exact arguments and reuses the existing signature, digest, cache, process-tree, and installed-package checks. Because the SDK's bundled SPIRV-Headers config resolves an invalid unversioned include root, the stack writes one guest-local imported target for the verified versioned headers. The Handy probe loads the verified app-owned Visual Studio developer environment, gives CMake 30 seconds to validate the Vulkan and corrected SPIRV imported targets with no compiler language enabled, compiles their headers to an object within 60 seconds using the same root-terminal compiler-helper cleanup contract, then links and runs it under separate 30-second deadlines. This reuses the proven MSVC probe path without a CMake build or reusable MSBuild/PDB lifecycle. Project dependencies, model downloads, ONNX Runtime packaging, signing, and project mutation remain outside provisioning. - The standard Rust/MSVC stack gives rustup the hash-verified local distribution mirror through its supported `file:` download path, so a Rust or Handy plan has no hidden Python helper, port, readiness loop, or cleanup lifecycle. - The same stack owner also exposes the separate `Install-NSISStack` identity and reserves `NSIS.NSIS` from global Base additions. The shared cached WinGet metadata owner defaults to x64 but accepts the package's explicit x86 architecture and an explicit payload extension for SourceForge-style download URLs. NSIS resolves latest stable unless requested exactly, validates x86/nullsoft/machine metadata and digest, invokes the official installer silently with `/S`, adds only the verified publisher install root to machine `PATH`, and compiles one minimal warnings-as-errors PE probe without launching it. This repository's project profile and `cmd/task package` use that same resolved compiler; no second compiler download, installer-builder abstraction, or project mutation exists. - The separate direct `Install-NushellStack` identity reserves `Nushell.Nushell` from global Base additions and participates in the existing literal-version planner. It resolves the x64 machine-scope WiX metadata through the shared WinGet owner, downloads and verifies the MSI through the existing cache, installs with the publisher's `ALLUSERS=1` contract, and requires exact `%ProgramFiles%\nu\bin\nu.exe` PATH plus successful command startup. One provisioner-owned file in Nushell's standard vendor autoload directory sets `show_banner` to false and includes the output of the selected `starship init nu`; provisioning sources that exact file through `nu.exe` and verifies its data root, banner state, and Starship shell identity without replacing user `config.nu`. No plugin, Rust owner, or second shell lifecycle is added. - Generic command verification preserves merged native diagnostics but treats version rendering, package-version correlation, and duplicated executable or manifest version metadata as warning-only evidence after a successful command or installation. It never weakens selected-payload hashes, signatures, publisher identity, safe paths, process exit status, required command ownership, or real capability checks. Remote SSH PowerShell launchers catch terminating errors and write one plain exception message to standard error, preventing CLIXML from becoming user output. ### Runtime Publication And Windows Policy - Go writes one strict per-run workspace manifest from the already validated/mapped workspace plans. - Configuration sync first consumes it to replace host-specific Git `safe.directory` values with exactly those guest roots; after configuration completion is acknowledged, bootstrap consumes the same manifest to create one Herdr workspace per mapping and focus the active entry. - Neither side enumerates arbitrary directories or grants wildcard trust. - GitHub Actions remains CI/release and fallback artifact ownership, not the local interactive guest provisioner. - `gh workflow run` is remote, container-oriented local emulators do not reproduce Windows Sandbox/WinGet/MSIX/Explorer/OpenSSH/Visual Studio semantics, and a self-hosted runner would add host execution, credentials, and service state. - Repository `cmd/task` commands may be shared by CI and explicit post-ready checks without embedding an Actions runner in the guest or rerunning full suites on every startup. - The registry-settings owner consumes the complete reviewed before/after delta from the privacy/debloat tool and deliberate Windows UI changes, including Explorer Folder Options and taskbar visibility settings for Search, Task View, Widgets, News and Interests, and Weather, rather than an aggressively sampled subset. Review is subtractive: only entries proven volatile, runtime-generated, duplicated, or unrelated to intended user state are removed. Exact canonical values corresponding to the user's explicitly selected ShutUp10++ switches remain included even when they restrict Defender, SmartScreen, updates, application inventory, activation, DRM, NCSI, or browser safety services; ambiguous service/autologger companions are not guessed from an aggregate audit. Base compares each declared registry kind and value before writing. When registry state changes, Base immediately repeats the stop operation until the observed Explorer process set is empty, invokes `explorer.exe` exactly once, and requires a fresh PID before package provisioning starts. Invoking an already-running shell is forbidden because it opens a folder window instead of restarting the shell. - The reviewed ShutUp10++ Chromium Edge selection is one dual-scope table written and read back under both `HKCU\SOFTWARE\Policies\Microsoft\Edge` and `HKLM\SOFTWARE\Policies\Microsoft\Edge`; the remaining Just the Browser table is machine-only. This matches the observed ShutUp10++ state, which remained incomplete when either selected scope was absent, and retains obsolete-but-explicitly-selected rows alongside supported companions. The confirmed location delta requires `LetAppsAccessLocation=2` plus `Value=Deny` in both current-user and machine ConsentStore location keys. - Shell-owned per-user taskbar values that return `UnauthorizedAccess` on the supported Sandbox build are not bypassed or silently skipped. Widgets/News/Weather uses the writable machine-policy owners `Dsh\AllowNewsAndInterests` and `Windows Feeds\EnableFeeds`; Explorer restart then materializes their audited disabled-by-policy state. - Top-level HKCU/HKLM capability consent defaults from the audited user action are explicit String settings and remain included; microphone consent alone is written as exact `Allow` when `audioInput` is true and exact `Deny` otherwise. Package/SID-specific ConsentStore descendants, AppX repository state, generated caches, and opaque binary UI/runtime blobs remain excluded. The same writer accepts only exact `DWord` and `String` values and reads every value back using its declared type. - Windows-app background execution is the functional exclusion from privacy hardening: `BackgroundAccessApplications\GlobalUserDisabled` remains absent. The separately audited `AppCompat\DisableInventory` value is part of the selected disposable-guest profile. Tailscale installation remains in the existing verified WinGet Wix/MSI adapter and package cache with the publisher's silent-install `TS_NOLAUNCH` property. When explicitly enabled, one focused host identity owner runs only after SSH host verification and before the configuration handoff: it consumes and unsets `HERDR_SANDBOX_TAILSCALE_AUTH_KEY` before any child process, discards it when protected identity already exists, and otherwise requires it for the one enrollment; uses hidden Windows PowerShell 5.1 to stop the `Tailscale` service, enforce plaintext portable state with TPM encryption and hardware attestation disabled, atomically restore or perform one fixed-hostname unattended enrollment, restart and verify the service; then captures the quiesced `C:\ProgramData\Tailscale\server-state.conf` through a separately bounded secret-redacting SSH result. Fresh and retained capture restart the service before continuing. Ready opted-in `down` instead leaves the service stopped after persisting local state and proceeds directly to exact-owned termination; only a failed capture, persistence, or termination attempt invokes the bounded restart rollback. An opted-in connectable session cannot race exact-owned termination, and a failed first enrollment can recover its live state before termination even when initial DPAPI publication failed. Stable node ID/key/IP/DNS and Windows user SID are strict; state or auth-key bytes never enter command lines, status, diagnostics, cache, run files, or mappings. - Tailscale SSH is not used because the inspected Windows client does not implement its SSH server. - Mobile access instead reuses the installed Win32-OpenSSH binaries under a dedicated process identity. - Preparation streams the DPAPI-restored or newly generated Ed25519 server private key only through the secret-redacting management SSH archive path, validates `sshd -t`, and persists the matching public identity. - Activation records and revalidates the exact process, command line, start time, listener, Tailscale IPv4, script digest, authorized-key digest, and firewall filters. - Every PowerShell 7 shell rebuilds its process `PATH` from current machine and user values so late guest publications are visible. - Because Windows OpenSSH does not reliably enforce `ForceCommand` for PTY sessions, the same all-host profile then dispatches only connections whose `SSH_CONNECTION` local port is exactly 2222 directly into the published guest Herdr executable; normal management shells on port 22 retain their established behavior. ### Artifact Acquisition And Package Adapters - Package IDs remain readable data in external scripts. WinGet resolves the latest available development-package version unless a project-owned toolchain/workflow defines an explicit version. Bootstrap resolves each external artifact for the current operation and binds its immutable release identity and hash. Bootstrap stores the selected WinGet bundle/dependencies, VC++ runtime, and OpenSSH MSI under one digest-keyed cache owner, repairs mismatches from the canonical URL, and verifies a guest-local copy before installation or extraction; it never executes a cached installer from the host mapping. Herdr's separate remote provision owner transfers and validates its matching payload over SSH. Before launch, Go detects Windows Terminal Preview or Stable from the host package/settings family and passes one strict `preview|stable` marker into provisioning. Base resolves and caches the stable `Microsoft.PowerShell` MSIX plus concrete Inno, MSI/Wix, Burn, MSIX, rustup EXE, and portable-ZIP payloads for Git, GitHub CLI (`GitHub.cli`), OpenCode, Starship (`Starship.Starship`), fzf (`junegunn.fzf`), ripgrep (`BurntSushi.ripgrep.MSVC`), WinDirStat (`WinDirStat.WinDirStat`), the current stable .NET SDK family, the `Microsoft.UI.Xaml.2.8` framework, matching Terminal edition, and selected project tools. File Pilot (`Voidstar.FilePilot`) is the one default installed through the exact online WinGet path because WinGet owns its deterministic user-scope portable package, command-link, and registration state while WinGet exposes no supported cached-installer input. The current stable official Nerd Fonts `GeistMono.zip` asset is a separately resolved immutable URL/SHA-256 selection consumed through the same locked cache/promotion owner; Base loads only its `GeistMono Nerd Font` OTF family into the disposable Windows session through `AddFontResourceExW` and broadcasts `WM_FONTCHANGE` before Terminal installation. Verified portable ZIPs are extracted guest-local with the inbox `tar.exe`, followed by a full reparse-point walk and unique-command check; there is no alternate extractor fallback. - Base resolves the unsigned upstream `opensrc` current stable Windows x64 release and binds its exact official asset digest. The existing package cache and staging owner revalidates every hit and guest-local copy, while its single-file portable executable adapter materializes only `C:\HerdrSandbox\tools\vercel-labs.opensrc\opensrc.exe` and verifies exact `opensrc --version` output. Machine `OPENSRC_HOME` points fetched sources to `C:\HerdrSandbox\cache\opensrc`; no Node.js runtime, npm global state, second cache mapping, or project stack is added. The opt-in native all-stack gate temporarily redirects that variable to guest-local smoke state, fetches the exact selected upstream tag through the installed command and Git, validates the returned source tree, and removes it with the existing smoke root. - Host Herdr inspection fingerprints the PATH command separately from the physical executable reported by `status client --json`, plus either zero or all four known adjacent app-local ConPTY files. These bytes remain host-side identity and race evidence only. Herdr's own SSH transfer, payload lease, validation, pruning, storage layout, and server lifecycle remain authoritative in the guest; Sandbox persists only the returned executable identity. - GUI-subsystem installer adapters (Inno, MSI/Wix, and Burn) use the existing native invocation owner with an explicit process-tree wait and the returned process exit code. Zero is the default sole success code; only the .NET owner explicitly adds documented restart-required `3010` before mandatory CLI readback. They never infer success from a stale PowerShell `$LASTEXITCODE` left by the preceding WinGet probe. - Base phases and concrete package/font/taskbar adapters are idempotent deployment owners. They inspect exact realized state first, skip downloads, reinstalls, rewrites, and shell restarts when that state already matches, and read back every changed state before success. During development the changed phase is rerun inside the existing ready Sandbox; one fresh Sandbox remains the final reproducibility gate rather than the edit-test loop. - The taskbar pin-layout adapter uses the current-user `MDM_Policy_User_Config01_Start02` WMI Bridge class in `root\cimv2\mdm\dmmap`, with `ParentID=./Vendor/MSFT/Policy/Config` and `InstanceID=Start`. One `CustomTaskbarLayoutCollection PinListPlacement="Replace"` owns the complete order as Microsoft Edge's `MSEdge` desktop application ID, File Explorer's `Microsoft.Windows.Explorer` desktop application ID, File Pilot's app-owned Start-menu link, the selected TradingView Desktop link, the selected Terminal package AUMID, then WinDirStat's installer-owned `WinDirStat` desktop application ID; complete ownership is required because appended policy pins do not reorder existing/default pins reliably. Base idempotently writes and verifies its managed Start-menu links against installed regular executables and exact arguments before referencing them through the supported `DesktopApplicationLinkPath` field. File Pilot retains empty arguments. TradingView's already resolved portable executable creates its link during stack provisioning with only `--remote-debugging-port=9222`, and the tool-version plan conditionally includes that link in the later complete layout. Provider writes receive HTML-encoded XML and provider read-back must equal the decoded canonical XML; only a changed and verified layout triggers a taskbar-owned Explorer restart after the independent early Registry-phase restart. Interactive bootstrap retains its synchronous restart path. Retained SSH provisioning atomically publishes a pending restart record and registers one randomly named one-shot Task Scheduler action with the existing user's interactive token. The action waits for its owning SSH PowerShell process to exit, stops the desktop shell once, verifies Winlogon's replacement PID in that session, deletes its task definition, and atomically publishes terminal evidence through `C:\SandboxStatus`; Go waits on the mapped host status owner before continuing. It never launches the shell into SSH session 0 or stores a password. No Taskband blob, shell pin verb, or UI-automation fallback exists. ### Visual Studio And Configuration Transfer - The Rust development profile declares its Visual Studio requirement without executing project code on the host. - The trusted host prelaunch adapter resolves Microsoft's current stable Build Tools package through exact WinGet metadata, then uses its verified bootstrapper and release channel to create an A/B layout containing only `Microsoft.VisualStudio.Component.VC.Tools.x86.x64`, the highest stable `Microsoft.VisualStudio.Component.Windows11SDK.` in that catalog, and their installer-declared dependencies. - Broad workloads and recommended/optional component expansion are excluded. - Downloads may use a temporary nonexecuted staging file, but every host bootstrapper invocation uses the signature/hash-verified app-owned path `\vsbt\bootstrapper\vs_BuildTools.exe` so firewall identity does not change with run or layout slot. - Repeat runs verify the selected persistent Visual Studio slot, materialize it at `C:\HerdrSandbox\visual-studio\layout`, verify it again there, and install the same two components with `--noWeb` and guest-local channel/catalog URIs into `C:\HerdrSandbox\toolchains\visual-studio`. - Before guest installation, explicit inbound/outbound block rules bind the stable guest bootstrapper and installer-engine paths; the project owner leaves exact matching rules untouched, replaces only its own mismatches, and reads all four rules back before invoking the installer. - This enforces the offline contract without duplicate CIM instances and suppresses per-Sandbox update-network prompts. - The Rust development profile explicitly owns the GUI bootstrapper process through exit and verifies that one installation. - Installer package caching and the guest-local layout are left intact because Sandbox disposal is the cleanup owner. - A real guest Rust MSVC build/test is the acceptance boundary for this minimum layout. - The SSH configuration-archive launcher never waits for standard-input EOF. - In-box Win32-OpenSSH 9.5 can stop forwarding a larger redirected stream when its PowerShell 7 default shell proxies stdin into nested Windows PowerShell. - The existing default-shell process therefore owns only an 8 KiB-buffered, exact-length copy into reparse-checked app staging, removes the inherited PowerShell 7 `PSModulePath`, then launches hidden Windows PowerShell 5.1 with that regular file as redirected stdin so 5.1 reconstructs its documented default module paths. - Windows PowerShell still owns staging revalidation, exact-length receipt, SHA-256 verification, extraction, apply, and cleanup; the outer transport staging is also removed in `finally`. - Launcher/apply phase markers use stderr only for bounded failure diagnosis, while stdout remains the strict schema-6 result channel. ### Host Configuration Sync And Guest Policy - After project provisioning and SSH host verification, but before Herdr activation or any interactive workspace/pane, Go builds one bounded in-memory archive containing available GitHub CLI `config.yml`/`hosts.yml`, global Git configuration, transient successful GitHub CLI account credentials, enabled fixed coding-agent configuration/portable credential files, an available host Herdr `config.toml` or the minimal required guest shell setting, the selected Terminal edition marker, a bounded Starship preset marker derived from the explicit host Terminal application theme, Windows Terminal settings/schemes, one strict coding-agent selection manifest, and the repository-owned apply script. - The coding-agent manifest is strict schema 4. Its nested `credentialSync` object contains exactly the six provider booleans and reaches the guest through the existing archive and SSH path. Go resolves configuration and credential sources independently, and the guest applies each credential file only when its nested provider field is true. Missing selected files remain no-ops; disabled fields never clear the corresponding guest destination. - It streams that archive over the verified connection under a separate five-minute timeout. - A short encoded PowerShell launcher receives the exact archive length on stdin, verifies SHA-256 before extraction or execution, and invokes the archived apply script; this keeps credentials and the growing script out of the Windows command line. - Its strict schema-9 result proves atomic Herdr config publication and managed OpenCode TVControl MCP state without reloading a server. - Only then may host Herdr provision the runtime/server and publish the completion acknowledgement that releases bootstrap to create panes. - GitHub CLI source discovery follows its documented `GH_CONFIG_DIR`, `XDG_CONFIG_HOME\gh`, `%APPDATA%\GitHub CLI`, then home-config precedence. Because Windows credentials may live outside `hosts.yml`, Go invokes the existing host `gh` with token environment overrides removed, parses `auth status --json hosts`, obtains each successful account through `auth token --hostname ... --user ...` into bounded memory, and resolves that token's current login through a bounded `gh api --hostname ... /user --jq .login` child whose credential exists only in its environment. The guest imports each token through `gh auth login --with-token --insecure-storage` standard input, restores each active account, requires `auth status` to resolve every imported token from the guest `hosts.yml`, and deletes the transient credential input without logging it. An authenticated import requires selected Git, then invokes `gh auth setup-git --hostname` for each imported host and reads back exactly the resolved `gh.exe auth git-credential` helper, whose leading empty helper entry severs inherited Git Credential Manager fallback. Before archiving, Go patches only `[terminal].default_shell` in an available host Herdr TOML copy. An exact host Nushell command becomes guest `nu.exe` only when the inspected provisioning plan includes the Nushell stack; every other case becomes `pwsh.exe`. If the file is absent, Go creates only the PowerShell section. Guest PowerShell atomically replaces `%APPDATA%\herdr\config.toml` and verifies its digest. The later single remote provision owner validates and applies it while starting, reloading, or restarting the server. The same apply path invokes the installed Starship preset command, changes Catppuccin's single default Mocha selector to `catppuccin_latte` for a light host theme, verifies the generated TOML with Starship, and writes no host prompt configuration. - Go parses Terminal settings as one JSON object, preserves unrelated keys, normalizes default/profile font faces to `GeistMono Nerd Font`, replaces both the profile default and every explicit profile `startingDirectory` with the active mapped root from the strict workspace manifest, ensures the canonical PowerShell 7 profile `{574e775e-4f2a-5b96-ac1e-a2962a402336}` launches `pwsh.exe`, and selects it as `defaultProfile`; it does not hide or synthesize a legacy Windows PowerShell 5.1 profile, and host files are never modified. Coding-agent discovery honors only the documented absolute overrides and standard roots: OpenCode `XDG_CONFIG_HOME`/`XDG_DATA_HOME`, Claude `CLAUDE_CONFIG_DIR`, Codex `CODEX_HOME`, Copilot `COPILOT_HOME`, and Pi `PI_CODING_AGENT_DIR`. Fixed allowlists include authored settings/instructions/agents/commands/rules/skills/prompts/hooks/themes/extensions and portable credential files while excluding conversations, runtime history, logs, caches, generated package/plugin state, trust databases, and unrelated home content; the Git-backed extension below adds only files selected by the repository index plus bounded metadata. Shared `%USERPROFILE%\.agents\skills` is copied once when Codex, Copilot, or Pi sync is enabled. Claude's mixed `.claude.json` contributes only user MCP declarations. The guest copies supplied allowlisted files additively without deleting absent host configuration or excluded guest runtime state, rejects reparse points in every existing destination component, verifies every copied destination SHA-256, removes temporary inputs, and returns a strict result containing the archive digest, copied-file count, Terminal edition, Starship preset, GitHub authentication outcome, and atomic Herdr configuration-publication outcome without logging content. Personal configuration never enters a Sandbox mapping or persistent run copy; private SSH/GPG keys and machine-bound Codex/Copilot Credential Manager state are never transferred. - Portable credential owners are fixed and separate from configuration roots: OpenCode `auth.json`, Claude Code `.credentials.json`, Codex `auth.json` plus `.credentials.json`, Pi `auth.json`, GitHub CLI `hosts.yml` plus the transient account envelope, and the filtered TradingView signed-session pair. Copilot uses selected GitHub CLI authentication and has no duplicate credential field; Codex has one selection for both portable files and no `codexMCP` alias. Host-configuration pulls always derive sources with an empty credential selection, so repository updates never discover or export secrets. - One host-configuration registry derives only exact roots already selected for transfer: the Herdr Sandbox config root, enabled agent roots and shared skills, Herdr, `.config\git`, GitHub CLI, and the exact Windows Terminal settings/fragments roots. It never walks from a file to an ancestor repository. Automatic `up`, automatic post-terminal-`down`, and explicit `pull-host-config` reuse this registry and one Git updater. The Herdr Sandbox config root is pulled first, then strict `config.json` is reloaded before remaining roots are derived. Each candidate must itself own one physical `.git` directory whose top-level, Git/common directories, worktree state, non-bare state, and files-based ref storage resolve to that root. Repositories without remotes and non-Git roots are reported as skipped; every remote-backed root requires an attached current branch with a remote-branch upstream. The updater retains host global/system Git configuration for existing credentials while removing inherited Git/credential-manager overrides, disabling terminal/GUI prompts, using SSH batch mode, and disabling optional locks, hook-directory and configured hooks, tags, submodules, rebase, autostash, and verification callbacks under one two-minute context. `git pull --ff-only` against the validated remote/ref is the sole mutation. Unsafe state fails before `up` transfers; after `down`, it returns failure only after shutdown is already terminal. No guest-to-host copy exists. `plan` reads and reports flags without invoking this owner. - Each enabled coding-agent root and shared-skills root additionally has one bounded Git-transfer extension. Read-only validation and archiving disable global/system Git configuration under one 30-second context. NUL-delimited staged-index enumeration contributes regular tracked files and records missing tracked files in the strict sync manifest; known credential/runtime paths, symlinks, submodules, case collisions, and unresolved entries fail closed. The in-memory archive includes bounded local config, HEAD, index, refs, and objects but omits hooks, reflogs, LFS/cache state, and transient files. Linked worktrees, active operations/locks, non-files refs, and external object stores fail closed. Guest PowerShell reuses the reparse-safe SHA-256 tree copier. This deliberately exposes selected repository metadata/history to guest administrators. - When OpenCode configuration sync is enabled, `SST.opencode` is selected, or `opencode.exe` is already available, the archived configuration-sync apply path owns `%ProgramData%\opencode\opencode.json` plus one local managed config plugin and rewrites both after the host copy. The managed file declares explicit allow rules for every built-in permission, including task/todo/external-directory and future actions through `*`; after all copied config and agent files merge, the plugin replaces top-level and every configured agent permission with that same allow set. When the inspected plan contains the TradingView stack, the same managed owner also merges one disabled-by-default `mcp.tvcontrol` local server with the verified absolute `node.exe` and TVControl `src\server.js` paths plus fixed `127.0.0.1:9222`, advanced-tools-off, and telemetry-off environment. Both the managed JSON and plugin carry that definition so a copied user config cannot remove or start it. OpenCode's `/mcps` action may connect it in memory for the current session without persisting an enabled default. When OpenCode is installed, configuration sync invokes its debug boundaries and rejects unexpected permissions or MCP state before panes are created. It does not start TVControl or TradingView. Base owns only package installation. This guest-only policy never modifies host OpenCode state. - Host `.gitconfig`, its adjacent optional Git files, `gh.exe`, GitHub CLI files, and authenticated accounts are independent optional configuration-sync inputs. Their absence never blocks guest Git/GitHub CLI installation: the archived apply path skips missing host files, imports an empty strict authentication envelope when no usable host CLI/account exists, and still writes only the exact guest workspace `safe.directory` set. Windows Terminal's valid dynamic `system` theme resolves to the deterministic dark Starship baseline because the disposable guest cannot track later host theme changes. - GitHub CLI `config.yml` remains a non-secret package-selected input. `hosts.yml`, account discovery, login, Git credential-helper mutation, and status verification require `credentialSync.githubCLI`. A selected TradingView stack always carries its cookie adapter and non-secret privacy/settings assets; when `credentialSync.tradingView` is false, Go supplies an empty strict authentication envelope and the adapter replaces only preference rows, preserving existing guest session rows. - Explicitly selected project roots, the optional worktree and shared model roots, and named folder mounts whose `readOnly` value is exactly false are the only user-data mappings allowed to be guest-writable. Generated build outputs stay guest-local where project tooling supports an external target directory; reusable package/tool state uses only the separate app-owned cache mapping below. - GitHub CLI authentication export treats `auth status` logins as configuration labels rather than durable account identity. - After retrieving each account token through the host CLI, Go supplies that token only through a bounded child environment and resolves its current canonical login with `gh api --hostname /user --jq .login`; account renames therefore update the guest payload without mutating host configuration or placing credentials in arguments, output, mappings, or run state. - Canonical host/login identities must remain unique before guest import; guest `gh auth login` plus exact status and token-source verification remain the final authentication boundary. ### Cache And Version Contracts - Package/tool caches use one explicit guest-writable mapping. Its host path is the optional absolute `cacheDirectory` from `%APPDATA%\herdr-sandbox\config.json`, defaulting through `os.TempDir()` to `\herdr-sandbox\cache` (normally `%TEMP%\herdr-sandbox\cache`), and its fixed guest path is `C:\HerdrSandbox\cache`. The default remains separate from `%LOCALAPPDATA%\herdr-sandbox` identity and run state. The cache must not overlap run state or a mapped workspace, and an entire volume or reparse-bearing cache path is rejected. No code path warms speculative payloads. Bootstrap assets and each demand-driven WinGet hit use digest-keyed immutable entries, verify hits and guest-local copies, atomically promote misses, repair mismatches only from their already validated canonical URLs, and prune superseded entries within the same role. Every cache-owned parent, payload, staging directory, and prune target is reparse-checked. A Rust request resolves the official HTTPS channel manifest plus its SHA-256 sidecar; `stable` must agree with a second exact-version manifest snapshot before that concrete version, target, manifest digest, component URLs, and component hashes become the run identity. Its seven-file distribution mirror is digest-keyed, copied and revalidated guest-local, and exposed only through a loopback server; rustup, Cargo homes, extracted sources, compiler outputs, Cargo targets, Zig caches, and executable tools remain guest-local beneath `C:\HerdrSandbox`. Their fixed guest-local paths are persisted as machine environment values so fresh SSH and Herdr processes resolve the installed toolchain without pointing at mapped executables. Visual Studio uses two persistent layout slots so a Current-channel mismatch can build the inactive slot without destroying the prior valid cache. Host preparation publishes a slot only after complete local identity and layout verification. A selected slot is never executed from the guest mapping: it is reparse-checked, copied and control-file-rehashed to `C:\HerdrSandbox\visual-studio\layout`, fully verified there, and installed from that stable guest-local source. Only then is the former slot removed; a failed refresh leaves the prior valid cache intact. - Visual Studio cache continuity is the explicit exception to the no-compatibility default. - If Current host preparation fails, the host and guest may use an existing A/B slot only after reconstructing its target from the signed channel, revalidating its complete artifact hashes, components, bootstrapper, layout, and safe paths, and warning with the cached build. - Schema 2 is accepted only for that fully verified existing slot; every newly published descriptor remains schema 3. - GeistMono payload integrity and current-session GDI activation are separate checks. - The exact immutable Regular and Bold `GeistMono Nerd Font` payload is reused in place and loaded into whichever Windows session invokes Base; unrelated release files and unused weights are not installed, and a missing GDI family in another session never authorizes deletion of valid, potentially loaded OTF files. - A nonempty `cacheDirectory` selects one dedicated app-owned cache root rather than a shared directory. - Normal provisioning still validates it as an absolute non-volume, non-reparse path that does not overlap run state, a selected workspace, or a named folder mount. - Installer cleanup never follows an unsafe overlap and attempts recursive removal only for the selected dedicated cache; a locked or otherwise nonremovable cache residual is preserved without blocking required application cleanup. - The default cache owner remains the complete `\herdr-sandbox` namespace. - WinGet v1.29 exposes no structured `show`/`search` output or direct cached-installer input. - Concrete WinGet package metadata therefore parses the exact English `show` labels, while latest package-family selection parses the exact English `search` table; both fail closed on label or shape drift. - The cached WinGet path treats the generated merged YAML plus trusted-source SHA as download authority, and online additions receive one resolved version before exact install and list read-back. - A failed installation remains terminal; an inconclusive exact ID/version read-back after installer success emits a warning and continues because WinGet correlation defects do not prove installation failure. - Package-specific functional verification remains strict. - No WinGet path falls back to a guessed package, localized label set, direct remote URL, or `install --manifest` pseudo-offline path. ### HyperFrames And Ready State - The separate `Install-HyperFramesStack` composition reuses the Node.js LTS owner and rejects any resolved runtime below Node.js 22. - It resolves omitted `Gyan.FFmpeg` and npm `hyperframes` versions through the current WinGet and npm latest-stable owners, uses WinGet's exact x64 `Gyan.FFmpeg` full-build ZIP metadata and digest with the shared package cache, installs the CLI globally below `C:\HerdrSandbox\tools\hyperframes`, and exposes only its generated `hyperframes.cmd` path. - The official `hyperframes browser ensure` owner downloads its release-matched Chrome Headless Shell. - The official `hyperframes skills` owner installs every current skill into a fresh staging home whose agent-related environment roots all remain below one app-owned staging directory. - The stack verifies the complete regular non-reparse tree, promotes only its Claude copy to `C:\HerdrSandbox\tools\hyperframes-opencode\skills`, and removes the staging home. - No normal global or project agent discovery root receives those skills. - The generated `hyperframes-opencode.ps1` launcher uses OpenCode's process-scoped `OPENCODE_CONFIG_CONTENT` `skills.paths` contract to expose that dormant root only to one explicitly started child, rejects a pre-existing inline override rather than replacing it, forwards arguments, and restores the environment when the child exits. - Machine-readable doctor output must confirm Node.js, FFmpeg, FFprobe, and Chrome. - A bounded generated-color `libx264` encode plus FFprobe readback proves the software H.264 path and is deleted immediately. - Browser vGPU capability remains independent from HyperFrames' FFmpeg GPU option; absent AMF, QSV, or NVENC runtime evidence means no hardware-encoder promise or fallback path is added. - When the shared model mapping exists, `Install-HyperFramesStack` strictly reads the host descriptor and completion record, rehashes every selected model plus the release archive, validates the sidecar and every archive entry and extracted file against the embedded manifest, and rejects every non-CPU runtime. - The provider's recorded HyperFrames version remains immutable build provenance but is not compared with the independently selected current HyperFrames release. - It installs the provider, direct CLI, selected German narrator reference, and one CPU server below `C:\HerdrSandbox\tools\hyperframes-voxcpm2`; provider and CLI syntax, CLI help identity, server commit identity, narrator identity, and availability with the mapped models must pass before machine environment and CLI PATH publication, while later request execution owns runtime compatibility failures. - The release provides only the verified `tts.ps1` launcher. - The provider fixes GPU layers at zero and clones the selected narrator when no voice mode is selected. - `voice_design`, `--voice-design`, and direct `tts.ps1 --design` explicitly select Voice Design for one request; `--voice` selects another reference. - No second stack, service, updater, model cache, or compatibility path is introduced. - Ready schema 3 reports the selected development profile and verified tool versions. - Package installation, configuration copy, initial workspace creation, and selected OpenCode startup remain bounded diagnosable phases; representative compiler checks run explicitly after ready and do not delay routine environment startup. - Host-side Rust tooling remains forbidden. - Rust installation, builds, and tests may run only inside the verified Herdr Sandbox guest or GitHub Actions; neither path authorizes host Rust execution. ## Release Packaging ### Artifact And Identity Ownership - `cmd/task` owns one Windows amd64 package layout built through the existing production build owner. - It stages exactly `sandbox.exe`, `base.ps1`, `stacks.ps1`, and `LICENSE.txt`; validates that no file is missing or extra; and feeds that same flat directory to both the deterministic ZIP writer and the installer. - Routine `package VERSION` generation verifies both formats below one temporary output directory and then replaces the single canonical local installer at `build/dist/herdr-sandbox_setup.exe`. Explicit `package VERSION --release` instead publishes the exact versioned ZIP and installer pair required by GitHub Actions. - Before and after packaging, `cmd/task` removes only its known generated stages, isolated outputs, and obsolete package artifacts. It preserves the shared compiler cache and unrelated private work, and refuses unknown build-root entries. - The release ZIP and installer are generated and verified together before publication; their SHA-256 values are computed locally for release evidence. - A failed generation leaves the prior coherent set, while failed publication removes partial new targets. - Generated stages and artifacts stay below ignored `build/` paths. - The production build links one version, one UTC `YYYY.MM.DD.HHMMZ` freshness label, and the full Git revision into `internal/productidentity`; `sandbox version` prints the version and freshness followed by the 12-hex revision in parentheses without crossing a Sandbox boundary. The installer carries the same display identity and metadata. - Ordinary development builds fall back to `devel`/unknown revision when Git is unavailable, while release packaging requires one valid full `HEAD` revision. - The same identity owner supplies the current product GUID, GUID uninstall key, and quiet-uninstall helper name. - `cmd/task` rejects empty, unsafe, reserved, colliding, path-bearing, overlong, or inconsistent identity/version/output values before invoking NSIS, validates the exact staged package, and treats compiler warnings as failures. ### Installer Lifecycle And Repair - `packaging/windows/installer.nsi` remains the single hand-readable MUI2 definition and direct lifecycle owner. - The current stable NSIS compiler builds a current-user fixed-path Windows 10+ x64 installer with forced CRC, Welcome/License/Files/Finish, the unchecked configuration-removal/Files uninstall flow, stable error codes, 8 MiB solid-final LZMA, and no product-specific source string. - NSIS owns package extraction, product-GUID/location validation, complete binary-root replacement and rollback, Installed Apps registration, PATH ownership recording, and uninstall. - No installer-state schema, marker file, mixed-directory ownership, junction, versioned directory, persistent journal, runtime installation definition, generic manifest engine, or PowerShell installer engine exists. - The fixed product-GUID key, exact registered `InstallLocation`, and a bounded product-GUID/location repair intent establish ownership of the complete fixed binary root. - A nonempty unregistered root and every historical registration or payload filename fail closed without migration. - The fixed-path attribute check treats only Win32 `ERROR_FILE_NOT_FOUND` and `ERROR_PATH_NOT_FOUND` as absence; every other lookup failure stops before mutation. - Before creating or replacing the root, setup snapshots the exact existence, registry kind, and data of every registration value it may change and publishes the repair intent. - One recursive owner revalidates every directory, deletes directory reparse points without traversing them, clears the read-only bit on installer-owned regular files before deletion, restores that bit if deletion fails, fails on a reparse root, and verifies a recreated root before copying. - Sharing, lock, and access-denied failures produce an explicit close-running-commands and retry action. - Setup stages and backs up the supported payload, clears a currently registered root, recreates it, and copies the complete current payload. - Rollback restores the supported prior files and exact prior registry snapshot or publishes one recognizable repair registration. - ProductGuid, `InstallComplete=1`, then final `DisplayVersion` form the Windows/WinGet commit. - Files placed manually in the registered binary root are installer-owned and do not survive upgrade or uninstall. - A hard interruption is repaired by rerunning the idempotent complete-payload setup; no power-loss rollback is promised. - Later PATH or registration failure leaves the complete application in explicit repair state, returns a stable nonzero status, and directs setup rerun rather than claiming full rollback. - `packaging/windows/path.ps1` is the only PATH helper and supports Contains, Add, and Remove. - It preserves `REG_SZ` versus `REG_EXPAND_SZ`, globally removes empty and duplicate effective entries while preserving the original spelling and first occurrence of each unique unrelated entry, and keeps one canonical literal product entry. - Literal and expanded comparisons use ordinal case-insensitive semantics so distinct Unicode spellings remain distinct. - Setup writes `PathAddPending=1` before convergence and records `PathAdded=1` after either a changed or already-converged result; this records only that setup manages the entry. - Notification precedes clearing the retry intent. - Uninstall always converges PATH by removing every effective product entry, including quoted, slash, trailing-separator, duplicate, and expandable-variable forms, while preserving unique unrelated or malformed entries. - A per-user file lock serializes cooperating helpers, while the installer-exclusive mutex serializes installer peers. - The helper's bounded snapshot recheck and exact registry type/data readback detect outside collisions without claiming an atomic lock over unrelated writers. - Default-configuration seeding follows the final install commit and remains create-if-missing and nonblocking. - Setup and uninstall alone share one stable, unversioned `InstallerExclusive` mutex. - They acquire actual ownership with a zero-time `WaitForSingleObject`, accept `WAIT_ABANDONED` after a crash, and report busy only for a live setup/uninstall owner. - Ordinary application commands do not acquire this mutex. - The separate existing application lifecycle mutex protects replacement and the destructive uninstall interval described above after exact installed command processes have been stopped. - Interactive cancellation is disabled from the first install or uninstall mutation through terminal commit or rollback, and close requests are rejected during that interval. - The installer validates ProductGuid and exact location before treating the fixed directory as its binary root. - `InstallComplete` and the bounded intent detect interrupted current payload work, and rerun rewrites the complete set. - If recursive uninstall removal fails after registration deletion, the temporary uninstaller recreates `uninstall.exe` plus a product/location-bound `UninstallPending=1` registration. - A retry accepts only that exact residual state, reruns application cleanup only while `sandbox.exe` remains, and continues root removal without setup. - The installed `uninstall.ps1` quiet runner copies `uninstall.exe` privately, verifies identical bytes through .NET Framework SHA-256 without PowerShell module loading, gives the full operation 25 seconds, then has at most 5 seconds to terminate and reap its exact process tree before returning failure. ### Installer Presentation And Release - `packaging/windows/assets/installer-welcome-finish-source.png` is the sole editable installer-artwork source. - The five product-defined BMP3/24-bit derivatives beside it were rendered in linear RGB with ImageMagick 7.1.2-27 using `magick packaging/windows/assets/installer-welcome-finish-source.png -colorspace RGB -filter Lanczos -define filter:lobes=3 -resize x! -colorspace sRGB -alpha off -depth 8 -type TrueColor -strip -compress None BMP3:`; ImageMagick is a maintainer rendering tool, not a build or CI dependency. - Tests pin the source and derivative hashes, dimensions, encoding, and complete asset set. - NSIS remains system-DPI aware: after MUI extracts the 96-DPI default, one GUI-init hook dynamically resolves `GetDpiForWindow($HWNDPARENT)`, falls back to 96 DPI when unavailable or unsuccessful, selects the nearest product-defined bucket with end clamping, and overwrites the shared Welcome/Finish bitmap before either page loads it. - `NoStretchNoCropNoAlign` keeps the selected pixels native and introduces no second page, control, installer mode, or compatibility path. - The successful interactive install flow continues from Files to the standard MUI2 Finish page. - That terminal page contains confirmation, terminal-first next actions, and one user-invoked documentation link backed by the canonical `APP_PRODUCT_URL`. - Fresh setup also shows MUI2's checked-by-default **Open Herdr Sandbox configuration** option. - The page-show callback unchecks and hides it when setup found owned registration, while the option function retains an explicit silent-mode guard. - When selected, that function invokes the installed executable's strict installer-only configuration-open command, which reuses the same `sandbox.OpenConfiguration` owner as `sandbox config` while the installer-only gate remains held; ordinary commands do not share that gate. - Standard WinGet's Nullsoft path and explicit silent setup skip the page; repair and upgrade hide the option. - No product GUI, browser, local readme, or restart is launched. - The tag remains the release identity. - GitHub Actions resolves and installs the current stable x86 NSIS compiler through exact WinGet metadata and its published installer digest, runs `package --release`, requires its exact two generated files, derives the release title from the installer's compiled `ProductName`, publishes one concise link to the tagged `CHANGELOG.md` without copying its entries, publishes the installer and ZIP without another product-name constant, and compares each local SHA-256 with GitHub's uploaded asset digest. - Both formats permanently contain only the same four Sandbox-owned application files and are never combined with a Herdr artifact. ## External Boundaries ### Unsafe Contracts And Diagnostics - Windows Sandbox `.wsb`, Core Audio COM and Windows service state, PowerShell 5.1, WinGet, Tailscale identity/network behavior, Windows Firewall, Android Command-line Tools/Platform Tools and wireless ADB, current .NET SDK installers and CLI, CMake, Vulkan SDK, WebView2, the Herdr Windows build, Windows OpenSSH, host OpenSSH behavior, and NSIS are unsafe external contracts. - Exact commands and output parsing require current official documentation or installed/versioned-source inspection. - External command failures preserve the command role, exit status, bounded UTF-8 head and tail, and status path needed for diagnosis. - During development provisioning, each native role updates the existing progress status and appends a bounded schema-versioned duration record to the private per-run status directory so cache-hit performance and failures remain measurable. - Guest-derived display fields reject nonprinting terminal controls, while host-persisted error summaries replace them before publication. - Secrets and private keys are never printed. - Application code uses direct process execution with explicit arguments and context cancellation. - PowerShell is used where Windows-specific orchestration or file association launch is required. ### TradingView Session Boundary - `Install-TradingViewStack` leaves the installed upstream TVControl package unmodified, verifies the regular `TradingView.exe`, and exposes it through machine `PATH`. TVControl and the guest agent run in the same interactive Session 1 context, so TVControl's upstream `launch` command and `tv_launch` tool directly spawn the visible Desktop with CDP. ## Verification Architecture ### Iteration And Packaging Gates - Fast tests cover product-owned parsing, planning, state, cleanup, mapping, identity, archive, status, installer-input, and safety decisions. - Focused executable Windows PowerShell 5.1 tests retain unique process, quoting, parser, reparse, package-adapter, configuration, and destructive-boundary signal. - Copied script-token inventories, absence assertions, fixture inventories, and incidental call-order tests are not acceptance owners; the current-Sandbox and fresh-native gates execute the shared Base and stack implementations instead. - This repository's package gate runs the PowerShell 5.1 validator and compiles the real installer with the exact product payload and artwork. - Installed clean/upgrade/repair/uninstall effects remain a native Windows release boundary; real microphone sharing, mute/service/playback behavior, mobile tailnet listener/firewall/login behavior, and modern .NET install/build evidence remain part of their respective native Sandbox gates. - PowerShell's parser validates the guest script with Windows PowerShell 5.1 before native use. - Normal iteration runs formatting, requires no pending Go fix modernization, runs pinned Staticcheck with all checks enabled plus the pinned Go nilness analyzer, then runs one batched Windows PowerShell 5.1 parse, product-focused Go tests, `go vet ./...`, and one stable `build/bin/sandbox.exe` production build through `cmd/task verify` under a five-minute hard deadline. - Tests that start external PowerShell or Git processes run only through the explicit `test-integration` or `verify-integration` owner. - Packaging runs `validate-build.ps1` against product identity, exact payload, helper syntax, version/output agreement, and artwork before warnings-as-errors NSIS compilation. - The shared build trims source paths, disables incidental VCS stamping, strips Go symbol/DWARF tables with linker flags `-s -w`, and keeps Go's normal build ID; release workflows do not add a second build implementation or binary packer. - The bounded `go run ./cmd/task provisioning-preflight` gate runs in the active Herdr-managed Windows Sandbox before either current-Sandbox gate. - Within 45 seconds it exercises the production AudioGridder manifest parser with a bounded fixture and applies the production Java, Android, and Visual Studio descriptor parsers to available current-guest inputs. - It installs nothing and treats unfamiliar tool-version output as a warning. - The later native gate remains responsible for complete payload, cache-slot, and capability verification. ### Current Sandbox Gates - The explicit `go run ./cmd/task native-current-sandbox` gate is separate from standard iteration. - Inside the active development Sandbox it prepares real provisioning plans and snapshots, runs Base plus every direct and virtual project stack in place, and uses their real package, compiler, browser, and read-back boundaries. - Its task-owned audio leg starts server ID 0 and an isolated REAPER Dummy Audio configuration in the active interactive session, handles only REAPER's exact no-device prompt and enabled `Still Evaluating` action, inserts the VST3 client, requires one server worker plus matching established loopback streams, and removes its processes, tasks, and temporary state. - It neither starts Windows Audio services nor uses a host audio interface. - It starts after bootstrap, OpenSSH, and Herdr remote provisioning, invokes none of those owners, launches no nested Sandbox, and requires the exact pre-existing Herdr server, remote-client bridge, and OpenSSH service process identities to remain unchanged. - The explicit `go run ./cmd/task package-current-sandbox VERSION` gate builds the exact ZIP and installer plus an immediate-predecessor installer from the same current layout and immutable source revision. It starts only when the canonical per-user registration and fixed binary root are absent. - The current installer being exercised replaces the canonical local installer before installation; terminal cleanup removes its internal ZIP, predecessor, stage, and compile outputs while retaining that exact candidate. - It requires exact registered identity, staged payload digests, and linked version, freshness, and revision after fresh install, same-version repair, immediate-predecessor current-layout install, and upgrade to the candidate. Between repair and upgrade it proves quiet uninstall removed registration and the binary root. - It executes the same current-Sandbox provisioning gate through the upgraded installed payload, then uses the installed bounded quiet-uninstall owner and again proves registration and binary-root state are absent. - Exact Herdr, remote-client bridge, OpenSSH, `config.json`, and `user.ps1` state must survive every install, repair, upgrade, provisioning, and uninstall transition. - Packaging also rejects any checked-in WinGet installer manifest whose ProductCode differs from the canonical uninstall key. ### CI, Release, And Fresh Native Gates - The manual `go run ./cmd/task release VERSION` owner accepts only a clean committed source with a matching structured changelog section and containment in the configured upstream. The user's release request records that the current installer and freshly provisioned Sandbox were already accepted. The command confirms that source stays unchanged, creates one ordinary annotated tag, pushes it, and verifies the remote tag target without running tests, installation, or provisioning. - GitHub Actions keeps assurance and publication separate: one read-only Windows workflow runs `go run ./cmd/task verify-integration` and pinned `go tool govulncheck ./...` nightly or on manual dispatch, with no ordinary push trigger. An exact `v0.0.RELEASE_ID` tag runs only `go run ./cmd/task package --release`, publishes the Windows amd64 ZIP and installer, and compares GitHub's uploaded asset digests with the runner-built files. GitHub-hosted runners do not claim Windows Sandbox provisioning evidence. - Release IDs begin at zero, increase for every tagged attempt, and are never reused; a failed attempt may therefore leave a gap between published releases. - Official checkout/setup actions are commit-pinned, while the installer compiler resolves from current stable WinGet metadata and remains bound to its selected digest. - The tag is the only release identity; no Actions-only build or packaging implementation, second version source, signing, or updater path exists. - The opt-in `go run ./cmd/task native-all-stacks` gate builds the stable CLI, owns one ignored credential-free fixture, launches a fresh real Windows Sandbox, completes WinGet/Herdr/OpenSSH provisioning with Android, AudioGridder and REAPER, C/C++, Java, .NET, Go, Node.js, and the Herdr virtual stack, and invokes its repository-owned smoke scripts from the fixture's existing read-only mount through short managed-SSH commands rather than placing those scripts on the Win32 process command line. - The smoke covers Android CLI/SDK identity plus ADB wireless commands without requiring a physical device, a real REAPER-to-AudioGridder worker connection, C and C++ compile/run, Java compile/run, .NET build/run, Go test/run, Node.js execution plus a second Playwright Chromium headless launch, Python execution, Rust/MSVC compile/run, Zig test, Bun execution, Nextest/Just discovery, `sh` execution, the libghostty output environment, and transferred Terminal/Starship assertions before exact-owned shutdown. - The separate interactive P0 acceptance attaches with the host `herdr` thin client, detaches, and verifies the same server remains available. - That native gate also selects HyperFrames. - Its provisioning path verifies the globally exposed CLI, isolated manual-activation skill tree and launcher, managed Chrome Headless Shell, doctor boundary, FFmpeg/FFprobe, and software H.264 encode before ready. - The same native gate selects NSIS independently and proves `makensis` can compile a minimal installer over managed SSH. - It does not launch that generated installer. - The same native gate maps a separate credential-free Handy-shaped project. - Its virtual stack performs the CMake C++ probe during provisioning, and the post-ready SSH smoke verifies the selected current CMake and Vulkan SDK versions, the corrected SPIRV-Headers package, and signed WebView2 before exact-owned shutdown. - If native launch, package network access, firewall approval, Herdr Windows behavior, or Herdr remote attach blocks the P0 gate, the exact artifact, command, status directory, and blocker are reported; unit tests are not presented as equivalent evidence.