@slicedearth/whoisleuth-cli 2.4.0 → 2.6.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 (340) hide show
  1. package/DISCLOSURE +1 -1
  2. package/NOTICE +2 -2
  3. package/cli/argument-values.mjs +55 -0
  4. package/cli/arguments.mjs +24 -470
  5. package/cli/artifact-validation/case-response.mjs +67 -9
  6. package/cli/artifact-validation/lookup-evidence.mjs +18 -4
  7. package/cli/artifact-validation/signed-review.mjs +61 -64
  8. package/cli/artifact-verify.mjs +11 -2
  9. package/cli/assurance-arguments.mjs +56 -0
  10. package/cli/assurance-command-definitions.mjs +179 -0
  11. package/cli/assurance-command-runner.mjs +1 -1
  12. package/cli/bounded-json.mjs +1 -1
  13. package/cli/bulk-checkpoint.mjs +1 -1
  14. package/cli/bulk-command-runner.mjs +6 -8
  15. package/cli/bulk.mjs +2 -3
  16. package/cli/case-command.mjs +99 -6
  17. package/cli/case-pack.mjs +19 -4
  18. package/cli/ci-report.mjs +6 -3
  19. package/cli/collection-arguments.mjs +123 -0
  20. package/cli/collection-command-definitions.mjs +330 -0
  21. package/cli/collection-preflight.mjs +8 -1
  22. package/cli/command-argument-grammar.mjs +8 -210
  23. package/cli/command-definition.mjs +330 -0
  24. package/cli/command-reference.mjs +55 -1388
  25. package/cli/command-seeds.mjs +18 -0
  26. package/cli/compare.mjs +1 -1
  27. package/cli/config-profile.mjs +1 -1
  28. package/cli/ct-event-intake.mjs +4 -4
  29. package/cli/discover.mjs +2 -2
  30. package/cli/discovery-observation-snapshot.mjs +2 -2
  31. package/cli/discovery-scan-command-runner.mjs +7 -9
  32. package/cli/discovery-scan.mjs +1 -1
  33. package/cli/discovery-snapshot.mjs +2 -2
  34. package/cli/discovery-workflow.mjs +4 -4
  35. package/cli/domain-control-monitor.mjs +6 -6
  36. package/cli/domain-control-observations.mjs +2 -1
  37. package/cli/domain-feed.mjs +61 -0
  38. package/cli/errors.mjs +5 -6
  39. package/cli/evidence-arguments.mjs +46 -0
  40. package/cli/evidence-command-definitions.mjs +69 -0
  41. package/cli/evidence-command-runner.mjs +2 -3
  42. package/cli/evidence-signing.mjs +3 -2
  43. package/cli/external-observation-mapping.mjs +2 -2
  44. package/cli/formatters/json.mjs +1 -13
  45. package/cli/formatters/terminal-command-formats.mjs +6 -0
  46. package/cli/formatters/terminal-lookup.mjs +6 -0
  47. package/cli/history-arguments.mjs +39 -0
  48. package/cli/history-command-definitions.mjs +88 -0
  49. package/cli/indicator-set-command.mjs +32 -0
  50. package/cli/inline-command-families.mjs +6 -47
  51. package/cli/inline-command-runner.mjs +4 -31
  52. package/cli/input.mjs +2 -2
  53. package/cli/intake-command.mjs +147 -0
  54. package/cli/interchange-report.mjs +4 -2
  55. package/cli/investigation-artifacts.mjs +3 -4
  56. package/cli/investigation-package-review.mjs +2 -0
  57. package/cli/investigation-plan.mjs +32 -154
  58. package/cli/investigation-recipes.mjs +177 -0
  59. package/cli/investigation-run.mjs +78 -12
  60. package/cli/local-mmdb-review.mjs +220 -17
  61. package/cli/lookalike-calibration.mjs +1 -1
  62. package/cli/lookup-brief.mjs +2 -2
  63. package/cli/lookup-command-runner.mjs +19 -35
  64. package/cli/lookup-diff.mjs +10 -9
  65. package/cli/lookup-plan.mjs +10 -14
  66. package/cli/lookup-reconcile.mjs +6 -5
  67. package/cli/lookup-timeline.mjs +7 -6
  68. package/cli/mail-header-review.mjs +24 -247
  69. package/cli/mail-review.mjs +9 -7
  70. package/cli/network-arguments.mjs +51 -0
  71. package/cli/network-command-definitions.mjs +130 -0
  72. package/cli/network-command-runner.mjs +43 -31
  73. package/cli/offline-evidence-review.mjs +85 -6
  74. package/cli/posture.mjs +1 -1
  75. package/cli/registry-fixture-scaffold.mjs +1 -1
  76. package/cli/retained-artifact-diff.mjs +8 -7
  77. package/cli/review-arguments.mjs +132 -0
  78. package/cli/review-command-definitions.mjs +279 -0
  79. package/cli/review-command-runner.mjs +72 -159
  80. package/cli/risk-calibration.mjs +14 -12
  81. package/cli/runner.mjs +20 -32
  82. package/cli/saved-lookup.mjs +2 -2
  83. package/cli/selected-input-worker.mjs +73 -0
  84. package/cli/sharing-review.mjs +5 -64
  85. package/cli/source-reliability.mjs +2 -2
  86. package/cli/support-arguments.mjs +49 -0
  87. package/cli/support-command-definitions.mjs +209 -0
  88. package/cli/support-command-runner.mjs +4 -4
  89. package/cli/watchlist-review.mjs +43 -0
  90. package/cli/workflow-arguments.mjs +100 -0
  91. package/cli/workflow-command-definitions.mjs +103 -0
  92. package/cli/workflow-command-runner.mjs +40 -1
  93. package/docs/cli-reference.md +27 -0
  94. package/docs/cli.md +322 -4
  95. package/docs/contextual-reviews.md +178 -0
  96. package/docs/infrastructure-observations.md +126 -0
  97. package/docs/offline-intake-context.md +213 -0
  98. package/lib/analyst-taxonomy.mjs +2 -40
  99. package/lib/application-version.mjs +1 -1
  100. package/lib/availability.mjs +13 -789
  101. package/lib/bounded-contract-normalizers.mjs +4 -0
  102. package/lib/bounded-json.mjs +2 -330
  103. package/lib/browser-library-profile.mjs +62 -84
  104. package/lib/candidate-provenance-bounds.mjs +2 -0
  105. package/lib/classify.mjs +1 -1
  106. package/lib/credential-form-attribution.mjs +136 -0
  107. package/lib/credential-surface-profile.mjs +6 -2
  108. package/lib/ct-query.mjs +2 -27
  109. package/lib/ct-response-bounds.mjs +2 -9
  110. package/lib/ct-search.mjs +83 -47
  111. package/lib/dmarc-discovery.mjs +62 -0
  112. package/lib/dns-convergence-review.mjs +21 -8
  113. package/lib/dns-delegation-health.mjs +35 -15
  114. package/lib/dns-inheritance-review.mjs +53 -63
  115. package/lib/dns-intelligence.mjs +27 -11
  116. package/lib/dns-query-coverage.mjs +40 -0
  117. package/lib/domain-assurance.mjs +1 -1
  118. package/lib/domain-change-packet.mjs +12 -13
  119. package/lib/domain-change-review.mjs +32 -14
  120. package/lib/domain-control-flight-recorder.mjs +103 -27
  121. package/lib/domain-control-manifest.mjs +25 -17
  122. package/lib/domain-posture-analysis.mjs +75 -7
  123. package/lib/domain-posture-parsers.mjs +9 -0
  124. package/lib/domain-posture.mjs +45 -25
  125. package/lib/domain-registration.mjs +392 -0
  126. package/lib/evidence-export-privacy.mjs +27 -17
  127. package/lib/evidence-export.mjs +3 -3
  128. package/lib/evidence-report.mjs +5 -1
  129. package/lib/external-intelligence-risk.mjs +2 -124
  130. package/lib/favicon.mjs +13 -4
  131. package/lib/generated/cisa-kev-catalog.mjs +41 -3
  132. package/lib/generated/registrar-standing-catalogue.mjs +18 -10
  133. package/lib/generated/retire-browser-catalog.mjs +332 -19
  134. package/lib/generated/{unicode-confusables-17.mjs → unicode-confusables.mjs} +33 -33
  135. package/lib/html-signals.mjs +13 -2
  136. package/lib/http-evidence-bounds.mjs +2 -8
  137. package/lib/http-intelligence.mjs +13 -1
  138. package/lib/idn-confusable-policy.mjs +6 -4
  139. package/lib/idn-confusables.mjs +1 -1
  140. package/lib/interchange-fidelity-registry.mjs +10 -0
  141. package/lib/lookup-child-profile-contract.mjs +28 -11
  142. package/lib/lookup-contract-primitives.mjs +1 -1
  143. package/lib/lookup-diagnostics.mjs +1 -23
  144. package/lib/lookup-network-evidence-bounds.mjs +1 -10
  145. package/lib/lookup-progress.mjs +50 -1
  146. package/lib/lookup-response-contract.mjs +70 -40
  147. package/lib/lookup-response.mjs +5 -15
  148. package/lib/lookup-source-progress.mjs +8 -22
  149. package/lib/lookup.mjs +1 -1
  150. package/lib/operation-budget.mjs +4 -0
  151. package/lib/opportunity-scoring.mjs +2 -107
  152. package/lib/outbound-identity.mjs +1 -1
  153. package/lib/page-fingerprints.mjs +18 -1
  154. package/lib/perceptual-hash-comparison.mjs +2 -34
  155. package/lib/perceptual-hash.mjs +36 -10
  156. package/lib/portable-generator.mjs +2 -29
  157. package/lib/project-metadata.mjs +2 -8
  158. package/lib/rdap-client.mjs +11 -7
  159. package/lib/registrable-domain.mjs +2 -56
  160. package/lib/registrar-standing-contract.mjs +1 -1
  161. package/lib/registrar-standing.mjs +9 -13
  162. package/lib/registry-capabilities.mjs +2 -2
  163. package/lib/registry-capability-catalogue.mjs +27 -19
  164. package/lib/risk-calibration-summary.mjs +2 -352
  165. package/lib/risk-scoring.mjs +2 -345
  166. package/lib/scoring-evidence-quality.mjs +2 -107
  167. package/lib/semantic-version.mjs +2 -54
  168. package/lib/service-binding-dns.mjs +46 -2
  169. package/lib/smtp-transport-review.mjs +48 -19
  170. package/lib/sslbl-certificates.generated.mjs +142 -139
  171. package/lib/static-html-analysis.mjs +32 -4
  172. package/lib/structured-data-identity.mjs +1 -1
  173. package/lib/technology-evidence-role.mjs +1 -51
  174. package/lib/threat-intelligence-manifests.mjs +1 -1
  175. package/lib/threat-intelligence-runtime.mjs +1 -1
  176. package/lib/threat-intelligence-targets.mjs +1 -1
  177. package/lib/threat-intelligence-types.mjs +2 -75
  178. package/lib/tls-intelligence.mjs +30 -5
  179. package/lib/typosquat-generator.mjs +11 -2
  180. package/lib/website-enrichment.mjs +404 -0
  181. package/lib/whois-authority.mjs +43 -5
  182. package/lib/whois-chain.mjs +12 -3
  183. package/lib/whois-common-formats.mjs +3 -1
  184. package/lib/whois-contacts.mjs +13 -2
  185. package/lib/whois-normalization.mjs +3 -1
  186. package/lib/whois-parser.mjs +5 -3
  187. package/package.json +15 -14
  188. package/packages/analysis/analyst-taxonomy.mjs +40 -0
  189. package/packages/analysis/bounded-json.mjs +330 -0
  190. package/packages/analysis/candidate-provenance-bounds.mjs +4 -0
  191. package/packages/analysis/cli-argument-grammar.mjs +216 -0
  192. package/packages/analysis/ct-query.mjs +27 -0
  193. package/packages/analysis/ct-response-bounds.mjs +9 -0
  194. package/packages/analysis/external-intelligence-risk.mjs +124 -0
  195. package/packages/analysis/http-evidence-bounds.mjs +8 -0
  196. package/packages/analysis/lookup-network-evidence-bounds.mjs +10 -0
  197. package/packages/analysis/opportunity-scoring.mjs +107 -0
  198. package/packages/analysis/perceptual-hash-comparison.mjs +34 -0
  199. package/packages/analysis/portable-generator.mjs +29 -0
  200. package/packages/analysis/project-metadata.mjs +8 -0
  201. package/packages/analysis/registrable-domain.mjs +56 -0
  202. package/packages/analysis/risk-calibration-summary.mjs +352 -0
  203. package/packages/analysis/risk-scoring.mjs +348 -0
  204. package/packages/analysis/scoring-evidence-quality.mjs +107 -0
  205. package/packages/analysis/semantic-version.mjs +54 -0
  206. package/packages/analysis/threat-intelligence-types.mjs +75 -0
  207. package/packages/cases/case-containment-handoff.mjs +195 -0
  208. package/packages/cases/case-evidence-links.mjs +151 -0
  209. package/packages/cases/case-evidence-model.mjs +89 -12
  210. package/packages/cases/case-evidence-quality.mjs +5 -0
  211. package/packages/cases/case-export-input.mjs +7 -5
  212. package/packages/cases/case-incident-context.mjs +52 -0
  213. package/packages/cases/case-markdown.mjs +11 -0
  214. package/packages/cases/case-migration-model.mjs +40 -24
  215. package/packages/cases/case-object-coverage.mjs +33 -0
  216. package/packages/cases/case-packet-correction.mjs +106 -0
  217. package/packages/cases/case-recheck-model.mjs +124 -36
  218. package/packages/cases/case-record-contracts.mjs +1 -1
  219. package/packages/cases/case-record-core.mjs +1 -1
  220. package/packages/cases/case-record-operations.mjs +111 -118
  221. package/packages/cases/case-record-projection.mjs +23 -4
  222. package/packages/cases/case-record-version-input.mjs +41 -0
  223. package/packages/cases/case-report.mjs +93 -27
  224. package/packages/cases/case-requested-evidence.mjs +146 -0
  225. package/packages/cases/case-response-actions.mjs +159 -1
  226. package/packages/cases/case-response-model.mjs +16 -1
  227. package/packages/cases/case-response-object.mjs +119 -0
  228. package/packages/cases/case-response-outcomes.mjs +108 -20
  229. package/packages/cases/case-response-packet-render.mjs +35 -12
  230. package/packages/cases/case-response-packet.mjs +55 -13
  231. package/packages/cases/case-response-records.mjs +0 -1
  232. package/packages/cases/case-response-review-inputs.mjs +60 -8
  233. package/packages/cases/case-storage-model.mjs +1 -1
  234. package/packages/cases/case-workflow-metadata.mjs +217 -0
  235. package/packages/cases/case-workflow-migration.mjs +43 -0
  236. package/packages/cases/http-summary.mjs +6 -1
  237. package/packages/comparison/favicon-similarity.mjs +1 -1
  238. package/packages/comparison/page-similarity.mjs +1 -1
  239. package/packages/comparison/relationship-evidence.mjs +21 -9
  240. package/packages/comparison/relationship-provenance.mjs +7 -1
  241. package/packages/contracts/analyst-interchange.mjs +35 -15
  242. package/packages/contracts/candidate-watch-review.mjs +54 -0
  243. package/packages/contracts/case-portability.mjs +360 -49
  244. package/packages/contracts/cli-command-semantics.mjs +5 -0
  245. package/packages/contracts/cli-grammar.mjs +6 -0
  246. package/packages/contracts/cli-lookup-brief.mjs +2 -0
  247. package/packages/contracts/context-review.mjs +25 -0
  248. package/packages/contracts/document-intake.mjs +11 -0
  249. package/packages/contracts/domain-control-flight-recorder.mjs +30 -14
  250. package/packages/contracts/domain-control-manifest.mjs +1 -1
  251. package/packages/contracts/domain-control-monitor.mjs +13 -2
  252. package/packages/contracts/domain-control-review.mjs +36 -15
  253. package/packages/contracts/external-observation-interchange.mjs +96 -28
  254. package/packages/contracts/har-review.mjs +2 -0
  255. package/packages/contracts/identity-events.mjs +4 -0
  256. package/packages/contracts/investigation-run.mjs +2 -0
  257. package/packages/contracts/ip-address.mjs +10 -0
  258. package/packages/contracts/lookup-evidence.mjs +3 -2
  259. package/packages/contracts/mail-authentication.mjs +5 -0
  260. package/packages/contracts/message-intake.mjs +37 -0
  261. package/packages/contracts/offline-comparison.mjs +4 -1
  262. package/packages/contracts/passive-mail.mjs +10 -0
  263. package/packages/contracts/risk-calibration.mjs +44 -29
  264. package/packages/contracts/schema-lifecycle.mjs +3 -1
  265. package/packages/contracts/web-capture.mjs +2 -2
  266. package/packages/contracts/workspace-portability.mjs +144 -28
  267. package/packages/evidence/collection-quality.mjs +67 -0
  268. package/packages/evidence/credential-form-attribution.mjs +60 -0
  269. package/packages/evidence/dns-query-outcome.mjs +72 -0
  270. package/packages/evidence/email-recipient.mjs +18 -0
  271. package/packages/evidence/image-regions.mjs +15 -0
  272. package/packages/evidence/lookup-target.mjs +5 -1
  273. package/packages/evidence/observation.mjs +2 -0
  274. package/packages/evidence/png-pixels.mjs +117 -0
  275. package/packages/evidence/public-address-policy.mjs +83 -0
  276. package/packages/evidence/record-identity.mjs +60 -16
  277. package/packages/evidence/technology-evidence-role.mjs +51 -0
  278. package/packages/interchange/defensive-indicator-export.mjs +264 -0
  279. package/packages/interchange/external-findings-import.mjs +36 -29
  280. package/packages/interchange/json-output.mjs +14 -0
  281. package/packages/interchange/managed-indicator-export.mjs +36 -0
  282. package/packages/interchange/managed-indicator-set.mjs +223 -0
  283. package/packages/interchange/misp-indicator-export.mjs +93 -0
  284. package/packages/interchange/sharing-policy.mjs +56 -0
  285. package/packages/interchange/stix-indicator-export.mjs +129 -0
  286. package/packages/interchange/web-capture-import.mjs +22 -15
  287. package/packages/investigation/acquisition-decision-packet.mjs +79 -1
  288. package/packages/investigation/bulk-mail-exposure.mjs +7 -13
  289. package/packages/investigation/capture-coverage.mjs +57 -0
  290. package/packages/investigation/connector-provenance-review.mjs +100 -0
  291. package/packages/investigation/context-review.mjs +35 -0
  292. package/packages/investigation/document-intake.mjs +87 -0
  293. package/packages/investigation/docx-intake.mjs +133 -0
  294. package/packages/investigation/domain-history-review.mjs +132 -0
  295. package/packages/investigation/domain-transition-review.mjs +49 -0
  296. package/packages/investigation/evidence-coverage-ledger.mjs +9 -1
  297. package/packages/investigation/har-intake.mjs +68 -0
  298. package/packages/investigation/identity-event-intake.mjs +131 -0
  299. package/packages/investigation/identity-incident-review.mjs +39 -0
  300. package/packages/investigation/incident-sequence-review.mjs +58 -0
  301. package/packages/investigation/infrastructure-observation.mjs +234 -0
  302. package/packages/investigation/intake-context.mjs +284 -0
  303. package/packages/investigation/intake-indicators.mjs +116 -0
  304. package/packages/investigation/intake-phones.mjs +155 -0
  305. package/packages/investigation/intake-report.mjs +20 -0
  306. package/packages/investigation/investigation-manifest.mjs +35 -9
  307. package/packages/investigation/link-intake.mjs +209 -0
  308. package/packages/investigation/lookup-asset-graph.mjs +1 -1
  309. package/packages/investigation/mail-authentication-review.mjs +222 -0
  310. package/packages/investigation/mail-header-identity.mjs +209 -0
  311. package/packages/investigation/message-intake.mjs +235 -0
  312. package/packages/investigation/page-behaviour.mjs +113 -0
  313. package/packages/investigation/pdf-intake.mjs +155 -0
  314. package/packages/investigation/platform-continuity-review.mjs +60 -0
  315. package/packages/investigation/qr-intake.mjs +56 -0
  316. package/packages/investigation/requested-action-hints.mjs +11 -0
  317. package/packages/investigation/selected-input-review.mjs +17 -0
  318. package/packages/investigation/storefront-review.mjs +70 -0
  319. package/packages/monitoring/domain-feed.mjs +321 -0
  320. package/packages/workspace/brand-candidate-workflow.mjs +351 -0
  321. package/packages/workspace/brand-keyword-campaign.mjs +231 -0
  322. package/packages/workspace/brand-profile-model.mjs +48 -4
  323. package/packages/workspace/bulk-review-model.mjs +28 -26
  324. package/packages/workspace/bulk-session-model.mjs +27 -13
  325. package/packages/workspace/campaign-model.mjs +1 -1
  326. package/packages/workspace/candidate-watch-handoff.mjs +195 -0
  327. package/packages/workspace/detection-rule-model.mjs +11 -3
  328. package/packages/workspace/hostile-input.mjs +1 -1
  329. package/packages/workspace/investigation-guide.mjs +2 -2
  330. package/packages/workspace/investigation-template-model.mjs +26 -2
  331. package/packages/workspace/page-baseline.mjs +2 -2
  332. package/packages/workspace/relationship-observation-model.mjs +17 -13
  333. package/packages/workspace/shortlist-model.mjs +24 -7
  334. package/packages/workspace/watchlist-history.mjs +59 -16
  335. package/packages/workspace/watchlist-store.mjs +152 -11
  336. package/packages/workspace/website-snapshot-model.mjs +28 -3
  337. package/packages/workspace/workspace-archive-crypto.mjs +1 -1
  338. package/packages/workspace/workspace-archive.mjs +5 -4
  339. package/third-party-notices.txt +549 -16
  340. package/lib/hostname.mjs +0 -2
