chore(cli): remove dead decnet correlate command

The CLI was a day-one debug helper that read a log file or stdin and
printed a traversal table. It hadn't been wired to the live data path
since the engine moved into the profiler worker (DEBT.md:218). No
deploy unit, no caller, no doc relied on it. Removed the command and
its two tests; `decnet/correlation/` stays as a library consumed by
the profiler and the reuse correlator.
This commit is contained in:
2026-04-26 04:26:15 -04:00
parent bf87f8794a
commit 0d2283e10c
2 changed files with 0 additions and 79 deletions

View File

@@ -82,65 +82,6 @@ def register(app: typer.Typer) -> None:
asyncio.run(_run())
@app.command(name="correlate")
def correlate(
log_file: Optional[str] = typer.Option(None, "--log-file", "-f", help="Path to DECNET syslog file to analyse"),
min_deckies: int = typer.Option(2, "--min-deckies", "-m", help="Minimum number of distinct deckies an IP must touch to be reported"),
output: str = typer.Option("table", "--output", "-o", help="Output format: table | json | syslog"),
emit_syslog: bool = typer.Option(False, "--emit-syslog", help="Also print traversal events as RFC 5424 lines (for SIEM piping)"),
daemon: bool = typer.Option(False, "--daemon", "-d", help="Detach to background as a daemon process"),
) -> None:
"""Analyse logs for cross-decky traversals and print the attacker movement graph."""
import sys
import json as _json
from pathlib import Path
from decnet.correlation.engine import CorrelationEngine
if daemon:
log.info("correlate daemonizing log_file=%s", log_file)
_utils._daemonize()
engine = CorrelationEngine()
if log_file:
path = Path(log_file)
if not path.exists():
console.print(f"[red]Log file not found: {log_file}[/]")
raise typer.Exit(1)
engine.ingest_file(path)
elif not sys.stdin.isatty():
for line in sys.stdin:
engine.ingest(line)
else:
console.print("[red]Provide --log-file or pipe log data via stdin.[/]")
raise typer.Exit(1)
traversals = engine.traversals(min_deckies)
if output == "json":
console.print_json(_json.dumps(engine.report_json(min_deckies), indent=2))
elif output == "syslog":
for line in engine.traversal_syslog_lines(min_deckies):
typer.echo(line)
else:
if not traversals:
console.print(
f"[yellow]No traversals detected "
f"(min_deckies={min_deckies}, events_indexed={engine.events_indexed}).[/]"
)
else:
console.print(engine.report_table(min_deckies))
console.print(
f"[dim]Parsed {engine.lines_parsed} lines · "
f"indexed {engine.events_indexed} events · "
f"{len(engine.all_attackers())} unique IPs · "
f"[bold]{len(traversals)}[/] traversal(s)[/]"
)
if emit_syslog:
for line in engine.traversal_syslog_lines(min_deckies):
typer.echo(line)
@app.command(name="reuse-correlate")
def reuse_correlate(
min_targets: int = typer.Option(

View File

@@ -324,26 +324,6 @@ class TestWebCommand:
assert "Serving DECNET Web Dashboard" in result.stdout
# ── correlate command ─────────────────────────────────────────────────────────
class TestCorrelateCommand:
def test_correlate_no_input(self):
with patch("sys.stdin.isatty", return_value=True):
result = runner.invoke(app, ["correlate"])
if result.exit_code != 0:
assert result.exit_code == 1
assert "Provide --log-file" in result.stdout
def test_correlate_with_file(self, tmp_path):
log_file = tmp_path / "test.log"
log_file.write_text(
"<134>1 2024-01-15T12:00:00+00:00 decky-01 ssh - auth "
'[relay@55555 src_ip="10.0.0.5" username="admin"] login\n'
)
result = runner.invoke(app, ["correlate", "--log-file", str(log_file)])
assert result.exit_code == 0
# ── api command ───────────────────────────────────────────────────────────────
class TestApiCommand: