# How Ego-Lite Handles Ownership Policies for Task Spaces

> Discover how ego-lite manages ownership policies for task spaces. Learn about the agent vs user flag controlling AI autonomy and user permissions for browser tabs.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: internals
- Published: 2026-08-24

---

**Ego-Lite enforces strict ownership policies for task spaces through an "agent" versus "user" flag that determines whether an AI can autonomously control a browser tab or must request explicit permission from the human user.**

Ego-Lite isolates browsing work into lightweight containers called *task spaces*, each governed by an ownership policy that prevents the AI from disrupting user-controlled tabs. According to the `citrolabs/ego-lite` source code, these policies are implemented in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) and define exactly what actions an autonomous agent can perform based on who owns the space.

## The Ownership Model

Every task space in Ego-Lite carries an **ownership** property that can be set to either `"agent"` or `"user"`. This binary flag creates a strict separation of control:

- **Agent-owned spaces**: The autonomous AI has full privileges to create, select, claim, complete, close, or hand off the space without human intervention.
- **User-owned spaces**: The human user retains final control. The agent may **select** the space to inspect its state, but attempting to claim it automatically raises the `EGO_TASK_SPACE_USER_IN_CONTROL` error. The agent must explicitly request a transfer of ownership before modifying the space.

This design ensures that an agent cannot unintentionally close tabs or alter browsing contexts that a user is actively working in.

## Core Helper Functions for Ownership Management

The ownership logic is implemented through seven primary helper functions exposed via the helper context in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts):

### Creating and Reusing Spaces

**`useOrCreateTaskSpace(nameOrId)`** is the primary entry point for task space acquisition. It first queries existing spaces via `listTaskSpaces()`. If no space exists, it delegates to `newTaskSpace(name)` to create an agent-owned container. If a space exists and is agent-owned, it selects it for the current Node process. However, if the space is user-owned, it selects the space for inspection but deliberately refrains from claiming it, leaving the user in control.

### Transferring Ownership

**`claimTaskSpace(nameOrId)`** facilitates the transfer of control from human to agent. When invoked on a user-owned space, it calls `ego.claimTaskSpace` to transfer ownership. Once claimed, the space behaves exactly like an agent-owned space, granting the AI full control privileges.

### Switching Contexts

**`switchTaskSpace(nameOrId)`** enforces ownership boundaries strictly. It only operates on agent-owned spaces; attempting to switch to a user-owned space throws an error, preventing the agent from silently hijacking user contexts.

### Handing Off and Resuming Control

**`handOffTaskSpace([nameOrId])** returns control to the human user. If the target space is already user-owned, the operation is a no-op and returns `{ done: false, skipped: "user-owned" }`. Conversely, **`takeOverTaskSpace([nameOrId])** restores the agent overlay, allowing the AI to resume work on a previously handed-off space.

### Completing Work

**`completeTaskSpace(nameOrId, { keep })** finalizes a task. When `keep` is `false`, it closes the browser tab. When `keep` is `true`, it leaves the page open for the user. For user-owned spaces with `keep:true`, the function skips any action because the page already belongs to the user.

## Ownership Enforcement in Code

All ownership checks rely on the internal helper **`isAgentOwned(ownership)`** (located at approximately line 143 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)). This function treats the string `"agent"` as the sole value that grants full agent privileges, rejecting any other ownership value:

```javascript
// Example: Creating and managing an agent-owned task space
const task = await useOrCreateTaskSpace('price-lookup');
// task = { id, name, ownership: 'agent', ... }

// Switch to an existing agent-owned space
await switchTaskSpace(task.id);

// Claim a user-owned space before modifying it
await claimTaskSpace('checkout-flow');

// Return control to the user after showing results
await handOffTaskSpace(task.id);

// Resume work later
await takeOverTaskSpace(task.id);

// Complete the task and close the tab
await completeTaskSpace(task.id, { keep: false });

```

The ownership system prevents accidental disruption while supporting seamless multi-round workflows when the agent maintains control.

## Summary

- **Agent-owned spaces** grant full autonomy to the AI for creating, modifying, and closing browser tabs.
- **User-owned spaces** protect human browsing contexts by requiring explicit `claimTaskSpace()` calls before the agent can modify anything.
- **The `isAgentOwned()` helper** at line 143 of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) enforces these boundaries by validating the ownership string.
- **Handoff mechanisms** allow graceful transitions between AI automation and human control without losing session state.

## Frequently Asked Questions

### What happens if an agent tries to claim a user-owned task space without permission?

The system raises the `EGO_TASK_SPACE_USER_IN_CONTROL` error. The agent must explicitly call `claimTaskSpace(nameOrId)` to transfer ownership from the user to itself before performing any modifying actions.

### Can an agent switch context to a user-owned task space?

No. The `switchTaskSpace()` helper strictly enforces ownership boundaries and throws an error when attempting to switch to a user-owned space. The agent can only inspect the space via `useOrCreateTaskSpace()`, which selects it without claiming it.

### How does `handOffTaskSpace` differ from `completeTaskSpace`?

`handOffTaskSpace` temporarily returns UI control to the user while keeping the task space active for future_agent resumption via `takeOverTaskSpace`. `completeTaskSpace` finalizes the task entirely, optionally closing the browser tab based on the `keep` parameter.

### Where is the ownership validation logic located?

All ownership checks are centralized in the `isAgentOwned()` helper function within [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (approximately line 143), which validates that the ownership string equals `"agent"` before granting privileged operations.