# How ego-browser Determines If a Task Space Is Agent-Owned

> Discover how ego-browser identifies agent-owned task spaces using the isAgentOwned predicate and ownership properties in ego-lite helpers.ts for clear access control.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-29

---

**ego-browser treats a task space as agent-owned when its `ownership` property equals `"agent"` or `"agentDelegatedToUser"`, enforced through the `isAgentOwned()` predicate in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts).**

The ownership model in `citrolabs/ego-lite` controls which task spaces an autonomous agent can manipulate versus those reserved for human users. This article explains the exact logic, source code implementation, and API behaviors that hinge on this classification.

## The Ownership Property and Valid Values

Task spaces in ego-browser carry an `ownership` field with three possible string values. According to the source code in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 118-124), these are:

- `"agent"` — fully controlled by the agent
- `"agentDelegatedToUser"` — agent retains ultimate ownership but has temporarily delegated control to a user
- `"user"` — fully controlled by a human user, agent cannot modify without claiming

This tri-state design allows flexible hand-offs between autonomous and human-driven workflows while maintaining clear boundaries.

## The `isAgentOwned()` Predicate Function

At the heart of ownership determination sits a single helper function defined in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 143-145):

```typescript
function isAgentOwned(ownership) {
  return ownership === "agent" || ownership === "agentDelegatedToUser";
}

```

This **pure predicate** returns `true` for both direct agent ownership and delegated states, `false` only for `"user"`. All higher-level helpers import and call this function rather than implementing ad-hoc checks, ensuring consistent policy enforcement.

## Runtime Enforcement in Public Helpers

Functions requiring exclusive agent access validate ownership before proceeding. The `switchTaskSpace` implementation (lines 57-63) demonstrates this pattern:

```typescript
const space = await findTaskSpace(nameOrId);
if (!isAgentOwned(space.ownership)) {
  throw new Error(
    `switchTaskSpace requires an agent-owned task space, got ownership ${JSON.stringify(space.ownership)}`,
  );
}

```

The error message explicitly reports the actual ownership value, aiding debugging when automation attempts to operate on user-controlled spaces.

## How Ownership Affects Different API Operations

The same predicate drives divergent behaviors across the task-space façade:

| Helper | Behavior on User-Owned Space | Behavior on Agent-Owned Space |
|--------|------------------------------|-------------------------------|
| `switchTaskSpace` | Throws `Error` | Selects space and continues |
| `useOrCreateTaskSpace` | Selects without claiming | Selects existing or creates new agent-owned |
| `claimTaskSpace` | Transfers to `"agent"` then selects | No-op, already owned |
| `handOffTaskSpace` | Returns `{ done: false, skipped: "user-owned" }` | Transfers to user |
| `completeTaskSpace` | Returns `{ done: false, skipped: "user-owned" }` | Marks complete and archives |

This design lets agents gracefully coexist with human users—the agent never forcefully seizes control without an explicit `claimTaskSpace` call.

## Practical Code Examples

### Check ownership manually for debugging

```typescript
import { listTaskSpaces } from "ego-browser";

async function printAgentOwnedSpaces() {
  const spaces = await listTaskSpaces();
  const agentOwned = spaces.filter(s => 
    s.ownership === "agent" || s.ownership === "agentDelegatedToUser"
  );
  console.log("Agent-owned task spaces:", agentOwned);
}

```

### Switch to a task space with enforced ownership

```typescript
import { switchTaskSpace } from "ego-browser";

async function goToSpace(idOrName) {
  // Throws if the target space is user-owned
  await switchTaskSpace(idOrName);
  console.log(`Switched to task space ${idOrName}`);
}

```

### Use or create with automatic ownership handling

```typescript
import { useOrCreateTaskSpace } from "ego-browser";

async function ensureSpace(name) {
  // If agent-owned: select it
  // If user-owned: select without claiming
  // If missing: create as agent-owned
  const space = await useOrCreateTaskSpace(name);
  console.log(`Operating in task space ${space.id}`);
}

```

### Claim control of a user-owned space

```typescript
import { claimTaskSpace } from "ego-browser";

async function takeControl(nameOrId) {
  const space = await claimTaskSpace(nameOrId);
  console.log(`Claimed task space ${space.id} – now agent-owned`);
}

```

## Key Source Files

- [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) — Core `isAgentOwned` definition, validation logic in `switchTaskSpace`, and all task-space helper implementations
- [`package/ego-browser/src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/format.ts) — Public façade documentation and type signatures (lines 653-699)

## Summary

- **Agent ownership** requires `ownership === "agent"` or `ownership === "agentDelegatedToUser"`
- **Single source of truth**: the `isAgentOwned()` predicate in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) (lines 143-145)
- **Strict enforcement**: functions like `switchTaskSpace` throw errors for user-owned spaces
- **Graceful degradation**: `handOffTaskSpace` and `completeTaskSpace` skip rather than crash on user-owned spaces
- **Explicit transfers**: `claimTaskSpace` is the only automatic path from `"user"` to `"agent"` ownership

## Frequently Asked Questions

### What happens if I call `switchTaskSpace` on a user-owned task space?

The function throws an `Error` with a descriptive message indicating that `switchTaskSpace` requires an agent-owned task space and reporting the actual ownership value found. This prevents accidental interference with human-controlled workspaces.

### Can an agent work in a user-owned space without claiming it?

Yes. The `useOrCreateTaskSpace` helper selects user-owned spaces without claiming them, allowing the agent to read or observe while leaving control with the user. This supports collaborative workflows where humans and agents share context.

### How does `agentDelegatedToUser` differ from `user` ownership?

`agentDelegatedToUser` means the agent retains ultimate ownership but has temporarily handed control to a user—the agent can reclaim without `claimTaskSpace`. Full `"user"` ownership requires an explicit `claimTaskSpace` call to transfer back to agent control.

### Where is the ownership policy documented in the source code?

The valid ownership values and their meanings are documented in a comment block at lines 118-124 of [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts), immediately above the helper function implementations.