Channel diagnostics
Status: binding design contract (2026-08-05) — implementation pending.
Channel diagnosis must be an owner-runnable product feature, not operator improvisation. “My persona is silent” begins with one command and ends with a receipt that identifies the failing boundary without inspecting the message.
Privacy boundary
An adapter's inbound observation records exactly:
- the configured lane identifier;
- whether an authentication value was present, as the boolean words
presentorabsent; and - the terminal HTTP or adapter admission status.
It never records the bearer or credential value, request body, query string, message text, sender, conversation identifier, attachment, or other payload. The trace is bounded to the diagnostic window and uses the same owner-private receipt store as other operator evidence.
Guided probe
virgo channel doctor [<binding>] performs this sequence:
- Resolve the exact adapter, persona address, lane, registration identity, and expected public callback from authenticated configuration.
- Verify the local listener and durable downstream components without sending a synthetic human-facing message.
- Acquire a single-flight diagnostic lease for the exact binding and arm the privacy-preserving inbound trace for a bounded window. A second doctor for the same binding refuses while the lease is live.
- Prompt the owner: Send one message to your persona now. The owner sends exactly one natural message through the affected channel.
- Correlate the trace with adapter admission, durable queue insertion, consumer receipt/ack, reaction, and reply terminals. Emit one redacted diagnostic receipt.
The trace counts all candidate requests on the exact route during the window. Exactly one candidate is required for an attributed verdict. Zero candidates is the no-trace branch. More than one is inconclusive_concurrent_traffic: the doctor emits the count and terminal-status histogram, attributes none of them to the owner's message, releases the lease, and asks the owner to retry later. It does not widen logging to sender, conversation, body, or credential fields to force correlation.
Blind resend is forbidden. If the adapter accepted the message, diagnosis continues with its durable identity rather than asking the owner to send it again.
Verdict branches
| Observation | Verdict | Next boundary |
|---|---|---|
| No route trace during the bounded window | The provider did not reach the configured adapter route | Registration callback/endpoint, installed app binding, provider delivery telemetry |
| More than one candidate route trace | Concurrent traffic prevents privacy-preserving attribution | Inconclusive; retry in a quiet window, with no configuration mutation |
| Request arrived with authentication absent | Unauthenticated traffic reached the route | Provider/adapter credential attachment and callback configuration |
| Request arrived with authentication present and was rejected (for HTTP adapters, normally 401 or 403) | Identity, credential, signature, tenant, or audience mismatch | Adapter authentication receipt; never log the presented token |
| Request arrived with authentication present and was admitted (for HTTP adapters, 2xx) | Provider registration and adapter authentication passed | Durable queue, target consumer, ack, reaction, and reply chain |
An admitted request does not prove the persona replied. Each downstream stage must produce its own terminal receipt. A long interval between adapter admission and consumer receipt is reported as downstream latency, not as a registration failure.
Registration checkpoints
The doctor shows a human checkpoint only when the no-trace branch requires it. It supplies the exact identity and expected value; it never sends the owner hunting through an unrelated control plane.
| Adapter registration | Machine-readable checkpoint | Human fallback |
|---|---|---|
| Teams Developer Portal bot | None guaranteed; compare the recorded bot App ID and expected callback | dev.teams.microsoft.com → Tools → Bot management → exact bot App ID → Messaging endpoint |
| Azure Bot | ARM Microsoft.BotService/botServices resource: App ID and endpoint | Azure Bot → Configuration → Microsoft App ID and Messaging endpoint |
| Telegram bot | Bot API getWebhookInfo: webhook URL and last delivery error | Bot owner checks the same webhook through the guided setup flow; the token is never displayed |
Adapters may extend this table, but every checkpoint must distinguish machine-readable state from a human-only control plane and must name the exact field to inspect.
Receipt schema
The receipt contains a timestamp, diagnostic operation ID, binding revision, adapter kind, lane, registration identity hash, expected callback hash, trace candidate count, redacted status histogram, verdict, downstream stage terminals (only for the exactly-one case), and the exact configuration generation used. It contains no message or credential material. Receipts are immutable evidence; rerunning the doctor creates a new operation.
Dashboard composition
The hub dashboard Diagnostics panel calls the same mechanism. It shows last admitted inbound time per lane, freshness of each downstream stage, and a guided-check action. The web path cannot widen the trace, bypass channel authority, or expose fields the CLI receipt omits.