ReconRelate is a CLI-first reconnaissance relationship mapper.
Current implementation status (early alpha):runexecutes a deterministic-first pivot workflow and can escalate ambiguous evidence to a configured local or cloud LLM.- Data is stored in SQLite. The current run graph remains compatible while a migrated, provenance-aware observation and claim ledger is being integrated underneath it.
tree,report, andexportcommands render findings.- Free providers work without API keys; optional BYOK providers are listed by
reconrelate providers. - Bare
reconrelate(orpython run.pywith no domain) opens an interactive shell with slash commands (/run,/model,/providers, ...) — every one-shot subcommand still works unchanged for scripts and CI.
The CLI is the primary product interface. ReconRelate is being developed as an open-source, free-first local tool.
Point it at a company and it maps the other domains that company owns or acquired — the freshly-acquired, less-tested scope that matters for authorized recon. Free profile, no API keys:
$ reconrelate quick automattic.com --acquisitions
automattic.com
wordpress.com (owns) woocommerce.com (owns)
tumblr.com (owns) jetpack.com (owns)
akismet.com (owns) pocketcasts.com (owns)
dayoneapp.com (owns) beeper.com (owns)
On a public known-truth case (Automattic, 11 documented properties), the free profile scores precision 0.89, recall 0.73 against a labeled evaluation case. Reproduce it end to end:
reconrelate run automattic.com --mode quick --max-depth 1 --acquisitions --profile free
reconrelate export <run_id> --out out
reconrelate eval out\<run_id>.graph.json --case tests\eval\cases\automattic-v1.json --jsonThis is an early alpha: the evaluation corpus is small and quality is measured, not yet
release-gated. See tests/eval/BASELINE.md for the baseline and its known misses, and
SYSTEM_DESIGN.md for the architecture and known weaknesses behind that number.
Run these from the project root:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
pip install -e .Optional: start from the recommended environment template:
Copy-Item .env.example .env
# Then edit .env if you want to set LLM_MODEL / keys.The installed command is reconrelate. Start with the smallest useful command:
reconrelate example.com
reconrelate quick example.comreconrelate <domain> uses the default deep preset. quick is a low-budget, shallow first look. Use help at any point to see examples:
reconrelate help
reconrelate help run
reconrelate providers
reconrelate providers doctorAfter a run, compare evidence contribution with recorded provider usage entirely offline:
reconrelate providers value --run-id <run_id>
reconrelate providers value --run-id <run_id> --jsonThe value report distinguishes sole-family support from corroborated support, but deliberately does not call either one causal provider lift. Paid-versus-free lift requires matched benchmark runs.
Compare exported free and BYOK runs against the same labeled case without contacting any service:
reconrelate providers compare `
--baseline artifacts\free.graph.json `
--candidate artifacts\byok.graph.json `
--case tests\eval\cases\organization.jsonThe command rejects conflicting crawl policies, reports labeled quality and usage deltas, and keeps planner learning disabled until minimum label counts are met and candidate-only findings are labeled.
Aggregate multiple matched organizations with a path-portable benchmark manifest:
reconrelate providers benchmark --manifest tests\eval\benchmark.example.jsonproviders doctor validates manifests and required API-key configuration without making network
or billable calls. Use --json for automation. Provider calls made during a run are included in
JSON exports and Markdown reports with status, attempts, latency, and conservatively counted paid
units. See the provider adapter contract before adding an API.
Inspect model support before a run:
reconrelate models list
reconrelate models doctormodels list shows the release-versioned catalog and clearly separates transport compatibility
from held-out quality evidence. models doctor checks the effective model, strict-output policy,
timeouts, local Ollama reachability/model installation, or cloud gate and credential presence. It
never generates text or calls a cloud API. ReconRelate does not automatically recommend an
unevaluated model.
Run a matched deterministic-versus-model benchmark over saved, provenance-labeled evidence:
reconrelate models benchmark `
--manifest tests\eval\model_benchmark.example.json `
--model qwen2.5:7b-instructThe checked-in manifest is only a synthetic smoke test and cannot make a model recommendation.
Cloud benchmarks additionally require cloud configuration, --approve-cloud, and positive hard
token and --max-cloud-cost-usd ceilings. Benchmarking never collects live recon evidence; each labeled case supplies the
same saved evidence to the deterministic baseline and model-assisted path.
Optionally route ambiguous cases through an economical model before the primary model:
reconrelate run example.com `
--fast-model qwen2.5:7b-instruct `
--model mannix/llama3.1-8b-abliterated:q5_K_MOnly a strict, semantically valid fast result at or above the versioned confidence threshold avoids
the primary call. models doctor checks both installations and reports mixed local/cloud routing.
Preview provider selection and hard ceilings before a scan. This command is offline and performs no database, network, model, or billable calls:
reconrelate plan example.com --profile free
reconrelate plan example.com --profile byok --approve-paid --max-billable-units 10The default free profile cannot activate billable providers, even when their keys are present.
An actual BYOK run requires both explicit approval and a positive billable-unit ceiling:
reconrelate run example.com --profile byok --approve-paid --max-billable-units 10--budget controls crawl breadth/depth; --max-provider-calls and
--max-billable-units are hard execution ceilings. See query planning and spend safety.
Registration lookup is RDAP-first: ReconRelate discovers the authoritative service
from IANA, preserves RDAP evidence, and uses legacy WHOIS only when RDAP lacks an identity pivot or
cannot answer. Pin RECONRELATE_SOURCE_WHOIS=rdap-iana to disable legacy fallback.
Use RECONRELATE_DISABLE_PROVIDERS=whoxy,duckduckgo as an immediate provider kill switch. Names
come from reconrelate providers; disabled adapters make no calls and consume no paid units.
providers doctor --json also reports each adapter's shared concurrency and per-minute safety
ceilings, plus maximum response bytes and result items. Per-provider environment overrides and the
adapter response contract are documented in the provider contract.
The optional paid Whoxy adapter uses domain-only micro responses, explicit BYOK
approval, one-credit worst-case reservations, and strict secret-safe response validation.
Its balance can be queried only through the explicit bounded command
providers balance --provider whoxy --approve-paid --max-billable-units 1; routine diagnostics
remain offline.
Provider data-use policies are enforced at shared-cache and JSON
export boundaries. Paid adapters cannot register without declaring one; Whoxy is run-local and
exports derived references only pending provider-specific legal review.
Manifests also cap nested upstream requests and pages per attempt; reports show both counts instead
of hiding multi-request adapters behind one logical call.
Contended calls wait in a bounded, cross-process FIFO queue; configure its deadline with
RECONRELATE_PROVIDER_CAPACITY_WAIT_SEC (default 5). Waiting never consumes a paid unit.
Subfinder integration is optional and automatically becomes the first passive subdomain source when its binary is installed. Its JSONL source attribution is retained as claim evidence; missing or failed installations fall back to crt.sh and HackerTarget. Corporate hierarchy can also be queried from the free official GLEIF Level 2 API, with exact-name abstention and accounting-specific relationship labels.
Completed acquisition evidence can optionally come from official SEC EDGAR Item 2.01 filings.
It requires a declared operator contact in RECONRELATE_SEC_USER_AGENT, but no API key or payment.
Bounded Wayback historical evidence is available through reconrelate history
and can be enabled during a scan with --history. Archived signals remain explicitly time-scoped.
The default current-page provider also records bounded redirect and labelled legal-page identity signals with source URLs and conservative pivot rules.
The default doctor remains offline. To explicitly test supported free providers against a domain
you are authorized to assess, use reconrelate providers doctor --live --target example.com. Paid
providers are always skipped, and no evidence payload is printed or stored.
For a bounded or expanded run:
reconrelate run example.com --budget medium --max-depth 2 --acquisitions --jsonCopy the run_id from the output, then inspect or export it:
reconrelate tree <run_id>
reconrelate report <run_id>
reconrelate export <run_id> --out artifactsEvaluate a saved graph against a provenance-backed ground-truth case without making any network, provider, database, or model calls:
reconrelate eval artifacts\<run_id>.graph.json --case tests\eval\cases\example.json
reconrelate eval artifacts\<run_id>.graph.json --case path\to\case.json --jsonThe evaluator reports precision only over labeled predictions and lists unlabeled discoveries
separately. See tests/eval/README.md before adding real cases.
Graph JSON and JSON reports also include normalized observations and evidence-backed claims.
Markdown reports summarize observation counts by provider, so a CLI user can see which free or
BYOK source contributed the underlying evidence. Relationship claims show their confidence class,
score, scoring-policy version, and supporting or contradicting evidence. The JSON payload's
claim_projection is a deterministic graph rebuilt only from those claims and evidence, without
depending on legacy graph IDs.
Domain work is durably queued in SQLite. If a process or machine stops mid-run, use the same target
with --resume; leased unfinished tasks are reclaimed without changing the run ID. Reports include
pending, in-progress, succeeded, and failed task counts. See the run recovery guide.
Windows-style slash shortcuts are also available for common actions:
reconrelate /quick example.com /depth:1 /json
reconrelate /providers
reconrelate /helpThe CLI can check, consistently back up, restore, and explicitly retain the local SQLite database:
reconrelate db check
reconrelate db backup
reconrelate db restore path\to\snapshot.sqlite --yes
reconrelate db retention --before 2025-01-01Retention is preview-only unless --apply --yes is provided. Restore and applied retention create
verified safety backups automatically. See the database operations runbook.
Useful dev test:
pip install -e ".[dev]"
$env:PYTHONPATH='src'; python -m pytest -q- Authorized use — Run ReconRelate only against targets you are permitted to assess. It performs real WHOIS, HTTP, DNS, CT, and third-party queries.
- Secrets — Do not commit
.envwithOPENAI_API_KEYor other provider keys. Prefer short-lived keys with least privilege. - Data egress — Pivot LLM calls send WHOIS-derived text to the configured model. Local Ollama is the default. Cloud requires administrative enablement, per-run
--approve-cloud, and a positive--max-cloud-tokensceiling; see the model gateway. - Scan targets — Direct HTTP adapters validate the exact DNS addresses used by aiohttp and every redirect hop, rejecting private, loopback, link-local, reserved, and metadata targets. See the network security model.
- Disk — SQLite and auto-saved artifacts are chmod
600on Unix after creation. Prefer a user-ownedRECONRELATE_DB_PATHandRECONRELATE_ARTIFACTS_DIR; delete runs when retention ends. - Logging — Avoid sharing logs that contain full WHOIS blobs in untrusted channels. litellm debug output is suppressed in-process.
- Blocking SDKs — WHOIS, DNS, and DuckDuckGo execute in killable subprocesses with bounded JSON I/O and a stripped secret environment.
CI runs pytest and pip audit (see .github/workflows/ci.yml). Dependabot is enabled for pip (.github/dependabot.yml).
Any LiteLLM-supported provider works. Add it as a named profile and assign it a role:
reconrelate model add local qwen2.5:7b-instruct # Ollama, the default
reconrelate model add gem gemini-3.6-flash --input-price 0.30 --output-price 2.50
reconrelate model add mini gpt-5-mini # price already in the catalog
reconrelate model use gem --role primaryA cloud model additionally needs allow_cloud true, per-run --approve-cloud, and positive
--max-cloud-tokens / --max-cloud-cost-usd ceilings. A model with no entry in the built-in
price catalog must supply --input-price / --output-price, so no run can spend against an
unknown rate.
The task is harder than it looks. The model must return a strict JSON schema and judge whether an identifier genuinely links two companies. Measured on the same fixture:
| Model | Result |
|---|---|
gemini-3.6-flash |
accepted — full atlassian.com scan, 3 calls, $0.007, 3.8–6.4 s/call |
qwen2.5:7b-instruct (local Ollama) |
accepted — same scan result, free, 7–14 s/call |
deepseek-chat, llama-3.3-70b-instruct (OpenRouter) |
accepted, well under a cent |
qwen3.8-max (OpenRouter) |
invalid — ignored the schema, despite costing ~50× the models that worked |
minimax-m3:free |
invalid — invented its own JSON shape |
nemotron-3-ultra:free |
abstained — correct format, but judged real evidence to be a placeholder |
glm-5.2:free |
rate-limited (HTTP 429) |
Free OpenRouter tiers are useful for smoke-testing the plumbing, but several either ignore the
response schema or abstain on evidence a capable model resolves confidently. Schema validation
catches these rather than admitting malformed output into the graph — an invalid disposition
in reconrelate report means the model failed, not the target. Price and availability change
often; re-check before relying on any row above.
ReconRelate is free-first by design: the default profile uses only free sources and a local model, and that will not change. Two specific things are currently limiting how good it can get, and both cost money rather than engineering time.
Reverse-WHOIS data access. The free reverse-WHOIS path is a web search, not a real
reverse-WHOIS database, so it is inherently noisy — noisy enough that org, name, and ns
pivots are excluded from it entirely because the false positives outweighed the signal. A proper
reverse-WHOIS provider returns registrant-indexed results instead of text matches. The
Whoxy adapter is already built and tested; it needs credits, not code.
A real evaluation corpus. Quality is currently measured against exactly one labelled
company (automattic.com: precision 0.889, recall 0.727). That is a real number from a real
offline evaluator, but one case is not a claim about general accuracy. Getting to
10–20 human-reviewed known-truth organisations is mostly patient manual research — reading
filings and press releases and recording verifiable ground truth — and it is the single change
that would most improve confidence in every number this tool reports.
If you would like to help fund either, sponsorship is welcome via the Sponsor button (see
.github/FUNDING.yml). Contributions of labelled evaluation cases are
equally valuable and cost nothing — see tests/eval/README.md for the
case format.
- Providers are registered in
src/reconrelate/data_gathering/registry.py. - WHOIS, basic intel, and reverse pivots all use free Python modules/resources.
- Relationship orchestration lives under
src/reconrelate/orchestrator/. - CLI command handling is in one file:
src/reconrelate/cli/app.py. - Set
LLM_MODELfor local Ollama or a LiteLLM-supported cloud model. An API key alone cannot enable cloud spending. - Offline quality evaluation lives in
src/reconrelate/quality/; versioned cases and fixtures live intests/eval/.
