Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .antigravity.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
Expand All @@ -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.

---

Expand Down
4 changes: 0 additions & 4 deletions .cargo/config.toml

This file was deleted.

2 changes: 1 addition & 1 deletion .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
Expand All @@ -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.

---

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.

Expand Down Expand Up @@ -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. |
Expand Down Expand Up @@ -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.
Expand Down
32 changes: 32 additions & 0 deletions crates/vessel/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use std::fs;
#[derive(Deserialize, Debug, Default)]
pub struct VesselConfig {
pub mcts: Option<MctsConfig>,
pub isolation: Option<IsolationConfig>,
}

#[derive(Deserialize, Debug)]
pub struct IsolationConfig {
pub mode: Option<String>,
}

#[derive(Deserialize, Debug)]
Expand Down Expand Up @@ -38,3 +44,29 @@ pub fn get_mcts_config() -> (usize, bool, f32) {

(max_depth, prune_stuck, attribution_weight)
}

pub fn get_isolation_mode() -> Option<String> {
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<VesselConfig, _> = toml::from_str(&content);
println!("Parse result: {:?}", config);
assert!(config.is_ok());
}
}
7 changes: 7 additions & 0 deletions crates/vessel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
5 changes: 2 additions & 3 deletions crates/vessel/src/sanitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ mod windows_impl {
const MAXIMUM_ALLOWED: DWORD = 0x02000000;

type DESKTOPENUMPROCW =
Option<unsafe extern "system" fn(lpszDesktop: *mut WCHAR, lParam: LPARAM) -> BOOL>;
Option<unsafe extern "system" fn(lpsz_desktop: *mut WCHAR, l_param: LPARAM) -> BOOL>;
type WINSTAENUMPROCW =
Option<unsafe extern "system" fn(lpszWindowStation: *mut WCHAR, lParam: LPARAM) -> BOOL>;
Option<unsafe extern "system" fn(lpsz_window_station: *mut WCHAR, l_param: LPARAM) -> 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(
Expand Down
12 changes: 6 additions & 6 deletions docs/decisions/ADR-001_isolation_strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`:
Expand All @@ -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.
4 changes: 2 additions & 2 deletions docs/ideas/vessel_agentic_mcts_extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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`.

---
Expand Down
5 changes: 3 additions & 2 deletions vessel.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading