How Ego-Lite Handles Ownership Policies for Task Spaces
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 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_CONTROLerror. 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:
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 keepisfalse, it closes the browser tab. When keepistrue, 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). This function treats the string "agent" as the sole value that grants full agent privileges, rejecting any other ownership value:
// 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 ofsrc/helpers.tsenforces 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 (approximately line 143), which validates that the ownership string equals "agent" before granting privileged operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →