Agent vs User Task Space Ownership in ego‑lite: Complete Guide to Control Models

The agent vs user ownership model in ego‑lite determines which party controls isolated browser contexts, with agent, agentDelegatedToUser, and user as the three valid states, and the agent must claim user‑owned spaces before manipulation.

Task spaces in ego‑lite are isolated browser environments that enable AI agents to perform web-based tasks without interfering with each other or the user's main browsing session. The ownership model governs every interaction with these spaces, from creation through completion. Understanding how agent vs user ownership works is essential for building reliable agent workflows that handle collaborative hand‑offs correctly.

Understanding the Three Ownership States

The ego‑lite runtime tracks ownership through a single field with three possible values. The core predicate that checks agent ownership resides in package/ego-browser/src/helpers.ts:

function isAgentOwned(ownership) {
  return ownership === "agent" || ownership === "agentDelegatedToUser";
}
Ownership value Who created it Control rules
agent Agent Full agent control; no restrictions on switching or manipulation
agentDelegatedToUser Agent (delegated) Agent retains ownership but user has control; agent can still act without reclaiming
user User Agent must claim before any manipulation; switch operations blocked

The agentDelegatedToUser state enables cooperative scenarios where the agent shares control without fully surrendering the space.

Creating and Retrieving Task Spaces

useOrCreate: Reuse Agent Spaces or Fail on User Spaces

The taskSpaces.useOrCreate(nameOrId) method in package/ego-browser/src/helpers.ts attempts to find an existing agent‑owned space matching the identifier, or creates a new one if none exists. Critically, it cannot reuse user‑owned spaces — the call throws an explicit error:


useOrCreateTaskSpace cannot use task space … with ownership …

This safety mechanism prevents accidental agent interference with user‑controlled contexts.

new: Force Fresh Agent‑Owned Creation

When you need guaranteed isolation, taskSpaces.new(name) always creates a brand‑new space with agent ownership, regardless of any existing spaces with that name.

Claiming User‑Owned Spaces

Before an agent can interact with a user‑owned space, it must explicitly claim ownership. The taskSpaces.claim(nameOrId) method performs this transfer:

// Claim transfers ownership and automatically selects the space
await taskSpaces.claim('user-created-space');

After claiming, the space's ownership becomes agent, enabling full manipulation. This claim‑then‑act pattern is mandatory for collaborative workflows where users initiate spaces that agents later take over.

Switching Between Spaces

The taskSpaces.switch(nameOrId) method enforces strict ownership validation. It only operates on spaces where isAgentOwned() returns true. Attempting to switch to a user‑owned space produces a clear runtime error:


switchTaskSpace requires an agent-owned task space, got ownership …

This error originates from the validation logic at line 160 of helpers.ts, ensuring agents never accidentally operate in unclaimed contexts.

Hand‑Off and Take‑Over Patterns

ego‑lite provides two special operations for collaborative workflows that bypass standard ownership checks:

  • taskSpaces.handOff(nameOrId?) — Agent voluntarily returns control to the user, setting ownership to user. Useful when the agent finishes its portion of a task and awaits user input.

  • taskSpaces.takeOver(nameOrId?) — Agent immediately regains control of a user‑owned space without requiring a separate claim operation. This "no‑ownership‑check" shortcut streamlines recovery from hand‑off states.

These methods are implemented as direct ownership transitions in the task‑space façade, enabling fluid agent‑user collaboration without repetitive claim/switch ceremonies.

Completing Tasks and Preserving Spaces

When work finishes, taskSpaces.complete(nameOrId, { keep }) handles cleanup:

// Default: close the space entirely
await taskSpaces.complete(task.id); // keep: false

// Preserve for live‑page scenarios
await taskSpaces.complete(task.id, { keep: true });

The keep parameter, documented in skills/ego-browser/SKILL.md at line 207, supports use cases where the space should remain available for continued user interaction after agent completion.

Waiting for Guaranteed Control

In multi‑step workflows involving hand‑offs, agents can ensure they have control before proceeding:

await taskSpaces.waitForAgentControl(task.id);

This utility from package/ego-browser/src/format.ts (lines 764‑766) polls until the space becomes agent‑owned, preventing race conditions in collaborative scenarios.

Complete Workflow Example

// 1️⃣ Create or reuse an agent‑owned space
const task = await taskSpaces.useOrCreate('research-topic');

// 2️⃣ Handle user‑owned spaces with explicit claim
if (task.ownership === 'user') {
  await taskSpaces.claim(task.id);
}

// 3️⃣ Switch to active work context
await taskSpaces.switch(task.id);

// ... perform agent operations ...

// 4️⃣ Collaborative hand‑off to user
await taskSpaces.handOff(task.id);

// 5️⃣ Later recovery of control
await taskSpaces.takeOver(task.id);
await taskSpaces.waitForAgentControl(task.id);

// 6️⃣ Clean termination
await taskSpaces.complete(task.id, { keep: false });

Source File Reference

File Purpose
package/ego-browser/src/helpers.ts Core ownership logic, isAgentOwned() predicate, claim/switch implementations
package/ego-browser/src/format.ts Public API surface, waitForAgentControl() utility
skills/ego-browser/SKILL.md Human‑readable API documentation including ownership semantics
AGENTS.md High‑level task‑space concepts for agent developers

Summary

  • Three ownership states (agent, agentDelegatedToUser, user) govern all task space interactions in ego‑lite according to the isAgentOwned() predicate in helpers.ts.

  • User‑owned spaces require explicit claims via taskSpaces.claim() before the agent can switch to or manipulate them.

  • useOrCreate() fails on user spaces by design, preventing accidental interference; use new() for guaranteed fresh spaces.

  • Hand‑off patterns use handOff() and takeOver() for collaborative workflows without repetitive ownership checks.

  • Completion with keep: true preserves spaces for live‑page scenarios where users continue interacting after agent work finishes.

Frequently Asked Questions

What happens if I call switch() on a user‑owned task space?

The runtime throws an error: "switchTaskSpace requires an agent-owned task space, got ownership …". You must first call taskSpaces.claim() to transfer ownership, then switch() will succeed. This validation occurs at line 160 of package/ego-browser/src/helpers.ts.

What's the difference between claim() and takeOver()?

claim() is the standard method for acquiring user‑owned spaces with full ownership validation—it transfers user ownership to agent. takeOver() is a shortcut that bypasses ownership checks entirely, allowing immediate control recovery after a handOff(). Both result in agent ownership, but takeOver() assumes you already understand the collaboration state.

Can an agent act on a space after calling handOff()?

Only if it reclaims control. After handOff(), ownership becomes user, so subsequent agent operations require either claim() (standard) or takeOver() (shortcut). The agentDelegatedToUser state is different—it allows agent action without reclaiming because ownership technically remains with the agent.

When should I use keep: true in taskSpaces.complete()?

Use keep: true when the user needs continued access to the space after agent completion—for example, reviewing results, filling additional forms, or interacting with a finalized page. The default keep: false closes the space entirely, which is appropriate for fully automated workflows with no human follow‑up.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →