
How AxiOwl Turns Agent Discovery Into a Usable Registry
Agent discovery is only useful when it produces something operators can trust. A scan that finds ten possible chat files, three stale session IDs, and one half-valid title is not a registry. A registry has to answer a harder question: which named agent can AxiOwl actually send to right now, through which provider edge, with what proof, and with what failure state if the route is not usable?
That is the job AxiOwl gives to its discovery and registry code. Discovery providers gather provider-specific evidence from real local state. The merge layer decides whether that evidence is strong enough to enroll, refresh, enrich, downgrade, or skip a row. The send pipeline then treats the registry as a routing table, not as a loose list of labels.
Sources read
Source repo: C:\Users\kjhgf\OneDrive\Documents\postfourth\axiowl-cplus
README.mdapps/windows-desktop/README.mddocs/reference/architecture-overview.mddocs/reference/provider-support-matrix.mddocs/developer/README.mddocs/support/forensics.mddocs/user/README.mdapps/windows-desktop/src/app_paths.cppapps/windows-desktop/src/models.hppapps/windows-desktop/src/registry.hppapps/windows-desktop/src/registry.cppapps/windows-desktop/src/discovery.hppapps/windows-desktop/src/discovery.cppapps/windows-desktop/src/discovery_provider_common.cppapps/windows-desktop/src/discovery_codex.cppapps/windows-desktop/src/discovery_vscode_native.cppapps/windows-desktop/src/discovery_vscode_copilot.cppapps/windows-desktop/src/discovery_cursor.cppapps/windows-desktop/src/discovery_cursor_cli.cppapps/windows-desktop/src/discovery_antigravity.cppapps/windows-desktop/src/discovery_antigravity_cli.cppapps/windows-desktop/src/discovery_claude.cppapps/windows-desktop/src/discovery_copilot_cli.cppapps/windows-desktop/src/discovery_opencode_cli.cppapps/windows-desktop/src/discovery_remote.cppapps/windows-desktop/src/discovery_codex_policy.cppapps/windows-desktop/src/discovery_vscode_policy.cppapps/windows-desktop/src/message_pipeline.cppapps/windows-desktop/src/provider_edges.cppapps/windows-desktop/src/mcp_server.cppapps/windows-desktop/src/cli.cppapps/windows-desktop/tests/core_tests.cpp
Discovery Starts With Provider Reality
AxiOwl does not use one generic "find agents" scraper. Each provider has its own discovery function because each provider exposes session state differently.
The current Windows desktop source wires discovery scopes for codex, codex_cli, vscode_native, vscode_copilot_backed, copilot_cli, antigravity, antigravity_cli, cursor, cursor_cli, claude_code_cli, and opencode_cli. The CLI exposes these through axiowl discover <provider> and axiowl discover all. In the current local-provider remediation build, remote is reported as excluded from local all-provider discovery rather than used as a silent fallback.
The provider implementations show the difference between discovery sources:
- Codex discovery reads Codex state under
.codex, includingstate_5.sqlite,session_index.jsonl, and global state. It separates local app threads from CLI threads and applies extra trust rules before a row can enroll. - VS Code native discovery scans
%APPDATA%\Code\User\workspaceStorage\*\chatSessionsandemptyWindowChatSessionsJSONL files. - VS Code Copilot-backed discovery reads Copilot session-state YAML under
.copilot\session-stateand checks patch health before keeping the row sendable. - Cursor discovery reads Cursor global state database material and checks whether the Cursor patch status blocks sending.
- Cursor CLI discovery reads AxiOwl-owned
cursor-cli\sessions.tsvstate and marks rows stale if the recorded workspace is gone. - Antigravity discovery reads
.gemini\antigravity\annotations.pbtxtfiles; Antigravity CLI discovery reads.gemini\antigravity-clicache and conversation state and checks for theagyexecutable. - Claude Code CLI discovery scans
.claude\projectsJSONL transcripts and requires matchingsessionIdproof plus a usablecwdbefore marking a row sendable. - Copilot CLI discovery scans
.copilot\session-state\*\workspace.yaml, filters to standalone CLI sessions, and does not mark rows sendable unless explicit headless auth is available. - OpenCode CLI discovery runs
opencode session list --format json --max-count 100and downgrades sessions whose working directory is missing.
This is why discovery output carries source paths, evidence strings, status, and error text. AxiOwl needs more than a chat title. It needs to know where that title came from and whether the provider state supports a route.
The Discovered Row Contract
Discovery produces DiscoveredAgent rows. Each row contains:
display_nameproviderprovider_session_idnode_idstatussendablehas_enrollment_proofsourceevidencelast_seen_atlast_error
The most important distinction is between "we saw evidence" and "this is safe to enroll as sendable." The merge code does not trust sendable by itself. It calls row_has_enrollment_proof, which rejects archived rows, rows with last_error, rows that are not marked sendable, and weak local Codex rows that do not meet the Codex policy.
Codex is the clearest example. A local Codex row from codex_active_workspace_vscode_thread or codex_active_codex_sqlite_thread_without_desktop_state is treated as evidence-only. A row with stronger proof, such as codex_desktop_thread_state or targeted Desktop IPC owner evidence, can enroll. The tests cover this: an evidence-only Codex row is counted and skipped, while a targeted IPC-owner row can become a sendable registry row.
Merge Makes Discovery Usable
The registry lives in AxiOwl local state. On Windows, registry_path() resolves to %LOCALAPPDATA%\AxiOwl\registry\agents.tsv. On non-Windows paths, it falls back through $XDG_STATE_HOME/axiowl or ~/.axiowl. The TSV header is explicit:
agent_id display_name aliases provider provider_session_id node_id enabled sendable source first_seen_at last_seen_at last_verified_at last_error
merge_discovered_agents_into_registry turns discovery into durable routing state. It loads the existing registry, applies the provider report, then saves the full registry back to disk.
The merge rules are deliberately conservative:
- Rows missing display name, provider, provider session id, or node id are skipped.
- Rows without enrollment proof do not create new sendable registry rows.
- Evidence-only Codex matches increment
evidence_only_matchesand remain visible in reporting instead of silently becoming routes. - Manual rows are protected. Discovery may add aliases and timestamps, but it does not overwrite a manual display name or downgrade a manual row.
- Existing rows with the same provider, node, and provider session id are enriched rather than duplicated.
- A stronger proven row can update the provider/session identity only when provider policy allows it.
- Non-proven discovery can downgrade an existing non-manual row by setting
sendable=false, updatingsource, and recordinglast_error. - Full VS Code native and VS Code Copilot-backed reports can prune stale auto-discovered rows for that same provider and node when current IDs are known.
That last point matters. A registry that only grows eventually becomes misleading. AxiOwl lets discovery remove stale auto rows for selected provider surfaces, while still protecting manual rows from automatic churn.
Enrolled Is Not The Same As Found
The DiscoveryReport counters make the distinction visible:
rowsare the raw discovered rows for that report.enrolledcounts new registry rows that were accepted as sendable targets.updatedcounts existing registry rows that were refreshed or changed.skippedcounts rows that were not safe or complete enough to use.evidence_only_matchescounts evidence that matched something but did not prove a sendable target.
This language prevents a common operator mistake. "Discovery found a file" does not mean "AxiOwl can route a message there." AxiOwl only treats a target as usable when the registry row is enabled and sendable, and when the row does not require repair.
The same boundary appears in MCP. The axiowl_list_agents tool is described as listing sendable AxiOwl agents from the local registry. The send tool is also explicit that success is a handoff receipt only; provider delivery and reply are not implied.
Lookup Turns Rows Into Addresses
The registry lookup code makes the discovered data usable from a human command. A target can match by provider session id, by a bare session id extracted from a provider-prefixed session string, by display name, or by alias.
The matching code prefers exact session matches over name matches. It also prefers sendable rows over enabled-only rows and chooses the newest row when duplicate display names exist. Recency comes from last_seen_at, then last_verified_at, then first_seen_at, with agent_id as a final tie-breaker.
That means duplicate names are allowed. If two sessions both show up as "Project Review", they should not collapse into one row just because a title matches. The provider session id keeps them separate, and a user can still target the exact session when needed.
AxiOwl also adds useful aliases during merge. It keeps the display name, a normalized "agent" alias, provider session aliases, and provider-specific aliases such as codex-thread:<session>. That is how discovery becomes ergonomic without giving up provider-owned identity.
Target Repair Happens Once
The message pipeline uses the registry first. During send, find_target_with_single_miss_resolution looks up the requested target. If the row exists and does not require repair, the pipeline uses it. If the row is missing or requires repair, AxiOwl logs registry_target_miss or registry_target_requires_repair, then runs targeted discovery once.
That targeted discovery pass tries the local providers in order: Codex, Codex CLI, VS Code native, VS Code Copilot-backed, Copilot CLI, Antigravity, Antigravity CLI, Cursor, Cursor CLI, Claude Code CLI, and OpenCode CLI. Each provider report is merged into the registry immediately. The pass stops when the target resolves to an enabled, sendable row that no longer requires repair.
The repair rules are narrow by design. A row requires repair when it is a stale remote-name row or when a local Codex row is evidence-only. If repair still leaves the target missing, evidence-only, non-sendable, or remote-out-of-scope, the send is rejected with a targeted discovery summary. AxiOwl does not keep scanning forever, and it does not convert weak evidence into delivery.
The final send checks are direct:
- If no target is found after targeted discovery, the receipt explains what was searched and what was found.
- If evidence was found but no sendable exact target row was discovered, the error says so.
- If a row is known but
sendable=false, the send is rejected withtarget is known but not sendable, pluslast_errorwhen available. - Only after a sendable route is resolved does AxiOwl return
accepted_by_axiowland hand the provider request to the delivery worker.
This keeps the registry honest. Discovery can repair state, but the send path still treats sendability as a hard gate.
Provider Dispatch Uses The Registry Provider
Once the target is resolved, AxiOwl dispatches through provider_edges.cpp. The provider string in the registry selects the implementation: codex, codex_cli, vscode_native, vscode_copilot_backed, antigravity, antigravity_cli, cursor, cursor_cli, claude_code_cli, copilot_cli, and opencode_cli.
If the registry provider is unknown, AxiOwl fails with an explicit unknown-provider result. If the provider is remote, the current local-provider remediation build returns excluded_remote_out_of_scope. That limit is important: remote state is not a hidden rescue path for local discovery failures.
The architecture docs make the receipt boundary explicit too. accepted_by_axiowl means AxiOwl accepted and validated the request and handed it to delivery. The stronger proof is a provider response over MCP with correct provider-owned sender identity.
Practical Value For Operators
This design gives operators a registry they can inspect and reason about:
sourceexplains where a row came from.sendableexplains whether AxiOwl will route to it.last_errorexplains why a known row is blocked.last_seen_atandlast_verified_atexplain freshness.provider_session_idpreserves provider identity when names change.- Aliases make targets easier to type without replacing session identity.
- Discovery reports separate rows found, rows enrolled, rows updated, rows skipped, and evidence-only matches.
It also gives developers a clear rule for adding new providers. A new discovery provider should not just emit names. It should emit provider-owned session identity, source paths, status, evidence, sendability, and a reason when it cannot prove sendability. The merge layer can then decide how that evidence affects the registry without special-casing every operator workflow.
Limits Are Part Of The Registry Design
AxiOwl's discovery is bounded and explicit. Shared discovery helpers cap recursive scans at 2,500 files and read at most 512 KiB per file. Providers can report missing executables, missing directories, stale workspaces, blocked patches, archived sessions, unavailable auth, and missing metadata. These are not hidden behind silent fallbacks.
The support matrix reinforces the same point. A provider is not supported just because AxiOwl can find a file or start a process. The current bar includes discovery, install/config, send, provider receive, provider MCP reply, and correct provider-owned sender identity. For CLI providers, environment-only identity injection is not considered final support.
That is why the registry is useful: it is not just a successful scan. It is the durable result of provider-specific evidence, proof-aware merge rules, sendability gates, and loud failure states.
Closing
AxiOwl turns discovery into a usable registry by refusing to blur evidence, identity, and reachability. Discovery providers find real provider sessions. The merge layer preserves manual rows, enriches known sessions, enrolls only proven sendable targets, and records why weaker rows are skipped or downgraded. The send pipeline then uses that registry once, repairs once, and fails clearly when a route is not safe to use.
That gives AxiOwl a practical operating model: friendly target names at the command line, provider-owned session identity underneath, and enough registry state for an operator to understand exactly why a message can or cannot be sent.
Image prompt:
Create a polished graphic image related to: agent discovery becoming a usable technical registry.
Subject: a clean technical directory console with glowing modular provider input streams feeding into organized metal registry trays, one tray highlighted as an active sendable route and several dim evidence-only trays separated beside it.
Style: halfway between a clean symbolic icon and a realistic product/technical illustration; professional SaaS/technical marketing style; crisp edges; high detail; no text; no logos.
Background: solid #00ff00 chroma key green screen background covering the full canvas edge to edge.
Restrictions: no owl, no axolotl, no birds, no animals, no mascot, no text, no watermark.