package/docs/cli.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # WHOISleuth CLI guide
2
2
 
3
+ `review-evidence` also reviews bounded source-qualified infrastructure snapshots and explicit earlier/later comparison inputs entirely offline. See [infrastructure observations](infrastructure-observations.md) for the exact schemas, outcome semantics and retained-evidence limitations.
4
+
3
5
  The first-party CLI runs on the operator's machine and does not call the hosted
4
6
  WHOISleuth deployment. Use this guide for installation, common commands,
5
7
  collection boundaries and output. Installed `whoisleuth --help`, focused
@@ -7,6 +9,11 @@ collection boundaries and output. Installed `whoisleuth --help`, focused
7
9
  version. The [CLI reference](cli-reference.md) covers durable command and
8
10
  artefact contracts.
9
11
 
12
+ The [website command reference](https://www.whoisleuth.com/cli) starts with common
13
+ tasks, then offers searchable commands with examples, option explanations and
14
+ defaults. Command-section links can be bookmarked. Its option guidance and
15
+ installed help derive from the same command definitions.
16
+
10
17
  The generated [privacy and data-flow catalogue](https://github.com/slicedearth/whoisleuth/blob/main/docs/privacy-data-flow-catalogue.md)
11
18
  lists the network, recipient, retention and export boundary for every command.
12
19
 
@@ -80,6 +87,11 @@ offline CLI workflow below.
80
87
  When several incident Cases share a domain, select the intended Case before
81
88
  retaining replay evidence. Case packs preserve each current Case ID separately;
82
89
  trusted and public packs exclude analyst-entered incident titles.
90
+ Every audience retains tags, decision summaries and rationale as well as domain
91
+ evidence and Case, pin and decision IDs. Public does not mean anonymous.
92
+ Browser Lookup evidence can be verified or packaged in the CLI. `brief`,
93
+ `export`, `compare`, `registry-doctor` and `source-report` instead require a
94
+ saved CLI Lookup; they do not reconstruct it from a browser export.
83
95
 
84
96
  Process selected local input:
85
97
 
@@ -96,6 +108,18 @@ One strict domain, IP address or ASN can occupy command position as Lookup
96
108
  shorthand. URL-like or ambiguous input requires the explicit `lookup` command.
97
109
  Only `bulk` accepts multiple targets.
98
110
 
111
+ For a downloaded plain-domain feed, use
112
+ `whoisleuth domain-feed review nrd7 feed.txt --select term:example --json`.
113
+ Repeat `--select exclude:literal` to veto a literal substring before the result
114
+ bound, including for exact-host selections. At most 20 positive and 20 negative
115
+ terms of 3–80 characters are supported; at least one positive term or exact host
116
+ is required. Matching uses canonical ASCII/punycode text without token, typo,
117
+ confusable or regular-expression expansion. These offline selectors do not infer
118
+ saved browser campaign identity or default priority.
119
+ This is an offline literal match, not a feed download or target Lookup. The
120
+ [candidate-review guide](https://github.com/slicedearth/whoisleuth/blob/main/docs/brand-candidate-review.md#review-a-domain-feed) covers
121
+ source attribution and the separate Watchlist handoff.
122
+
99
123
  `discover` accepts a brand label or registrable domain and supports multi-part
100
124
  public suffixes in `--tlds` (for example, `co.uk,com.au`). It preserves the full
101
125
  suffix and does not collect candidate evidence; use `discover-scan` only after
@@ -136,6 +160,132 @@ their focused help. They do not use the hosted login or hosted usage controls.
136
160
  `lookup --plan` lists planned source families and disclosure targets before
137
161
  collection. `doctor` is offline unless `--network` is selected.
138
162
 
163
+ Deep Lookup reports IPv4 and IPv6 results separately, including empty answers,
164
+ NODATA, resolver-reported missing names and query failures. These outcomes remain
165
+ distinct in evidence exports; none alone establishes domain removal.
166
+
167
+ Plans are target-specific: Fast IP and ASN plans contain RDAP only; Deep IP
168
+ adds WHOIS and eligible reverse DNS, while Deep ASN adds WHOIS. Domain-only web,
169
+ TLS and selected intelligence do not apply to address or ASN targets.
170
+ Plans do not probe source health or measure remaining quota, cost, result fan-out
171
+ or exact request counts. CLI configuration profiles repeat supported settings;
172
+ optional selections made on the website do not transfer to a CLI command.
173
+ For completed website results, see [Source quality](https://github.com/slicedearth/whoisleuth/blob/main/docs/application-guide.md#lookup).
174
+
175
+ ### Message and link intake
176
+
177
+ Use `intake email message.eml --json` for MIME email and nested messages,
178
+ `intake calendar invitation.ics`, `intake qr selected.png`, or `intake text`
179
+ with text on standard input. These commands never open a destination or execute
180
+ supplied content. Output compares displayed and actual hosts, retains reported
181
+ header authentication and interprets supplied authorisation parameters without
182
+ retaining URL tokens. The source hash identifies the original bytes.
183
+ Defanged schemes and hosts are accepted, including `hxxps[:]//host[.]example`.
184
+ Path, query and fragment characters keep their supplied meaning; text scanning
185
+ removes unmatched surrounding prose brackets, while explicit links remain exact.
186
+
187
+ Add a repeatable `--reported-action`, such as `entered_device_code` or
188
+ `granted_consent`, to include account-recovery guidance based on an explicitly
189
+ reported action. The report does not infer a stolen session from domain evidence.
190
+ `--strict-exit` returns 4 for a partial review. QR review supports still PNGs;
191
+ no decoded result is not proof that a symbol is absent.
192
+ Excluded links and unsupported QR payloads make the review partial, with
193
+ category counts rather than private payload text. Bare QR hostnames are not
194
+ automatically treated as URLs.
195
+
196
+ Current message-intake reports also retain bounded literal IPv4/IPv6 and
197
+ explicitly labelled MD5, SHA-1 and SHA-256 observations from supported body and
198
+ document text. Each observation links to its selected source part and digest;
199
+ it is not a Lookup target, file identification or threat verdict. Complete URLs,
200
+ message headers, QR payloads, HAR and identity-event fields are excluded from
201
+ this text scan. Historical version-1 reports do not acquire new observations.
202
+
203
+ Use `intake text selected.txt --intake-context context.json --json` to add an
204
+ explicit analyst-supplied distribution declaration. The separate context file
205
+ is limited to 8 KiB and cannot use stdin. Its channel, non-sensitive source
206
+ label and optional declared time, reference, observer and vantage labels are
207
+ included in the output, not verified as delivery or capture conditions. See
208
+ [selected-input indicators and declarations](offline-intake-context.md) for the
209
+ exact schema, privacy exclusions and extraction bounds.
210
+
211
+ Plain-text phone discovery reports only candidate counts, the source digest and
212
+ UTF-16 selection ranges to standard error; unselected numbers do not enter JSON
213
+ output. Use a version-2 `--intake-context` file to select exact ranges and declare
214
+ their source, basis, role and known time. The same optional file can supply a
215
+ displayed/destination pair for local hostname comparison. See the
216
+ [selection example](offline-intake-context.md#select-phone-observations-in-the-cli).
217
+ `--quiet` suppresses discovery guidance, and `--strict-exit` reports partial
218
+ phone coverage as well as other incomplete intake work.
219
+
220
+ ### Local IP-location database review
221
+
222
+ `review-evidence query.json --mmdb selected.mmdb --json --strict-exit` reads
223
+ one analyst-selected database locally. It never downloads, updates or transmits
224
+ the database. A current query uses this input:
225
+
226
+ ```json
227
+ {
228
+ "schema": "whoisleuth.local-mmdb-query",
229
+ "version": 2,
230
+ "address": "192.0.2.1",
231
+ "sourceLabel": "Selected local database",
232
+ "databaseVersion": "Analyst-declared edition",
233
+ "license": "Analyst-declared licence",
234
+ "freshnessPolicy": {
235
+ "maxAgeDays": 90,
236
+ "rationale": "Quarterly research review; recheck before operational use"
237
+ }
238
+ }
239
+ ```
240
+
241
+ Replace the reserved example address with the public IP under review. Reserved
242
+ and private addresses are unavailable in current reviews. Select and justify an
243
+ age limit appropriate to the task; the example is not a default or an accuracy
244
+ guarantee. The policy requires positive whole days and a plain-text rationale
245
+ of at most 240 characters. The command's review time is compared with the
246
+ intrinsic build time; a future build, stale database, unsupported format/type,
247
+ miss or unusable record cannot supply current location context. Malformed
248
+ fields remain unknown, with partial coverage when other useful fields survive.
249
+
250
+ Current output retains SHA-256 of the exact read bytes, byte length, intrinsic
251
+ database type, build time, binary format and IP version. Analyst source, version
252
+ and licence labels remain separate claims. Only coarse network, country, region,
253
+ city and ASN attribution can be returned; no raw record or local path is included.
254
+ The existing version-1 review envelope contains the self-described
255
+ `whoisleuth.local-mmdb-review` version-1 result. Reject future result versions
256
+ rather than treating them as current evidence.
257
+
258
+ The file must remain a regular, stable file of at most 512 MiB. After the bounded
259
+ read and digest, one disposable worker limits synchronous parsing and lookup to
260
+ ten seconds, with bounded heap/stack and an 8 KiB result. This is not a ten-second
261
+ whole-command or filesystem deadline. Default exit 0 means a report was produced;
262
+ `--strict-exit` returns 4 for unavailable or partial current reviews. Version-1
263
+ queries retain their historical JSON shape and exit behaviour, without intrinsic
264
+ metadata or freshness admission; terminal output identifies that limitation.
265
+
266
+ ### Contextual reviews
267
+
268
+ `review-evidence` also accepts [contextual review inputs](contextual-reviews.md)
269
+ for source-qualified incident sequences, retained domain history, platform-object continuity, authorised storefront
270
+ comparison and connector provenance. These workflows are offline; partial
271
+ context reviews return 4 when `--strict-exit` is selected. Browser-generated
272
+ reusable inputs use the same validators.
273
+
274
+ Domain-history input version 2 adds analyst-declared registration, deletion,
275
+ re-registration, transfer or review boundaries linked to retained snapshot or
276
+ pin IDs. Version 1 remains supported with its original output. Boundaries prompt
277
+ reassessment; they do not establish ownership or discard prior evidence.
278
+
279
+ `review-evidence containment.json --json --strict-exit` accepts a
280
+ `whoisleuth.internal-containment.input` version-1 document containing a supported
281
+ Case export, selected next-step assertion and linked pin IDs, internal or trusted
282
+ audience, recipient role and an explicit disclosure-review acknowledgement.
283
+ It exports only that selected handoff, never writes the Case or performs a
284
+ control. Missing or unselected supporting context stays partial (exit 4 under
285
+ `--strict-exit`), and a resolved Case or provider outcome does not close an open
286
+ internal follow-up. See [internal containment](offline-intake-context.md#selected-internal-containment-handoff)
287
+ for the complete input and audience limitations.
288
+
139
289
  ### Message-header review
140
290
 
141
291
  `mail-headers` parses only the bounded header block from a selected message file
@@ -145,11 +295,87 @@ reported order. It makes no request and does not retain address local parts,
145
295
  display names, subject, body, attachments, or raw header values in its output.
146
296
  Authentication states are header claims, not an independent DNS or
147
297
  cryptographic validation, and alignment differences can be legitimate.
298
+ Both `mail-headers` and `intake email` preserve individual authentication header
299
+ positions and service identifiers. Evaluate the receiver boundary yourself; to
300
+ record trust in one exact header, add `--trusted-auth-header 1:3` (message part 1,
301
+ header 3). Repeat for separate headers. This annotates the supplied claim without
302
+ validating it or extending trust to matching service names or nested messages.
303
+
304
+ `intake pdf selected.pdf`, `intake docx selected.docx` and `intake har selected.har`
305
+ use the same offline review as the browser. Document results include part hashes,
306
+ page references and extraction coverage. Encrypted documents require a separately
307
+ decrypted copy; no password is requested. HAR results preserve file order and
308
+ reported timings, with unavailable values distinct from zero. Neither document
309
+ resources nor recorded requests are fetched. Add `--strict-exit` for exit 4 when
310
+ coverage is partial, and `--json` for the minimised report.
311
+
312
+ `intake identity events.json --json` reads an Entra sign-in `value` array or an
313
+ Okta System Log array. To record a scoped comparison, wrap the selected provider
314
+ records in this input (timestamps require an explicit timezone):
315
+
316
+ ```json
317
+ {
318
+ "schema": "whoisleuth.identity-events.input",
319
+ "version": 1,
320
+ "provider": "entra",
321
+ "events": [],
322
+ "match": {
323
+ "applicationId": "11111111-1111-4111-8111-111111111111",
324
+ "tenantId": null,
325
+ "actorLabel": null,
326
+ "startedAt": "2026-01-01T00:00:00Z",
327
+ "endedAt": "2026-01-01T01:00:00Z"
328
+ }
329
+ }
330
+ ```
331
+
332
+ Replace `events` with the selected records. Actor labels apply only within that
333
+ file; missing fields stay unavailable. The source hash identifies the complete
334
+ selected file, including an envelope when supplied. No provider API is contacted.
148
335
 
149
336
  ## Output and automation
150
337
 
151
338
  ### Local Case files
152
339
 
340
+ Manual response scope is explicit and offline. `case incident-link` takes
341
+ `{"url":"https://example.test/reported-page"}`; use its retained ID to bind
342
+ `responseObjects` on `case action`. Each object contains `kind`, `identifier`
343
+ and `incidentTargetId` (null for the Case domain or an associated hostname).
344
+ New URL objects must match that exact retained link. Exact historical identities
345
+ already retained in response records remain selectable after a link edit or
346
+ removal; they are not rebound to its replacement. An action may bind up to 20
347
+ objects; missing historical scope stays unknown.
348
+
349
+ `case action-event` takes `{"id":"action-id","transition":{...}}`, using
350
+ the same reviewed, authorised and manually submitted workflow as Console.
351
+ After submission, a typed `objectOutcome` such as `removed`, `restricted`,
352
+ `suspended`, `delisted`, `restored` or `disputed` requires explicit event
353
+ `responseObjects`: a partial receipt never applies to all objects by default.
354
+ Acknowledgement is a workflow event, not independently observed remediation.
355
+
356
+ A self-initiated correction uses a new `case action`, with `originActionId`
357
+ identifying the original action and `responseObjects` selecting a subset of that
358
+ delivery's exact objects. Its `correction` block identifies one delivery event,
359
+ packet digest/version and profile, plus the purpose (`correction` or
360
+ `retraction_request`), reason, previous and corrected statements, and retained
361
+ evidence-pin IDs. This is separate from `amendment`, which still requires an
362
+ actual provider-request event. The correction must match a retained typed packet
363
+ receipt on the selected delivery; a historical free-text digest alone is
364
+ insufficient. The usual recipient, authority and disclosure review then applies
365
+ to the new draft. The original packet and delivery remain unchanged.
366
+
367
+ `case recheck-question` saves `statement` and `recheck` comparison conditions.
368
+ Pins, questions and recheck input can retain one `responseObject`; exact-object
369
+ non-reproduction requires matching complete baseline/current evidence, a later
370
+ observation and comparable conditions. Hostname similarity is insufficient.
371
+ Independent removal, restriction, suspension, delisting, transfer and restoration
372
+ use those same comparison requirements. Disputes and warnings retain procedural
373
+ source attribution separately; provider claims are not independent observations.
374
+ `case close-object` requires one `responseObject` and the usual typed closure
375
+ reason/evidence links. It leaves the Case and other objects unchanged.
376
+ All these JSON operations require `--input`, `--output`, deliberate file
377
+ replacement and the existing digest/lease checks. No report or request is sent.
378
+
153
379
  Create a working file, inspect its Case IDs, then append a note:
154
380
 
155
381
  ```sh
@@ -162,14 +388,20 @@ Use `--case-id` when the file contains several Cases. `open` reuses the selected
162
388
  Case; `--new-incident --title "Another incident"` creates a distinct ID for the
163
389
  same domain. It does not open a browser or collect anything.
164
390
 
165
- `pin`, `assess` and `recheck` read a selected JSON file with `--input`:
391
+ `pin`, `link`, `withdraw-link`, `assess` and `recheck` read a selected JSON file with `--input`:
166
392
 
167
393
  ```sh
168
394
  whoisleuth case pin cases.json --input pin.json --output cases.json --force
395
+ whoisleuth case link cases.json --input relationship.json --output cases.json --force
169
396
  whoisleuth case assess cases.json --input assessment.json --output cases.json --force
170
397
  whoisleuth case recheck cases.json --input recheck.json --output cases.json --force
171
398
  ```
172
399
 
400
+ For `link`, use `fromPinId`, `toPinId`, `kind` (`derived_from` or
401
+ `shared_source`) and `basis`. `withdraw-link` takes the relationship `id` and
402
+ `reason`; its original declaration remains in the file. `case show` lists the
403
+ identities and `--json` includes the full history.
404
+
173
405
  A pin describes the supplied observation, not a new collection. For example:
174
406
 
175
407
  ```json
@@ -255,12 +487,17 @@ An ordinary Case JSON file alone provides structural validity, not a checksum.
255
487
  They use generated entry names, not original paths. Ordinary ZIPs and folders
256
488
  are private and unencrypted; packaging does not redact selected files. The report distinguishes
257
489
  file identity, supported source formats, opaque content, exact capsule/source
258
- links and capture-manifest attachment matches. Include the capture manifest and
490
+ links, declared image derivation and capture-manifest attachment matches.
491
+ Image derivation reports an immediate-parent digest and byte length, editing
492
+ method and operation kinds, not proof of transformation. Parent inclusion matches
493
+ another selected manifest entry by exact byte digest and size; an unselected Case
494
+ attachment reference does not count. Parent pixels are optional; absent declarations
495
+ leave editing history unknown. Include the capture manifest and
259
496
  its screenshot/DOM-digest files together to check their declared bytes; original
260
497
  filenames are not needed to establish a match. It does not import files or establish source truth, signature trust or a
261
498
  trusted timestamp. Unsupported or rejected entries produce a partial report;
262
499
  `--strict-exit` returns 4. Without `--package` or `--folder`, `manifest` produces a
263
- standalone JSON manifest; exact public version-2 manifests remain readable.
500
+ standalone JSON manifest; exact version-2 and version-3 manifests remain readable.
264
501
 
265
502
  For [BagIt 1.0](https://www.rfc-editor.org/rfc/rfc8493.html) interchange, use
266
503
  `--bagit` with `--package` or `--folder` on both commands:
@@ -316,6 +553,17 @@ selected evidence exports, not complete workspace backups.
316
553
 
317
554
  ### Resuming a fixed workflow
318
555
 
556
+ Inspect a paused run without executing any step or rewriting its checkpoint:
557
+
558
+ ```sh
559
+ whoisleuth workflow-run domain-triage example.test --resume run.json --preview --json
560
+ ```
561
+
562
+ The preview separates validated complete and partial outputs, failed steps that
563
+ can be retried, unresolved inputs, pending upstream outputs and fresh approval
564
+ requirements. It does not open selected input files. Preview output goes to
565
+ stdout; approval, interactive and output-file flags cannot be combined with it.
566
+
319
567
  All recipes listed by `workflow-plan --list` can run through `workflow-run`.
320
568
  Planning remains offline. Execution emits a checkpoint; terminal output shows
321
569
  retained steps, output identities, missing inputs and the next required action.
@@ -348,6 +596,12 @@ remain analyst selections. No external file is inferred or extracted automatical
348
596
  disagreement and unavailable evidence separate. Distinct labels do not verify
349
597
  independent collection; timing and shared caches can affect the comparison.
350
598
 
599
+ `domain-control-flight-recorder` retains the last comparable complete observation
600
+ across failed or partial collections. A changed recovery records the interval
601
+ between complete source observations; it does not assign the change to the
602
+ recovery time. An approved window must contain that entire interval. Historical
603
+ report versions remain readable without acquiring this newer qualification.
604
+
351
605
  For example, registry review can reuse its collection without extracting files:
352
606
 
353
607
  ```sh
@@ -385,6 +639,52 @@ an interrupted process, confirm that its owner has stopped before removing its
385
639
  abandoned lock. Locks have no automatic expiry. Shell redirection and external
386
640
  editors do not participate in this cooperative file-ownership protocol.
387
641
 
642
+ ### Managed indicator revisions
643
+
644
+ `indicator-set` uses the same file-backed revision model as Bulk. It performs
645
+ no collection or submission. A plan names the set, gives a review `basis` and
646
+ UTC `expiresAt`, and supplies `rows` plus an explicit `selectedDomains` list.
647
+ Rows use the normal Bulk eligibility rules, including available profile
648
+ context, a Suspicious or Confirmed abuse disposition and retained risk evidence.
649
+ Supply `officialDomains`, `allowlistedDomains` and `commonInfrastructureDomains`
650
+ where applicable; excluded candidates never become additions.
651
+
652
+ Example plan shape (fictional input; replace the evidence and expiry):
653
+
654
+ ```json
655
+ {
656
+ "name": "Reviewed candidates",
657
+ "basis": "Reviewed the selected page observation",
658
+ "expiresAt": "2026-10-23T00:00:00.000Z",
659
+ "selectedDomains": ["candidate.example.test"],
660
+ "rows": [{
661
+ "domain": "candidate.example.test", "availability": "registered",
662
+ "analystDisposition": "suspicious", "risk": 80,
663
+ "profileContext": { "sourceState": "ready" }
664
+ }]
665
+ }
666
+ ```
667
+
668
+ ```sh
669
+ whoisleuth indicator-set revise indicator-plan.json --json --output indicators-r1.json
670
+ whoisleuth indicator-set inspect indicators-r1.json
671
+ whoisleuth verify-artifact indicators-r1.json --strict-exit
672
+ whoisleuth indicator-set stix indicators-r1.json --output indicators-r1.stix.json
673
+ whoisleuth indicator-set misp indicators-r1.json --output indicators-r1.misp.json
674
+ ```
675
+
676
+ Later plans embed the last manifest as `previous` and explicitly list `renewIds`
677
+ or `withdrawIds`. New domains still require reviewed rows and selection.
678
+ `reintroduceDomains` permits a previously withdrawn domain to receive a new
679
+ identity; it never revives the old one. Missing domains stay unchanged.
680
+ Renewal updates the review window and note, not the original observation.
681
+
682
+ Keep previous manifests and use separate output paths. File ownership checks
683
+ reject concurrent source/destination changes and refuse replacing the input,
684
+ even with `--force`. STIX and MISP operations always emit JSON. MISP expiry is
685
+ a review deadline, not automatic deletion; exports require separate recipient
686
+ review. Digests verify content, not authorship or an unavailable earlier chain.
687
+
388
688
  ### Formats and exit behaviour
389
689
 
390
690
  Terminal text is the default. Commands expose JSON, JSONL, CSV, Markdown, HTML
@@ -414,7 +714,20 @@ diagnostics, and missing health metadata remains unmeasured.
414
714
  collection times visible. Source-output and review-generation times do not
415
715
  stand in for missing observation times. `domain-change` and
416
716
  `domain-change-packet` retain authority, resolver and certificate observation
417
- times; previously published version-2 packets remain verifiable.
717
+ times; previously published version-2 and version-3 packets remain verifiable.
718
+ Current DNS convergence and domain-change inputs use version 2. Each snapshot
719
+ declares `queries`, for example
720
+ `[{"owner":"example.test","type":"MX","state":"observed"}]`.
721
+ An `observed` query with no matching records means an empty answer; `partial`
722
+ and `unavailable` queries do not. Omitted queries are not queried. Version-1
723
+ inputs remain readable but establish query scope only for supplied records.
724
+ An expected empty set alone cannot establish an observed empty answer.
725
+
726
+ Domain-control review version 3 keeps renewal reminders separate from observed
727
+ configuration: `due` and `not_due` describe the chosen review date, not DNS or
728
+ registration changes. Incomplete evidence remains `partial` even when a reminder
729
+ is due. Terminal and JUnit summaries report due reminders separately. Previous
730
+ review and monitor checkpoints retain their original versioned interpretation.
418
731
 
419
732
  ## Exit codes
420
733
 
@@ -426,6 +739,11 @@ For scripts, use `whoisleuth verify-artifact evidence.json --json --strict-exit`
426
739
  An incomplete verification returns **4** with that option. Without it, **0**
427
740
  means a report was produced, not that the artefact passed verification; inspect
428
741
  the report's state and checks.
742
+ Unencrypted workspace archives retain mutable root metadata outside their
743
+ section digests, so they return 4 under `--strict-exit` even when all supported
744
+ section checks pass. Structure-only exports can pass their narrower contract;
745
+ strict exit is not a ranking of cryptographic assurance. `interchange-report`
746
+ separately describes import/export support and is not the full verifier inventory.
429
747
 
430
748
  ## Command details
431
749
 
@@ -0,0 +1,178 @@
1
+ # Contextual evidence reviews
2
+
3
+ Cases → Evidence → **Specialist evidence reviews** offers incident-sequence, domain-history,
4
+ platform-object, storefront and connector reviews. Inputs stay in page memory until you
5
+ save or download. Saved reports use the existing Case attachment and evidence
6
+ summary controls; select the report file explicitly when preparing a response
7
+ packet. Switching tasks or Case sections preserves opened drafts; leaving the Case
8
+ discards them. Save the review in the Case, download its JSON, or print a summary.
9
+ Reusable inputs are a separate download. Storefront columns keep unreviewed fields
10
+ distinct from reviewed fields with no values; platform histories separate report
11
+ status, provider response and independent recheck. Sources and interpretation are
12
+ available beneath each review, with exact observation times and citation copying.
13
+
14
+ The CLI uses the same models:
15
+
16
+ ```sh
17
+ whoisleuth review-evidence selected-input.json --json --strict-exit
18
+ ```
19
+
20
+ Each input has `schema`, a supported `version` and `evidence`. Most inputs use
21
+ version 1; domain history also supports version 2 as described below. Unknown
22
+ versions and fields are rejected. Inputs are bounded to 16 MiB; each supplied context list permits
23
+ 200 records. `--strict-exit` returns 4 for a partial contextual review. Neither
24
+ adapter contacts a destination or executes selected software.
25
+
26
+ ## Incident sequence
27
+
28
+ Build an analyst-ordered sequence from retained Case pins, imported records and
29
+ reported actions. A retained pin supplies its own source, time, completeness and
30
+ limitations; unknown times stay unknown. Reordering is deliberate, and reversed
31
+ timestamps are flagged without rewriting the sequence. A displayed instruction
32
+ is not recorded as a person having followed it.
33
+
34
+ Schema: `whoisleuth.incident-sequence.input`. `evidence` is an array:
35
+
36
+ ```json
37
+ {
38
+ "schema": "whoisleuth.incident-sequence.input", "version": 1,
39
+ "evidence": [{
40
+ "id": "stage-1", "kind": "credential_entry", "basis": "reported_action",
41
+ "description": "The reporter entered a password into the displayed form.",
42
+ "occurredAt": null, "hostname": "example.test",
43
+ "source": "Reporter interview", "reference": "interview-17",
44
+ "referenceSha256": null, "completeness": "unknown",
45
+ "limitations": ["Event time not supplied."]
46
+ }]
47
+ }
48
+ ```
49
+
50
+ Kinds cover messages, navigation, identity prompts, credential entry, consent,
51
+ browser instructions, clipboard events, local execution, payment, recovery and
52
+ other events. Basis is `retained_observation`, `imported_record` or
53
+ `reported_action`. Reference hashes identify the supplied record; they do not
54
+ authenticate its source. Save the reusable input with the review to continue
55
+ later. These stages never execute a command, submit a form or open a destination.
56
+
57
+ ## Domain history and retirement
58
+
59
+ The Case view compares retained snapshots using the existing source, hostname,
60
+ scan-depth and model-version rules. Registration, DNS, mail and web changes are
61
+ shown alongside source-qualified certificate pins.
62
+ Registration and nameserver changes target the Case registration domain; mail
63
+ and web changes target the explicit observation hostname. Certificate pins keep
64
+ their own hostname, or an unknown target when none was retained. These targets
65
+ are preserved in review downloads, retained reports and print previews.
66
+ Equal-time observations are not ordered into a change sequence. Retired dependencies must involve the Case
67
+ domain or one of its hostnames. An expected window qualifies the review; it does
68
+ not approve a change automatically or establish transfer or takeover.
69
+ Review prompts connect comparable page, mail, delegation and registration changes
70
+ to the retained concern. Incomplete comparisons remain visible. A changed creation
71
+ date asks for reassessment of earlier decisions without asserting a new owner,
72
+ resetting a baseline or discarding history; expiry alone never establishes deletion.
73
+
74
+ Schema: `whoisleuth.domain-history.input`. Its `evidence` contains:
75
+
76
+ - `caseExport`: an ordinary supported editable Case export, with `version` and
77
+ `cases`; the exact existing Case reader rejects data loss or silent repair.
78
+ - `caseId`: the Case selected from that export.
79
+ - `declarations`: `expectedChanges` and `retiredDependencies` arrays; version 2
80
+ also requires `registrationBoundaries`. Version 1 remains readable unchanged.
81
+
82
+ An expected change is `{family, start, end, reason}`. A retired dependency is
83
+ `{asset, dependency, family, retiredAt, source}`. Families are `registration`,
84
+ `dns`, `mail`, `certificate` and `web`; times are explicit ISO timestamps. The
85
+ reusable input download includes the selected Case and is not duplicated in
86
+ workspace storage when saving the report.
87
+
88
+ Version-2 registration boundaries are analyst declarations, not confirmed
89
+ registration epochs. Each has `{kind, occurredAt, source, rationale,
90
+ snapshotIds, evidencePinIds}`. Kinds are `registration_reported`,
91
+ `deletion_reported`, `reregistration_reported`, `transfer_reported` and
92
+ `review_boundary`. Supply an explicit ISO time and at least one exact reference
93
+ to a snapshot or evidence pin retained in the selected Case. References must be
94
+ unique; unavailable references fail rather than selecting a replacement.
95
+ Up to 40 boundaries and 20 references of each type per boundary are accepted.
96
+
97
+ The Case history form exposes the same declarations. Reports count retained
98
+ observations before and at/after a declared time without assigning ownership or
99
+ asserting that deletion, re-registration or transfer occurred. Earlier evidence,
100
+ decisions, exceptions and open follow-ups are not rewritten. Reports retain the
101
+ declared source and exact evidence references, and can be deliberately saved as
102
+ ordinary Case files. The reusable input remains a separate download containing
103
+ the selected Case, not an additional workspace copy.
104
+
105
+ ## Platform objects
106
+
107
+ Schema: `whoisleuth.platform-continuity.input`. `evidence` is an array:
108
+
109
+ ```json
110
+ {
111
+ "schema": "whoisleuth.platform-continuity.input",
112
+ "version": 1,
113
+ "evidence": [{
114
+ "platformOrigin": "https://platform.example.test",
115
+ "objectType": "extension", "objectId": "extension-17", "version": "1.0.0",
116
+ "observedAt": "2026-09-22T00:00:00.000Z", "source": "Selected manifest",
117
+ "report": "acknowledged", "providerOutcome": "provider_reports_resolved",
118
+ "recheck": "not_checked", "recheckedAt": null
119
+ }]
120
+ }
121
+ ```
122
+
123
+ Object types include account, tenant, application, extension, package, page,
124
+ channel and post. Identity is scoped to platform origin and object type, not a
125
+ URL alone. Version is nullable. Report status is `not_reported`, `submitted` or
126
+ `acknowledged`. Provider outcomes and independent rechecks use the existing Case
127
+ response vocabulary. A recheck needs its own time; provider resolution does not
128
+ establish removal. Save or download the reusable input to add later observations.
129
+
130
+ ## Storefronts
131
+
132
+ Schema: `whoisleuth.storefront-review.input`. `evidence` contains `official`,
133
+ `candidate`, `authorisedComparator: true`, `resellerStatus` and `resellerSource`.
134
+ Reseller status is `authorised`, `not_authorised` or `unknown`; a non-unknown
135
+ declaration needs a source. Both observations use this shape:
136
+
137
+ ```json
138
+ {
139
+ "hostname": "shop.example.test",
140
+ "observedAt": "2026-09-22T00:00:00.000Z", "source": "Selected capture",
141
+ "brandNames": ["Example shop"], "contactDomains": ["example.test"],
142
+ "policyHashes": null, "checkoutOrigins": ["https://checkout.example.test"],
143
+ "paymentMethods": ["card"], "assetHashes": null
144
+ }
145
+ ```
146
+
147
+ Null means not reviewed; an empty array means no values were recorded. Policy
148
+ and asset hashes are lowercase hexadecimal SHA-256. Checkout values are origins
149
+ only. Exact shared values are displayed without a combined scam score. Check
150
+ reseller, affiliate and regional-store authority before preparing a complaint.
151
+
152
+ ## Connectors
153
+
154
+ Schema: `whoisleuth.connector-review.input`. `evidence` contains `current` and
155
+ nullable `previous` configuration objects, each with exactly one `mcpServers`
156
+ or `servers` map. Select that section rather than unrelated application settings.
157
+
158
+ ```json
159
+ {
160
+ "schema": "whoisleuth.connector-review.input", "version": 1,
161
+ "evidence": {
162
+ "current": {"mcpServers": {
163
+ "remote": {"url": "https://connector.example.test/service"},
164
+ "local": {"command": "npx", "args": ["--yes", "@example/connector@1.0.0"]}
165
+ }},
166
+ "previous": null
167
+ }
168
+ }
169
+ ```
170
+
171
+ The browser accepts the configuration itself. Reports retain names, endpoint
172
+ origins, executable basenames, recognised package identities, declared
173
+ capabilities and metadata counts. They exclude local paths, argument contents,
174
+ environment values, header values, authentication material and URL paths or
175
+ queries. Raw configuration is not saved with the report. Matching retained
176
+ metadata does not mean excluded values are unchanged. No command, connector,
177
+ tool, prompt or model is run; declarations are not negotiated capabilities or a
178
+ safety assessment.