@slicedearth/whoisleuth-cli 1.36.1 → 1.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +32 -2
  2. package/bin/whoisleuth.mjs +52 -24
  3. package/cli/archive-inspect.mjs +37 -2
  4. package/cli/arguments.mjs +493 -157
  5. package/cli/artifact-verify.mjs +91 -15
  6. package/cli/bulk-checkpoint.mjs +7 -11
  7. package/cli/bulk-command-runner.mjs +19 -2
  8. package/cli/case-pack.mjs +136 -0
  9. package/cli/ci-report.mjs +73 -0
  10. package/cli/collection-preflight.mjs +59 -0
  11. package/cli/command-reference.mjs +395 -0
  12. package/cli/compare.mjs +1 -1
  13. package/cli/completion.mjs +49 -11
  14. package/cli/config-profile.mjs +180 -0
  15. package/cli/ct-event-intake.mjs +159 -0
  16. package/cli/discovery-scan-command-runner.mjs +15 -1
  17. package/cli/doctor.mjs +11 -5
  18. package/cli/domain-control-monitor.mjs +104 -0
  19. package/cli/domain-control-observations.mjs +235 -0
  20. package/cli/evidence-command-arguments.mjs +12 -1
  21. package/cli/evidence-command-runner.mjs +3 -2
  22. package/cli/evidence-signing.mjs +4 -4
  23. package/cli/external-observation-mapping.mjs +162 -0
  24. package/cli/fail-policy.mjs +64 -0
  25. package/cli/formatters/html.mjs +2 -2
  26. package/cli/formatters/json.mjs +13 -1
  27. package/cli/formatters/terminal.mjs +7 -3
  28. package/cli/investigation-manifest.mjs +113 -0
  29. package/cli/investigation-plan.mjs +2 -2
  30. package/cli/investigation-run.mjs +112 -0
  31. package/cli/local-mmdb-review.mjs +76 -0
  32. package/cli/lookalike-calibration.mjs +121 -0
  33. package/cli/lookup-brief.mjs +116 -0
  34. package/cli/lookup-command-runner.mjs +12 -2
  35. package/cli/lookup-diff.mjs +17 -19
  36. package/cli/lookup-plan.mjs +3 -3
  37. package/cli/lookup-reconcile.mjs +141 -0
  38. package/cli/lookup-timeline.mjs +1 -1
  39. package/cli/mail-review.mjs +1 -1
  40. package/cli/network-command-runner.mjs +4 -1
  41. package/cli/offline-evidence-review.mjs +125 -10
  42. package/cli/open-asset-model-bridge.mjs +169 -0
  43. package/cli/registry-cohort.mjs +121 -0
  44. package/cli/registry-doctor.mjs +220 -0
  45. package/cli/registry-fixture-scaffold.mjs +73 -0
  46. package/cli/risk-calibration.mjs +117 -9
  47. package/cli/runner.mjs +561 -280
  48. package/cli/saved-lookup.mjs +2 -2
  49. package/cli/sharing-review.mjs +202 -0
  50. package/cli/source-reliability.mjs +1 -1
  51. package/docs/cli-reference.md +1336 -0
  52. package/docs/cli.md +259 -940
  53. package/frontend/src/lib/analysis/acquisition-decision-packet.js +1 -1
  54. package/frontend/src/lib/analysis/acquisition-due-diligence.js +7 -7
  55. package/frontend/src/lib/analysis/brand-profile-model.js +46 -4
  56. package/frontend/src/lib/analysis/bulk-domain-comparison.js +12 -12
  57. package/frontend/src/lib/analysis/bulk-mail-exposure.js +1 -1
  58. package/frontend/src/lib/analysis/bulk-session-model.js +7 -2
  59. package/frontend/src/lib/analysis/case-evidence-model.js +26 -4
  60. package/frontend/src/lib/analysis/case-migration-model.js +6 -1
  61. package/frontend/src/lib/analysis/case-record-contracts.js +4 -2
  62. package/frontend/src/lib/analysis/case-record-core.js +5 -1
  63. package/frontend/src/lib/analysis/case-record-operations.js +6 -1
  64. package/frontend/src/lib/analysis/case-report.js +573 -0
  65. package/frontend/src/lib/analysis/case-response-model.js +30 -1
  66. package/frontend/src/lib/analysis/case-response-packet.js +7 -7
  67. package/frontend/src/lib/analysis/detection-rule-model.js +36 -0
  68. package/frontend/src/lib/analysis/evidence-coverage-ledger.js +328 -0
  69. package/frontend/src/lib/analysis/external-findings-import.js +320 -0
  70. package/frontend/src/lib/analysis/investigation-capsule.js +105 -0
  71. package/frontend/src/lib/analysis/lookup-asset-graph.js +806 -0
  72. package/frontend/src/lib/analysis/lookup-decision-support.js +487 -0
  73. package/frontend/src/lib/analysis/lookup-investigation-brief.js +153 -0
  74. package/frontend/src/lib/analysis/lookup-presentation.js +64 -0
  75. package/frontend/src/lib/analysis/lookup-response.js +2 -0
  76. package/frontend/src/lib/analysis/lookup-source-refresh.js +304 -0
  77. package/frontend/src/lib/analysis/lookup-summary-model.js +398 -0
  78. package/frontend/src/lib/analysis/page-similarity.js +1 -1
  79. package/frontend/src/lib/analysis/relationship-evidence.js +3 -3
  80. package/frontend/src/lib/analysis/relationship-observation-model.js +4 -4
  81. package/frontend/src/lib/analysis/scoring.js +9 -89
  82. package/frontend/src/lib/analysis/shortlist-model.js +8 -4
  83. package/frontend/src/lib/analysis/visualization-bounds.js +26 -0
  84. package/frontend/src/lib/analysis/visualization-force-graph.js +352 -0
  85. package/frontend/src/lib/analysis/visualization-matrix.js +88 -0
  86. package/frontend/src/lib/analysis/visualization-models.js +369 -0
  87. package/frontend/src/lib/analysis/visualization-time-series.js +144 -0
  88. package/frontend/src/lib/analysis/workspace-archive-crypto.js +1 -1
  89. package/frontend/src/lib/analysis/workspace-archive.js +4 -2
  90. package/lib/abusech-auth.mjs +1 -1
  91. package/lib/analyst-taxonomy.mjs +40 -0
  92. package/lib/availability.mjs +2 -2
  93. package/lib/bounded-contract-normalizers.mjs +33 -0
  94. package/lib/browser-library-profile.mjs +15 -2
  95. package/lib/certificate-extension-profile.mjs +71 -0
  96. package/lib/credential-surface-profile.mjs +1 -1
  97. package/lib/dns-convergence-review.mjs +183 -0
  98. package/lib/dns-delegation-health.mjs +196 -3
  99. package/lib/domain-assurance.mjs +368 -0
  100. package/lib/domain-change-packet.mjs +133 -0
  101. package/lib/domain-change-review.mjs +307 -0
  102. package/lib/domain-control-flight-recorder.mjs +268 -0
  103. package/lib/domain-control-manifest.mjs +50 -7
  104. package/lib/domain-portfolio-review.mjs +151 -0
  105. package/lib/domain-posture.mjs +9 -9
  106. package/lib/encrypted-dns-contract.mjs +1 -1
  107. package/lib/evidence-export.mjs +1 -1
  108. package/lib/evidence-report-markdown.mjs +1 -1
  109. package/lib/evidence-report.mjs +1 -1
  110. package/lib/generated/cisa-kev-catalog.mjs +1668 -0
  111. package/lib/html-signals.mjs +5 -11
  112. package/lib/ip-prefix.mjs +34 -1
  113. package/lib/local-geoip-evidence.mjs +2 -2
  114. package/lib/lookup-response-contract.mjs +346 -0
  115. package/lib/nameserver-preflight-review.mjs +159 -0
  116. package/lib/observed-network-context.mjs +1 -1
  117. package/lib/opportunity-scoring.mjs +107 -0
  118. package/lib/page-fingerprints.mjs +1 -1
  119. package/lib/page-language-signals.mjs +124 -0
  120. package/lib/rdap-capabilities.mjs +6 -6
  121. package/lib/rdap-search-workbench.mjs +96 -6
  122. package/lib/registry-access.mjs +1 -1
  123. package/lib/registry-capability-catalogue.mjs +4 -4
  124. package/lib/registry-insights.mjs +6 -6
  125. package/lib/risk-scoring.mjs +247 -83
  126. package/lib/scoring-evidence-quality.mjs +107 -0
  127. package/lib/security-txt.mjs +3 -3
  128. package/lib/static-html-analysis.mjs +29 -1
  129. package/lib/threat-intelligence-manifests.mjs +1 -1
  130. package/lib/threatfox-intelligence.mjs +1 -1
  131. package/lib/tls-intelligence.mjs +13 -3
  132. package/lib/trust-store-comparison.mjs +146 -0
  133. package/lib/urlhaus-intelligence.mjs +1 -1
  134. package/lib/website-security-posture.mjs +5 -5
  135. package/lib/website-technology.mjs +25 -11
  136. package/lib/whois-chain.mjs +1 -1
  137. package/lib/zone-intent-review.mjs +534 -0
  138. package/package.json +5 -1
  139. package/third-party-notices.txt +911 -19
package/docs/cli.md CHANGED
@@ -1,17 +1,11 @@
1
- # WHOISleuth CLI
1
+ # WHOISleuth CLI guide
2
2
 
