# How an Agent Regains Control of a Task Space After a User Handoff in ego-lite

> Learn how an agent regains control of a task space in ego-lite using takeOverTaskSpace or claimTaskSpace after a user handoff. Ownership transitions are tracked atomically.

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

---

**In ego-lite, an agent regains control by invoking `takeOverTaskSpace()` or `claimTaskSpace()` after the user relinquishes ownership via `handOffTaskSpace()`, with ownership transitions tracked atomically in the shared runtime state.**

The **ego-lite** browser automation framework enables collaborative workflows where control of a **task space**—an isolated browsing context—can alternate between an AI agent and a human user. Understanding how to **regain control of a task space after a user handoff** is essential for building resilient automation that gracefully handles manual intervention.

## Understanding Task Space Ownership Transfers

### The Handoff Mechanism

When a human user needs to take manual control, the system calls `handOffTaskSpace()` implemented in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts). According to the source code analysis, this function marks the current task space as user-owned and returns `{ done: false, skipped: "user-owned" }` if the space is already under user control, preventing redundant handoffs. The implementation spans lines 326-338 in the helpers file, ensuring that ownership transfer is explicit and logged.

### Runtime State Tracking

Ownership status is not merely a flag on the browser instance but is maintained in the centralized runtime state defined in [`package/ego-browser/src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts). This shared state object tracks which entity (agent or user) currently owns each task space, ensuring that subsequent helper calls—such as navigation or clicking—are routed through the correct controller.

## Methods for Regaining Control

### Using takeOverTaskSpace()

To resume automation after a user handoff, the agent invokes `takeOverTaskSpace(nameOrId?)` from [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts). This function inspects the current ownership record in the runtime state; if the space is marked as user-owned, it atomically swaps ownership back to the agent. Once executed, the agent can safely issue further commands like `nav.goto()` or `click()` without interference.

### Using claimTaskSpace()

Alternatively, agents can call `claimTaskSpace(nameOrId?)`, which provides a more aggressive reclamation strategy. If the specified task space does not exist, this function creates it; if it exists but is user-owned, it transfers ownership to the agent. This method is particularly useful when the agent needs to guarantee control regardless of the space's previous state or when initializing new workspaces.

## Practical Implementation Pattern

In production workflows, agents typically follow a structured pattern when handling user handoffs. The example below demonstrates yielding control for manual CAPTCHA solving, then reclaiming the space to continue automation:

```javascript
import { handOffTaskSpace, takeOverTaskSpace, nav, click, type, waitFor } from 'ego-lite';

async function collaborativeWorkflow() {
  // Agent performs preliminary automation
  await nav.goto('https://example.com/login');
  await type('input#username', 'alice');
  await type('input#password', 'secret123');

  // Yield control to user for manual intervention
  console.log('Handing off to user for CAPTCHA...');
  await handOffTaskSpace();  // Ownership transfers to user

  // User manually solves CAPTCHA and clicks submit...

  // Agent regains control to verify success
  console.log('Regaining control of task space...');
  await takeOverTaskSpace(); // Ownership returns to agent

  // Continue with post-login automation
  await waitFor('div.dashboard', { timeout: 5000 });
  await click('button#start-session');
}

```

For scenarios requiring explicit workspace management, target specific task spaces by passing identifiers:

```javascript
// Hand off a specific workspace
await handOffTaskSpace('checkout-flow');

// Later, reclaim that specific workspace
await claimTaskSpace('checkout-flow');

// Safe to proceed with domain-specific automation
await nav.goto('https://shop.example.com/cart');

```

## Summary

- **Task spaces** in ego-lite represent isolated browsing contexts with distinct ownership states tracked in [`package/ego-browser/src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts).
- **Handoff**: Users gain control via `handOffTaskSpace()` in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 326-338), which marks the space as user-owned.
- **Reclamation**: Agents regain control by calling `takeOverTaskSpace(nameOrId?)` to resume existing sessions or `claimTaskSpace(nameOrId?)` to forcibly establish ownership.
- **State Management**: The runtime atomically updates ownership records in the shared state, preventing race conditions between user and agent operations.
- **Path References**: Core logic resides in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) with end-to-end tests available in `package/ego-browser/src/taskspace-e2e.test.mjs`.

## Frequently Asked Questions

### What happens if an agent attempts automation without reclaiming the space?

The runtime will block or skip agent-side operations because the task space remains marked as user-owned in the shared state. Helper functions check this ownership flag before executing browser commands, ensuring that agents cannot interfere with active user sessions.

### Can an agent target a specific task space when reclaiming control?

Yes, both `takeOverTaskSpace()` and `claimTaskSpace()` accept an optional `nameOrId` parameter. This allows agents to specify which workspace to reclaim rather than operating on the default current space, enabling multi-tab or multi-workflow orchestration.

### How does `claimTaskSpace()` differ from `takeOverTaskSpace()`?

`takeOverTaskSpace()` specifically handles the transition from user-owned to agent-owned states for existing spaces, while `claimTaskSpace()` is more versatile: it creates a new task space if the identifier does not exist, or transfers ownership of an existing space regardless of its current state.

### Where is the ownership state managed in the source code?

The ownership state is maintained in [`package/ego-browser/src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts), which defines the central runtime state object. Helper functions in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) reference this state to determine control permissions and execute ownership transitions safely.