# Agent ID repository guide
## Documentation boundaries
Keep `README.md` human-facing: what the project does, installation, normal use, and project origins. Keep implementation details and complete command references in this file. Instructions for a running agent belong in the output generated by `src/prime.rs` (`agent-id prime`).
## CLI reference
The binary is installed as `agent-id`; the Rust crate is `agent-id-cli`.
### `agent-id register [SESSION_ID]`
Allocates a permanent identity. Registration is idempotent: an existing session keeps its identity and receives a new `updated_at`.
```text
--family NAME Prefer a family name, useful for child agents
--realm NAME Select the computer realm
--session-id ID Provide the session ID explicitly
--json Print the complete assignment as JSON
```
### `agent-id lookup [IDENTIFIER]`
Reads an existing identity by session ID, canonical name, or slug. Without an explicit identifier, lookup uses `AGENT_ID_SESSION_ID`.
```text
--session-id ID Provide the session ID explicitly
--json Print the complete assignment as JSON
```
### `agent-id current`
Reads the identity for `AGENT_ID_SESSION_ID` without registering a missing session. Use `--json` to print the complete assignment.
```text
--json Print the complete assignment as JSON
```
### `agent-id annotate [SESSION_ID]`
Updates summary, lifecycle state, working-directory metadata, or namespaced extension metadata independently; omitted fields remain unchanged.
```text
--summary TEXT Set a concise summary (maximum 240 characters)
--clear-summary Remove the summary
--state VALUE Set working, idle, waiting, blocked, or stopped
--clear-state Remove the activity state
--cwd PATH Set the current working directory
--clear-cwd Remove the current working directory
--extension OWNER=JSON Set namespaced unstructured JSON metadata; repeatable
--clear-extension NAME Remove one extension namespace; repeatable
--session-id ID Provide the session ID explicitly
--json Print the complete assignment as JSON
```
### `agent-id discover`
Lists non-stopped assignments by `updated_at`, newest first. Use `--all` to include stopped assignments. Human-readable results include available summaries, states, and working directories; JSON includes the complete assignments. Inside Herdr, discover queries `herdr api snapshot` and adds a non-persistent `runtime` projection to assignments whose OMP session-file metadata exactly matches a live Herdr agent.
```text
--limit N Maximum records (default 20; zero means all)
--recent HOURS Only records updated within this many hours
--realm NAME Only records in this realm
--all Include stopped assignments
--json Print the complete assignments and available runtime projections as JSON
```
### `agent-id prune`
Removes assignments older than an RFC 3339 cutoff, including their name claims.
```text
--before TIMESTAMP Delete records updated before this timestamp
--dry-run Preview matches without deleting
--json Print the prune report as JSON
```
### `agent-id prime`
Prints the agent-facing workflow and command contract. `--prelude` omits the command reference; `--json` wraps the documentation in a JSON object.
## OMP extension implementation
`extensions/agent-id.ts` is the companion adapter. It reads the authoritative session ID and working directory from OMP, invokes the `agent-id` binary from `PATH` with explicit arguments, parses the returned assignment, and manages session lifecycle and summaries.
| Session start, switch, or branch | Looks up or registers the identity, records the OMP session file and working directory, and marks the session `idle`. |
| Agent turn starts | Refreshes the OMP session file and marks the session `working`. |
| Agent turn ends | Marks the session `idle` and may refresh its current-work summary. |
| Tool call | Injects `AGENT_ID_SESSION_ID` only into matching `agent-id current` invocations through OMP's Bash tool. |
| Session shuts down | Marks the session `stopped`. |
On session start, switch, branch, and tree navigation, the extension inserts one hidden persistent context message per branch pointing agents to `agent-id prime` and `agent-id current --json`. It checks the stable message type before insertion so resumed branches reuse the existing prompt prefix.
The extension does not register an identity tool. For matching `agent-id current` invocations through OMP's Bash tool, the extension injects the current session ID as `AGENT_ID_SESSION_ID`. It preserves a caller-provided value and does not modify the parent shell or unrelated Bash commands.
After completed turns, the extension can derive up to three successful summaries. Each completion receives only the previous summary, latest request, and latest reply; it uses the `@tiny` model role with `@smol` as fallback, caps output at 80 characters, and persists through `agent-id annotate`. Summary generation state is stored as a session entry and restored across resume, branch, and tree navigation. Missing model access does not prevent registration or lifecycle updates.
Lifecycle states are `working`, `idle`, `waiting`, `blocked`, and `stopped`. Agent ID generates state timestamps; stale sessions remain distinguishable by `state.updated_at`.
## Registry implementation
The registry root is `$AGENT_ID_HOME` when set, otherwise `$XDG_DATA_HOME/agent-id`, or `$HOME/.local/share/agent-id` when `XDG_DATA_HOME` is unset.
Session records live at `by-session/<session-id>.json`; session IDs must be filename-safe. Name claims live under `by-name/`. The assignment stores the permanent name and slug, realm, optional timestamped activity fields, and optional timestamped extension-owned JSON metadata.
Realm resolution order is `--realm`, `AGENT_REALM` for tests or overrides, then `$XDG_CONFIG_HOME/agent-id/realm` with `$HOME/.config/agent-id/realm` as fallback. If no configuration exists, registration selects a realm and persists it for future sessions on the machine.
Summary, state, working-directory, and extension fields update independently of the permanent name. Extension owners are bounded lowercase namespaces; each update atomically replaces one owner's JSON value. The OMP extension writes its absolute session file under `extensions.omp`, which discover uses only as a correlation key for ephemeral Herdr data.
## Release workflow
When the user says “Let's do the release workflow,” drive the release through publication:
1. Confirm the worktree contains only the intended release changes, the branch is `main`, and the `v<version>` tag does not already exist.
2. Update the version in `Cargo.toml` and `package.json`, then run Cargo without `--locked` once to refresh the root `agent-id-cli` entry in `Cargo.lock`.
3. Run `cargo fmt --all -- --check`, `cargo test --all --locked`, `bun test extensions/agent-id.test.ts`, and `cargo package --locked --allow-dirty`.
4. Commit all release changes with a Conventional Commit message, the relevant `SQ-Task` trailer, and the required OMP/model co-author trailers.
5. Push `main`, create and push the annotated `v<version>` tag, then publish a GitHub release for that existing tag with generated notes. A tag push runs only the version check; publishing the GitHub release triggers macOS artifacts, crates.io publishing, and the Homebrew tap update.
6. Watch the release-triggered `Publish` workflow until every required job succeeds. Verify the GitHub release has both macOS archives and checksums; report whether crates.io and the Homebrew tap published successfully.
Required repository secrets are `CARGO_REGISTRY_TOKEN` and `HOMEBREW_TAP_TOKEN`.