AxiOwl Session Discovery Explained

AxiOwl session discovery is the step that turns provider-owned chat state into routing facts AxiOwl can use. It answers a practical question: which real agent sessions exist, what provider owns them, what stable session id identifies them, and whether AxiOwl has enough proof to send to them?

That sounds simple, but it is one of the most important boundaries in AxiOwl. AxiOwl is not trying to scrape every possible application artifact and guess where messages should go. Its product contract is narrower: a named sender sends a text body to a named target, AxiOwl resolves those names, selects one provider edge, records what happened, and returns an honest receipt. Discovery exists so that target resolution is based on durable provider facts rather than stale display names or hopeful filesystem guesses.

Discovery Is Not Delivery

The key rule in the AxiOwl design docs is blunt:

discovered != enrolled
enrolled != live
live != replied

Discovery means AxiOwl found evidence that a provider session exists. Enrollment means that evidence has been merged into the local registry as a target row. Sendability means the row has enough provider, session, node, and capability information for AxiOwl to try delivery. A reply over MCP is stronger proof than any discovery scan because it proves the target received the message and had enough sender identity to respond.

This separation keeps receipts honest. AxiOwl should not tell an operator that a message was delivered just because a chat-like file existed on disk. It should say only what it can prove: the request was accepted by AxiOwl, accepted by the provider edge, degraded, failed, or unknown.

The Registry Is The Center

AxiOwl discovery feeds a durable local registry. The registry maps human-friendly names and aliases to provider-owned session identifiers. In the current Linux CLI provider implementation, the registry is persisted under the CLI state root as:

registry/cli_providers.json

The registry row model includes fields such as:

provider_id
provider_display_name
node_id
executable_path
auth_state
mcp_config_path
mcp_server_name
provider_session_id
sender_address
chat_name
chat_aliases
workspace_path
transcript_path
provider_log_path
last_seen_at
sendable
create_supported
rename_supported
discovery_source
evidence_summary

The important part is not the storage format. The important part is the identity model. AxiOwl routes to a provider session id, not to a loose title. A title is useful for humans. A provider session id is what lets a provider edge target the right chat.

The registry code also preserves useful human naming. When a discovered row already exists, AxiOwl updates operational fields and may retain or alias the previous chat name. That matters because users rename sessions, providers expose names inconsistently, and operators still need stable names they can type.

What The Discovery Commands Do

The Linux CLI provider tool exposes provider-specific discovery commands:

axiowl-linux codex-cli discover
axiowl-linux opencode-cli discover
axiowl-linux antigravity-cli discover

Each command loads the registry, runs the matching provider discovery adapter, merges rows, deduplicates by provider session id, saves the registry, and prints a compact JSON summary with fields like:

ok
new_rows
updated_rows
total_rows
failure_reason

That shape is useful operationally. A discovery run should be inspectable. If it found nothing, failed to read provider state, or detected a duplicate-delivery condition, the command has a place to say so.

Codex Discovery

The current Codex CLI discovery implementation scans the Codex sessions root for rollout JSONL files whose names contain a thread UUID. For each unique thread id, it reads the first JSONL line to capture workspace context, then writes a registry row.

The Codex row uses:

provider_id = codex_cli
provider_session_id = <thread uuid>
sender_address = <thread uuid>
discovery_source = rollout_scan

If the row is already known, AxiOwl keeps the existing chat name and aliases. If it is new, the implementation assigns a default name using the thread id prefix, such as codex-<first eight characters>. The row is marked sendable in this CLI implementation, and Codex create and rename support are recorded as supported.

The newer lightweight discovery plan points toward an even tighter Codex source: provider-owned SQLite thread state plus optional session-index name evidence. The direction is the same either way: use known Codex-owned state, extract the thread id, and store that id as the routing fact.

OpenCode Discovery

OpenCode discovery uses the provider CLI directly:

opencode session list --format json

AxiOwl parses session ids, titles, and workspace directories from that JSON output. The registry row uses:

provider_id = opencode_cli
provider_session_id = ses_...
sender_address = opencode_cli:<session id>
discovery_source = session_list

If OpenCode gives AxiOwl a title, that title becomes the human-facing chat name. If no title is available, AxiOwl falls back to a deterministic name based on the session id. The transcript path points to the OpenCode database path, and provider logs point to the OpenCode log path.

This is the cleanest kind of discovery: ask the provider for its sessions in a structured format, then merge the result into AxiOwl's registry.

Antigravity Discovery

Antigravity discovery has a different shape because its useful state is exposed through local conversation data. The current implementation looks for the Antigravity executable first. If it is not present, discovery fails instead of inventing rows.

When available, AxiOwl combines two sources:

conversation_summaries.db
conversations_dir

The summary database can provide conversation ids and titles. The conversations directory can provide conversation ids from files with UUID names. For each seen conversation id, AxiOwl records:

provider_id = antigravity_cli
provider_session_id = <conversation uuid>
sender_address = <conversation uuid>
discovery_source = conversation_summaries.db or conversations_dir

If a summary title exists, it becomes the chat name. Otherwise AxiOwl assigns a deterministic fallback such as antigravity-<first eight characters>. Rename support is recorded as false in this CLI implementation, while create support is recorded as true.

The lightweight discovery plan is stricter about future Antigravity enrollment: conversation files alone should not imply full sendability unless the AgentAPI send path is proven. That distinction is exactly why discovery, enrollment, and delivery proof are separate concepts.

Why AxiOwl Avoids Broad Scans

The discovery plans are intentionally conservative. They reject broad recovery scans, process scans, installer scans, shortcut scans, memory scans, and speculative filesystem walks for normal discovery. The reason is operational correctness.

If AxiOwl scans too widely, it can find stale or unrelated artifacts. A half-remembered title from an old workspace is not a safe target. A copied registry is not proof that a remote chat is still available. A file path that looks like a session is not always a live provider route.

The intended lightweight rule is:

Discovery reads provider-owned state.
Enrollment writes the AxiOwl registry.
Sending reads only the AxiOwl registry.

That gives operators a clean mental model. Run discovery to refresh known facts. Inspect or list agents to see what AxiOwl believes. Send only after the registry contains a target row with the right provider, session id, node id, and sendability state.

Sender Identity Matters Too

Discovery is not only about targets. AxiOwl also has to know who is sending. The developer docs require provider replies to include enough metadata for AxiOwl to identify the sender session. Preferred sender resolution starts with provider-owned MCP metadata, then explicit provider session ids, then explicit sender addresses or aliases, and only then targeted discovery repair.

That rule prevents a common class of routing mistakes. A display name might be duplicated. A path might be stale. A raw session id might appear in text without being the sender. AxiOwl should not guess when it is building a return route.

The Operator Value

For an operator, session discovery provides three practical benefits.

First, it makes agent targets visible. Instead of remembering provider-specific session ids, the registry can expose names and aliases that map to real provider sessions.

Second, it makes failures explainable. If discovery cannot find a provider executable, cannot read session state, or cannot classify a row as sendable, the failure belongs in the discovery output or registry row rather than being hidden behind a silent fallback.

Third, it keeps sending predictable. A send command should resolve a target, build the visible body once, select one provider edge, and record the evidence. It should not start a surprise filesystem search in the middle of delivery.

A Small Boundary That Keeps The System Honest

AxiOwl session discovery is deliberately boring infrastructure. It reads known provider state, extracts stable session facts, and updates a registry. That boring boundary is what lets the rest of AxiOwl stay honest: names resolve through durable rows, provider edges receive exact session ids, and receipts do not claim more than the evidence supports.

As AxiOwl grows across Codex, OpenCode, Antigravity, VS Code, Copilot-backed sessions, and remote nodes, this boundary becomes more important rather than less. Every provider can have its own messy way of storing sessions. AxiOwl's job is to normalize those facts into one routing model: name, provider, provider session id, node, sendability, and evidence.