@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
@@ -0,0 +1,126 @@
1
+ # Source-qualified infrastructure snapshots
2
+
3
+ The retained infrastructure inventory combines admitted browser-local evidence,
4
+ not all infrastructure belonging to an organisation. It makes no requests on
5
+ import, opening a view, filtering, selecting a host or comparing history.
6
+
7
+ Import a `whoisleuth.infrastructure-observation` version 1 document through the
8
+ existing external-findings import. The exact bounded snapshot is retained as one
9
+ Case evidence pin. Review the preview before confirming the mutation. The source
10
+ descriptions are supplied provenance, not authenticated source identities.
11
+ Legacy DNS and certificate imports remain readable: an old Case-domain DNS pin
12
+ does not acquire a precise queried hostname or complete collection scope.
13
+
14
+ The document records an explicit target, selected full hostnames and DNS types,
15
+ collection mode, observation time and coverage. Each DNS response retains its
16
+ queried name, response owner, type, outcome and source. An alias link uses its
17
+ record owner; an address returned after an alias belongs to the returned address
18
+ owner, not automatically to the initial query. Only retained alias links are
19
+ drawn. Links from different dates do not prove one contemporaneous alias chain.
20
+ No-data, NXDOMAIN, failed and not-checked outcomes remain different observations
21
+ and do not decide registration availability.
22
+
23
+ Certificate-log and TLS observations keep distinct sources and exact SHA-256
24
+ identities. Full names remain visible; `*.example.test` is a wildcard pattern,
25
+ not an enumerated hostname, and cannot be selected for Lookup or Bulk.
26
+ Certificate names alone do not establish current resolution or activity.
27
+
28
+ DNS operator, observed edge/CDN/proxy, application platform, runtime, embedded
29
+ dependency, address registration, routing origin and independently observed
30
+ origin are distinct source-qualified roles. Routing requires a routing source;
31
+ IP-registration data cannot substitute for it. Edge indicators cannot identify
32
+ a hidden origin. Multiple providers and conflicting observations remain separate.
33
+ The snapshot reader does not derive physical location, responsibility, ownership,
34
+ safety or maliciousness from these roles.
35
+
36
+ ## Review and deliberately act
37
+
38
+ Open the inventory from saved-work search. Type, source and date filters apply to
39
+ the admitted set before pagination. Inspect one snapshot to review every retained
40
+ DNS outcome, certificate name and provider role, or select two snapshots in
41
+ chronological order to compare. Export preserves the exact snapshot format.
42
+ Topology search applies to the complete admitted one-hop relationship set, not
43
+ the current source page. Its diagram has a 50-relationship budget; the paginated
44
+ source list and exact snapshot review retain access to evidence beyond the diagram.
45
+
46
+ Lookup links fill the selected target for review without submitting it. Explicitly
47
+ selected hostnames can be prepared in existing Bulk. That handoff does not scan,
48
+ recursively expand targets, change a watchlist or enrol a host in monitoring.
49
+ Use the existing reviewed Lookup/Bulk/Monitor collection plans and explicit
50
+ save actions to collect or retain another observation.
51
+
52
+ ## Historical comparison and CLI
53
+
54
+ Source, mode and exact selection scope must match, and the later snapshot must
55
+ have a strictly later observation time. Newly observed means newly present in
56
+ retained evidence, not newly created. A value not returned by a complete,
57
+ comparable selected collection is labelled **not returned**, never confirmed
58
+ absence or disappearance. Failed, partial, limited, changed-source and
59
+ incomparable snapshots cannot generate removal findings. Equal-time observations
60
+ have no temporal order. Provider-reported history stays labelled separately from
61
+ supplied local observations.
62
+
63
+ Comparison rows retain the exact DNS query, response owner and record type, or
64
+ the certificate SHA-256, alongside their source and observation clocks. Labels
65
+ are presentation only: relationship groups and graph exports use canonical
66
+ entity identities, including when long nameserver-set labels look identical.
67
+
68
+ Derived relationship-group, graph-node and cluster IDs can change when their
69
+ identity calculation changes, including for short labels. They are not durable
70
+ cross-export keys; use the canonical `entityId` where provided. Historical groups
71
+ without it use their complete retained value. Graph fields named `canonical`
72
+ and `value` are bounded display text, not a replacement for that identity. Inspect
73
+ the contributing Case evidence for full nameserver members. Component selections
74
+ and cluster adjustments are transient and are not persisted review history.
75
+
76
+ In GraphML and GEXF, the display label for `node_canonical` is now
77
+ `Bounded display value` (previously `Canonical value`). The field key, JSON
78
+ property, entity identities and values are unchanged; XML consumers should use
79
+ the field key rather than its display label.
80
+
81
+ The existing offline command shares the website reader and comparison owner:
82
+
83
+ ```sh
84
+ whoisleuth review-evidence infrastructure-observation.json --json
85
+ whoisleuth review-evidence infrastructure-comparison.json --json
86
+ ```
87
+
88
+ The comparison input is exactly:
89
+
90
+ ```json
91
+ {
92
+ "schema": "whoisleuth.infrastructure-comparison.input",
93
+ "version": 1,
94
+ "earlier": { "...": "complete version-1 snapshot" },
95
+ "later": { "...": "complete version-1 snapshot" }
96
+ }
97
+ ```
98
+
99
+ The placeholders above are illustrative, not valid evidence. See the reserved
100
+ fixture in `test/fixtures/infrastructure-observations/` for an exact snapshot.
101
+ The CLI performs no DNS, registry, BGP, TLS, HTTP or provider request.
102
+
103
+ Changed or incomplete latest retained pairs surface as existing local Review
104
+ Items with supporting Case navigation. Complete earlier snapshots remain
105
+ available as stronger baselines; later failures do not rewrite them. There is no
106
+ new history store or scheduling engine.
107
+
108
+ ## Resource and compatibility boundary
109
+
110
+ One snapshot is limited to 128 KiB, 128 selected hostnames, six DNS types, 16
111
+ source identities, 512 DNS response rows with at most 32 values each, 32
112
+ certificate observations with at most 128 exact names each, 128 role observations
113
+ and 12 bounded limitations. Bounds reject oversized documents rather than
114
+ silently prune accepted snapshot evidence. Existing Case/workspace quotas still
115
+ apply. Projection/diagram budgets may admit a smaller disposable view, with
116
+ incomplete coverage disclosed; exact snapshot review/export remains available.
117
+
118
+ Version 1 has exact keys and refuses future versions. Existing external-findings
119
+ version 4 and typed version-1 row imports preserve their historical meaning;
120
+ version 5 adds the optional exact infrastructure snapshot. No external discovery
121
+ API, new provider, dependency, collector or automatic request is required.
122
+ Current snapshot and version-5 findings exports use compact UTF-8 JSON with a
123
+ terminal line feed so the emitted representation stays within its parser ceiling.
124
+ An offline comparison input is bounded to two snapshot budgets plus 1 KiB of
125
+ framing. Historical version-4 fixture bytes and reader meaning remain unchanged;
126
+ new typed row conversions emit version 5.
@@ -0,0 +1,213 @@
1
+ # Selected-input indicators and internal containment
2
+
3
+ Message intake remains local and inert. It does not resolve indicators, open
4
+ links, consult reputation services, execute attachments or apply controls.
5
+
6
+ ## Source-linked indicator review
7
+
8
+ Version 2 of `whoisleuth.message-intake` adds literal IPv4/IPv6 observations and
9
+ explicitly labelled MD5, SHA-1 and SHA-256 strings from selected plain text,
10
+ message body text, supported calendar fields and extracted document text.
11
+ Private and reserved addresses are valid textual observations, not permission
12
+ to contact them. A labelled hash string is a supplied claim, not proof that a
13
+ file has that digest. Bare opaque hexadecimal values are not interpreted.
14
+
15
+ Each indicator identifies its input/message/document part and page when known.
16
+ The review retains the source-byte and part digests separately. Identical values
17
+ from different parts remain separately attributed; repeated identical values
18
+ within one part are deduplicated. The UI can copy a source citation. Indicators
19
+ are not added to Lookup targets and do not become a risk score or finding.
20
+
21
+ Complete URL spans, address local parts, recognised credential-bearing lines,
22
+ message headers and QR payloads are not scanned for indicators. MIME HTML
23
+ extraction also excludes script and style nodes. Explicit plaintext is literal
24
+ supplied text: an IP inside a pasted code snippet can be an inert observation;
25
+ the code is never executed. Phone candidates have their own stricter markup
26
+ exclusions. HAR and identity-event imports keep their existing restricted
27
+ projections: no broad scan of their original fields occurs. Extraction is
28
+ limited to 512 observations, 4,096 candidate checks and 2,097,152 text code
29
+ units across an input. Reached bounds are partial coverage, never proof that
30
+ no further indicators exist.
31
+
32
+ Version-1 reports remain readable without invented indicator coverage. Their
33
+ original source digests do not acquire new observations retrospectively.
34
+
35
+ ### Supplied phone candidates
36
+
37
+ Plain-text intake can also identify possible telephone numbers, including a
38
+ support number in a supplied snippet with no link. Candidates are review leads:
39
+ they do not authenticate a caller, identify an operator or establish wrongdoing.
40
+ No number is dialled, resolved or checked against a reputation service.
41
+
42
+ Review and select each observation deliberately before including it in a saved
43
+ review. Unselected candidates remain transient. The selected observation keeps
44
+ its original spelling, source digest and exact text range, not the surrounding
45
+ snippet. Text ranges use zero-based, end-exclusive UTF-16 code-unit offsets;
46
+ supplementary characters occupy two units. A declared source time is separate
47
+ from the local review time. Identify manual transcription or OCR-derived text
48
+ when that is how the supplied text was obtained.
49
+
50
+ The browser provides a shared declaration for selected occurrences. Open
51
+ **Declaration for candidate** to override a source label, role, observation time
52
+ or text basis for one occurrence. Apply or clear edits before saving or
53
+ downloading; only equivalent numbers with equivalent declarations share a group.
54
+
55
+ An advertised support contact and a sender or caller-ID claim describe different
56
+ roles; neither verifies ownership. International formatting can be compared only
57
+ where its prefix and supported separators permit a defensible normalisation.
58
+ National-format numbers, conflicting country context and unsupported characters
59
+ remain uncertain. Extensions are separate, not appended to the destination.
60
+ Dates, identifiers and unsupported forms must not be treated as verified numbers.
61
+
62
+ Selected numbers can still be private contacts. Review the selected content
63
+ before saving or sharing it. Ordinary public/trusted Case projections do not
64
+ include the private intake attachment; domain-focused interchange does not invent
65
+ a telephone mapping. A missing exported phone observation is not evidence that
66
+ none was supplied.
67
+
68
+ ### Compare a displayed claim with a supplied destination
69
+
70
+ Use the intake's manual destination comparison when supplied ad, search or
71
+ screenshot material shows one destination and a separate source supplies another.
72
+ Identify each source, any known observation time, and whether its text is a claim,
73
+ transcription or supplied observation. The comparison uses the same safe hostname
74
+ parsing as an HTML link's displayed-host comparison.
75
+
76
+ Review the exact hostname and registrable boundary. A hostname such as
77
+ `store.example.test.attacker.invalid` is not `store.example.test`. Legitimate
78
+ tracking destinations can also differ. Missing, malformed or credential-bearing
79
+ input leaves insufficient evidence rather than inventing a redirect chain.
80
+
81
+ Exact entered URLs stay in the private transient view. Retained output uses the
82
+ minimised hostname/origin projection and supplied qualifications, not private
83
+ paths, query values or fragments. Comparing the pair never follows either URL
84
+ and does not establish that a redirect occurred.
85
+
86
+ ## Optional distribution declarations
87
+
88
+ After reviewing input in Lookup or a Case, open **Declare distribution
89
+ context**. Supply a channel, non-sensitive source label and optional declared
90
+ time, reference, observer and vantage labels. Apply or clear changed declarations
91
+ before saving or downloading. These are analyst claims, not verified delivery,
92
+ capture conditions, network location or independent collection. The local review
93
+ time remains separate from a declared observation time.
94
+
95
+ The CLI accepts the same explicit declaration:
96
+
97
+ ```sh
98
+ whoisleuth intake text selected.txt --intake-context context.json --json
99
+ ```
100
+
101
+ ```json
102
+ {
103
+ "schema": "whoisleuth.intake-context",
104
+ "version": 1,
105
+ "context": {
106
+ "channel": "sms",
107
+ "observedAt": "2026-01-02T03:04:05.000Z",
108
+ "sourceLabel": "Reported message",
109
+ "reference": "CASE-17",
110
+ "observerLabel": "Reviewer A",
111
+ "vantageLabel": "Selected device"
112
+ }
113
+ }
114
+ ```
115
+
116
+ The separate context file is limited to 8 KiB; stdin is not accepted for it.
117
+ Use `null` for unknown optional values. Channels are `email`, `sms`, `messaging`,
118
+ `social`, `advertisement`, `website`, `document`, `other` and `unknown`.
119
+ Do not supply credentials, recipients, personal account identifiers or exact
120
+ URLs in labels. All declarations are included in the downloaded or deliberately
121
+ retained review. The Case summary pin contains counts and the report identity,
122
+ not the indicator values or declaration text. Retaining original input remains
123
+ a separate choice.
124
+
125
+ ### Select phone observations in the CLI
126
+
127
+ First run `whoisleuth intake text selected.txt --json`. Standard error shows a
128
+ candidate count, the full source digest, UTF-16 ranges and uncertainty, but not
129
+ the numbers themselves. JSON output excludes unselected candidates. `--quiet`
130
+ suppresses this discovery guidance. Inspect the corresponding text in your
131
+ selected file before choosing a range.
132
+
133
+ A version-2 context file binds selections to those exact input bytes. For
134
+ example, a file containing `Support: +1 202 555 0107` followed by one LF newline
135
+ has this selection:
136
+
137
+ ```json
138
+ {
139
+ "schema": "whoisleuth.intake-context",
140
+ "version": 2,
141
+ "context": null,
142
+ "review": {
143
+ "sourceDigestSha256": "sha256:4ff4224ff4ed496fb67fa2ccb25f87b284d1d291f8e79b57646d6c32700eeb52",
144
+ "phones": [{
145
+ "start": 9,
146
+ "end": 24,
147
+ "declaration": {
148
+ "sourceLabel": "Selected support snippet",
149
+ "observedAt": null,
150
+ "basis": "supplied_text",
151
+ "role": "advertised_support_contact",
152
+ "countryCallingCode": null
153
+ }
154
+ }],
155
+ "destinationPair": null
156
+ }
157
+ }
158
+ ```
159
+
160
+ Run the earlier `--intake-context context.json` command to include that selected
161
+ observation. A changed file or incorrect range is rejected; obtain its current
162
+ digest and review it again. `context` can also carry the existing distribution
163
+ declaration. Version-1 context files remain supported.
164
+
165
+ ## Selected internal containment handoff
166
+
167
+ In **Case → Response → Account and device recovery**, open **Prepare an internal
168
+ containment handoff**. Select retained next-step assertions and, independently,
169
+ their linked evidence pins. Choose security operations, identity response,
170
+ endpoint response or network response for tailored review guidance.
171
+
172
+ The preview displays the selected statements, rationale, recorded state,
173
+ times, pin values and source metadata. **Exact JSON disclosure** exposes the
174
+ complete download, including selected pin scope, provenance and recheck fields.
175
+ Supports, contradicts, unresolved and
176
+ unrecorded relationships remain distinct. A linked pin that is not selected is
177
+ not silently included; an unavailable referenced pin remains unavailable.
178
+ The handoff is limited to 20 requests, 40 pins and 128 KiB, with no silent
179
+ truncation. No original file bytes or unrelated Case notes, title, contacts,
180
+ recipient values, assertions or pins are included.
181
+
182
+ Review the audience disclosure before copy, download or explicit retention.
183
+ Internal and trusted audiences use the existing Case disclosure policy. Public
184
+ preview excludes internal requests and supporting pins and cannot produce a
185
+ containment export. Selected analyst text may still be sensitive: minimisation
186
+ does not provide anonymisation. Saving uses an ordinary retained Case file and
187
+ a source-hashed summary pin, not another task or state store.
188
+
189
+ The existing `review-evidence` CLI command accepts an equivalent selected input:
190
+
191
+ ```json
192
+ {
193
+ "schema": "whoisleuth.internal-containment.input",
194
+ "version": 1,
195
+ "caseExport": { "version": 18, "cases": [] },
196
+ "caseId": "selected-case-id",
197
+ "selection": {
198
+ "audience": "internal",
199
+ "recipientRole": "identity_response",
200
+ "assertionIds": ["selected-next-step-id"],
201
+ "evidencePinIds": ["selected-linked-pin-id"]
202
+ },
203
+ "disclosureReviewed": true
204
+ }
205
+ ```
206
+
207
+ Replace the empty example with a supported ordinary Case export and exact
208
+ retained IDs after reviewing its selected content. The CLI does not write the
209
+ Case; `--strict-exit` returns 4 when selected supporting context is incomplete.
210
+ Output uses `whoisleuth.internal-containment` version 1 inside the existing
211
+ offline-review envelope. Neither external resolution nor a resolved Case closes
212
+ an open internal request. The handoff performs no assignment, notification,
213
+ blocking, credential change, isolation or other containment action.
@@ -1,40 +1,2 @@
1
- // Deliberately small interoperability projection over reviewed MISP
2
- // taxonomies. WHOISleuth retains its own bounded workflow vocabulary and
3
- // derives machine tags only when an analyst-owned disposition and reason make
4
- // the mapping unambiguous. These tags never alter collection or scoring.
5
- const ANALYST_REVIEW_REASONS = Object.freeze([
6
- Object.freeze({ value: '', label: 'Not recorded' }),
7
- Object.freeze({ value: 'authorized_or_owned', label: 'Authorised or owned domain' }),
8
- Object.freeze({ value: 'shared_infrastructure', label: 'Shared infrastructure explained the signal' }),
9
- Object.freeze({ value: 'generic_platform_or_template', label: 'Generic platform or template' }),
10
- Object.freeze({ value: 'parked_or_reseller', label: 'Parking or reseller page' }),
11
- Object.freeze({ value: 'insufficient_evidence', label: 'Insufficient evidence' }),
12
- Object.freeze({ value: 'legitimate_third_party', label: 'Legitimate third party' }),
13
- Object.freeze({ value: 'confirmed_credential_abuse', label: 'Confirmed credential abuse' }),
14
- Object.freeze({ value: 'confirmed_malware', label: 'Confirmed malware' }),
15
- Object.freeze({ value: 'other_reviewed', label: 'Other reviewed reason' }),
16
- ]);
17
- const ANALYST_REVIEW_REASON_VALUES = new Set(ANALYST_REVIEW_REASONS.map(({ value }) => value).filter(Boolean));
18
- const MISP_TAXONOMY_REFERENCES = Object.freeze([
19
- Object.freeze({ namespace: 'domain-abuse', version: 2, sourceSha256: '5fcfb44742daac97061726faaaadd2ce6b7eac55306acaae3d30c3882d18f991', sourceUrl: 'https://github.com/MISP/misp-taxonomies/blob/main/domain-abuse/machinetag.json' }),
20
- Object.freeze({ namespace: 'estimative-language', version: 5, sourceSha256: '1010927d396f66f7cc58a229ebb8af6ad2cdc0250ad5f8ce3b1bd9aacf5ab4da', sourceUrl: 'https://github.com/MISP/misp-taxonomies/blob/main/estimative-language/machinetag.json' }),
21
- Object.freeze({ namespace: 'event-assessment', version: 2, sourceSha256: '39291bdd50e1b2975a93e33e396f42b398178015580a84402bc3d8d549dd721e', sourceUrl: 'https://github.com/MISP/misp-taxonomies/blob/main/event-assessment/machinetag.json' }),
22
- Object.freeze({ namespace: 'false-positive', version: 7, sourceSha256: 'ffc8d35ae36eb1d39f33611d1090793021f2bfe3b4b31ae41631e22cf544a2fb', sourceUrl: 'https://github.com/MISP/misp-taxonomies/blob/main/false-positive/machinetag.json' }),
23
- Object.freeze({ namespace: 'phishing', version: 5, sourceSha256: '8628ebe4d5935216a7b006a4d975669c4ae1a554ef8ed78ffaadd62f763d7263', sourceUrl: 'https://github.com/MISP/misp-taxonomies/blob/main/phishing/machinetag.json' }),
24
- ]);
25
- function analystInteroperabilityTags(disposition, reviewReasonCode) {
26
- const tags = new Set();
27
- if (disposition === 'false_positive')
28
- tags.add('false-positive:confirmed="true"');
29
- if ((disposition === 'false_positive' || disposition === 'expected')
30
- && ['authorized_or_owned', 'shared_infrastructure', 'generic_platform_or_template', 'parked_or_reseller', 'legitimate_third_party'].includes(String(reviewReasonCode)))
31
- tags.add('false-positive:risk="high"');
32
- if (reviewReasonCode === 'insufficient_evidence') {
33
- tags.add('estimative-language:confidence-in-analytic-judgment="low"');
34
- }
35
- if (disposition === 'confirmed_abuse' && reviewReasonCode === 'confirmed_credential_abuse') {
36
- tags.add('phishing:techniques="fake-website"');
37
- }
38
- return [...tags].sort();
39
- }
40
- export { ANALYST_REVIEW_REASONS, ANALYST_REVIEW_REASON_VALUES, MISP_TAXONOMY_REFERENCES, analystInteroperabilityTags, };
1
+ // Retained public import; the runtime-neutral implementation lives in the domain layer.
2
+ export * from "../packages/analysis/analyst-taxonomy.mjs";
@@ -1,3 +1,3 @@
1
1
  import packageDocument from '../package.json' with { type: 'json' };
2
- import { normalizeBoundedSemanticVersion } from "./semantic-version.mjs";
2
+ import { normalizeBoundedSemanticVersion } from "../packages/analysis/semantic-version.mjs";
3
3
  export const WHOISLEUTH_APPLICATION_VERSION = normalizeBoundedSemanticVersion(packageDocument.version, 'Application manifest');