rootecho
v0.1.0
Published
Catch recurring root causes across postmortems — flags when a new incident echoes a past one, and whether that past incident's action items were ever finished. Zero dependencies, no server.
Maintainers
Readme
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.
npx rootecho init incident.json # scaffold a postmortem
npx rootecho add incident.json # record it, flag any echo of a past root cause
npx rootecho check incident.json # same check, no recording — use as a CI gateWhy
"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.jsonlCommands
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.jsonFlags: --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
