How Task Spaces Work in ego-lite: Ownership Model and Control Flow Explained
Task spaces in ego-lite are isolated browser contexts with a strict ownership model where spaces are either agent-owned (AI-controlled) or user-owned (human-controlled), requiring explicit claims before cross-party control transfers.
ego-lite divides browsing work into independent units called task spaces. Each space operates as its own browser context, complete with cookies, storage, and state. Understanding how these spaces function and who controls them is essential for building reliable automation workflows. This guide examines the ownership model, control methods, and runtime enforcement based on the actual source implementation in citrolabs/ego-lite.
What Are Task Spaces?
A task space is a named, isolated browsing environment within ego-lite. Spaces can be created, selected, transferred between parties, and terminated. The taskSpaces facade—implemented in src/helpers.ts and documented in src/format.ts—provides the primary interface for JavaScript code.
Unlike shared browser sessions, task spaces enforce clear boundaries. Each space receives a numeric ID and carries metadata including its name and ownership status.
The Ownership Model: Agent vs. User
Every task space carries an ownership flag with two possible values:
| Ownership | Controller | Permissions |
|---|---|---|
agent |
AI autonomous agent | Full control: switch, claim, handOff, takeOver, complete |
user |
Human end user | Blocks agent actions until explicitly claimed |
This binary model prevents accidental conflicts. When the agent creates a space via newTaskSpace(), it receives agent ownership automatically. Spaces created through other flows may default to user ownership, requiring explicit takeover.
Core Task Space Operations
The taskSpaces facade exposes eight primary methods. Each enforces ownership rules through the runtime's task-space manager.
Creating and Selecting Spaces
newTaskSpace(name) creates a fresh space with automatic selection:
const task = await taskSpaces.new('research-task')
// Returns: { id: 5, name: 'research-task', ownership: 'agent' }
// The new space is immediately active
The underlying implementation calls ego.createTaskSpace, validates the response through taskSpaceNumericId, and sets the new space as current.
useOrCreate(nameOrId) provides idempotent reuse:
const task = await taskSpaces.useOrCreate('research-task')
This method only matches agent-owned spaces. If a user-owned space exists with that name, it will not be automatically selected—the agent must claim it first.
Claiming User-Owned Spaces
claim(nameOrId) transfers ownership from user to agent:
await taskSpaces.claim('user-checkout')
await taskSpaces.switch('user-checkout')
Attempting to switch directly to a user-owned space without claiming throws an error with guidance directing the user to take control. The claim operation validates the space's numeric ID and updates the ownership flag before permitting further actions.
Switching Between Spaces
switch(nameOrId) activates a specified space:
The method fails under two conditions:
- Unknown space ID
- Unclaimed user-owned space
Ownership verification occurs in src/helpers.ts before ego.useTaskSpace is invoked.
Transferring Control
handOff(nameOrId?) yields control to the user:
await taskSpaces.handOff() // Current space becomes user-owned
takeOver(nameOrId?) regains agent control after hand-off:
await taskSpaces.takeOver()
waitForAgentControl(nameOrId?, options?) pauses execution until ownership returns:
await taskSpaces.handOff()
await taskSpaces.waitForAgentControl() // Blocks until user releases
await taskSpaces.takeOver()
Completing Spaces
complete(nameOrId, {keep}) terminates a space:
await taskSpaces.complete(task.id, { keep: false }) // Discard
await taskSpaces.complete(task.id, { keep: true }) // Preserve for later
Runtime Enforcement and Error Handling
The task-space manager in src/helpers.ts validates all operations against ownership state. Key enforcement points include:
taskSpaceNumericId()validates numeric IDs and extracts ownership fieldsclaimandswitchverify ownership before callingego.useTaskSpace- Violations surface clear errors defined in
src/ego-errors.ts
Error messages specifically guide developers toward correct ownership operations rather than generic failures.
Testing the Ownership Flow
The end-to-end test suite in src/taskspace-e2e.test.mjs validates the complete model:
- Agent-owned spaces work immediately with
useOrCreate - User-owned spaces require
claimbeforeswitch - Direct
switchattempts on user spaces surface guidance messages - Unknown IDs and binding misuse throw descriptive errors
These tests confirm that the ownership model prevents automation failures while supporting intentional collaboration patterns.
Summary
- Task spaces are isolated browser contexts with unique IDs and metadata
- Ownership is binary:
agent(full AI control) oruser(human control, requires claim) new()creates agent-owned spaces;useOrCreate()only matches agent-owned spacesclaim()is mandatory before controlling user-owned spaces- Hand-offs use
handOff(),waitForAgentControl(), andtakeOver()for safe collaboration - Runtime enforcement in
src/helpers.tsprevents accidental control violations - Clear errors in
src/ego-errors.tsguide correct usage patterns
Frequently Asked Questions
What happens if I try to switch to a user-owned task space without claiming it?
The runtime throws an error with guidance directing the user to take control. According to src/helpers.ts, switch() validates ownership before calling ego.useTaskSpace, and unclaimed user spaces fail this check with a specific message from src/ego-errors.ts.
Can two agents share the same task space?
No. The ownership model only recognizes agent and user as valid states. While multiple agent processes could theoretically interact with the same space ID, the runtime expects single-party control. Use handOff and takeOver for sequential control transfers rather than concurrent sharing.
How do I detect if a space is agent-owned or user-owned before switching?
The taskSpaces methods abstract ownership checks—you don't manually inspect the flag. Instead, use useOrCreate for agent spaces or wrap claim attempts in try-catch blocks. The test suite in src/taskspace-e2e.test.mjs demonstrates this pattern: claim first, then proceed on success.
What's the difference between complete() with keep: true and keep: false?
keep: true preserves the space's state for potential future reactivation, while keep: false discards it entirely. Both operations end the current active session. The space's ownership history does not affect this—completion works regardless of whether the space was agent or user controlled.
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 →