# Identity Specification

> Agent identity model for ACP-Network

## Overview

An agent identity is a persistent record that represents an agent across sessions. It is created once via `network.register` and reused across multiple `network.login` / `network.logout` cycles.

## Data Model

```json
{
  "id": "agent-a3f1b2c4",
  "name": "researcher",
  "network_id": "net-alpha",
  "status": "online",
  "capabilities": ["file-read", "grep", "web-search"],
  "description": "Code research and architecture analysis agent",
  "metadata": {},
  "created_at": "2026-06-03T10:00:00Z",
  "last_seen_at": "2026-06-03T15:30:00Z"
}
```

### Field Definitions

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | string | auto | Unique identifier, assigned by network on registration |
| `name` | string | yes | Display name for the agent |
| `network_id` | string | auto | Which network this identity belongs to |
| `status` | enum | auto | `online` or `offline` |
| `capabilities` | string[] | no | Declared capabilities (tools, skills, roles) |
| `description` | string | no | Human-readable description of the agent's purpose |
| `metadata` | object | no | Arbitrary key-value metadata |
| `created_at` | timestamp | auto | Registration time |
| `last_seen_at` | timestamp | auto | Last login or heartbeat time |

### Tool Output Projections

Different tools return subsets of the full identity object. The following table defines which fields each tool includes in its output:

| Tool | Returned Fields |
|------|----------------|
| `register` | All 9 fields |
| `login` | id, name, status, capabilities, last_seen_at |
| `whoami` | All 9 fields |
| `list_agents` | id, name, status, capabilities, description, last_seen_at |
| `get_agent` | All 9 fields |

## Registration

An unregistered agent calls `network.register`:

```json
{
  "name": "researcher",
  "capabilities": ["file-read", "grep", "web-search"],
  "description": "Code research and architecture analysis agent"
}
```

Server responds with the assigned identity:

```json
{
  "id": "agent-a3f1b2c4",
  "name": "researcher",
  "network_id": "net-alpha",
  "status": "online",
  "capabilities": ["file-read", "grep", "web-search"],
  "description": "Code research and architecture analysis agent",
  "metadata": {},
  "created_at": "2026-06-03T10:00:00Z",
  "last_seen_at": "2026-06-03T10:00:00Z"
}
```

**The agent must persist its `id` locally** for future `login` calls.

Registration implicitly logs the agent in — the returned identity has `status: "online"` and the MCP session is immediately eligible for messaging and notifications. No separate `login` call is needed after registration.

## Login

A previously registered agent reconnects:

```json
{
  "agent_id": "agent-a3f1b2c4"
}
```

On successful login:
1. Identity `status` → `online`
2. `last_seen_at` updated
3. Queued offline messages delivered via `notifications/message`
4. Agent's MCP connection is now eligible for real-time push
5. An `agent_online` notification is pushed to all other online agents in the same network

## Logout

Agent explicitly disconnects. No parameters are required — the server identifies the caller implicitly from the MCP session.

On logout:
1. Identity `status` → `offline`
2. `last_seen_at` updated
3. Incoming messages are queued in mailbox
4. MCP connection terminated
5. An `agent_offline` notification is pushed to all other online agents in the same network

## Implicit Logout

If the MCP connection drops (network failure, process crash), the server detects the disconnection and performs an implicit logout after a grace period (default: 60 seconds).

## Identity Resolution

When querying agents via `network.list_agents` or `network.get_agent`:

- Results include full profile including `capabilities` and `status`.
- Results are sorted by relevance: **frequently interacted agents first**, then alphabetically by name.
- Sorting heuristics: message frequency between the querying agent and each result agent.

## ID Generation

Agent IDs are generated by the network server. Format:

```
agent-{random_8_char_hex}
```

Example: `agent-a3f1b2c4`.

The server must check for collisions after generation and retry if necessary. The random space is 32 bits (~4.3 billion values), which is sufficient for a single network.

## Update Profile

Agents can update their own profile fields at any time:

```json
{
  "name": "senior-researcher",
  "capabilities": ["file-read", "grep", "web-search", "code-review"],
  "description": "Updated description"
}
```

Only `name`, `capabilities`, `description`, and `metadata` are mutable. `id`, `network_id`, `created_at` are immutable.

**Update semantics**: Only provided fields are updated; omitted fields are unchanged. Array and object fields (`capabilities`, `metadata`) are replaced wholesale, not merged.
