Catch recurring root causes across postmortems. Zero dependencies, no server.
Project description
rootecho
Catch recurring root causes across postmortems. Heavyweight incident
platforms (rootly, incident.io) flag when a new incident shares a root cause
with a past one — teams without that budget just... don't find out, until the
same failure bites twice. rootecho does the comparison locally: no account,
no server, your incident history lives in your repo.
pip install rootecho
rootecho init incident.json # scaffold a postmortem
rootecho add incident.json # record it, flag any echo of a past root cause
rootecho check incident.json # same check, no recording — use as a CI gate
This is the Python build — a Node build (npx rootecho) exists too and reads
the exact same .rootecho/history.jsonl, so a team split across both
ecosystems shares one history.
Why
"We use rootly to track this automatically. It flags when incidents have the same root cause as previous ones."
That's a paid, hosted feature. For everyone else, a postmortem gets written,
action items get filed, and six months later the exact same root cause causes
the exact same outage — because nobody had a system for "hey, we've seen this
before, and last time's fix never shipped." rootecho is that system, as a
zero-dependency local CLI.
How it works
- Each postmortem is one JSON record —
root_cause(free text) and/orroot_cause_tags(curated labels), plusaction_itemswith a status. add/checkcompare it against your history using Jaccard similarity over tags (primary signal) blended with free-text overlap (secondary). No ML dependency, no network call.- A match above the threshold prints the past incident's action items — so you see immediately whether last time's fix ever actually shipped.
Incident format
{
"id": "INC-2026-014",
"date": "2026-07-03",
"title": "Payment webhook retries exhausted",
"root_cause": "webhook retry queue misconfigured to drop after 3 attempts, no dead-letter fallback",
"root_cause_tags": ["webhook", "retry-queue", "dead-letter", "config"],
"action_items": [
{ "id": "AI-1", "description": "Add dead-letter queue for webhook retries", "owner": "alice", "status": "open", "due_date": "2026-07-20" }
]
}
Only id and one of root_cause/root_cause_tags are required. rootecho init
writes a starter file.
Example
$ rootecho add inc-2026-014.json
⚠ root cause echo detected for "INC-2026-014":
INC-2026-003 (2026-03-15) — 100% similar root cause
Payment webhook retries exhausted
✓ Add retry backoff [done]
✗ Add monitoring alert for queue depth [open] — 93d overdue
→ 1 action item(s) from this past incident were never finished.
recorded to .rootecho/history.jsonl
Commands
rootecho add <file> # record + compare (always exits 0 on success)
rootecho check <file> # compare only, no recording — exit 1 if an echo is found
rootecho list [--json] # show recorded incidents and open action-item counts
rootecho init [file] # write a starter incident.json
Flags: --dir <path> (state location), --threshold <0-1> (default 0.34,
lower = more sensitive), --json, --force (init: overwrite; add: allow a
duplicate id).
Storage
History is a JSON-Lines file at .rootecho/history.jsonl, local to your
project by default (not your home directory) — the idea is your team commits
it alongside the postmortems it describes, so git blame/git log on the file
doubles as an incident timeline. Override the location with --dir or
$ROOTECHO_HOME.
Exit codes
| Code | Meaning |
|---|---|
0 |
add succeeded, or check found no echo |
1 |
check found an echo of a past root cause |
2 |
error (bad args, invalid JSON, duplicate id) |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rootecho-0.1.0.tar.gz.
File metadata
- Download URL: rootecho-0.1.0.tar.gz
- Upload date:
- Size: 15.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
988554c3896af1b1ac47df3e148cce91b34265fc7c185e1eebcf7bf4271e3a58
|
|
| MD5 |
fe17618f54fc1c3e8f0d5fffbeb48567
|
|
| BLAKE2b-256 |
97dbbdd19e8c98ca67def63eaffb25eeab5febd19a845134bffb53aec5daa846
|
File details
Details for the file rootecho-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rootecho-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
543f3830d582b2220e0e5d7f794d7ecba612db780f413459c26f41d8ecd822ce
|
|
| MD5 |
71497a551120f69830cd75bbab728f47
|
|
| BLAKE2b-256 |
c3a29047de655d85a988a587c3b100eb5efa3c6c8b402c7ea60f939fb027c9b8
|