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
Metadata
Release files for rootecho 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| rootecho-0.1.0.tar.gz | 15.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rootecho-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.1 kB
Release files / rootecho-0.1.0.tar.gz
| Download URL | rootecho-0.1.0.tar.gz |
|---|---|
| Size | 15.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
988554c3896af1b1ac47df3e148cce91b34265fc7c185e1eebcf7bf4271e3a58
|
|
BLAKE2b-256 checksum How to use checksums |
97dbbdd19e8c98ca67def63eaffb25eeab5febd19a845134bffb53aec5daa846
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Release files / rootecho-0.1.0-py3-none-any.whl
| Download URL | rootecho-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
543f3830d582b2220e0e5d7f794d7ecba612db780f413459c26f41d8ecd822ce
|
|
BLAKE2b-256 checksum How to use checksums |
c3a29047de655d85a988a587c3b100eb5efa3c6c8b402c7ea60f939fb027c9b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Security for rootecho 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.