comis trace command is your one-stop tool for going from a user complaint to a diagnostic
bundle. Five subcommands cover every correlation pattern: search by messageId, search by traceId,
live-tail a chat, scan failures by time, and export a bundle.
The If you’ve aliased
comis CLI is not on PATH by default. All invocations on this page use the canonical form:comis to that path, the shorter form works too.Subcommands at a Glance
| Subcommand | Use case | RPC |
|---|---|---|
--message-id <uuid> | A user said “my message didn’t get a reply” and quoted the messageId | obs.trace.search |
--trace-id <uuid> | You have a traceId from a log line and want the full causal chain | obs.trace.search |
--chat <id> --tail | Watch a chat live while debugging an active issue | obs.trace.tail |
--since <dur> --where <filter> | ”Show me failures in the last 10 minutes” | obs.trace.search |
export <sessionId> | Produce a self-contained bundle for engineer handoff | obs.trace.export |
--json for machine-readable output.
--message-id <uuid>
Search for all trace events associated with a specific inbound message. Use this when a
user can give you the messageId from their chat — it’s the fastest path from complaint to trace.
Default (human-readable) output
JSON mode
--trace-id <uuid>
Search all log and trajectory events by traceId. Use this when you’ve found a traceId in
a log line and want the full causal chain across the channel / queue / agent / delivery stages.
traceId is injected via AsyncLocalStorage for the
entire request lifecycle, so all events from inbound parse through final delivery share the same
value — including error events and retry attempts.
JSON mode
{"rows": [...]} structure as --message-id --json.
--chat <chatId> --tail
Stream trace events live for a specific chat. Use this when a user reports an issue
while it’s happening — open a terminal, start --tail on their chat, and watch the next message
in real time.
obs.trace.tail RPC approximately every second. Press Ctrl+C to exit cleanly
(handled via AbortController; the connection closes gracefully).
--tail requires --chat. Running --tail without specifying a chat exits immediately with:
--tail requires --chat <chatId>Tail output (human-readable)
Three space-separated fields per line:JSON tail mode (NDJSON)
Emits one JSON object per line (newline-delimited JSON). Suitable for piping intojq or another
consumer:
rows[] entry.
--since <dur> --where <filter>
Scan the session index for recent failures. Use this when you need a quick overview of
what went wrong in the last N minutes across all chats.
--since argument accepts duration suffixes: 10m, 1h, 2d. The --where argument is a
filter expression — error matches sessions that have a non-null lastError in the session index.
Common queries
JSON mode
{"rows": [...]} with the same 4-field shape (ts, event, sessionId, traceId).
export <sessionId>
Export a self-contained diagnostic bundle for a session. Invokes the bundle
pipeline, applies platform-aware-v1 redaction, and prints the bundle directory path.
JSON mode
/export-trajectory
slash command — is at Incident Bundle.
Output Format Reference
Human-readable — search modes (--message-id, --trace-id, --since/--where)
Four-column space-padded table. Column widths auto-fit content:
ts (ISO 8601), event (dot-notation event name), sessionId (first 8 chars of UUID),
traceId (full UUID).
Human-readable — tail mode (--chat --tail)
Three space-separated fields per line:
Human-readable — export mode
Single line:JSON — search modes
JSON — tail mode (NDJSON)
One JSON object per line. Each object has the same shape as arows[] entry:
nextSinceMs cursor internally (used by the polling loop); it is not
surfaced in the per-line JSON objects.
JSON — export mode
Worked Example — User Complaint to Bundle in 3 Commands
A user reports: “I asked the bot a question 10 minutes ago and it never replied.”The acceptance gate — under 5 minutes from complaint to bundle. Command 1 — Find sessions with recent errors:
channelType in the session-index JSONL if
needed).
Command 2 — Verify the failure mode:
- Missing delivery rows — execution completed but delivery failed
- Retry events — message was retried (check for
queue.retryevents) - Dedup events — message was seen before (
dedup.duplicate_inbound) - Execution absent — message enqueued but no
execution.started(queue stall or gate rejection)
Bundle written to: <path>. Compress, share with engineer per Incident Bundle.
Three commands. Under 5 minutes from complaint to bundle. This is the acceptance gate.
Performance Bounds
| Subcommand | Bound |
|---|---|
--message-id | Under 2 s on a 100-turn session (LRU O(1) + bounded 2-day index scan on miss) |
--trace-id | Under 2 s (same backend as --message-id) |
--chat --tail | ~1 s poll cadence; events appear within 1–2 polls of bus emission |
--since --where | Bounded by session index size (2-day scan window) |
export | Bounded by bundle pipeline; refuses sessions exceeding 50 MB |
The backend uses an LRU bounded at 1024 entries for messageId lookups, falling back to a 2-day
session-index scan on miss. The LRU starts cold on daemon restart — if a restart just happened,
--message-id may return empty rows for messages processed before the restart. Use
--since <dur> --where error as a fallback in that case.Related Pages
Incident Bundle
Bundle export workflow — 8-file shape, hard limits, redaction policy, and the
/export-trajectory slash command.Observability
Bridge mapping, lifecycle envelopes, INFO promotions, and the dedup detector.
Logging
Log levels, field dictionary, and log rotation policy.
Daemon
The process that serves the RPCs — startup, shutdown, and configuration.
