# Understanding the Task Space Handoff Protocol Between Agent and User Control in ego-browser

> Learn how ego-browser's task space handoff protocol safely transfers control from AI to user. Discover validation, ownership verification, and secure method invocation for seamless transitions.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-07-26

---

**The task space handoff protocol in ego-browser enables an AI agent to safely transfer control of a browsing context back to the user by validating runtime capabilities, verifying ownership, and invoking a secure runtime method that returns either a success confirmation or a skip status indicating the space is already user-owned.**

The **task space handoff protocol** governs how the autonomous **agent** relinquishes browser control to the **user** within the `citrolabs/ego-lite` repository. This mechanism ensures that ownership transitions occur atomically, preventing privilege escalation while maintaining session continuity across the control boundary.

## How the Handoff Protocol Works

The implementation follows a select-then-invoke pattern defined in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), progressing through four distinct validation and execution stages.

### Target Identification

The process begins when the agent calls `handOffTaskSpace(nameOrId?)`, defined at **line 326** of [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), accepting an optional string or numeric identifier. If omitted, the protocol defaults to the currently active **task space**.

### Runtime Capability Validation

Before attempting any transfer, the helper validates that the embedded **ego runtime** actually implements the capability. **Lines 328–329** explicitly check `if (!ego || typeof ego.handOffTaskSpace !== "function")` and throw an error if the method is missing, preventing silent failures when the runtime lacks support.

### Task Space Selection and Ownership Verification

At **line 336**, the helper invokes `selectTaskSpace(ego, match, "handOffTaskSpace")` to resolve the identifier to a concrete task-space object. This step acts as a gatekeeper, ensuring the operation targets a legitimate space and verifying that the space is currently **user-owned**—if so, the protocol skips the handoff rather than performing a redundant transfer.

### Executing the Transfer

Finally, **line 338** delegates to the runtime via `assertNoEgoError(await ego.handOffTaskSpace(), "handOffTaskSpace")`. This call surfaces any runtime-level problems immediately. The operation resolves to `{ done: true }` upon successful agent relinquishment, or `{ done: false, skipped: "user-owned" }` when the space already belongs to the user.

## Implementation Details and Source Files

The protocol is distributed across several key files in the ego-browser package:

- **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)**: Contains the `handOffTaskSpace` function implementing the four-stage validation and invocation logic.
- **[`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)**: Exposes the public API list including the `"handOffTaskSpace"` capability.
- **[`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts)**: Holds the singleton runtime state, tracking **task-space ownership** transitions.
- **`src/taskspace-e2e.test.mjs`**: Provides end-to-end tests verifying that handoff behavior respects ownership boundaries.

## Practical Code Examples

Hand off the current active task space and handle the result:

```javascript
const result = await handOffTaskSpace();

if (result.done) {
  console.log("Control transferred to user");
} else {
  console.log("Skipped:", result.skipped); // "user-owned"
}

```

Hand off a specific task space by name:

```javascript
await handOffTaskSpace("project-context-42");
// The helper validates ownership before invoking ego.handOffTaskSpace()

```

Handle unsupported runtimes with explicit error catching:

```javascript
try {
  await handOffTaskSpace();
} catch (err) {
  // Throws if ego.handOffTaskSpace is not a function (lines 328-329)
  console.error("Runtime does not support handoff:", err.message);
}

```

## Summary

- The **task space handoff protocol** ensures safe transitions from **agent** control to **user control** through a validated runtime interface implemented in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts).
- The `handOffTaskSpace()` helper follows a select-then-invoke pattern that verifies the **ego runtime** capability before execution, throwing immediately if support is missing.
- Ownership validation prevents redundant handoffs, returning `{ done: false, skipped: "user-owned" }` when the user already owns the space.
- Successful transfers return `{ done: true }` only after the runtime confirms the agent has relinquished privileges via `ego.handOffTaskSpace()`.

## Frequently Asked Questions

### What happens if the ego runtime does not support handOffTaskSpace?

The helper function throws a descriptive error immediately upon invocation if `ego.handOffTaskSpace` is undefined or not a function, as enforced by the validation logic at lines 328–329 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts). This early validation prevents the agent from attempting an unsupported operation and ensures callers handle the missing capability explicitly rather than failing silently.

### Can an agent hand off a task space that is already user-owned?

Yes, but the operation returns `{ done: false, skipped: "user-owned" }` rather than performing a redundant transfer. The `selectTaskSpace` logic detects the current ownership state during the selection phase at line 336, making the protocol idempotent and safe to call regardless of current ownership.

### How does the protocol prevent the agent from controlling user-owned spaces?

The handoff is unidirectional by design; once `ego.handOffTaskSpace()` executes successfully and returns without error, the agent loses the ability to issue navigation or interaction commands for that specific **task space**. The underlying runtime enforces this boundary, and subsequent agent actions require an explicit claim or new task space creation.

### Where is the handoff protocol tested?

End-to-end coverage exists in `src/taskspace-e2e.test.mjs`, which verifies that ownership transitions occur correctly and that the helper returns appropriate status objects when switching between **agent** and **user control** contexts, ensuring the handoff protocol behaves reliably across different runtime environments.