Investigate Run Telemetry

VerifiedCaution

Investigate failed or suspicious agent runs using production telemetry in D1. Analyze run lifecycles and LLM calls to find root causes.

Sby Skills Guide Bot
DevOpsIntermediate
7/23/2026
Claude CodeCursorCodex
#llm-telemetry#cloudflare-d1#incident-debugging#observability#sql-queries

Recommended for

Automated summary

This skill walks through investigating a failed or suspicious agent run by querying the `agent_runs` and `llm_call_metrics` telemetry tables in the production D1 database `cat_factory`.

Strengths

  • Provides ready-to-run SQL queries in sequence: locate the run, read the failure verdict, then read the per-call LLM telemetry.
  • Explains how to read each column as a signal — `ok=0` or non-2xx `http_status` points to infrastructure, while `finish_reason='length'` points to output truncation.
  • Connects the structured `agent_runs.failure` verdict to the full prompt/response bodies in `llm_call_metrics` through `execution_id`.
  • Calls out the short retention window for LLM call metrics, pushing you to investigate recent runs promptly.

Limitations

  • Assumes authenticated access to the production `cat_factory` D1 database via wrangler from `deploy/backend`.
  • Tightly coupled to this project's specific schema (`agent_runs`, `llm_call_metrics`), so it is not portable to other codebases.
  • Prompt and response bodies are kept only a few days (3 by default), so older runs cannot be fully analysed.
When to use it

Use it when a run failed, aborted with a 'no progress' message, got stuck or looped, or produced poor model output and you need the root cause.

When not to use it

Do not use it for live real-time monitoring, or for runs from another project or older than the telemetry retention window.

Security analysis

Caution
Quality score88/100

The skill performs read-only SQL queries on production telemetry data via wrangler, which is a legitimate investigative purpose but involves network access to a remote database and exposure of potentially sensitive LLM I/O. The instruction to skip auth pre-check adds a mild risk, but the actions are non-destructive and do not exfiltrate data outside the local analysis. Overall it is caution, not risky.

Findings
  • •Instructs executing remote wrangler d1 queries against a production database (cat_factory) using --remote and --json.
  • •Accesses full prompt_text and response_text from llm_call_metrics, which may contain sensitive data such as internal prompts, tool results, or secrets.
  • •Tells the agent to assume Cloudflare authentication is already correct and not to pre-check it, which could lead to unauthorized access if the environment is misconfigured.
  • •Uses bash command execution (npx wrangler, node -e) even though no allowed-tools are declared, meaning the skill may not be executable in gated environments.
How this analysis is made

Examples

Diagnose latest failed run
What went wrong with the latest implementer run? Pull the telemetry from D1 and tell me the root cause.
Investigate a no-progress abort
A run aborted with a ProgressGuard 'no progress' failure. Query agent_runs and llm_call_metrics for that run and explain why the agent stalled.
Check for output truncation
Look into the coder step of my most recent run — I suspect the model was being cut off. Check finish_reason and completion_tokens versus request_max_tokens.

name: investigate-telemetry description: Investigate a failed or suspicious agent run (implementer/coder, bootstrap, reviewer, etc.) using the production telemetry in D1. Use when asked to look into a run failure, "no progress" abort, a stuck/looping agent, model output quality, token/truncation issues, or "what went wrong with the latest run". Pulls the run lifecycle from agent_runs and the per-LLM-call prompt/response/usage from llm_call_metrics, then reads the tool-call loop to find the root cause.

Investigate run telemetry (from D1)

Telemetry lives in the production D1 database cat_factory, NOT (primarily) in Cloudflare Workers Observability. Two tables carry everything you need:

  • agent_runs — one row per container-backed run (kind='execution' for the task pipeline / implementer, kind='bootstrap' for repo bootstrap). Holds status, the structured failure JSON (kind/message/hint/lastSubtasks), and a detail JSON with every pipeline step (agentKind, state, model, approvals, per-step metrics). This is the lifecycle + the failure verdict.
  • llm_call_metrics — one row per proxied LLM call (migration 0026). Holds agent_kind, provider, model, ok, http_status, finish_reason, token counts, request_max_tokens, the latency split (upstream_ms/overhead_ms), error_message, and the full prompt_text + response_text. Linked to a run by execution_id. This is what the model actually saw and produced.

Retention: llm_call_metrics is pruned aggressively (default 3 days, LLM_CALL_METRICS_RETENTION_DAYS) because the full bodies are heavy; agent_runs lives longer. Investigate recent runs promptly.

How to query

Run wrangler from deploy/backend (its wrangler.toml defines the cat_factory binding). Always pass --remote (production) and --json (parseable). Do NOT pre-check Cloudflare auth — assume the login is correct (see CLAUDE.md).

cd deploy/backend
npx wrangler d1 execute cat_factory --remote --json --command "SELECT ..."

Parse the JSON with node -e (Python is not on PATH here). The result shape is [{ results: [...rows], success, meta }].

Step 1 — find the run

Latest implementer/pipeline runs (drop the WHERE kind to see bootstrap too):

SELECT id, kind, status, block_id,
       datetime(created_at/1000,'unixepoch') AS created,
       datetime(updated_at/1000,'unixepoch') AS updated
