# What Are Ego-Lite Spaces and How Do They Prevent Interference?

> Discover Ego-Lite Spaces: logical containers that isolate browser tabs and prevent interference. Learn how strict ownership rules protect your automation and user sessions.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: explanation
- Published: 2026-07-31

---

**Ego-Lite Spaces are logical containers that isolate browser tabs and their state, enforcing strict ownership rules—either "agent" or "user"—to ensure automation code cannot interfere with human-controlled sessions or other concurrent tasks.**

Ego-Lite, developed by CitroLabs as an open-source browser automation framework, introduces **Task Spaces** (commonly called *spaces*) to solve the fundamental problem of shared browser interference. Each space wraps a single browser tab along with its associated state—including reference maps, snapshots, and Chrome DevTools Protocol (CDP) sessions—creating deterministic boundaries for automation workflows that may involve both scripted agents and human users.

## Understanding Task Spaces in Ego-Lite

A **Task Space** is the fundamental unit of isolation in the Ego-Lite architecture. Rather than operating directly on browser contexts, automation scripts interact with named spaces that encapsulate all tab-specific resources. This design allows multiple automation tasks to coexist within the same browser instance without cross-contamination.

When you invoke `taskSpaces.useOrCreate()` or `taskSpaces.switch()`, the framework selects that specific space as the active context. All subsequent helper calls—such as `page.goto()`, `locator.click()`, or `browser.close()`—operate exclusively on the selected space. The underlying native bridge rejects commands targeting different spaces, ensuring that one task cannot inadvertently affect another tab's state.

## Ownership Models and Access Control

Every space carries an **ownership** flag that determines who may issue commands against it. According to the implementation in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) (lines 18‑32), three ownership states exist:

- **`"agent"`** – The automation script has full control and may execute any command.
- **`"agentDelegatedToUser"`** – Initially agent-owned but temporarily shared; the agent retains ownership while allowing user interaction.
- **`"user"`** – The human user currently controls the tab; the agent is restricted to read-only or polling operations.

This ownership model is enforced by the **Task-Space Façade** created via `createTaskSpacesFacade` in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts). The façade methods validate ownership before delegating to native `ego` APIs such as `ego.createTaskSpace`, `ego.useTaskSpace`, and `ego.claimTaskSpace`.

### Agent-Only Actions and Protective Errors

When the agent attempts actions like `switchTaskSpace`, `newTaskSpace`, or `claimTaskSpace` on a user-owned space, the façade throws an error immediately. As implemented in lines 52‑63 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), the `switch` method checks ownership before proceeding, preventing the agent from hijacking a user's active session.

If the agent attempts to mutate a user-owned space through lower-level commands, the native bridge raises the **`EGO_TASK_SPACE_USER_IN_CONTROL`** error (defined in [`src/ego-errors.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/ego-errors.ts)). The helpers translate this into a safe, high-level exception rather than allowing accidental page mutations.

## How Spaces Prevent Interference

The interference prevention mechanism operates at multiple layers, from the JavaScript façade down to the native browser bridge.

### Command Isolation via the Native Bridge

Once a space is selected through `taskSpaces.useOrCreate(nameOrId)`, all subsequent helper invocations are scoped to that space. The native bridge maintains this context and rejects cross-space commands. This ensures that even if multiple automation scripts run concurrently, each operates within its own sandboxed tab environment.

### Ownership Validation in the Task-Space Façade

The façade enforces ownership rules through explicit checks before executing sensitive operations:

- **Hand-off operations** (`handOffTaskSpace`) are silently skipped if the space is already user-owned, avoiding unnecessary errors when the user already has control.
- **Completion** (`complete`) verifies agent ownership before closing spaces, as shown in lines 66‑73 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts).
- **Claiming** a user-owned space (lines 24‑28) requires explicit takeover logic that respects the current user's session.

### Safe Hand-Off and Takeover Patterns

To facilitate human-in-the-loop workflows, Ego-Lite provides `waitForAgentControl`, which polls a harmless snapshot until the agent regains ownership (lines 77‑84). This prevents busy-loops and guarantees that automation only proceeds when it truly owns the space, eliminating race conditions between user input and script execution.

## Working with Task Spaces: Code Examples

The following examples demonstrate practical patterns for creating isolated spaces and managing ownership transitions without interference.

```javascript
// Create (or reuse) a space for a research task
const task = await taskSpaces.useOrCreate('research-task');
// The agent now owns `task.id` and all subsequent calls target this tab
await page.goto('https://news.ycombinator.com');

```

```javascript
// Hand the space back to the user for review (no interference)
await taskSpaces.handOff(task.id);   // Skips if already user-owned

// Later the agent can retake control
await taskSpaces.takeOver(task.id);
await page.locator('text=Ask HN').click();

```

```javascript
// When done, close the space (agent-owned) or keep it open for the user
await taskSpaces.complete(task.id, { keep: false });

```

```javascript
// Detect whether the agent currently has control before proceeding
try {
  await taskSpaces.waitForAgentControl(task.id, { timeout: 120 });
  // Safe to run automation now
  await page.click('#submit');
} catch (e) {
  console.error('Agent never regained control:', e);
}

```

## Core Implementation Details

The interference prevention logic resides primarily in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), where the `createTaskSpacesFacade` function builds the public API. Key implementation points include:

- **Ownership policy validation** (lines 18‑32): Establishes the three-state ownership model and initial checks.
- **Switching guards** (lines 52‑63): Ensures `switch` operations only proceed when the agent owns the target space.
- **Claiming logic** (lines 24‑28): Handles transitions from user-owned to agent-owned states.
- **Completion safety** (lines 66‑73): Validates ownership before destroying space resources.
- **Control polling** (lines 77‑84): Implements `waitForAgentControl` using safe snapshot polling.

Supporting files include [`src/ego-errors.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/ego-errors.ts), which defines the `EGO_TASK_SPACE_USER_IN_CONTROL` constant used throughout the façade, and `src/taskspace-e2e.test.mjs`, which contains end-to-end tests verifying isolation behavior. Public API signatures are documented in [`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts) for integration with the `help()` system.

## Summary

- **Task Spaces** are logical containers in Ego-Lite that isolate browser tabs, state, and CDP sessions to prevent cross-task contamination.
- **Ownership flags** (`agent`, `agentDelegatedToUser`, `user`) enforce strict access control, ensuring agents cannot mutate user-controlled pages.
- The **Task-Space Façade** in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) validates all operations, throwing errors or skipping actions that would violate ownership rules.
- **Native bridge integration** rejects cross-space commands and raises `EGO_TASK_SPACE_USER_IN_CONTROL` when agents attempt unauthorized mutations.
- **`waitForAgentControl`** provides safe polling mechanisms for agents to resume work only after regaining ownership from users.

## Frequently Asked Questions

### Can multiple agents control the same space simultaneously?

No. Ego-Lite enforces single-owner semantics through the ownership flag system. While multiple agents might exist in the same browser instance, only the entity holding the current ownership token—either an agent or the user—may issue mutating commands to a specific space. Other agents attempting to access that space will encounter ownership validation errors from the façade.

### What happens if an agent tries to click while the user is actively browsing?

The native bridge raises the `EGO_TASK_SPACE_USER_IN_CONTROL` error, which the helpers in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) translate into a high-level exception. The click command is blocked before reaching the browser's CDP layer, ensuring the user's interactions remain uninterrupted. Agents should use `waitForAgentControl` to poll for ownership recovery before attempting mutations.

### How do I safely transition a task from automation to human review?

Use `taskSpaces.handOff(task.id)` to transfer ownership to the user. This method safely skips if the space is already user-owned, preventing redundant errors. The agent can later reclaim control via `taskSpaces.takeOver(task.id)` once the user has finished reviewing, enabling seamless human-in-the-loop workflows without data loss or state corruption.

### Where is the space isolation logic implemented in the source code?

The core isolation and ownership logic lives in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) within the `createTaskSpacesFacade` function. This file contains the ownership validation checks (lines 18‑32, 52‑63), the claiming logic (lines 24‑28), and the safe polling mechanism for agent control (lines 77‑84). Error definitions reside in [`src/ego-errors.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/ego-errors.ts), while integration tests are available in `src/taskspace-e2e.test.mjs`.