Install
openclaw skills install @voronindenis5/failure-forensicsUse when an agent task fails or produces unexpected results. Performs structured post-mortem root cause analysis: categorizes the failure, traces the exact failure point through tool-call logs, reconstructs the decision chain, generates a post-mortem report, and saves lessons to prevent recurrence.
openclaw skills install @voronindenis5/failure-forensicsWhen an agent task fails, the default response is to retry — hoping for a different outcome. Failure Forensics rejects that reflex. Instead, the agent performs structured root cause analysis before retrying, treating every failure as evidence to be collected, categorized, and learned from.
The workflow has four phases:
references/failure-taxonomy.md.scripts/failure_forensics.py automates this from JSON or JSONL log formats.references/post-mortem-template.md and persist it so future sessions can learn.This skill turns a single failure into a permanent, reusable lesson.
systematic-debugging for that. Run forensics after the process is dead or the task is abandoned.Read the full taxonomy in references/failure-taxonomy.md. At a high level, every failure falls into one of six categories:
| Category | Signature | First Question |
|---|---|---|
| Network | Connection refused, timeout, DNS, TLS, 5xx HTTP | "Is the endpoint reachable right now?" |
| Permissions | 401/403, EACCES, "permission denied", "unauthorized" | "Does the credential/token have the needed scope?" |
| Logic | Code runs but output is wrong; assertions fail; data is corrupt | "What assumption did the code make that was false?" |
| Environment | Missing binary, wrong version, missing env var, wrong OS | "What does env/which/uname say vs. what was expected?" |
| Dependency | ImportError, version conflict, package not found, ABI mismatch | "What changed in the dependency graph?" |
| Resource | OOM, disk full, too many open files, rate limit, quota exhausted | "What was the ceiling, and what hit it?" |
Record the category — it determines the questions you ask next.
Collect the evidence:
Tool-call logs. If the agent session logged tool calls (JSON or JSONL with timestamps, tool name, args, result/error), feed them to the analyzer:
python3 scripts/failure_forensics.py analyze \
--log session.jsonl \
--output timeline.md
The script produces a chronological timeline with:
Manual reconstruction. If no structured logs exist, reconstruct the timeline from memory of the session. List each decision and action in order. Be honest about uncertainty — mark gaps explicitly.
What to capture for each step:
This is the core of forensics. You're looking for the causal chain — the sequence where each link made the next failure more likely.
Ask these questions in order:
What was the immediate (proximate) cause of failure?
What was the agent doing when it failed?
Why did the agent take that action at that point?
Was that assumption valid?
Continue backward until you reach either:
Look for contributing factors that didn't cause the failure but made it worse or harder to recover from:
Anti-pattern: the "five whys" that stops at one. The first "why" almost always produces the symptom, not the cause. Keep going. The root cause is usually 3-5 links back.
Fill out the template in references/post-mortem-template.md. Key sections:
web_extract call in session.py:142" is good.Save the report. Write it to a persistent location (e.g., a post-mortems/ directory, an issue tracker, or a knowledge base). A post-mortem that isn't saved didn't happen.
The script scripts/failure_forensics.py has three subcommands:
analyze — Build a failure timeline from logs# JSONL log (one JSON object per line)
python3 scripts/failure_forensics.py analyze --log session.jsonl --format jsonl
# JSON array
python3 scripts/failure_forensics.py analyze --log session.json --format json
# Write report to file
python3 scripts/failure_forensics.py analyze --log session.jsonl --output report.md
categorize — Classify an error messagepython3 scripts/failure_forensics.py categorize --error "ConnectionRefusedError: [Errno 111] Connection refused"
# Output: network
python3 scripts/failure_forensics.py categorize --error "PermissionError: [Errno 13] Permission denied"
# Output: permissions
report — Generate a post-mortem template pre-filled with timeline datapython3 scripts/failure_forensics.py report --log session.jsonl --title "Deploy failure 2024-01-15" --author "agent"
The analyzer accepts JSON/JSONL where each entry is a tool call record:
{
"timestamp": "2024-01-15T10:23:45Z",
"tool": "terminal",
"args": {"command": "npm install"},
"result": {"success": false, "error": "EACCES: permission denied, open '/usr/lib/node_modules'"},
"duration_ms": 1200
}
Required fields: timestamp (ISO 8601), tool. The script tolerates missing optional fields (result, duration_ms, args).
Confusing symptom with cause. "The deploy failed because the build failed" is a symptom. "The build failed because package-lock.json was regenerated with a different Node version than CI" is a cause. Keep digging past the symptom.
Stopping at human error. "I made a mistake" is never a root cause. Ask why the mistake was possible — missing validation? Misleading documentation? Fatigue from context switching? Fix the system, not the human.
Writing action items that aren't actionable. "Be more careful" is worthless. Every action item must specify what to change, where, and how to verify it works.
Skipping the timeline. Without a chronological timeline, causal chain analysis becomes guessing. Build the timeline first, even if it's rough.
Not saving the post-mortem. A post-mortem kept in chat history is lost when the session ends. Write it to a durable artifact (file, issue, doc).
Blame-oriented language. Post-mortems are blameless by design. Describe what happened, not who messed up. This is especially important when the "who" is an agent — focus on the decision and the information available at the time.
Retrying before forensics. The whole point is to analyze before retrying. If you retry first, you lose the original failure state and may introduce changes that mask the real cause.