FROM agent_runs
WHERE kind='execution'
ORDER BY created_at DESC LIMIT 10;

Take the id (e.g. exec_44c8387cac02) of the run in question.

Step 2 — read the failure verdict and step list

SELECT failure, detail FROM agent_runs WHERE id='<run id>';
  • failure (JSON): kind (job_failed, evicted, timeout, agent, …), message (the abort reason — e.g. the ProgressGuard text), hint, and lastSubtasks. This tells you HOW the run died.
  • detail.steps[] (JSON): which step was running at failure (state:'working'), the model each step used, and each step's rolled-up metrics (calls, truncatedCalls, errors, warnings, peakCompletionTokens, maxOutputTokens). The step with jobId === <run id> is the container step.

Step 3 — read the per-call LLM telemetry

Overview of every call for the failing step's kind (usually coder):

SELECT agent_kind, provider, model, ok, http_status, finish_reason,
       prompt_tokens, completion_tokens, request_max_tokens, upstream_ms,
       datetime(created_at/1000,'unixepoch') AS t, substr(error_message,1,300) AS err
FROM llm_call_metrics
WHERE execution_id='<run id>' AND agent_kind='coder'
ORDER BY created_at ASC;

Read the columns as signals:

  • ok=0 / non-2xx http_status / non-null error_message → transport, proxy, or spend-gate failure (an infra problem, not a model problem).
  • finish_reason='length' or completion_tokens near request_max_tokens → output truncation; the model was cut off mid-answer (raise the output limit or shrink the task). truncatedCalls in the step metrics counts these.
  • ok=1 + finish_reason='tool_calls' everywhere → the LLM side is healthy; the failure is in tool EXECUTION inside the container (see step 4). The ProgressGuard (harness pi.ts) counts failing tool calls from Pi's event stream — those tool errors are NOT rows here, only the LLM calls that drove them.

Step 4 — read the actual tool-call loop (the root cause)

prompt_text is stored as a DELTA vs the previous call (migration 0027), so each call's prompt_text contains the new assistant message(s) plus the tool RESULT messages returned to the model — including tool validation errors. response_text is the model's text content (tool-call arguments are echoed inside the assistant message in the next call's prompt delta).

Dump responses to see what the model was trying to do:

SELECT completion_tokens, response_text
FROM llm_call_metrics
WHERE execution_id='<run id>' AND agent_kind='coder'
ORDER BY created_at ASC;

Dump the tail of the final prompt to see the last tool result/error the model got:

SELECT prompt_text FROM llm_call_metrics
WHERE execution_id='<run id>' AND agent_kind='coder'
ORDER BY created_at DESC LIMIT 1;

Look for, in prompt_text: Validation failed for tool "<tool>" / must have required properties <field> (the model is emitting malformed tool args), repeated identical tool calls (a stuck loop), or <tool_call>…</tool_call> appearing as literal TEXT in response_text (the model emitted a tool call as prose instead of through the structured channel — fragile parsing, a model-quality smell). In response_text: garbled token-soup completions point at a Workers AI decode bug for that model (cf. the streaming token-doubling fix, commit 23b9fb6).

Step 5 — classify and report

Decide whether the failure is:

  • Model quality — malformed/looping tool calls, garbled output, ignored validation errors. Fix: don't default that role to that model; pin a stronger tool-calling model or denylist it for code steps.
  • Truncation — finish_reason='length'. Fix: raise output limit / split task.
  • Infra — ok=0, HTTP errors, spend-gate refusals, eviction/timeout (failure.kind). Fix: the proxy/runner/budget, not the prompt.
  • Working as designed — the ProgressGuard aborting a genuinely stuck run is the safety net doing its job; the bug (if any) is upstream of it.

Report: the run id, the failing step + model, the abort reason, the root-cause class with the evidence (quote the specific tool error or response), and a concrete fix. Then the run can be retried (POST /workspaces/:ws/agent-runs/:id/retry, or the board "retry" button) to spin a fresh container.

Notes

  • Helper one-liner to scan all deltas for tool validation failures: pipe the prompt_text rows through node and match(/must have required properties (\w+)/g).
  • The app also exposes this without SQL: GET /executions/:id/llm-metrics (per-call list) and GET /executions/:id/llm-metrics/export (LLM-friendly JSON bundle). Use D1 directly when you need cross-run queries or the app is unreachable.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/investigate-run-telemetry-mrx3xzxo' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/investigate-run-telemetry-mrx3xzxo/download' --output '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md.part' && mv '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md.part' '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md' && test -s '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/investigate-telemetry' && cp -R '.skill-downloads/investigate-run-telemetry-mrx3xzxo' '.claude/skills/investigate-telemetry'

Cursor
test -f '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md' && test -s '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/investigate-telemetry' && cp -R '.skill-downloads/investigate-run-telemetry-mrx3xzxo' '.cursor/skills/investigate-telemetry'

Codex
test -f '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md' && test -s '.skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/investigate-telemetry' && cp -R '.skill-downloads/investigate-run-telemetry-mrx3xzxo' '.agents/skills/investigate-telemetry'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/investigate-run-telemetry-mrx3xzxo'

openskills read 'investigate-run-telemetry-mrx3xzxo'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/investigate-run-telemetry-mrx3xzxo/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills