AxiOwl Command Telemetry Explained

Command telemetry in AxiOwl is the local evidence trail that explains what happened when a command, MCP tool call, or provider reply moved through the system. It is not just a success message. It is the difference between "AxiOwl accepted this request" and "the target provider received it, accepted it, and replied with usable identity."

That distinction matters because AxiOwl coordinates multiple AI provider sessions. A command can enter AxiOwl correctly, resolve a known target, and start provider delivery, while the target provider still may not display, process, or reply to the message. AxiOwl's telemetry is designed to keep those boundaries visible.

What AxiOwl Records

AxiOwl is built around a local Windows executable, a durable registry, provider-specific delivery modules, a delivery worker, and an MCP server. The current architecture routes CLI and MCP requests through MessagePipeline, resolves sender and target identity from the registry, performs a targeted discovery repair when needed, dispatches through provider edges, and writes delivery evidence.

The local state paths are explicit in the implementation. On Windows, AxiOwl stores state under LOCALAPPDATA\AxiOwl. The registry lives under registry\agents.tsv and registry\nodes.tsv. Command and delivery evidence is written as JSONL logs under logs\events.jsonl, logs\delivery.jsonl, logs\create-lifecycle.jsonl, and logs\activation.jsonl.

Those logs are append-only event records with a timestamp and named fields. The evidence log writer creates the parent directory, rotates oversized logs, and appends one JSON object per line with an event_type, created_at, and event-specific fields. That makes the evidence readable by a person, scriptable by tooling, and narrow enough to inspect during a failed send.

The Receipt Boundary

The most important command telemetry concept in AxiOwl is the receipt boundary.

When you run a command such as:

axiowl send --to "Target chat name" --body "Message text" --from "Sender chat name"

the CLI builds a message request and sends it through MessagePipeline. If the request passes AxiOwl validation and the target route is found, the command can print an AxiOwl handoff receipt. That receipt includes a message ID, a delivery state, the provider, and the delivery log path.

The CLI text is intentionally careful. For the normal accepted_by_axiowl state, it says that provider delivery, provider wake-up, and provider reply are not implied. If a path reports provider delivery status explicitly, the CLI says that status is shown only because that path reported it explicitly.

That is not hedging. It is the product contract. accepted_by_axiowl means AxiOwl accepted and validated the request and handed it to the delivery layer. It does not prove that the target provider displayed the message or responded. A stronger proof is a provider result such as accepted_by_provider. The strongest proof is a response over AxiOwl MCP, because that demonstrates that the target provider received the message, acted on it, had AxiOwl MCP available, and replied with sender identity that AxiOwl could resolve.

How A Send Becomes Telemetry

The send pipeline starts by assigning a message ID and run ID. It immediately records a delivery stage showing that the MCP or CLI request entered the AxiOwl message pipeline. The detail on that stage is explicit: provider delivery is not implied.

The pipeline then validates the target and body. Empty targets and empty bodies are rejected with send_rejected events. Sender identity is resolved from explicit CLI sender fields, provider-owned MCP metadata, or registry state. If AxiOwl cannot resolve the sender, the send fails loudly instead of guessing. That is why the developer docs say MCP metadata should fail loudly when identity is missing.

Next, AxiOwl resolves the target from the registry. If the target is missing or stale, the pipeline runs one targeted discovery repair. The telemetry records whether this was a registry miss, whether repair was attempted, whether a target was found after discovery, or whether the target still required repair. If the target is known but not sendable, the command is rejected and the last known registry error can be included in the reason.

Only after those steps does AxiOwl mark the request as accepted by AxiOwl. At that point it logs message_accepted_by_axiowl with the target, provider, sender resolution status, delivery_receipt=axiowl_only, and a receipt boundary that says the record was made after target resolution and before delivery worker or provider completion.

That sequence is useful operationally. You can tell whether a failed command died because the target name was wrong, the sender identity was missing, discovery could not repair the registry, the target was known but not sendable, or provider handoff failed later.

Delivery Worker Evidence

AxiOwl separates acceptance from provider delivery by handing provider work to a delivery worker. The worker request file contains the run ID, message ID, target display name, provider, provider session ID, target node, sender identity, requested delivery method, and final visible body.

The handoff itself has telemetry. If the background worker starts, AxiOwl logs delivery_handoff_started and writes a delivery stage such as delivery_worker_handoff_started. The handoff evidence can include the request file path. If startup fails, AxiOwl logs delivery_handoff_failed.

Inside the worker, AxiOwl logs when the request is accepted for provider dispatch, then calls the provider edge. Provider results carry a standard shape: provider, state, accepted flag, degraded flag, method used, evidence, and error. The delivery log then records whether the provider write succeeded, failed, or started through an unverified handoff path.

This structure is why AxiOwl can distinguish different outcomes instead of flattening everything into "sent." A provider module can report accepted_by_provider, failed, a degraded path, an unsupported provider, or an out-of-scope remote path. The provider dispatch table currently routes concrete providers such as Codex, Codex CLI, VS Code native, VS Code Copilot-backed sessions, Antigravity, Cursor, Claude Code CLI, Copilot CLI, and OpenCode CLI. It also explicitly treats remote as out of scope for the local-provider remediation build.

Registry Telemetry

The registry is part of command telemetry because delivery depends on real provider sessions, not just names. Registry rows contain display names, aliases, providers, provider-owned session IDs, node IDs, enablement, sendability, source, first-seen and last-seen timestamps, last-verified timestamp, and last error.

AxiOwl prefers sendable and recent rows when resolving targets and senders. For sender resolution, exact provider session IDs and sender addresses matter because replies must route back to a real session. The current docs are explicit that AxiOwl should not rely on display-name guessing when a provider-owned identity is required.

This means registry telemetry answers questions that raw console output cannot answer. Was the row discovered automatically or added manually? Was it last seen recently? Is it sendable? Is the session ID a provider-owned identifier or a stale display string? Does the row carry a last error explaining why the command was blocked?

MCP Identity Is Part Of The Evidence

AxiOwl exposes typed MCP tools including axiowl_send_message, axiowl_create_agent, axiowl_list_agents, axiowl_whoami, and status/discovery helpers. The MCP tool description for axiowl_send_message states that success is an MCP-to-AxiOwl handoff receipt only, and that provider delivery and reply are not implied.

The MCP server resolves identity from host metadata and provider/session context. For providers such as Codex, VS Code, Cursor, Antigravity, and CLI-backed surfaces, the implementation has provider-specific metadata handling. If expected metadata is missing, AxiOwl records why identity was not accepted instead of silently inventing a sender.

That behavior is central to the support bar. The provider support matrix says a provider is supported only when discovery, install/config, send, provider receive, provider MCP reply, and correct sender identity all work. For CLI providers, environment-only identity injection is not considered final support. Telemetry is what makes that bar auditable.

Rate Limits And Delays

AxiOwl also records command behavior that is not a failure. The message pipeline includes a global send delay mechanism. It writes send_rate_limit_delay_started and send_rate_limit_delay_finished events with the message ID, target, burst count, delay seconds, and whether the burst window reset.

That is a practical detail. If a command appears slow, telemetry can show that AxiOwl intentionally delayed outbound sending rather than hanging. If repeated sends happen too quickly, the logs show the burst count and delay applied.

How Operators Should Read It

For day-to-day use, start with the CLI receipt. The message ID tells you which command to follow. The delivery state tells you whether AxiOwl accepted the request or rejected it before handoff. The delivery log path points at the JSONL record chain.

Then read the evidence in layers:

  1. Did the request enter the pipeline?
  2. Was the sender identity resolved?
  3. Was the target found in the registry?
  4. Did targeted discovery repair the target?
  5. Was the target sendable?
  6. Did AxiOwl start delivery worker handoff?
  7. Did the provider edge report acceptance, failure, degraded delivery, or unsupported scope?
  8. Did the provider later reply through AxiOwl MCP with correct identity?

The last question is the strongest one. A command receipt is useful, but a provider reply with correct MCP identity is the end-to-end proof that the path worked.

Why This Design Matters

AxiOwl coordinates tools that have different APIs, extension models, CLI behaviors, session stores, and metadata quality. A single "success" boolean would hide too much. It would make a registry miss look like a provider failure. It would make an AxiOwl handoff look like target-provider proof. It would make missing sender metadata look like a routing mystery.

Command telemetry keeps those cases separate. It gives operators a local audit trail, gives developers concrete event names to debug, and gives provider integrations a higher standard than "the process started." In real AxiOwl usage, that clarity is what turns a message router into an inspectable coordination system.