Your Internet connection’s black box.
English | Русский
routewitness watchInternet problems often disappear before you can diagnose them. RouteWitness keeps a bounded history of local network evidence, detects sustained degradation, records recovery, and explains which failure domain the measurements support.
It records connection diagnostics around a failure, not traffic contents. There is no account, cloud backend, telemetry, automatic upload, or automatic privilege elevation.
Example report · Diagnosis rules · Privacy
RouteWitness requires Python 3.11–3.13. The package is not yet published to PyPI.
From the repository:
pipx install .
routewitness doctor
routewitness watchOr install a built wheel:
pipx install dist/routewitness-0.1.0-py3-none-any.whlwatch is a foreground recorder in v0.1. Keep the terminal open; Ctrl+C stops cleanly and preserves an active incident as interrupted rather than pretending the connection recovered.
You can inspect the complete workflow without disrupting your network:
routewitness demo --data-dir ./routewitness-demo
routewitness show 20260913T214324Z-00000018 --data-dir ./routewitness-demo
routewitness report 20260913T214324Z-00000018 --data-dir ./routewitness-demo --openThe demo is deterministic, offline, and marked SIMULATED. This excerpt is generated by RouteWitness:
Incident 20260913T214324Z-00000018 [SIMULATED]
Likely source: upstream-or-isp
Confidence: high
Evidence is most consistent with an upstream connectivity failure.
Evidence
upstream-or-isp: 12/14 affected rounds; sample seq 24,25,26,27,28,29,30,31,32,33,34,35
Gateway reachable in 14/14 examined rounds.
Local interface reported up in 14/14 examined rounds.
cloudflare: 12/14 failed reachability rounds (86% probe loss).
google: 12/14 failed reachability rounds (86% probe loss).
quad9: 12/14 failed reachability rounds (86% probe loss).
Duration: 14.0 s · recovered
Recovered/end: 2026-09-13T21:43:36+00:00
High confidence means the recorded pattern strongly matches a diagnosis rule. It does not prove an ISP is at fault.
| Command | Purpose |
|---|---|
routewitness diagnose |
One-shot layered network diagnosis |
routewitness watch |
Observe continuously and capture incidents automatically |
routewitness watch --live |
Print each observation round while watching |
routewitness status |
Show watcher heartbeat and current health |
routewitness incidents |
List recorded incidents |
routewitness show <id> |
Show a concise sanitized explanation |
routewitness report <id> --open |
Regenerate/open the offline HTML report |
routewitness compare <a> <b> |
Compare two incidents for repeated patterns |
routewitness config |
Show effective configuration and paths |
routewitness doctor |
Check local capabilities without external probes |
routewitness demo |
Generate the deterministic offline example |
All commands except watch support --json. JSON stdout contains data only; expected errors go to stderr. --data-dir and --config-file work before or after the command.
RouteWitness separates several layers instead of treating one failed ping as an outage:
- active interface, addresses, default routes, gateways, and configured resolvers;
- default-gateway reachability when the platform supports it;
- low-volume TCP reachability to independent public operators;
- system DNS and direct DNS resolution;
- TCP/TLS/HTTP service checks;
- bounded path observations at useful incident transitions rather than every second.
The default cadence is one second and switches to half a second during an incident. A rolling baseline is used for sustained latency detection. Prehistory is bounded, path work is bounded, and there is no unbounded healthy-history log in memory.
The classification engine is deterministic. It can produce evidence consistent with a local interface/link problem, gateway/router problem, DNS failure, upstream-like failure, remote-service/path-specific failure, route/network change, mixed evidence, or insufficient evidence. The exact rules are documented in docs/diagnosis-model.md.
TCP connect timing is not ICMP RTT or game UDP latency. A router, VPN, local firewall, endpoint policy, or remote service can produce symptoms that resemble an ISP problem.
Each incident directory contains:
incident.json raw canonical local evidence — keep private by default
shareable.json sanitized structured evidence
report.html sanitized self-contained report
report.md sanitized text report
timeline.csv sanitized per-probe timeline
SHA256SUMS checksums for the files above
Share report.html or shareable.json, not incident.json, unless you have reviewed the raw evidence yourself. Shareable output pseudonymizes interfaces, addresses, resolvers, hostnames, and path hops while keeping UTC timestamps for correlation.
RouteWitness does not collect packet payloads, browser history, credentials, .env contents, SSID/BSSID, MAC addresses, or unrelated files. Reports contain no remote scripts, fonts, analytics, or other network-loaded assets. Diagnostic probes still contact the configured endpoints, which can see ordinary network requests and your source IP.
See docs/privacy.md for the exact collection boundary.
Run routewitness config to find the OS-specific configuration path. Example overrides:
interval = 2.0
incident_interval = 0.5
pre_seconds = 45.0
recovery_seconds = 6.0
family = "auto" # auto, 4, 6, both
paths = true
targets = ["github.com"]
# retention_days = 30Unknown keys and invalid ranges are rejected. Old completed incidents are only removed when retention_days is explicitly configured. RouteWitness does not change adapter, DNS, VPN, firewall, or router settings.
Target platforms are Windows 11, modern Linux, and macOS. GitHub Actions validates formatting, linting, strict typing, the offline test suite, package builds, wheel installation, CLI startup, doctor, and the offline demo on all three operating systems with Python 3.11, 3.12, and 3.13.
That matrix is useful cross-platform evidence, but it is not the same as running a long-lived watcher on every real network. Native foreground-watch, recovery, and cancellation sessions remain part of the release validation record. See docs/validation.md.
Other known limits:
- Linux route discovery expects iproute2 JSON; ICMP/path diagnostics depend on installed system tools.
- Windows uses read-only PowerShell NetTCPIP objects and .NET Ping; process startup makes sub-second cadence best-effort.
- macOS uses numeric BSD route output plus psutil; split-VPN and scoped DNS policy are not fully enumerated.
- Wi-Fi RSSI is not collected in v0.1 rather than guessed.
- A foreground process records nothing while stopped, powered off, or asleep; sampling gaps are marked unknown.
- This is not a speed test, packet analyzer, service-status oracle, or ISP-fault certificate.
python -m pip install -e '.[dev]'
python -m ruff format --check .
python -m ruff check .
python -m mypy
python -m pytest --cov=routewitness --cov-branch
python -m buildCorrectness tests use fake clocks/providers and mocked OS/network responses. They block external socket access while allowing localhost plumbing needed by the event loop.
See CONTRIBUTING.md, docs/architecture.md, and docs/product-research.md.
MIT. See LICENSE.