3
- The first-party command-line interface runs the same local classification and
4
- lookup modules as the Express and serverless adapters. It does not call the
5
- hosted WHOISleuth deployment.
6
-
7
- `whoisleuth --help` displays the copyright, AGPL-3.0-only licence, and official
8
- source location. It groups commands by investigation, discovery, saved-evidence,
9
- integrity, and calibration workflows. `whoisleuth <command> --help` displays the
10
- command's purpose, focused invocation, example, and collection boundary without
11
- printing the full command list. `whoisleuth commands --json` exposes those same
12
- contracts as a stable local catalogue for wrappers and terminal tooling.
13
- Packaged copies include `LICENSE`, `NOTICE`, and
14
- `TRADEMARKS.md` alongside the CLI documentation.
3
+ The first-party CLI runs locally and uses the same bounded classification,
4
+ collection, and analysis modules as the web application. It does not call the
5
+ hosted WHOISleuth deployment. Use this guide for installation, first commands,
6
+ collection boundaries, output, and automation behaviour. The
7
+ [complete CLI reference](cli-reference.md) documents every command family and
8
+ artefact contract.
15
9
 
16
10
  ## Installation
17
11
 
@@ -24,959 +18,284 @@ npm install --global --ignore-scripts @slicedearth/whoisleuth-cli
24
18
  whoisleuth doctor
25
19
  ```
26
20
 
27
- Update and verify an existing global installation with:
21
+ Update and verify an existing installation with:
28
22
 
29
23
  ```bash
30
24
  npm install --global --ignore-scripts @slicedearth/whoisleuth-cli@latest
31
25
  whoisleuth --version
26
+ whoisleuth doctor
32
27
  ```
33
28
 
34
- The scoped package and application share one semantic version. The package runs
35
- locally and does not call the hosted WHOISleuth deployment. Networked commands
36
- contact only the sources described by their collection profile; offline review,
37
- comparison, verification, completion, and manual commands remain local.
29
+ The scoped package and application share one semantic version. The package
30
+ includes `LICENSE`, `NOTICE`, `TRADEMARKS.md`, this guide, and the complete
31
+ reference. It requires no lifecycle scripts, so the examples disable them.
32
+ An unqualified `npx whoisleuth` is not this project.
38
33
 
39
- ## Commands
34
+ From a repository checkout, replace `whoisleuth` with
35
+ `node bin/whoisleuth.mts`. Maintainers can assemble, install, and smoke-test the
36
+ exact compiled package closure without publishing it:
40
37
 
41
38
  ```bash
42
- node bin/whoisleuth.mts lookup example.com
43
- node bin/whoisleuth.mts lookup AS13335 --json
44
- printf 'example.com\n' | node bin/whoisleuth.mts lookup --json
45
- node bin/whoisleuth.mts lookup example.com --deep
46
- node bin/whoisleuth.mts lookup example.com --deep --plan --json
47
- node bin/whoisleuth.mts lookup example.com --deep --summary
48
- node bin/whoisleuth.mts lookup example.com --deep --verbose
49
- node bin/whoisleuth.mts lookup example.com --deep --markdown --output lookup.md
50
- node bin/whoisleuth.mts lookup example.com --deep --json --strict-exit --events
51
- cat domains.txt | node bin/whoisleuth.mts bulk --jsonl
52
- node bin/whoisleuth.mts bulk domains.txt --csv --registered-only
53
- node bin/whoisleuth.mts bulk domains.txt --domains --inconclusive-only
54
- node bin/whoisleuth.mts bulk domains.txt --queries --errors-only
55
- node bin/whoisleuth.mts bulk domains.txt --concurrency 4
56
- node bin/whoisleuth.mts bulk domains.txt --deep --checkpoint bulk-checkpoint.json
57
- node bin/whoisleuth.mts bulk domains.txt --deep --checkpoint bulk-checkpoint.json --resume
58
- node bin/whoisleuth.mts ct-search 'example brand' --json
59
- node bin/whoisleuth.mts discover example.com --preset common --jsonl
60
- node bin/whoisleuth.mts discover example.test --dictionary private-terms.txt --snapshot discovery-state.json --json
61
- node bin/whoisleuth.mts discover-scan example.test --scan-limit 50 --checkpoint candidate-scan.json --json
62
- node bin/whoisleuth.mts discover-scan example.test --deep --scan-limit 20 --resolver 192.0.2.53 --observation-snapshot observed-candidates.json --csv
63
- node bin/whoisleuth.mts posture example.com --selectors selector1 --retired-selectors selector0 --mail-profile defensive-no-mail --json
64
- node bin/whoisleuth.mts http example.com --json
65
- node bin/whoisleuth.mts tls example.com --json
66
- node bin/whoisleuth.mts registry-support example.uk --json
67
- node bin/whoisleuth.mts risk-calibrate calibration.json --json
68
- node bin/whoisleuth.mts verify-artifact workspace.json --json
69
- node bin/whoisleuth.mts verify-artifact lookup.json --json
70
- node bin/whoisleuth.mts verify-artifact workspace-encrypted.json --passphrase-file passphrase.txt --json
71
- node bin/whoisleuth.mts source-report lookup.json --json
72
- node bin/whoisleuth.mts inspect-archive workspace.json --json
73
- node bin/whoisleuth.mts inspect-archive workspace.json --search example.invalid --json
74
- node bin/whoisleuth.mts sign-artifact response-packet.json --private-key-file analyst-private.pem > response-packet.signed.json
75
- node bin/whoisleuth.mts verify-signature response-packet.signed.json --public-key-file analyst-public.pem
76
- node bin/whoisleuth.mts lookup example.com --deep --json > lookup.json
77
- node bin/whoisleuth.mts compare lookup.json --json
78
- node bin/whoisleuth.mts page-compare official.json candidate.json --json
79
- node bin/whoisleuth.mts mail-review bulk.json --json
80
- node bin/whoisleuth.mts review-evidence dnssec-evidence.json --json
81
- node bin/whoisleuth.mts domain-control domain-control-input.json --json
82
- node bin/whoisleuth.mts workflow-plan domain-triage example.test --json
83
- node bin/whoisleuth.mts diff first-lookup.json second-lookup.json --json
84
- node bin/whoisleuth.mts timeline first-observation.json second-observation.json latest-observation.json --json
85
- node bin/whoisleuth.mts export lookup.json > evidence.json
86
- node bin/whoisleuth.mts export lookup.json --markdown > evidence.md
87
- node bin/whoisleuth.mts export lookup.json --html > evidence.html
88
- node bin/whoisleuth.mts doctor
89
- node bin/whoisleuth.mts doctor --network --json
90
- node bin/whoisleuth.mts commands --json
91
- node bin/whoisleuth.mts completion zsh
92
- node bin/whoisleuth.mts completion powershell
93
- node bin/whoisleuth.mts manual | man -l -
39
+ npm run cli:package:check
94
40
  ```
95
41
 
96
- These examples run from a checked-out repository; replace
97
- `node bin/whoisleuth.mts` with `whoisleuth` after installation. The root
98
- application package remains private. A separate scoped CLI archive is assembled
99
- from the exact executable dependency closure, installed in a temporary
100
- directory, and smoke tested with:
42
+ ## First commands
43
+
44
+ Inspect the installed capabilities before collection:
101
45
 
102
46
  ```bash
103
- npm run cli:package:check
47
+ whoisleuth --help
48
+ whoisleuth commands
49
+ whoisleuth doctor
50
+ whoisleuth lookup example.com --plan --json
51
+ ```
52
+
53
+ Run a fast lookup or deliberately request the deeper profile:
54
+
55
+ ```bash
56
+ whoisleuth lookup example.com
57
+ whoisleuth lookup example.com --deep
58
+ whoisleuth lookup example.com --deep --summary
59
+ whoisleuth lookup example.com --deep --markdown --output lookup.md
60
+ ```
61
+
62
+ Process an explicit bounded list, generate lookalike candidates, or inspect a
63
+ saved result without sending it anywhere:
64
+
65
+ ```bash
66
+ whoisleuth bulk domains.txt --csv
67
+ whoisleuth discover example.com --preset common --jsonl
68
+ whoisleuth verify-artifact lookup.json --json
69
+ whoisleuth compare lookup.json --json
70
+ whoisleuth brief lookup.json
71
+ whoisleuth registry-doctor lookup.json --json
104
72
  ```
105
73
 
106
- The check includes only the executable, reachable TypeScript modules, CLI
107
- guide, licence, notices, and trademark terms. It excludes application routes,
108
- deployment adapters, tests, and development tools. Direct runtime dependencies
109
- are pinned to the exact versions exercised by the reviewed repository lockfile.
110
- The package and its dependencies require no lifecycle scripts, so the install
111
- examples disable them explicitly.
112
- Its generated manifest stays private. Release-candidate assembly is a separate
113
- explicit operation and never publishes from a developer checkout. Use the
114
- scoped package name; an unqualified `npx whoisleuth` is not this project.
115
-
116
- Lookup defaults to the conservative fast profile. `--deep` must be requested
117
- explicitly and can add bounded WHOIS, DNS, website, TLS, registrar RDAP, and
118
- observed-network IP RDAP work for a domain. The browser Console's optional
119
- security.txt and external intelligence selections are not CLI flags; the CLI
120
- does not run those actions implicitly.
121
-
122
- For a directly entered public IP address, `lookup --deep` can also run one
123
- bounded reverse-DNS query. Terminal output shows the explicit source state and
124
- up to five normalized PTR names; JSON retains up to eight. PTR names are
125
- operator-published routing context, not proof of hosting control or ownership.
126
- Fast lookups do not run this query.
127
-
128
- `lookup --plan` performs classification and prints a versioned preflight without
129
- starting collection. It lists the normalized target, selected fast or deep
130
- mode, planned source families, conditional operations, and the data each family
131
- may receive. The plan cannot predict live feature configuration, cache state,
132
- redirects, referrals, source availability, or an exact request count. It can be
133
- combined with `--json`, but not with report, detail, strict-exit, progress-event,
134
- or quiet options.
135
-
136
- Only one query is accepted by `lookup`. Multiple-input processing belongs to
137
- the explicit `bulk` command rather than being silently inferred by `lookup`.
138
- Standard input is capped at 4 KiB and must contain one non-empty line.
139
-
140
- `registry-support` is an offline catalogue view. It accepts one domain, bare
141
- suffix, or leading-dot suffix as an argument or on stdin and makes no network
142
- request. Its output is described below.
143
-
144
- `doctor` is offline by default. It checks the Node runtime, platform, terminal
145
- capabilities, and availability of offline command families. `doctor --network`
146
- adds independent bounded public-DNS, HTTPS/RDAP bootstrap, and WHOIS port 43
147
- checks against fixed IANA diagnostic infrastructure. The three probes run
148
- within the same per-probe ceiling so one stalled transport does not block the
149
- others. The report retains only state, HTTP status, and a bounded explanation,
150
- not resolved addresses or response content. A failed optional network check
151
- returns the partial-failure exit code rather than claiming that all CLI
152
- collection is unavailable.
153
-
154
- `completion bash`, `completion zsh`, `completion fish`, and `completion
155
- powershell` print static shell completion scripts to stdout. The command does
156
- not edit a shell profile or make a network request. Review the generated script
157
- before sourcing it or placing it in the relevant shell completion directory.
158
- `manual` prints a generated roff manual page and likewise changes no local
159
- configuration.
160
-
161
- `commands` prints the installed command catalogue without running collection or
162
- reading evidence. `commands --json` emits version 1 of the
163
- `whoisleuth.cli.command-catalogue` schema, including each command's usage,
164
- example, declared collection mode, collection scope, and boundary. This is the
165
- supported discovery contract for local wrappers; it is not a permission grant
166
- or a substitute for focused help.
167
-
168
- Focused command help and the generated manual classify every operation as
169
- offline or networked and state the relevant target, input, and concurrency
170
- ceiling. These labels describe observable behavior rather than granting
171
- authorization. The packaged `DISCLOSURE` defines the intended defensive scope;
172
- operators remain responsible for law, provider terms, and authorization.
173
-
174
- ## Deployment boundary
175
-
176
- The CLI runs locally. The serverless deployment publishes only `frontend/build`
177
- and packages functions only from `netlify/functions`, so `bin/` and `cli/` are
178
- not part of the hosted static site or function bundle. The application root and
179
- ordinary package-check candidate remain private. Explicitly reviewed CLI
180
- release candidates can be published under the scoped public package described
181
- in the installation section.
182
-
183
- Commands that query RDAP, WHOIS, DNS, HTTP, TLS, or Certificate Transparency do
184
- so directly from the machine running the CLI. They do not use the hosted login,
185
- hosted session, or deployment usage controls; upstream providers can see and
186
- rate-limit the local machine's network address. Offline `discover`, `compare`,
187
- `page-compare`, `mail-review`, `review-evidence`, `domain-control`, `workflow-plan`, `diff`, `timeline`, `risk-calibrate`, `verify-artifact`, `source-report`, `export`,
188
- `commands`, `completion`, and `manual` operations make no network requests. Commands write
189
- to stdout unless the analyst deliberately selects a local output file.
190
-
191
- ## Output
192
-
193
- Human-readable terminal output is the default. On an interactive terminal it
194
- uses restrained semantic colour, groups Lookup evidence by purpose, wraps
195
- prose to the detected terminal width, and shows transient progress on stderr
196
- for slower collection. State remains explicit in text, so colour is never the
197
- only distinction. Redirected terminal output, JSON, and JSONL contain no ANSI
198
- sequences or progress text. `--no-color` and a non-empty conventional
199
- `NO_COLOR` environment variable disable colour; `WHOISLEUTH_NO_PROGRESS=1`
200
- disables the transient indicator. Command examples remain one copyable line
201
- even when prose is wrapped for a narrow terminal.
202
-
203
- Every command accepts `--output <file>` as a safer alternative to shell
204
- redirection. WHOISleuth buffers bounded output, creates a private temporary file
205
- beside the destination, syncs it, and publishes it atomically with mode `0600`.
206
- An existing destination is refused. `--force` is valid only with `--output` and
207
- allows an intentional atomic replacement. A failed or cancelled command does
208
- not publish a partial output file. Output is capped at 32 MiB.
209
-
210
- `lookup --markdown` and `lookup --html` build the existing normalized evidence
211
- report directly after one completed domain lookup. They do not start a second
212
- collection. These report formats reject IP and ASN inputs before collection;
213
- JSON and terminal output remain available for those query types.
214
-
215
- Lookup terminal output supports three detail levels. The standard view keeps
216
- the normal bounded evidence summary. `--summary` keeps the source states and
217
- key findings while omitting endpoints and supporting detail. `--verbose` adds
218
- the document generation time and the existing bounded per-source collection
219
- timings. These switches are presentation-only and cannot be combined with
220
- `--json`; they do not change collection or the result document.
221
-
222
- `--json` writes one versioned document to standard output:
223
-
224
- ```json
225
- {
226
- "schema": "whoisleuth.cli.lookup",
227
- "version": 1,
228
- "generatedAt": "2026-07-14T00:00:00.000Z",
229
- "mode": "fast",
230
- "query": "example.com",
231
- "type": "domain"
232
- }
74
+ Only one query is accepted by `lookup`; multi-input processing belongs to
75
+ `bulk`. Standard input to `lookup` is capped at 4 KiB and must contain one
76
+ non-empty line.
77
+
78
+ ## Collection profiles
79
+
80
+ Commands are classified as either networked or offline in focused help, the
81
+ generated manual, and `commands --json`.
82
+
83
+ | Profile | Boundary |
84
+ | --- | --- |
85
+ | Fast Lookup | Conservative default for domain triage. It does not run WHOIS or deep website and TLS collection. |
86
+ | Deep Lookup | Explicitly requested bounded RDAP, WHOIS, DNS, website, TLS, registrar-RDAP, and observed-network work where applicable. |
87
+ | Compact deep Bulk | Uses the shared Lookup orchestration but omits full-only response fields and collectors. |
88
+ | Offline review | Reads only the named bounded artefact or analyst-authored input and makes no network request. |
89
+
90
+ Networked commands run from the local machine and contact the sources declared
91
+ by their profile. They do not use the hosted login or hosted usage controls;
92
+ upstream services can see and rate-limit the local network address. The CLI
93
+ does not implicitly enable the browser Console's optional external intelligence
94
+ actions.
95
+
96
+ `lookup --plan` performs classification and emits a versioned preflight without
97
+ starting collection. It lists planned source families and disclosure targets,
98
+ but cannot predict cache state, live configuration, redirects, referrals,
99
+ source availability, or exact request count.
100
+
101
+ `doctor` is offline by default. `doctor --network` adds three independent,
102
+ bounded checks against fixed diagnostic infrastructure and retains only state,
103
+ HTTP status, and a bounded explanation.
104
+
105
+ ## Command map
106
+
107
+ | Goal | Commands |
108
+ | --- | --- |
109
+ | Investigate a target | `lookup`, `http`, `tls`, `posture`, `registry-support` |
110
+ | Review many targets | `bulk`, `discover`, `discover-scan`, `ct-search`, `ct-intake` |
111
+ | Compare saved evidence | `compare`, `page-compare`, `diff`, `reconcile`, `timeline`, `mail-review` |
112
+ | Review supplied evidence | `brief`, `review-evidence`, `registry-doctor`, `registry-cohort`, `source-report`, `sharing-review`, `map-observations` |
113
+ | Plan and assure changes | `domain-control`, `monitor-once`, `assurance`, `change-packet`, `workflow-plan`, `workflow-run` |
114
+ | Verify and package evidence | `case-pack`, `manifest`, `oam-export`, `verify-artifact`, `inspect-archive`, `sign-artifact`, `verify-signature`, `export` |
115
+ | Calibrate offline | `risk-calibrate`, `lookalike-calibrate` |
116
+ | Operate the CLI | `doctor`, `registry-scaffold`, `commands`, `completion`, `manual` |
117
+
118
+ Use focused help for the exact arguments and collection ceiling:
119
+
120
+ ```bash
121
+ whoisleuth lookup --help
122
+ whoisleuth sharing-review --help
123
+ whoisleuth commands --json
124
+ whoisleuth manual | man -l -
233
125
  ```
234
126
 
235
- The complete document also carries the normalized `rdap`, `whois`,
236
- `availability`, and `diagnostics` sections returned by the shared lookup
237
- orchestrator. Machine output goes to stdout. Usage and lookup errors go to
238
- stderr, so redirected JSON is not mixed with diagnostics.
239
-
240
- Human-readable domain lookup output separately shows the registrar RDAP status
241
- and endpoint whenever the shared lookup diagnostics represent that follow-up.
242
- Deep mode may report success, unsupported, not found, or an explicit failure;
243
- fast mode reports the existing skipped state. IP, ASN, and lookup responses
244
- without registrar diagnostics remain unchanged. These source states are
245
- provenance only and do not decide availability or imply safety.
246
-
247
- When a deep domain response includes registry interpretation version 1, the
248
- terminal summary also shows the lifecycle label, separately attributed RDAP and
249
- WHOIS disclosure states, reconciliation state, and complete, partial, and
250
- unavailable publication counts. It does not print published contact routes.
251
- The JSON document retains the bounded interpretation and its limitations.
252
-
253
- A deep domain lookup can also show the status, selected public address, and
254
- registered network name from the bounded observed network context. It uses the
255
- same address and IP RDAP source represented in the JSON document. This is
256
- point-in-time edge or network-registration context, not proof of the origin
257
- host, hosting control, ownership, intent, or maliciousness. Fast and compact
258
- commands do not run the enrichment.
259
-
260
- The deep terminal summary also reports the website activity state, page title,
261
- DNS, HTTP, and TLS source states, bounded publisher-declared structured
262
- identity entities, up to six bounded technology indicators, a browser-library
263
- profile count, and the four passive security-posture counts.
264
- These are concise projections of the same evidence already present in the
265
- lookup response. The browser-library line counts apparent components and
266
- catalogue advisory matches without retaining script references or raw
267
- signatures. These summaries make no extra request, omit raw evidence
268
- descriptions, and do not turn a technology or advisory match, or a missing
269
- posture signal, into proof of exploitability, hosting control, ownership, or
270
- maliciousness. Use `--json` when the full bounded evidence, limitations, and
271
- source diagnostics are required.
272
-
273
- `lookup --strict-exit` is an opt-in automation policy. It still emits the
274
- ordinary complete output document, but returns exit code 4 when a requested
275
- diagnostic source is partial, unavailable, rate-limited, timed out, or failed.
276
- The default exit contract remains unchanged, so inconclusive source health does
277
- not silently break existing scripts.
278
-
279
- `lookup --events` and `bulk --events` write versioned
280
- `whoisleuth.cli.progress` version 1 JSONL lifecycle events to stderr while the
281
- ordinary final result stays on stdout. Events contain only the command,
282
- sequence, time, source state or Bulk item index, categorical failure reasons,
283
- and final exit status. They do not contain a target, query, endpoint, file
284
- path, error detail, or evidence value. Human progress and error text are
285
- suppressed while events are active. `--events` cannot be combined with
286
- `--output`, because the final event must describe the same completed stdout
287
- delivery observed by the caller.
288
-
289
- Pressing Ctrl-C asks an in-flight Lookup or Bulk run to stop, suppresses any
290
- partial final result, flushes an enabled Bulk checkpoint, and exits with code
291
- 130. Already started network operations remain subject to their existing hard
292
- timeouts while the shared in-process API unwinds; the executable terminates
293
- after CLI cleanup. A second Ctrl-C removes any known unpublished temporary
294
- output file on a best-effort basis before exiting immediately.
295
-
296
- Bulk can persist compact progress with `--checkpoint <file>`. A new checkpoint
297
- is private, bounded to 16 MiB, versioned, and tied to the exact ordered input
298
- and scan mode by SHA-256. It stores only compact per-item results, never full
299
- Lookup responses. Reusing the same path is refused unless `--resume` is also
300
- specified. Resume revalidates the complete untrusted document and skips only
301
- the exact completed rows; changed input, mode, schema, digest, or malformed
302
- results fail closed.
303
-
304
- If checkpoint persistence fails after collection, WHOISleuth still emits the
305
- completed final result, reports the checkpoint limitation, and exits with code
306
- 4. The last successfully published checkpoint remains available, but it may
307
- not contain the final completed items.
308
-
309
- `diff <left.json> <right.json>` compares two different saved domain Lookup
310
- documents entirely offline. It reuses the bounded Bulk comparison model for
311
- registration, DNS, page identity, mail, certificate, and relationship fields,
312
- keeps missing and unavailable evidence distinct, and makes no ownership or
313
- maliciousness inference. The output records both original observation times.
314
-
315
- `timeline <observation.json> <observation.json> [...]` accepts from 2 to 20
316
- saved Lookup documents for one domain, orders them by their validated
317
- observation times, and compares each adjacent pair offline. The 32 MiB aggregate
318
- input ceiling is enforced while files are read and again by the timeline
319
- builder. Output retains normalized field states and observation times but no
320
- input filenames or raw registry payloads. A difference can reflect a domain
321
- change or changed collection conditions, so the command makes no current-state,
322
- ownership, intent, safety, or maliciousness conclusion.
323
-
324
- When diagnostics version 5, 6, 7, or 8 reports a documented registry collection
325
- constraint, terminal output also shows the suffix, WHOIS and RDAP access
326
- profiles, and the bounded limitation. This is static access-policy context: it
327
- does not make another request, and restricted, unpublished, or unavailable
328
- machine access is not evidence that a domain is unregistered or safe.
127
+ ## Output and automation
128
+
129
+ Human-readable terminal output is the default. Interactive terminals use
130
+ restrained semantic colour and transient progress on stderr. Redirected output,
131
+ JSON, and JSONL contain no ANSI sequences or progress text. State remains
132
+ explicit in text, so colour is never the only distinction.
133
+
134
+ - `--json` and `--jsonl` provide bounded machine-readable documents.
135
+ - `--summary` and `--verbose` change human detail without changing collection.
136
+ - `--no-color` or `NO_COLOR` disables colour.
137
+ - `WHOISLEUTH_NO_PROGRESS=1` disables the transient progress indicator.
138
+ - `--events` keeps the final document on stdout and writes versioned JSONL
139
+ lifecycle events to stderr.
140
+ - `--strict-exit` treats failures in explicitly requested source families as a
141
+ partial failure while keeping skipped or unsupported sources neutral.
142
+ - `--fail-on` applies explicit `source-failure`, `inconclusive`, `danger`, or
143
+ `material-drift` automation policy where the selected command supports it.
144
+ - `--junit` emits bounded CI test cases for Lookup, Bulk, and one-shot control
145
+ reviews; owned-domain Posture can emit `--sarif` only with
146
+ `--owned-domain`.
147
+
148
+ `--config <file> --profile <name>` applies a strict version-1 local profile.
149
+ The default path is `$XDG_CONFIG_HOME/whoisleuth/config.json`. Profiles can set
150
+ only presentation mode, Fast collection, bounded concurrency, and observer or
151
+ vantage labels. They cannot add targets, enable Deep collection, select output
152
+ paths, approve network work, or set failure policy. Explicit command options
153
+ override defaults from the same option group.
154
+
155
+ Every command accepts `--output <file>`. WHOISleuth buffers bounded output,
156
+ creates a private temporary file beside the destination, syncs it, and publishes
157
+ it atomically with mode `0600`. Existing destinations are refused unless
158
+ `--force` is deliberately combined with `--output`. Failed or cancelled
159
+ commands do not publish partial files. Output is capped at 32 MiB.
329
160
 
330
161
  ## Exit codes
331
162
 
332
163
  | Code | Meaning |
333
164
  | ---: | --- |
334
- | 0 | Command completed. Individual sources may still be partial or inconclusive; inspect diagnostics. |
165
+ | 0 | Command completed. Individual sources can still be partial or inconclusive; inspect diagnostics. |
335
166
  | 2 | Invalid command, option, input, or stdin shape. |
336
- | 3 | The requested lookup, collection, or comparison operation could not run. |
337
- | 4 | A bounded operation completed partially, such as Bulk item failures or failed explicit Doctor network checks. |
167
+ | 3 | The requested lookup, collection, or comparison could not run. |
168
+ | 4 | A bounded operation completed partially. |
338
169
  | 70 | Unexpected CLI bootstrap failure. |
339
- | 130 | The analyst cancelled the command. No partial final result was emitted. |
340
-
341
- This release supports `lookup`, `bulk`, `ct-search`, `discover`, `discover-scan`, `posture`,
342
- `http`, `tls`, `registry-support`, `risk-calibrate`, `verify-artifact`,
343
- `inspect-archive`, `sign-artifact`, `verify-signature`, `source-report`,
344
- `compare`, `page-compare`, `mail-review`, `review-evidence`, `domain-control`, `workflow-plan`, `diff`, `timeline`, `export`, `doctor`, `commands`, `completion`, and `manual`. Additional command families
345
- are added as separate bounded increments rather than exposing incomplete
346
- aliases.
347
-
348
- ## Registry capability coverage
349
-
350
- `registry-support` projects the embedded, versioned registry compatibility
351
- catalogue for one domain or suffix. It distinguishes an explicit
352
- fixture-backed or access-documented suffix profile from the generic IANA
353
- discovery profile and reports the RDAP and WHOIS discovery/access paths,
354
- WHOIS query and parser profiles, fixture scenarios,
355
- verification references, documentation references, and the catalogue's
356
- limitation. The same document includes a dated, official-source aggregate of
357
- generic, generic-restricted, sponsored, and infrastructure RDAP coverage. That
358
- snapshot is separate from the suffix profile and from live reachability.
359
-
360
- Terminal output is bounded and control-safe. `--json` emits version 3 of the
361
- `whoisleuth.cli.registry-support` schema. Unknown but syntactically valid
362
- suffixes retain the generic `discovery_only` profile; malformed input exits
363
- with code 2. The command never probes a registry or tests current reachability.
364
- Coverage is context only and cannot decide registration, availability,
365
- ownership, safety, or maliciousness.
366
-
367
- The separate maintenance command `npm run rdap-extensions:drift` compares the
368
- pinned official RDAP extension fixture with the reviewed local interpretation
369
- catalogue entirely offline. `--live` performs one bounded manual fetch from the
370
- fixed official CSV URL and reports added, removed, renamed, status-changed,
371
- unrecognized, and local-only identifiers. `--json` emits
372
- `whoisleuth.rdap-extension-drift-audit` version 1. Drift exits with status 1 and
373
- requires specification and fixture review; the command never enables an
374
- extension, changes authority or availability logic, or issues reverse search.
375
-
376
- `npm run service-dependencies:audit` validates the passive service-dependency
377
- catalogue entirely offline. It checks the catalogue digest, duplicate
378
- identifiers and target suffixes, evidence classes, source and licence
379
- treatment, source dates, and a fixed 180-day review age. `--json` emits
380
- `whoisleuth.service-dependency-signature-audit` version 1. A stale or changed
381
- signature requires manual provider and benign-fixture review; the command
382
- never resolves a target, checks an account, or tests claimability.
383
-
384
- ## Offline Risk calibration
385
-
386
- `risk-calibrate` replays a versioned analyst-labelled fixture dataset through
387
- the exact Risk model shared with the web application. It does not perform a
388
- lookup, contact the hosted deployment, persist the dataset, alter model weights,
389
- choose a threshold, or tune the model automatically. The report compares fixed
390
- thresholds from 40 through 90 and identifies 70 as the current review band.
391
-
392
- Input is capped at 2 MiB and 500 records. Each record requires a unique bounded
393
- ID, an ASCII DNS hostname, one existing analyst disposition, and a strict
394
- whitelist of current scoring inputs. Unknown fields are discarded; arrays,
395
- strings, ages, booleans, provider records, and external findings are revalidated
396
- and bounded before scoring. The accepted dataset envelope is:
397
-
398
- ```json
399
- {
400
- "schema": "whoisleuth.risk-calibration-dataset",
401
- "version": 1,
402
- "records": [
403
- {
404
- "id": "fixture-1",
405
- "domain": "login.example.test",
406
- "analystDisposition": "confirmed_abuse",
407
- "evidence": {
408
- "availability": "registered",
409
- "mutationTypes": ["dictionary"],
410
- "hasPasswordField": true
411
- }
412
- }
413
- ]
414
- }
415
- ```
170
+ | 130 | The analyst cancelled the command; no partial final result was emitted. |
416
171
 
417
- `confirmed_abuse` is treated as a positive calibration label; `false_positive`
418
- and `expected` are negative labels. `unreviewed`, `suspicious`, and
419
- `closed_no_action` remain contextual and are excluded from threshold quality
420
- metrics, as are records for which Risk is not applicable. Terminal output caps
421
- its record list at 100 while `--json` retains the complete bounded report,
422
- factor breakdowns, score bands, and per-threshold confusion metrics. Analyst
423
- dispositions and heuristic scores are review context: neither proves
424
- maliciousness or safety.
425
-
426
- The authenticated Monitor workspace can deliberately create the accepted
427
- dataset from explicitly selected cases. Selection is available only when a case
428
- has a reviewed disposition and retained normalized evidence. That local export
429
- contains the case ID, domain, disposition, and a bounded whitelist of current
430
- scoring inputs. It excludes notes, tags, assertions, actions, contacts, raw
431
- source data, provider payloads, and stored Risk scores. Before download, a local
432
- review step shows the selected, included, and excluded counts, the domains and
433
- dispositions that will be written, and the excluded evidence classes. The CLI
434
- still validates every exported record and never trains, tunes, or changes the
435
- Risk model.
436
-
437
- ## Offline artifact verification
438
-
439
- `verify-artifact` validates a supported local artifact without printing its
440
- evidence contents. Input is capped at 15 MiB. It currently recognises ordinary
441
- and encrypted workspace archives, case-response packets, acquisition-decision
442
- exports, domain-comparison exports, Bulk mail-exposure exports, and Bulk review
443
- manifests. It also validates the bounded versioned structure of saved CLI
444
- Lookup JSON. Because saved Lookup documents do not embed a checksum or
445
- signature, that result is reported as `structure_valid` with content integrity
446
- explicitly unchecked. Saved Lookup validation retains its stricter 8 MiB
447
- document ceiling.
448
-
449
- For an ordinary workspace archive, the command validates the versioned
450
- structure, section byte counts, record counts, and per-section checksums. For a
451
- supported signed review artifact, it validates the declared SHA-256 digest. An
452
- encrypted archive without `--passphrase-file` can establish only that the
453
- envelope is structurally valid; it reports `envelope_valid` and explicitly
454
- leaves authenticated encryption and inner checksums unchecked.
455
-
456
- Supplying a separate passphrase file, capped at 1 KiB, allows authenticated
457
- decryption followed by the ordinary workspace checks. The passphrase is never
458
- accepted as a command-line value, printed, or retained. Verification detects
459
- changes against the artifact's declared contract; it does not authenticate the
460
- analyst or establish that an observation was accurate or remains current.
461
-
462
- ## Privacy-safe source reliability report
463
-
464
- `source-report` summarises source states, durations, truncation, and rate-limit
465
- counts from one version-1 CLI Lookup, Bulk, or Bulk-item document, a JSON array
466
- of up to 100 such documents, or an array containing only previously generated
467
- source-reliability reports. Lookup documents and reports cannot be mixed.
468
- Merged reports preserve exact state and sample totals and add bounded ranges
469
- for each input report's median and p95 duration, a bounded source timeline,
470
- fast/deep/unknown cohorts, and the earliest and latest valid report generation
471
- times. Exact duplicate reports are rejected so one saved report is not
472
- accidentally counted twice. Per-source failure, partial, truncation, and
473
- rate-limit rates remain separate. The command does not pretend that aggregate
474
- timing distributions can reconstruct the original target-level samples. Input
475
- is capped at 12 MiB and traversal, source, duration, and output counts are
476
- bounded.
477
-
478
- The report retains only fixed source identifiers and aggregate operational
479
- counts. It does not output targets, queries, endpoints, source limitations, raw
480
- evidence, or provider payloads. Observation-envelope duration and the
481
- potentially overlapping Lookup timing are reported separately and never added
482
- together. It is a local engineering diagnostic, not analytics, a source-quality
483
- score, or evidence that a collector is currently healthy.
484
-
485
- ## Workspace archive inspection
486
-
487
- `inspect-archive` verifies an ordinary or encrypted workspace archive and then
488
- reports its versioned sections, counts, byte sizes, and checksum states without
489
- printing stored records. An encrypted archive requires
490
- `--passphrase-file`; passphrases are never accepted on the command line.
491
-
492
- An optional `--search` is exact and case-insensitive across a fixed allowlist
493
- of target fields. Default matches disclose only the section, field name, and a
494
- SHA-256 digest. `--reveal` must be selected explicitly to print the matched
495
- value. Notes, contacts, raw evidence, arbitrary object fields, and partial text
496
- search are excluded. Unicode domain searches are canonicalized to their
497
- DNS-safe ASCII form before exact comparison. `--require-match` makes a
498
- no-match result fail for automation and is valid only with `--search`.
499
- Traversal, input size, matches, depth, arrays, and strings are bounded.
500
-
501
- ## Optional evidence-package signing
502
-
503
- `sign-artifact` signs a locally verified case-response packet or supported
504
- review manifest with an externally managed Ed25519 private key:
172
+ ## Detailed command reference
505
173
 
506
- ```bash
507
- node bin/whoisleuth.mts sign-artifact packet.json --private-key-file analyst-private.pem > packet.signed.json
508
- node bin/whoisleuth.mts verify-signature packet.signed.json --public-key-file analyst-public.pem
509
- ```
174
+ The headings below preserve the established guide anchors while moving their
175
+ full contracts into the packaged reference.
510
176
 
511
- The signed package embeds the public key, key identifier, signature time, and
512
- original artifact. Verification first checks the exact package field set and
513
- signature, then the artifact's own checksums or manifest. A result is reported
514
- as `signature_valid`; signer trust is separately reported as `trusted_key` or
515
- `embedded_key_only`. Without a separately supplied trusted public key,
516
- verification establishes only that the package is internally self-consistent.
517
- WHOISleuth does not generate, store, recover, rotate, publish, or establish
518
- trust in signing keys.
519
-
520
- ## Bulk lookup
521
-
522
- `bulk` accepts a newline-delimited file or stdin. It preserves input order,
523
- removes case-insensitive duplicates, and returns a result for every retained
524
- query. Input is capped at 1 MiB. Fast mode is capped at 500 queries with four
525
- workers by default. Deep mode is capped at 50 queries with two workers by
526
- default. Explicit concurrency cannot exceed eight in fast mode or three in
527
- deep mode.
528
-
529
- Bulk uses the shared compact lookup response, so it does not retain raw RDAP
530
- objects or WHOIS response bodies. `--json` returns one bounded collection;
531
- `--jsonl` emits one self-contained versioned item per line. `--domains` emits
532
- only successfully normalized domain names, while `--queries` preserves the
533
- selected bounded input queries and is suitable for an exact retry queue.
534
- Version 2 adds a
535
- bounded `dnsSummary` projection for observed A, AAAA, NS, and MX records plus
536
- null MX, SPF, and DMARC state. `--csv` writes fixed columns for automation,
537
- including the DNS summaries and explicit outcome.
538
-
539
- `--registered-only`, `--inconclusive-only`, and `--errors-only` are mutually
540
- exclusive output filters. The first retains registered, for-sale, and expiring
541
- authority-aware states. The second retains unknown authority states and failed
542
- rows. The third retains only rows whose lookup operation failed, which is useful
543
- for producing an exact retry queue without treating an inconclusive successful
544
- lookup as an operational error. Filtering does not change collection and never
545
- converts an unavailable or failed source into an unregistered result. Machine
546
- documents record collected and emitted counts. A mixture of successful and
547
- failed queries exits with code 4 while preserving every collected result before
548
- output filtering. For example, `bulk domains.txt --queries --errors-only`
549
- produces only the exact failed inputs while retaining the partial-failure exit.
550
-
551
- ## Certificate Transparency search
552
-
553
- `ct-search` accepts one keyword as an argument or on stdin and calls the same
554
- bounded Certificate Transparency module as the web application. It contacts
555
- the upstream public log search service directly from the local machine; it
556
- does not call the hosted WHOISleuth deployment. Quote a multi-word keyword so
557
- the shell passes it as one argument.
558
-
559
- Terminal output summarizes certificate rows, observed hostnames, canonical
560
- registrable-domain matches, observation times, bounded certificate-issuance
561
- groups, and completeness. An issuance group contains names observed together
562
- in one public certificate record; a cross-domain group is a review lead, not
563
- an attribution or ownership finding. Terminal output shows at most 100 matches
564
- and five hostnames per match, with explicit omission notes. `--json` returns
565
- the complete bounded structured result in the versioned
566
- `whoisleuth.cli.ct-search` schema. The certificate-group cap is reported
567
- separately from the registrable-domain result cap. CT observations do not prove
568
- that a website is active or malicious.
569
-
570
- ## Lookalike discovery
571
-
572
- `discover` runs the same pure, bounded lookalike generator as the Discover
573
- tool without making network requests. It accepts a brand label or a
574
- domain with one suffix label. The default TLD set is `com,net,org`; replace it
575
- with `--tlds com,net` when narrower coverage is wanted.
576
-
577
- Generation presets are `common`, `impersonation`, and `all` (the default).
578
- Keyboard-aware mutations support `qwerty` (the default), `azerty`, and
579
- `qwertz`; `--keyboard all` uses their bounded combined neighbour set, including
580
- adjacent number-row keys. Supply a UTF-8 text file with
581
- `--dictionary terms.txt` to add up to 100 local terms when
582
- using the `impersonation` or `all` preset. Dictionary input is capped at 4,096
583
- bytes and individual terms at 32 characters. Machine output records accepted
584
- and rejected term counts but never copies the private terms into its metadata.
585
-
586
- Use `--families <ids>` instead of `--preset` to run an exact comma-separated
587
- selection. Supported IDs are `character_addition`, `character_omission`,
588
- `character_duplication`, `character_transposition`, `pluralization`,
589
- `tld_embedding`, `www_prefix`, `hyphenation`, `separator_omission`,
590
- `word_reordering`, `keyboard_substitution`, `keyboard_insertion`, `vowel_swap`,
591
- `bitsquatting`, `ascii_homoglyph`, `unicode_homoglyph`,
592
- `unicode_whole_label`, `unicode_homoglyph_depth_2`, `dictionary`,
593
- `dictionary_token_replacement`, `tld_typo`, and `tld_substitution`. Machine
594
- output records the normalized custom selection. A custom dictionary file
595
- requires `dictionary` or `dictionary_token_replacement` in that selection.
596
-
597
- `--domains` writes the unique candidate names only. `--snapshot <file>` keeps
598
- one private, versioned local observation of the normalized seed, generation
599
- configuration, custom-dictionary digest, and candidate set. The first run
600
- creates the snapshot; later runs report added and removed candidates before
601
- atomically replacing it. The snapshot never stores private dictionary terms.
602
- Use the same command from a local scheduler such as cron or a system timer to
603
- perform repeatable discovery runs. WHOISleuth does not install a scheduler,
604
- run a background daemon, or infer that an added candidate is registered,
605
- active, available, or malicious.
606
-
607
- Dotted subdomain permutations are intentionally excluded because the lookup
608
- pipeline validates a hostname's registrable parent. The CLI does not present
609
- authoritative parent registration evidence as proof that a generated hostname
610
- exists.
611
-
612
- Terminal output is capped at 200 candidates with an explicit notice. Versioned
613
- JSON and JSONL use `whoisleuth.cli.discover` schema version 2 and retain the
614
- complete bounded candidate set and mutation provenance. Internationalised
615
- candidates show the DNS-safe ASCII form and readable Unicode form together in
616
- terminal output. The Impersonation and All presets can add up to six
617
- deterministic whole-label Unicode candidates when every letter has a reviewed
618
- same-script replacement. The command generates candidates only. It does not
619
- claim that a domain is registered, active, or malicious.
620
-
621
- `unicode_homoglyph_depth_2` is an explicit `--families` option and is never
622
- enabled by a preset. It replaces exactly two ASCII letters with characters
623
- from the same reviewed script, ranks curated mappings first, and returns at
624
- most 256 candidates. JSON and terminal output report generated candidates,
625
- cross-script or invalid combinations omitted by policy, and lower-ranked
626
- label variants omitted by the family or overall generation budget.
627
-
628
- ## Supervised candidate scan
629
-
630
- `discover-scan` composes the same bounded generator with the compact Lookup
631
- collector. Unlike `discover`, it is an explicitly networked command. It selects
632
- the first deterministic candidates up to `--scan-limit`, processes fixed
633
- chunks sequentially, and retains each registration and DNS source state. Fast
634
- mode is the default and accepts at most 500 candidates. Explicit `--deep` mode
635
- is capped at 50 candidates and concurrency 3 because it can add WHOIS, DNS,
636
- HTTP, TLS, page, and technology work for every selected candidate.
637
-
638
- Use `--chunk-size 1-100`, `--concurrency 1-8`, and the existing private
639
- `--checkpoint <file> [--resume]` boundary to control a run. The checkpoint is
640
- tied to the exact ordered candidate set and scan mode. A new generation order,
641
- limit, or mode requires another checkpoint. `--resolver` accepts at most three
642
- literal IPv4 or IPv6 recursive-resolver addresses and applies them only to DNS
643
- observations in this local run. Resolver hostnames and automatic third-party
644
- resolver selection are not supported. The selected resolvers can observe the
645
- queried candidates and may apply their own logging and retention policies.
646
-
647
- An optional newline-delimited `--allowlist` accepts at most 500 domains and 64
648
- KiB. Matching candidates remain in evidence and are labelled `suppressed` in
649
- the review queue; the full list and unmatched entries are not copied into
650
- output, while each matching scanned candidate necessarily exposes that match.
651
- Allowlisting never deletes a result or asserts that it is safe. Output filters
652
- select registered, inconclusive, acquisition-review, or
653
- suppressed rows without changing whole-run counts or source health. JSON,
654
- JSONL, CSV, and domain-list forms retain mutation provenance and explicit
655
- review lanes. The queue provides next manual actions, not automatic lookup,
656
- acquisition, blocking, submission, or enforcement.
657
-
658
- Deep compact results can group exact shared addresses, nameservers, and mail
659
- servers observed across at least two candidates. These bounded relationships
660
- are pivot leads only. Common hosting, delivery, registrar, and mail services
661
- can produce the same relationship without common ownership or control.
662
-
663
- `--observation-snapshot <file>` keeps a private versioned local projection of
664
- registration state, confidence, and bounded A, AAAA, NS, MX, null-MX, SPF, and
665
- DMARC summaries for the exact candidate set, mode, and resolver selection.
666
- Version 2 records registration and DNS observation times and latest component
667
- states separately; version 1 is read and normalized on the next write. A later
668
- identical run reports material field changes only for components collected
669
- with enough completeness to support the comparison. If registration or DNS is
670
- partial or unavailable, the prior usable evidence for that component is
671
- preserved and the attempt is reported as unavailable rather than converting
672
- missing data into a removal. Raw registry
673
- records, contacts, page content, and request details are excluded. Snapshot
674
- differences are review prompts, not proof of ownership, control, intent,
675
- safety, or maliciousness.
676
-
677
- ## Domain posture audit
678
-
679
- `posture` runs the standard-profile form of the owned-domain DNS and
680
- email-security audit used by Brand Profiles. It queries registry status and
681
- DNSSEC evidence, nameserver delegation, SPF, DMARC, MX, CAA, MTA-STS, TLS-RPT,
682
- and BIMI directly from the local machine. Literal SPF include and redirect
683
- branches are expanded within fixed depth, policy-query, DNS-term, void-answer,
684
- cycle, and time bounds. External DMARC reporting authorization and external
685
- nameserver, mail, SPF, and reporting dependencies are separately reported.
686
- Supply up to ten known active and retired DKIM selectors in total with
687
- `--selectors selector1,selector2` and `--retired-selectors selector0`;
688
- selectors cannot be reliably discovered from DNS, so no-selector output
689
- reports DKIM as not checked. Use `--mail-profile standard`,
690
- `--mail-profile defensive-no-mail`, or `--mail-profile parked` to make the
691
- intended mail posture explicit rather than inferring it from DNS.
692
-
693
- Terminal output shows each pass, review, action, or informational result and
694
- caps displayed records at five per check with an explicit omission notice.
695
- Versioned JSON retains the complete bounded report, including SPF traversal,
696
- DMARC authorization, and dependency provenance. Warnings and dangers are
697
- findings rather than command failures; transient resolver or policy-fetch
698
- failures remain informational and should be retried before changing DNS.
699
-
700
- ## HTTP intelligence
701
-
702
- `http` runs the same bounded safe homepage probe used by a deep lookup. It
703
- tries HTTPS before HTTP, follows only validated public-network redirects, caps
704
- each attempt at six seconds, and captures at most 300,000 response bytes for
705
- hashing and metadata. A non-success HTTP response still proves that a web
706
- service answered; failure of both schemes remains inconclusive rather than
707
- evidence that no website exists.
708
-
709
- The command reports normalized redirect, response, content, selected security-
710
- header, body-hash, completeness, and attempt provenance. Captured homepage text
711
- is never written to terminal or JSON output. Query strings are removed by the
712
- shared HTTP evidence normalizer, and terminal values are additionally bounded
713
- and control-safe.
714
-
715
- ## TLS intelligence
716
-
717
- `tls` runs the same bounded one-connection TLS collector used by deep lookups.
718
- It resolves the hostname once through the public-address guard, validates every
719
- answer, connects directly to the first validated address on port 443, and keeps
720
- the original hostname for SNI and certificate identity checking. Resolution
721
- and handshake work share a five-second deadline.
722
-
723
- The report retains the negotiated protocol, ALPN and cipher, runtime trust and
724
- hostname checks, certificate validity, bounded subject and issuer names, SANs,
725
- SAN class counts, signature algorithm and OID, extended-key-usage purposes,
726
- classified Authority Information Access presence counts, SHA-256 certificate
727
- and public-key fingerprints, a bounded certificate chain, and neutral
728
- findings. AIA responder and issuer locations are classified as HTTP, HTTPS, or
729
- other and then discarded; they are not retained or followed. The collector
730
- stores no certificate bytes, session material, or application data and does
731
- not enumerate supported protocol or cipher suites.
732
- A failed collection is inconclusive rather than proof that no TLS service
733
- exists.
734
-
735
- ## Registry-source comparison
736
-
737
- `compare` reads one version-1 `whoisleuth.cli.lookup` domain document from a
738
- file or stdin and emits a version-3 `whoisleuth.cli.compare` document. Its
739
- primary comparison reconciles normalized registry RDAP and WHOIS fields. When
740
- the saved deep lookup also represents the optional registrar RDAP follow-up,
741
- an additional sibling comparison reconciles the portable registry and
742
- registrar RDAP publication fields. The command does not repeat the lookup,
743
- contact the hosted deployment, or treat a conflict as a command failure. Use a
744
- deep lookup when multiple sources are wanted; a fast lookup deliberately
745
- records WHOIS as skipped, and comparison preserves that state as unavailable
746
- rather than misreporting RDAP-only publication.
747
-
748
- Input is capped at 8 MiB and must retain the lookup schema, mode, source
749
- diagnostics, and normalized parsed source sections. Per-value, list, and event
750
- bounds are revalidated because saved JSON is treated as untrusted input. A
751
- successful registrar source must include a normalized object and agree with
752
- its diagnostic status. Raw RDAP JSON, registrar contacts and source-specific
753
- handles, WHOIS response bodies, availability evidence, and unrelated lookup
754
- fields are not copied into the comparison result.
755
-
756
- When the saved Lookup contains valid version-5, version-6, or version-7, context-only
757
- registry-access diagnostics, version 3 retains their bounded suffix, access profiles, and
758
- limitation. Terminal output labels the same collection context explicitly.
759
- It explains source reachability only and cannot decide registration,
760
- availability, ownership, safety, or maliciousness. Older documents and saved
761
- lookups without that context do not gain a registry-access field.
762
-
763
- Terminal and versioned JSON output cover domain identity, registry object ID,
764
- registrar, registrar IANA ID, lifecycle dates, DNSSEC, statuses, and name
765
- servers. The shared comparison model normalizes harmless case, punctuation,
766
- ordering, and date-precision differences while distinguishing conflicts,
767
- one-source publication, redaction, incomplete sources, and unavailable
768
- sources. This is source reconciliation, not an availability, ownership, or
769
- maliciousness decision.
770
-
771
- ## Static page comparison
772
-
773
- `page-compare <left.json> <right.json>` reads two different version-1 saved
774
- Deep domain Lookup documents and compares the already-retained static page
775
- identity, exact and perceptual favicon evidence, technology identifiers, TLS
776
- issuer label, and TLS public-key fingerprint. DOM structure is compared first
777
- by its exact bounded tag-sequence digest, then, when both captures provide it,
778
- by a parse5-tokenized structural SimHash. It makes no request and requires
779
- complete supported static page-identity observations on both sides.
780
-
781
- Each page component remains independent. Exact, similar, overlapping,
782
- different, unavailable, and partial evidence are not collapsed into a score.
783
- Matching components are investigative relationships rather than proof of
784
- copying, common ownership, control, intent, safety, or maliciousness. Static
785
- comparison does not execute JavaScript; use the optional local rendered
786
- capture package only when that additional active behavior is authorised.
787
-
788
- ## Passive mail exposure review
789
-
790
- `mail-review [bulk.json|bulk.jsonl]` reads version-2 Bulk output locally and
791
- summarizes MX, null MX, SPF, DMARC, and mail-provider relationships. It keeps
792
- authenticated mail, authentication gaps, incomplete authentication evidence,
793
- no explicit MX, null MX, and incomplete DNS evidence as separate states.
794
- Shared-provider relationships are based only on the registrable domain of an
795
- observed MX hostname and do not establish shared ownership or control.
796
-
797
- The command makes no DNS or SMTP request and retains no source path. It does
798
- not test message acceptance, relay behavior, mailbox existence, catch-all
799
- behavior, SMTP banners, or whether a mail server is rogue, safe, or malicious.
800
-
801
- An analyst may add a bounded `tlsaEvidence` object to a version-2 Bulk item for
802
- offline DANE review. It must name the exact `_25._tcp.<mx-host>` service, and
803
- that host must occur in the same item's retained MX evidence. A certificate
804
- association match is complete only when `dnssecState` is `validated`. TLSA
805
- usages 0 and 1 additionally require `pkixValidationState: "validated"`.
806
- Usages 0 and 2 compare against the bounded `authorityMaterials` array; usages
807
- 1 and 3 compare against the supplied leaf certificate or SPKI. Mismatched
808
- service names, missing certificate roles, unvalidated prerequisites, malformed
809
- material, and truncation remain invalid, partial, or untrusted rather than
810
- becoming a DANE match.
811
-
812
- ## Offline supplied-evidence review
813
-
814
- `review-evidence [evidence.json]` accepts one version-1 JSON input and performs
815
- only deterministic local parsing, comparison, or request planning. Input is
816
- capped at 16 MiB. The command never retrieves DNS, opens SMTP, contacts an
817
- RDAP server, submits a resolver query, or looks up an address in a hosted
818
- GeoIP service.
819
-
820
- Supported input schemas are:
821
-
822
- - `whoisleuth.dnssec-evidence-input`: compares bounded DS and DNSKEY records,
823
- recalculates DNSKEY key tags and supported DS digests, and reviews supplied
824
- RRSIG validity windows at `observedAt`. `consistent` describes only the
825
- supplied DS/DNSKEY relationship. It does not authenticate a chain to a root
826
- trust anchor, validate RRSIG cryptography, or prove that a missing record is
827
- absent.
828
- - `whoisleuth.tlsa-evidence-input`: binds TLSA records to one explicit
829
- `_port._transport.hostname` service and compares supplied leaf or authority
830
- certificate/SPKI bytes. `matched` requires independently validated DNSSEC;
831
- PKIX-TA and PKIX-EE usages also require an independently validated PKIX path.
832
- The command does not retrieve the certificate or negotiate STARTTLS.
833
- - `whoisleuth.rdap-search-input`: normalizes a supplied RDAP search-help
834
- response and prepares an exact supported reverse-search request without
835
- sending it.
836
- - `whoisleuth.rpki-route-input`: compares a route prefix and origin ASN with a
837
- bounded analyst-supplied VRP set.
838
- - `whoisleuth.local-geoip-query`: queries an analyst-supplied bounded prefix
839
- database whose source, version, and licence metadata remain in the result.
840
- - `whoisleuth.encrypted-dns-plan-input`: validates an explicitly reviewed
841
- encrypted-DNS provider contract and prepares a bounded query plan. It does
842
- not execute the plan.
843
-
844
- The common output is `whoisleuth.cli.offline-evidence-review` version 1. It
845
- retains the nested result's explicit state and limitations. A locally
846
- consistent relationship is not converted into a claim about current
847
- publication, ownership, safety, or maliciousness.
848
-
849
- ## Domain control manifests
850
-
851
- `domain-control [input.json]` builds or reviews a bounded desired-state
852
- manifest without making a request or changing configuration. A manifest input
853
- uses `whoisleuth.domain-control-manifest-input` version 1, includes an expiry,
854
- and may record expected nameservers, DS, MX, CAA, TLS issuer, TLS SPKI
855
- fingerprint, registrar-lock preference, and a renewal-review date for up to 100
856
- domains. Empty fields mean unconfigured; they do not require a record to be
857
- absent.
858
-
859
- The emitted `whoisleuth.domain-control-manifest` version 1 is normalized and
860
- protected by a canonical SHA-256 digest. It can also be passed to
861
- `sign-artifact` for an optional local Ed25519 signature. Integrity and
862
- signature verification detect changes and authenticate possession of the
863
- selected key; neither establishes that the desired state is correct.
864
-
865
- A review input uses `whoisleuth.domain-control-review-input` version 1 and
866
- contains one manifest plus separately attributed observations. Only a complete
867
- `observed` field may produce `drift`. Partial, unavailable, unsupported, and
868
- missing observations remain inconclusive, and unrelated observations are
869
- counted but ignored. The review performs no DNS, RDAP, HTTP, TLS, SMTP, or
870
- registrar request.
871
-
872
- ## Fixed investigation plans
873
-
874
- `workflow-plan <recipe> <domain|brand>` turns one of four fixed recipes into a
875
- versioned `whoisleuth.cli.investigation-plan` document. Supported recipes are
876
- `domain-triage`, `lookalike-review`, `owned-domain-review`, and
877
- `historical-comparison`. Each step names an existing CLI command, carries its
878
- arguments as a JSON array, declares whether it is offline or networked, and
879
- marks network-disclosure or analyst-selection approval gates.
880
-
881
- The command is plan-only. It does not execute a step, construct a shell script,
882
- interpret a placeholder as a file path, read an artifact, make a request,
883
- change a case, or submit evidence. Analysts deliberately run selected commands
884
- after reviewing their collection boundaries. This provides repeatable
885
- domain-specific workflows without an arbitrary automation or plugin surface.
886
-
887
- ## Optional local rendered capture
888
-
889
- `packages/web-capture` is a private repo-local Playwright package, not part of
890
- the distributable core CLI or hosted application. It requires an explicit
891
- authorization flag and one new output directory:
177
+ ### Registry capability coverage
892
178
 
893
- ```bash
894
- npm run capture:local -- https://example.test --output-dir ./capture-example --authorize-rendered-capture
895
- npm run capture:compare -- ./official/manifest.json ./candidate/manifest.json --json
896
- ```
179
+ [Read the complete registry capability reference.](cli-reference.md#registry-capability-coverage)
180
+
181
+ ### Offline Risk calibration
182
+
183
+ [Read the calibration dataset and replay contract.](cli-reference.md#offline-risk-calibration)
184
+
185
+ ### Lookalike review-yield calibration
186
+
187
+ [Read the reviewed candidate calibration contract.](cli-reference.md#lookalike-review-yield-calibration)
188
+
189
+ ### Offline artefact verification
190
+
191
+ [Read the archive, saved Lookup, and signed-artefact verification contract.](cli-reference.md#offline-artefact-verification)
192
+
193
+ ### Privacy-safe source reliability report
194
+
195
+ [Read the target-free source diagnostic contract.](cli-reference.md#privacy-safe-source-reliability-report)
196
+
197
+ ### Workspace archive inspection
198
+
199
+ [Read the redacted archive summary, stable content-digest, transfer-check, and
200
+ search contract.](cli-reference.md#workspace-archive-inspection)
201
+
202
+ ### Optional evidence-package signing
203
+
204
+ [Read the local signing and verification contract.](cli-reference.md#optional-evidence-package-signing)
205
+
206
+ ### Reproducible investigation manifest
207
+
208
+ [Read the ordered, path-free artefact digest contract.](cli-reference.md#reproducible-investigation-manifest)
209
+
210
+ ### Bulk lookup
211
+
212
+ [Read Bulk bounds, filters, formats, checkpoints, and cancellation behaviour.](cli-reference.md#bulk-lookup)
213
+
214
+ ### Certificate Transparency search
215
+
216
+ [Read the CT query and source-limit contract.](cli-reference.md#certificate-transparency-search)
217
+
218
+ ### Local certificate event intake
219
+
220
+ [Read the offline, source-qualified event import contract.](cli-reference.md#local-certificate-event-intake)
221
+
222
+ ### Declarative observation interchange
223
+
224
+ [Read the bounded field-mapping and Open Asset Model bridge contracts.](cli-reference.md#declarative-observation-interchange)
225
+
226
+ ### Lookalike discovery
227
+
228
+ [Read candidate generation, dictionaries, snapshots, and output behaviour.](cli-reference.md#lookalike-discovery)
229
+
230
+ ### Supervised candidate scan
231
+
232
+ [Read the bounded candidate collection workflow.](cli-reference.md#supervised-candidate-scan)
233
+
234
+ ### Domain posture audit
235
+
236
+ [Read the DNS, mail, and certificate posture contract.](cli-reference.md#domain-posture-audit)
237
+
238
+ ### HTTP intelligence
239
+
240
+ [Read the bounded HTTP collection contract.](cli-reference.md#http-intelligence)
241
+
242
+ ### TLS intelligence
243
+
244
+ [Read the bounded TLS collection contract.](cli-reference.md#tls-intelligence)
245
+
246
+ ### Registry-source comparison
247
+
248
+ [Read the normalised RDAP and WHOIS comparison contract.](cli-reference.md#registry-source-comparison)
249
+
250
+ ### Static page comparison
251
+
252
+ [Read saved page-identity comparison behaviour.](cli-reference.md#static-page-comparison)
253
+
254
+ ### Passive mail exposure review
255
+
256
+ [Read the saved-evidence mail review contract.](cli-reference.md#passive-mail-exposure-review)
257
+
258
+ ### Offline supplied-evidence review
259
+
260
+ [Read the DNSSEC, DANE, zone-intent, portfolio, domain-change, and supplied-observation review contract.](cli-reference.md#offline-supplied-evidence-review)
261
+
262
+ ### Domain control manifests
263
+
264
+ [Read desired-state manifest and drift-review behaviour.](cli-reference.md#domain-control-manifests)
265
+
266
+ ### Domain assurance review
267
+
268
+ [Read planned-change, recovery-dependency, and retirement contracts.](cli-reference.md#domain-assurance-review)
269
+
270
+ ### Domain change assurance packet
271
+
272
+ [Read the bounded pre-change, post-change, planning, and integrity contract.](cli-reference.md#domain-change-assurance-packet)
273
+
274
+ ### Pre-sharing review
275
+
276
+ [Read the local marking, scope, redaction, and integrity preflight.](cli-reference.md#pre-sharing-review)
277
+
278
+ ### Fixed investigation plans
279
+
280
+ [Read the plan-only recipe contract and approval gates.](cli-reference.md#fixed-investigation-plans)
281
+
282
+ ### Local handoffs and one-shot monitoring
283
+
284
+ [Read brief, case-package, fixed-recipe execution, and one-shot control-review contracts.](cli-reference.md#local-handoffs-and-one-shot-monitoring)
285
+
286
+ ### Optional local rendered capture
287
+
288
+ [Read the separate Playwright capture package boundary.](cli-reference.md#optional-local-rendered-capture)
289
+
290
+ ### Lookup evidence export
291
+
292
+ [Read normalised JSON, Markdown, and HTML export behaviour.](cli-reference.md#lookup-evidence-export)
293
+
294
+ ## Safety and limitations
897
295
 
898
- It writes a fixed 1024x768 PNG, screenshot SHA-256 and perceptual dHash, a DOM
899
- digest containing hashes and bounded element counts rather than markup or page
900
- text, and a version-2 `whoisleuth.web-capture-manifest` compatible with the
901
- Cases importer. Version-1 manifests remain importable.
902
-
903
- Rendered capture executes page JavaScript. It caps HTTP(S) requests and request
904
- hostnames, blocks downloads, service workers, WebSockets, non-read methods,
905
- credentials, non-default ports, and private or reserved addresses, and retains
906
- no request path, query, headers, bodies, cookies, credentials, DOM markup, or
907
- page text. The browser connection is not pinned to the address checked before
908
- each hostname's first request, so DNS rebinding remains a residual risk. Use a
909
- disposable network-restricted environment for untrusted targets.
910
-
911
- The separate offline comparison command accepts two selected version-2 local
912
- capture manifests. It first verifies each referenced screenshot and DOM digest
913
- against its declared size, SHA-256, screenshot dimensions, and perceptual hash;
914
- it also validates bounded source and limitation metadata and requires the DOM,
915
- manifest, and source collection times to agree. It then
916
- compares screenshot distance, exact rendered DOM and visible-text digests,
917
- bounded element counts, page identity, technologies, and request-domain sets.
918
- It does not recrawl either target, reveal the input paths, or collapse the
919
- independent components into a similarity or maliciousness score. A missing
920
- perceptual hash remains unavailable rather than becoming a visual difference.
921
-
922
- ## Lookup evidence export
923
-
924
- `export` converts one version-1 `whoisleuth.cli.lookup` domain document from a
925
- file or stdin into the same versioned `whoisleuth.lookup-evidence` JSON package
926
- produced by the web Lookup tool. It performs no lookup and writes only to
927
- stdout, so use ordinary shell redirection when a file is wanted. Pretty JSON is
928
- the default; `--compact` emits one compact JSON line for pipeline use, while
929
- `--markdown` produces a readable source-attributed summary and `--html`
930
- produces a self-contained printable report. Compact, Markdown, and HTML output
931
- are mutually exclusive.
932
-
933
- The saved input is capped at 8 MiB and revalidated using the same schema,
934
- source-status, parsed-data, scalar, list, and event boundaries as `compare`.
935
- The export retains query context, source diagnostics, normalized registry data,
936
- raw registry RDAP JSON, the raw WHOIS referral chain, availability analysis,
937
- and the shared registry-source comparison. Version 23 can add the exact local
938
- SSLBL comparison already represented by a deep full Lookup. Version 21 adds the bounded registry
939
- lifecycle, disclosure, publication-quality, reconciliation, and abuse-routing
940
- interpretation derived from the already-collected sources. Registrar RDAP raw
941
- data, contacts, entities, links, notices, and source-specific handles remain
942
- excluded. Schema version 20 replaces selected security-policy values in
943
- retained HTTP evidence
944
- with presence-only markers and can include fixed response-policy findings from
945
- an already-represented deep lookup. Version 19 additionally retains the bounded credential-surface projection
946
- when the saved deep lookup represents it. Version 18 retains the bounded structured identity projection
947
- when the saved deep lookup represents it. Version 17 retains the normalized portable-field comparison, explicit
948
- source-health states, a strict bounded projection of observed network
949
- registration, an optional normalized security.txt disclosure source, HTTPS
950
- service-binding publications, and the passive browser-library profile when the
951
- saved deep lookup represents them. Raw IP RDAP payloads, security.txt response
952
- bodies, script references, matched script content, and contact entities remain
953
- excluded.
954
-
955
- Markdown output summarizes query context, assessment state, registry sources,
956
- source reconciliation, network observations, and collection diagnostics. It
957
- escapes all upstream text as untrusted content, bounds displayed values and
958
- lists, and deliberately omits raw RDAP JSON and full WHOIS response bodies.
959
- Use JSON when the complete evidence package or machine processing is required.
960
- The browser Console reuses this bounded Markdown renderer for domain results
961
- after first reducing the typed Lookup response to the known normalized fields
962
- needed by the report. It separately offers bounded IP and ASN summaries from
963
- their normalized RDAP and source-health fields; IP reports can also include
964
- bounded reverse-DNS context already collected by Lookup. The browser action
965
- does not change the CLI input or output contract.
966
- When a version-5, version-6, or version-7 lookup records a documented registry-access constraint, both
967
- Markdown and HTML include that context in collection diagnostics without
968
- changing its non-authoritative interpretation. Both formats also include the
969
- selected address and bounded network registration when present, together with
970
- the edge-versus-origin limitation.
971
-
972
- HTML uses the same bounded summary model as Markdown. The generated document
973
- contains inline styling for screen and print, but no scripts, forms, active
974
- links, or external resources. A restrictive embedded Content Security Policy
975
- provides defense in depth when the local file is opened in a browser. All
976
- registry values are HTML-escaped and displayed as text.
977
-
978
- This is a deliberately rich evidence package. Raw registry sources can contain
979
- publicly published contact data, and deep availability evidence can contain
980
- bounded website, DNS, mail, page-identity, and TLS observations. Review and
981
- secure the output before sharing it. The CLI does not add browser-only IDN
982
- profile analysis, so that optional evidence field is `null`.
296
+ WHOISleuth is a defensive investigation tool, not an authorisation mechanism.
297
+ Operators remain responsible for applicable law, registry and provider terms,
298
+ and permission to assess a target. Missing, unsupported, partial, or failed
299
+ evidence never establishes absence, availability, safety, ownership, or intent.
300
+ Offline analyst assertions remain separately attributed and are not converted
301
+ into observed facts.