"Stop the Scream Test. Use Screamless Instead."
Every sysadmin faces this nightmare:
- "Can we decommission web-old-03?"
- "I dunno, let's shut it down and see what breaks."
This is the scream test — and it's how most infrastructure changes happen in 2026.
The real questions are:
- What other servers depend on me?
- Will shutting me down break anyone?
- What am I actually used for?
Most servers have no documentation. You inherit them. Nobody knows why they still exist.
Experimental dependency archaeology. During a passive observation window, Screamless can show:
- What this server connects to (outbound dependencies)
- What connects to this server (inbound dependencies)
- Evidence and confidence for each (with data-quality warnings)
- Impact if you shut it down (cascade analysis)
- High-fan-in services (redundancy is not inferred)
# Install the published release (no Rust toolchain required)
# The binary installer requires cosign to authenticate the signed release checksums.
curl -fsSL https://raw.githubusercontent.com/cyberducttape/ScreemLess/v1.1.0/install.sh | bash
# Or download a versioned artifact from GitHub Releases
# screamless-1.1.0-linux-amd64.tar.gz
# Observe for 7 days (the default)
screamless observe
# Generate report
screamless report
# Check if safe to decommission
screamless decommission-check
# Check before deployment/restart
screamless preflight --server db01 --operation restart
# Interactive dashboard
screamless dashboard --output analysis.htmlWhen installing the systemd agent, a custom INSTALL_DIR must be under a
root-owned directory tree that is not writable by group or other users. This
prevents the root service from executing a user-replaceable binary. /tmp and
/var/tmp are not valid service install locations; use --no-service for a
user-owned CLI installation without registering the system service.
The packaged agent runs as root with a bounded Linux capability set for host-wide process, socket, and protected-configuration inventory. This remains sensitive host access; review the security policy before deployment.
The observer emits structured diagnostics to stderr. Set RUST_LOG to tune
verbosity, for example RUST_LOG=screamless=info for journal-friendly run,
snapshot, timing, and failure fields.
Observed outbound dependencies:
db01:3306 94% confidence (42 socket observations, nginx process, wp-config.php reference)
redis01:6379 87% confidence (15 socket observations, php-fpm process)
api.vendor.com:443 61% confidence (2 socket observations; config evidence is supporting context)
These servers depend on THIS one:
web01 95% confidence (outbound socket observations in the shared database)
monitor01 92% confidence (outbound socket observations in the shared database)
Process activity counts snapshots in which a process was observed; it does not claim to count process executions. Cron discovery parses schedules from system and user crontabs, while command bodies are redacted and job activity is not inferred.
Long-running observe sessions retain the most recent 30 days of snapshots automatically.
The snapshot in snapshots.data is the canonical audit/provenance record and is the
source used by analysis. Large snapshots are gzip-compressed; older uncompressed JSON
rows remain readable after the schema upgrade. Legacy normalized relationship tables
are retained for compatibility with older databases, but new snapshots are not
duplicated into those tables. This preserves the complete evidence while reducing
database and write-ahead-log growth.
If you shut down db01:
✗ web01 fails immediately (depends directly)
✗ app02 fails immediately (depends directly)
⚠️ elasticsearch01 degrades (loses replication peer)
Cascade risk: MEDIUM (2 systems lose access, 1 degrades)
| Feature | Status |
|---|---|
| Network observation | ✅ Phase 1 |
| Process tracking | ✅ Phase 1 |
| Cron/timer detection | ✅ Phase 1 |
| Dependency inference | ✅ Phase 2 |
| Confidence scoring with evidence | ✅ Phase 2 |
| 7-day observation window | ✅ Phase 2 |
| Configuration scanning | ✅ Phase 3 |
| DNS resolution | ✅ Phase 3 |
| ASCII dependency graphs | ✅ Phase 3 |
| Interactive HTML dashboard | ✅ Phase 4 (local data only) |
| Reverse dependency detection | ✅ Phase 5 |
| Snapshot-database mapping | ✅ Phase 5 (requires local data from each host) |
| Pre-flight safety checks | ✅ Phase 7 |
| Cascade failure analysis | ✅ Phase 5 |
| Website and infrastructure inventory | ✅ Config-backed, evidence-labeled |
The inventory shown in JSON reports and the dashboard includes configured virtual hosts, host-level listener status (including shared-port ambiguity), document roots, observed users, recognized application processes, inferred database/storage connections, and load-balancer candidates backed by upstream/proxy configuration. Reverse-proxy configuration is parsed for Nginx, Apache, HAProxy, Traefik, and Caddy. Listener activity is reported as host-level socket observations, not assigned to individual virtual hosts. It is not HTTP request or visitor analytics, and an observation is not a count of unique connection events.
The infrastructure --format json integration output declares schema version
3.1. Consumers should branch on schema_version; version 3.0 represents
hosts as an ordered array and reports site listener evidence without claiming
virtual-host health. Version 3.1 adds fleet-scope coverage to each analysis.
The report --format json output declares schema version 2.2 and includes
generated_at, collector_version, and host_identity (hostname aliases,
machine identifiers, and observed interface addresses) metadata.
# Core observation
screamless snapshot # Single observation now
screamless observe --duration 7d # 7-day observation (default)
# Analysis & Reports
screamless report # Text report
screamless report --format json # Machine-readable output
screamless decommission-check # Evidence and coverage assessment
screamless dashboard --output rep.html \
--fleet-inventory expected-hosts.txt # Interactive HTML with scope
# Safety & Planning
screamless preflight --server db01 --operation restart \
--fleet-inventory expected-hosts.txt # Is restart safe?
screamless infrastructure --servers db01,web01,cache01 # Map all dependenciesDecommission and maintenance checks require --fleet-inventory to return a
positive result. The file is a newline-separated roster of every dependency-capable
host; blank lines and full-line # comments are ignored. Listed hostnames must
match the hostnames used by the observations, and the roster must also account for
every host already present in the shared database window. Every listed host must
have complete, high-quality evidence in the requested window. This is an operator attestation:
Screamless cannot independently verify that the roster itself is exhaustive. Without
the file, fleet scope remains unknown and the check returns exit code 4.
screamless observe --duration 7d
screamless decommission-check --fleet-inventory expected-hosts.txt
# Output: an evidence assessment; incomplete collection is reported as UNKNOWNscreamless preflight --server nginx01 --operation update \
--fleet-inventory expected-hosts.txt
# Output: a safety result; incomplete evidence is non-zero and must be reviewedAutomation exit codes are consistent across preflight and decommission checks:
0: evidence supports the operation1: internal failure2: evidence identifies an operation-specific blocker3: invalid invocation4: insufficient or unknown evidence
Operation policy is specific to the requested action. A listening service is
relevant to decommissioning but is not, by itself, evidence that a restart is unsafe.
When systems are observed depending on a host, preflight reports the expected
impact and blocks automation until the caller passes --acknowledge-impact.
That flag acknowledges impact only; it does not override incomplete observations
or verify that a maintenance window has been approved. Preflight JSON declares
schema version 1.1 and includes the observed coverage, fleet-scope result, probe states, inbound
dependency evidence, and impact_acknowledged; unavailable data is null.
# Database went down — what was depending on it?
screamless infrastructure --servers prod-db01
# Shows: which apps lost connectivity, which degradedscreamless infrastructure --servers web01,web02,web03,db01,cache01
# Shows: observed relationships and high-fan-in servicesscreamless dashboard --output compliance-report.html
# Shareable, timestamped, evidence-backed dependency map- Polls TCP and UDP sockets through
sswith anetstatfallback - Correlates with running processes
- Finds config file references
- Assigns confidence based on evidence
Polling is a fallback observation method and can miss very short-lived connections or datagrams. Event-driven eBPF, conntrack, and service-mesh telemetry are not currently included.
Screamless derives inbound dependencies by reversing observed outbound edges from the other hosts in the database. If web01 is observed connecting to db01:3306, the topology records web01 as a dependent of db01. Local DNS records, access-log IPs, Git remotes, SSH configuration, and mount configuration are not treated as server-to-server inbound dependencies.
Each relationship should be read by evidence class:
- OBSERVED: a socket observation from a collector. This is the strongest current evidence, but polling can miss short-lived traffic.
- DECLARED: a configuration reference that matches a host or address and compatible port. It is supporting evidence, not proof of traffic.
- INFERRED: a heuristic hint such as log, DNS, or access information. Current inbound topology is deliberately based on reversed observed edges instead.
- UNKNOWN: a probe failed, permissions were insufficient, or the observation window was inadequate. Unknown is not equivalent to no dependency.
Confidence is a summary of available evidence and data quality; it is not a probability that a dependency exists.
- Cascade detection: "If I shut down, these servers lose access, those degrade"
- High-fan-in candidates: highlights observed inbound concentration; redundancy, VIPs, replication, and alternate paths are not verified
- Cluster mapping: "These 8 services always work together"
Screamless is useful when treated as an evidence collector:
✅ Solves the real problem: Not "detect services," but "what breaks if I change this?"
✅ Evidence-based: Every claim shows WHY we think it's true
✅ Fast: a lightweight polling collector, not a complete network tap
✅ Safe: Color-coded confidence, clear risk levels
✅ Shareable: Single HTML file with no CDN runtime dependency
✅ Conservative: separates observed network evidence from supporting hints
# Source build (development only)
git clone --branch v1.1.0 https://github.com/cyberducttape/ScreemLess
cd ScreemLess
# Build
cargo build --release
# Deploy the binary to the host being observed
scp target/release/screamless root@server:/usr/local/bin/
ssh root@server screamless observe --duration 7d
ssh root@server screamless reportPublished releases include:
screamless_1.1.0_amd64.debscreamless-1.1.0-1.x86_64.rpmscreamless-1.1.0-linux-amd64.tar.gzscreamless-1.1.0-linux-arm64.tar.gzscreamless-1.1.0-source.tar.gz(tracked source only; no.git/)SHA256SUMS,SBOM.spdx.json, and Cosign signature material
The package/installer can enable the collector with:
sudo systemctl enable --now screamless-agentRemoving the Debian or RPM package stops and disables the agent, but preserves
/var/lib/screamless and its observation database. Package upgrades leave the
service running while the replacement package is installed.
In 2026, most infrastructure is undocumented. Screamless provides local observational evidence, but it does not replace an event-driven network sensor or a central multi-host ingest service.
- No config files to maintain
- Collectors inspect only the local host; the infrastructure command cannot collect remote hosts and requires their snapshots to already be in the same database
- Polling can miss short-lived TCP/UDP activity
- Configuration evidence is matched by hostname/IP and compatible port, not by port alone
A report is a starting point for validation, not proof that no dependency exists.
Prototype / experimental. The collection and analysis paths are useful for investigation, but this is not a production safety oracle.
- Phase 1-4: Foundational observability and dashboards
- Phase 5: Reverse observed outbound edges for inbound reporting
- Phases 6-7: Infrastructure mapping and automation
╭──────────────────────────────────────────╮
│ DECOMMISSION EVIDENCE REPORT │
╰──────────────────────────────────────────╯
Server: legacy-web-03
Observation: 2 snapshots across 0.02 observed hours (requested window: 168 hours)
OBSERVATION COVERAGE
Expected samples: 10080 | Successful samples: 2 | Coverage: <0.1%
Evidence quality: LOW
Remaining unknowns:
- observation window is not sufficiently covered
? INSUFFICIENT EVIDENCE
OUTBOUND DEPENDENCIES:
No outbound dependencies observed, but collection evidence is insufficient to infer absence.
INBOUND DEPENDENCIES:
No inbound dependencies observed, but collection evidence is insufficient to infer absence.
RISKS:
⚠️ 47 scheduled jobs configured
ℹ️ Old PHP 5.6 observed during the window
RECOMMENDATION:
Validate with service owners and independent telemetry before decommissioning.
Keep a backup of configuration and evidence.
See SECURITY.md for operational limitations and CONTRIBUTING.md for development guidance.
Pull requests are expected to pass formatting, Clippy with warnings denied, all tests, Debian/RPM package smoke tests, and a locked release build. Generated databases and dashboards are written with owner-only permissions and dashboard writes are atomic.
The dashboard drag interaction also has Chromium and Firefox browser tests.
Run them locally with npm ci, npx playwright install chromium firefox,
cargo build --locked --bin screamless, and
SCREAMLESS_BIN=target/debug/screamless npm run test:browser.
MIT
Built by sysadmins, for sysadmins who are tired of the scream test.