diff --git a/.antigravity.md b/.antigravity.md index ef22dbc..c65c077 100644 --- a/.antigravity.md +++ b/.antigravity.md @@ -49,7 +49,7 @@ This file contains the context rules and development guidelines for the Antigrav - **Maintain Plain Text:** `Worklog.md` must remain a plain markdown file. Do not introduce YAML or JSON structures. ### Windows Systems & Sandbox Conventions -- **Desktop Isolation:** All guest application processes must be spawned explicitly on the separate desktop `"VesselDesktop"`. Verify `lpDesktop` is set correctly in `STARTUPINFO`. +- **Desktop Isolation:** Guest application processes are currently spawned on the primary desktop (`WinSta0\Default`). The separate desktop (`"VesselDesktop"`) is planned but not fully functional. - **Job Object Boundaries:** Guest processes must be assigned to a Win32 Job Object with active hard limits: - Memory: Cap at **1GB RAM** (`JOB_OBJECT_LIMIT_JOB_MEMORY`). - CPU: Cap at **50% CPU cycles** (`JOB_OBJECT_LIMIT_CPU`). @@ -60,7 +60,7 @@ This file contains the context rules and development guidelines for the Antigrav ## Boundaries & Guardrails - **Credential Safety:** Never log or commit the NVIDIA NIM API key or store it in plaintext configuration files. Retrieve it programmatically via `wincredentials` from `Antigravity/NimApiKey`. - **Sandbox Escapes:** Subprocesses spawned inside the sandbox must restrict shell execution and validate arguments against strict allowlists (`allowed_commands` in `vessel.toml`). -- **Focus Preservation:** Never send active inputs (keystrokes/clicks) directly to the user's primary desktop session (`WinSta0\Default`). Always target `"VesselDesktop"` inputs programmatically or via PostMessage to avoid focus stealing. +- **Focus Preservation:** When developing future isolation, never send active inputs (keystrokes/clicks) directly to the user's primary desktop session (`WinSta0\Default`). Always target inputs programmatically or via PostMessage to avoid focus stealing. --- diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 6b6f51d..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[target.x86_64-pc-windows-gnu] -linker = "C:/Users/hp1/mingw64/bin/gcc.exe" -ar = "C:/Users/hp1/mingw64/bin/ar.exe" - diff --git a/.cursorrules b/.cursorrules index 823bf77..d5a6e0e 100644 --- a/.cursorrules +++ b/.cursorrules @@ -4,7 +4,7 @@ Please refer to the root `CLAUDE.md` file for the complete guidelines on tech st ## Core Directives - **Architecture:** Rust workspace with modular crates. Refer to `Cargo.toml`. -- **Isolation:** Guest processes must always target the separate desktop `"VesselDesktop"`. +- **Isolation:** Guest processes currently run on the user's primary desktop session (`WinSta0\Default`). Desktop isolation (`"VesselDesktop"`) is planned but not functional. - **Resource Constraints:** Under 1GB memory cap via Job Objects. - **Safety:** Wrap raw unsafe Win32 FFI inside safe RAII handlers in Rust. - **Secrets:** Never log or commit the NVIDIA NIM API key. Use `wincred`. diff --git a/CLAUDE.md b/CLAUDE.md index 4d2c949..cbd1203 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -45,7 +45,7 @@ - **Maintain Plain Text:** `Worklog.md` must remain a plain markdown file. Do not introduce YAML or JSON structures. ### Windows Systems & Sandbox Conventions -- **Desktop Isolation:** All guest application processes must be spawned explicitly on the separate desktop `"VesselDesktop"`. Verify `lpDesktop` is set correctly in `STARTUPINFO`. +- **Desktop Isolation:** Guest application processes are currently spawned on the primary desktop (`WinSta0\Default`). The separate desktop (`"VesselDesktop"`) is planned but not fully functional. - **Job Object Boundaries:** Guest processes must be assigned to a Win32 Job Object with active hard limits: - Memory: Cap at **1GB RAM** (`JOB_OBJECT_LIMIT_JOB_MEMORY`). - CPU: Cap at **50% CPU cycles** (`JOB_OBJECT_LIMIT_CPU`). @@ -56,7 +56,7 @@ ## Boundaries & Guardrails - **Credential Safety:** Never log or commit the NVIDIA NIM API key or store it in plaintext configuration files. Retrieve it programmatically via `wincred` from `Antigravity/NimApiKey`. - **Sandbox Escapes:** Subprocesses spawned inside the sandbox must restrict shell execution and validate arguments against strict allowlists (`allowed_commands` in `vessel.toml`). -- **Focus Preservation:** Never send active inputs (keystrokes/clicks) directly to the user's primary desktop session (`WinSta0\Default`). Always target `"VesselDesktop"` inputs programmatically or via PostMessage to avoid focus stealing. +- **Focus Preservation:** When developing future isolation, never send active inputs (keystrokes/clicks) directly to the user's primary desktop session (`WinSta0\Default`). Always target inputs programmatically or via PostMessage to avoid focus stealing. --- diff --git a/README.md b/README.md index 93a11ee..c122416 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ To multiply baseline model capabilities from **~20% to ~80%** on SWE benchmarks, The architecture is designed to be lightweight, secure, and programmatically fast: 1. **Lightweight Sandbox Containment:** - By default, applications (browsers, shell loops) are spawned on a secondary Windows Desktop (`"VesselDesktop"` via `CreateDesktopW`), completely isolating the AI's visual display and input stream. + By default, applications (browsers, shell loops) are currently spawned on the active user's primary desktop (`WinSta0\Default`). Desktop isolation (`"VesselDesktop"`) is an experimental placeholder and is not yet functional. Containment boundaries are enforced via **Win32 Job Objects** (`SetInformationJobObject`), applying a hard cap of 1GB memory and restricting CPU slices, eliminating virtual machine memory overhead (0MB VM footprint). 2. **MCTS Capability Multiplier:** The host coordinator uses a local Monte Carlo Tree Search engine to evaluate coding and tool-use actions. For each modification step, it runs parallel rollouts in the sandbox, evaluates them using a deterministic reward function (lint success, compile success, and test suite pass rate), and prunes stuck or looping branches. @@ -34,7 +34,7 @@ The architecture is designed to be lightweight, secure, and programmatically fas At the moment, AI Vessel is heavily optimized for and tied to Windows-specific APIs to achieve its lightweight, sandboxed environment without virtualization overhead. The core dependencies include: - **Win32 Job Objects** for strict memory and CPU sandboxing. -- **Windows Virtual Desktops** (`CreateDesktopW`) for input isolation and preventing cursor collision. +- **Windows Virtual Desktops** (Planned: `CreateDesktopW`) for future input isolation and preventing cursor collision. Currently runs on `WinSta0\Default`. - **Windows UI Automation (UIA) & COM** for structural DOM crawling without physical mouse movement. - **Windows Credential Manager** for secure storage of API keys. @@ -117,7 +117,7 @@ cargo test --workspace | Command | Description | |---------|-------------| -| `vessel start` | Parses `vessel.toml`, creates `"VesselDesktop"`, binds Job limits, and boots the MCTS search loop. | +| `vessel start` | Parses `vessel.toml`, binds Job limits, and boots the MCTS search loop. | | `vessel stop` | Shuts down guest applications and cleans up isolated desktop instances. | | `vessel credentials set` | Saves the NIM API key securely inside the Windows Credential Manager. | | `vessel credentials clear` | Removes the stored API key from Windows Credential Manager. | @@ -159,8 +159,8 @@ cargo test --workspace - `crates/nim-credentials/Cargo.toml` **Estimated scope:** Small -#### Task 3: Win32 Isolated Input Desktop Setup (C/Rust) -**Description:** Implement the systems code to create a custom independent Window Desktop (`CreateDesktopW`) and spawn processes with an independent input loop. +#### Task 3: Win32 Isolated Input Desktop Setup (C/Rust) (Planned) +**Description:** Implement the systems code to create a custom independent Window Desktop (`CreateDesktopW`) and spawn processes with an independent input loop. Currently, this is a placeholder and processes run on the active user's desktop (`WinSta0\Default`). **Acceptance criteria:** - Creates a secondary desktop `"VesselDesktop"` within the current Window Station (`WinSta0`). - Spawns test GUI processes (e.g. `notepad.exe`) bound to `"VesselDesktop"` via `CreateProcessW` StartupInfo. diff --git a/crates/vessel/src/config.rs b/crates/vessel/src/config.rs index df8ba8d..24a8a65 100644 --- a/crates/vessel/src/config.rs +++ b/crates/vessel/src/config.rs @@ -4,6 +4,12 @@ use std::fs; #[derive(Deserialize, Debug, Default)] pub struct VesselConfig { pub mcts: Option, + pub isolation: Option, +} + +#[derive(Deserialize, Debug)] +pub struct IsolationConfig { + pub mode: Option, } #[derive(Deserialize, Debug)] @@ -38,3 +44,29 @@ pub fn get_mcts_config() -> (usize, bool, f32) { (max_depth, prune_stuck, attribution_weight) } + +pub fn get_isolation_mode() -> Option { + let content = fs::read_to_string("../../vessel.toml") + .or_else(|_| fs::read_to_string("vessel.toml")) + .unwrap_or_default(); + + let config: VesselConfig = toml::from_str(&content).unwrap_or_default(); + + config.isolation.and_then(|i| i.mode) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + #[test] + fn test_parse_toml() { + let content = fs::read_to_string("../../vessel.toml") + .or_else(|_| fs::read_to_string("vessel.toml")) + .unwrap(); + let config: Result = toml::from_str(&content); + println!("Parse result: {:?}", config); + assert!(config.is_ok()); + } +} diff --git a/crates/vessel/src/main.rs b/crates/vessel/src/main.rs index f19ef8e..5c2e735 100644 --- a/crates/vessel/src/main.rs +++ b/crates/vessel/src/main.rs @@ -105,6 +105,13 @@ async fn main() -> Result<()> { Commands::Start => { log::info!("Starting Vessel agent..."); + if let Some(mode) = config::get_isolation_mode() { + if mode == "desktop" || mode == "hyper-v" { + log::warn!("Warning: Isolation mode '{}' is currently unsupported and non-functional.", mode); + log::warn!("Guest processes will run on the default user desktop (WinSta0\\Default) instead of an isolated environment."); + } + } + let _global_lock = match lock::GlobalLock::acquire() { Ok(l) => l, Err(e) => { diff --git a/crates/vessel/src/sanitation.rs b/crates/vessel/src/sanitation.rs index 2f87e07..3278c74 100644 --- a/crates/vessel/src/sanitation.rs +++ b/crates/vessel/src/sanitation.rs @@ -12,13 +12,12 @@ mod windows_impl { const MAXIMUM_ALLOWED: DWORD = 0x02000000; type DESKTOPENUMPROCW = - Option BOOL>; + Option BOOL>; type WINSTAENUMPROCW = - Option BOOL>; + Option BOOL>; #[link(name = "user32")] extern "system" { - fn GetProcessWindowStation() -> HWINSTA; fn EnumWindowStationsW(lpEnumFunc: WINSTAENUMPROCW, lParam: LPARAM) -> BOOL; fn EnumDesktopsW(hwinsta: HWINSTA, lpEnumFunc: DESKTOPENUMPROCW, lParam: LPARAM) -> BOOL; fn OpenWindowStationW( diff --git a/docs/decisions/ADR-001_isolation_strategy.md b/docs/decisions/ADR-001_isolation_strategy.md index ca9164b..034e8ae 100644 --- a/docs/decisions/ADR-001_isolation_strategy.md +++ b/docs/decisions/ADR-001_isolation_strategy.md @@ -23,12 +23,12 @@ We need a solution that offers: 3. **Privilege Containment:** Prevent the agent from accessing sensitive host directories or editing system registry hives. ## Decision -We will use **Win32 Job Objects combined with an Isolated Windows Desktop (`VesselDesktop`)** as our primary lightweight isolation strategy. +We will use **Win32 Job Objects combined with an Isolated Windows Desktop (`VesselDesktop`) (Planned)** as our primary lightweight isolation strategy. -1. **Desktop Isolation via `CreateDesktopW`:** - - The coordinator creates a secondary input desktop named `"VesselDesktop"` in the current window station (`WinSta0`). - - Guest applications (like Chromium or VS Code) are spawned directly on this desktop via `CreateProcessW` by setting the `lpDesktop` parameter of `STARTUPINFO` to `"WinSta0\\VesselDesktop"`. - - These applications run natively on the host kernel but are completely invisible on the user's primary desktop (`WinSta0\\Default`), eliminating active window focus conflicts and cursor jitter. +1. **Desktop Isolation via `CreateDesktopW` (Planned):** + - The coordinator will create a secondary input desktop named `"VesselDesktop"` in the current window station (`WinSta0`). + - Guest applications (like Chromium or VS Code) will be spawned directly on this desktop via `CreateProcessW` by setting the `lpDesktop` parameter of `STARTUPINFO` to `"WinSta0\\VesselDesktop"`. + - **Current Status**: This feature is currently non-functional. Guest applications currently spawn on the user's primary desktop (`WinSta0\\Default`). 2. **Resource & Security Containment via Win32 Job Objects:** - Spawned guest processes are assigned to a Windows **Job Object** (`CreateJobObjectW`, `AssignProcessToJobObject`). - We apply strict resource limits using `SetInformationJobObject` with `JOBOBJECT_EXTENDED_LIMIT_INFORMATION`: @@ -51,4 +51,4 @@ We will use **Win32 Job Objects combined with an Isolated Windows Desktop (`Vess ## Consequences - **Memory Footprint:** The total RAM overhead is reduced to **0MB** for virtualization. The application easily operates within the 1-2GB RAM budget (e.g., Chromium takes ~250MB, the Rust UIA agent takes ~20MB, the Rust CLI takes ~10MB). - **Security model:** Relies on Win32 DACLs (Discretionary Access Control Lists) and Job Objects rather than a hypervisor boundary. If the agent runs an exploit that escalates privileges to `NT AUTHORITY\SYSTEM`, it could theoretically break the sandbox. We mitigate this by executing the guest process under a restricted, non-admin user token. -- **Window Management:** The guest UIA agent must run on `"VesselDesktop"` to inspect and control the isolated windows. +- **Window Management:** The guest UIA agent will run on `"VesselDesktop"` (once functional) to inspect and control the isolated windows. diff --git a/docs/ideas/vessel_agentic_mcts_extension.md b/docs/ideas/vessel_agentic_mcts_extension.md index cd4ed86..f2d7f49 100644 --- a/docs/ideas/vessel_agentic_mcts_extension.md +++ b/docs/ideas/vessel_agentic_mcts_extension.md @@ -8,7 +8,7 @@ ## Recommended Direction We recommend a **Local MCTS Controller + Persistent Tool-Synthesis Sandbox** architecture. -Instead of treating the LLM as a single-step completion model, the Rust-based host controller wraps the NVIDIA NIM API inside a local **Monte Carlo Tree Search (MCTS)** loop. Each node represents a state of the guest workspace (source files, compile states, test logs), and each edge is a proposed tool action. The controller queries the LLM for action hypotheses, executes them inside the isolated Win32 sandbox (`VesselDesktop` restricted by Job Object limits), evaluates their success using a multi-criteria reward function, and performs search rollouts to select the path that passes all tests. +Instead of treating the LLM as a single-step completion model, the Rust-based host controller wraps the NVIDIA NIM API inside a local **Monte Carlo Tree Search (MCTS)** loop. Each node represents a state of the guest workspace (source files, compile states, test logs), and each edge is a proposed tool action. The controller queries the LLM for action hypotheses, executes them inside the Win32 sandbox (eventually planned to be `VesselDesktop`, but currently the default desktop, restricted by Job Object limits), evaluates their success using a multi-criteria reward function, and performs search rollouts to select the path that passes all tests. Inside the sandbox, the agent can extend its own capabilities via a **Self-Software Synthesis Loop**: 1. When a task requires a missing utility, the agent writes the helper in C or Python. @@ -42,7 +42,7 @@ The workspace is protected by a **Transactional Syncer**. Host project directori --- ## Not Doing (and Why) -* **Host-Level DLL Injection:** All self-created binaries must execute strictly inside the isolated `VesselDesktop` workspace. +* **Host-Level DLL Injection:** All self-created binaries must execute strictly inside the guest workspace bounds. * **Unrestricted Internet Access:** All self-created scripts and compiled helpers are subject to the domain whitelist configured in `vessel.toml`. --- diff --git a/vessel.toml b/vessel.toml index 728f6c1..eda9ab0 100644 --- a/vessel.toml +++ b/vessel.toml @@ -5,8 +5,9 @@ # network rules, compiler paths, and agent behavior for the AI Vessel. [isolation] -# Enforce native Win32 Desktop isolation for the 1-2GB RAM restriction -mode = "desktop" # Options: "desktop", "hyper-v" +# NOTE: Desktop isolation mode is currently experimental and unsupported. +# Processes will run on the default desktop instead of an isolated environment. +mode = "desktop" # Options: "desktop", "hyper-v" (Desktop isolation is unsupported) memory_limit_mb = 1024 # Hard limit on all guest processes (1GB) cpu_limit_percent = 50 # Limit guest processes to a maximum of 50% CPU