@slicedearth/whoisleuth-cli 2.2.0 → 2.4.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.
- package/NOTICE +6 -0
- package/README.md +20 -15
- package/bin/whoisleuth.mjs +8 -1
- package/cli/archive-content-digest.mjs +14 -0
- package/cli/archive-inspect.mjs +20 -53
- package/cli/arguments.mjs +454 -1748
- package/cli/artifact-validation/case-response.mjs +66 -35
- package/cli/artifact-validation/investigation-capsule.mjs +52 -31
- package/cli/artifact-validation/lookup-evidence.mjs +12 -6
- package/cli/artifact-validation/signed-review.mjs +112 -72
- package/cli/artifact-validation/structure-primitives.mjs +1 -105
- package/cli/artifact-verify.mjs +90 -24
- package/cli/assurance-command-runner.mjs +39 -4
- package/cli/bagit-folder.mjs +57 -0
- package/cli/bagit-review.mjs +23 -0
- package/cli/bounded-json.mjs +1 -1
- package/cli/bulk-checkpoint.mjs +34 -3
- package/cli/bulk-command-runner.mjs +2 -0
- package/cli/bulk-output.mjs +29 -3
- package/cli/case-command.mjs +195 -0
- package/cli/case-pack.mjs +66 -111
- package/cli/command-argument-grammar.mjs +215 -0
- package/cli/command-reference.mjs +342 -285
- package/cli/completion.mjs +303 -80
- package/cli/config-profile.mjs +7 -5
- package/cli/ct-event-intake.mjs +12 -12
- package/cli/discover.mjs +4 -3
- package/cli/discovery-observation-snapshot.mjs +59 -18
- package/cli/discovery-scan-command-runner.mjs +21 -0
- package/cli/discovery-scan.mjs +13 -4
- package/cli/discovery-workflow.mjs +1 -1
- package/cli/domain-control-monitor.mjs +50 -20
- package/cli/domain-control-observations.mjs +149 -102
- package/cli/errors.mjs +33 -1
- package/cli/evidence-command-runner.mjs +16 -5
- package/cli/evidence-signing.mjs +2 -2
- package/cli/external-observation-mapping.mjs +7 -8
- package/cli/formatters/terminal-lookup.mjs +18 -46
- package/cli/formatters/terminal-shared.mjs +5 -3
- package/cli/formatters/terminal-technology.mjs +114 -0
- package/cli/inline-command-families.mjs +2 -0
- package/cli/input.mjs +116 -0
- package/cli/interactive-launcher.mjs +2 -160
- package/cli/interchange-report.mjs +18 -8
- package/cli/investigation-artifacts.mjs +176 -0
- package/cli/investigation-checkpoint.mjs +10 -0
- package/cli/investigation-folder.mjs +114 -0
- package/cli/investigation-manifest.mjs +1 -112
- package/cli/investigation-package-review.mjs +103 -0
- package/cli/investigation-plan.mjs +32 -19
- package/cli/investigation-run.mjs +188 -33
- package/cli/local-document-checkpoint.mjs +170 -0
- package/cli/lookalike-calibration.mjs +7 -2
- package/cli/lookup-brief.mjs +4 -2
- package/cli/lookup-browser-view.mjs +1 -1
- package/cli/lookup-browser.mjs +5 -12
- package/cli/lookup-command-runner.mjs +17 -6
- package/cli/lookup-diff.mjs +37 -3
- package/cli/lookup-plan.mjs +11 -5
- package/cli/lookup-reconcile.mjs +10 -8
- package/cli/mail-header-review.mjs +467 -0
- package/cli/mail-review.mjs +66 -14
- package/cli/manual.mjs +1 -0
- package/cli/network-command-runner.mjs +2 -0
- package/cli/output-file.mjs +31 -5
- package/cli/registry-doctor.mjs +3 -1
- package/cli/registry-support.mjs +1 -1
- package/cli/retained-artifact-diff.mjs +2 -2
- package/cli/review-command-runner.mjs +70 -0
- package/cli/risk-calibration.mjs +19 -17
- package/cli/runner.mjs +62 -7
- package/cli/sharing-review.mjs +21 -34
- package/cli/signer-trust.mjs +104 -0
- package/cli/source-reliability.mjs +74 -83
- package/cli/terminal-input.mjs +168 -0
- package/cli/workflow-command-runner.mjs +68 -13
- package/docs/cli-reference.md +77 -24
- package/docs/cli.md +300 -25
- package/lib/abort.mjs +4 -1
- package/lib/availability.mjs +161 -112
- package/lib/bounded-file.mjs +3 -1
- package/lib/bounded-html-document.mjs +125 -0
- package/lib/bounded-json.mjs +51 -8
- package/lib/browser-library-profile.mjs +42 -51
- package/lib/browser-library-worker.mjs +112 -0
- package/lib/client-behavior-profile.mjs +3 -3
- package/lib/ct-search.mjs +11 -4
- package/lib/dns-convergence-review.mjs +1 -0
- package/lib/dns-delegation-health.mjs +24 -14
- package/lib/dns-inheritance-review.mjs +217 -0
- package/lib/dns-intelligence.mjs +73 -26
- package/lib/dns-mx.mjs +1 -1
- package/lib/dnssec-chain-validation.mjs +6 -0
- package/lib/dnssec-evidence-validation.mjs +11 -3
- package/lib/domain-change-packet.mjs +49 -16
- package/lib/domain-change-review.mjs +14 -8
- package/lib/domain-control-flight-recorder.mjs +221 -117
- package/lib/domain-control-manifest.mjs +129 -69
- package/lib/domain-posture-analysis.mjs +20 -7
- package/lib/domain-posture-parsers.mjs +201 -8
- package/lib/domain-posture.mjs +147 -29
- package/lib/evidence-export-privacy.mjs +561 -0
- package/lib/evidence-export.mjs +11 -543
- package/lib/evidence-report.mjs +5 -3
- package/lib/favicon.mjs +117 -41
- package/lib/generated/cisa-kev-catalog.mjs +12 -4
- package/lib/generated/registrar-standing-catalogue.mjs +7 -7
- package/lib/generated/retire-browser-catalog.mjs +2335 -940
- package/lib/hostname.mjs +2 -38
- package/lib/html-signals.mjs +111 -108
- package/lib/http-evidence-bounds.mjs +2 -1
- package/lib/http-intelligence.mjs +39 -26
- package/lib/local-geoip-evidence.mjs +19 -3
- package/lib/lookup-cache.mjs +34 -11
- package/lib/lookup-child-profile-contract.mjs +24 -15
- package/lib/lookup-diagnostics.mjs +24 -1
- package/lib/lookup-progress.mjs +30 -13
- package/lib/lookup-response-contract.mjs +1048 -0
- package/lib/lookup-response.mjs +8 -10
- package/lib/lookup-source-progress.mjs +40 -14
- package/lib/lookup.mjs +48 -27
- package/lib/nameserver-preflight-review.mjs +1 -0
- package/lib/observed-network-context.mjs +43 -27
- package/lib/outbound-request-bounds.mjs +4 -1
- package/lib/page-fingerprints.mjs +69 -133
- package/lib/page-role-profile.mjs +12 -8
- package/lib/perceptual-hash.mjs +43 -14
- package/lib/rdap-bootstrap.mjs +72 -22
- package/lib/rdap-capabilities.mjs +1 -1
- package/lib/rdap-client.mjs +15 -7
- package/lib/rdap-normalization.mjs +33 -18
- package/lib/rdap-search-workbench.mjs +1 -1
- package/lib/rdap-transport.mjs +47 -20
- package/lib/rdap-types.mjs +2 -1
- package/lib/rdap.mjs +18 -3
- package/lib/registrable-domain.mjs +21 -1
- package/lib/registrar-standing-contract.mjs +1 -0
- package/lib/registry-capabilities.mjs +5 -1
- package/lib/registry-capability-catalogue.mjs +2 -1
- package/lib/registry-dates.mjs +2 -190
- package/lib/registry-insights.mjs +85 -34
- package/lib/response-policy.mjs +86 -48
- package/lib/risk-calibration-summary.mjs +18 -6
- package/lib/rpki-evidence.mjs +8 -5
- package/lib/safe-fetch.mjs +54 -47
- package/lib/security-txt.mjs +42 -7
- package/lib/service-binding-dns.mjs +8 -0
- package/lib/smtp-transport-review.mjs +27 -15
- package/lib/sslbl-certificates.generated.mjs +136 -135
- package/lib/static-html-analysis.mjs +178 -151
- package/lib/structured-data-identity.mjs +1 -0
- package/lib/technology-markup.mjs +100 -0
- package/lib/threat-intelligence-manifests.mjs +11 -139
- package/lib/threat-intelligence-runtime.mjs +24 -52
- package/lib/threat-intelligence-targets.mjs +6 -34
- package/lib/threat-intelligence-types.mjs +39 -0
- package/lib/typosquat-generator.mjs +19 -15
- package/lib/urlhaus-intelligence.mjs +8 -3
- package/lib/urlscan-intelligence.mjs +1 -1
- package/lib/website-security-posture.mjs +30 -6
- package/lib/website-technology.mjs +153 -45
- package/lib/whois-authority.mjs +14 -2
- package/lib/whois-chain.mjs +9 -2
- package/lib/whois-common-formats.mjs +5 -5
- package/lib/whois-contracts.mjs +2 -1
- package/lib/whois-dialects.mjs +2 -2
- package/lib/whois-parser-support.mjs +8 -1
- package/lib/whois-transport.mjs +23 -7
- package/lib/zone-intent-review.mjs +16 -6
- package/package.json +2 -1
- package/packages/cases/case-attachment-model.mjs +83 -0
- package/packages/cases/case-evidence-model.mjs +156 -62
- package/packages/cases/case-export-input.mjs +53 -0
- package/packages/cases/case-migration-model.mjs +127 -44
- package/packages/cases/case-model.mjs +1 -0
- package/packages/cases/case-recheck-model.mjs +91 -0
- package/packages/cases/case-record-contracts.mjs +5 -20
- package/packages/cases/case-record-core.mjs +12 -22
- package/packages/cases/case-record-decisions.mjs +72 -0
- package/packages/cases/case-record-model.mjs +1 -0
- package/packages/cases/case-record-operations.mjs +95 -31
- package/packages/cases/case-record-projection.mjs +221 -0
- package/packages/cases/case-report.mjs +70 -54
- package/packages/cases/case-response-actions.mjs +654 -0
- package/packages/cases/case-response-model.mjs +64 -1115
- package/packages/cases/case-response-outcomes.mjs +317 -0
- package/packages/cases/case-response-packet-render.mjs +153 -0
- package/packages/cases/case-response-packet-types.mjs +1 -0
- package/packages/cases/case-response-packet-vocabulary.mjs +48 -0
- package/packages/cases/case-response-packet.mjs +74 -572
- package/packages/cases/case-response-records.mjs +94 -0
- package/packages/cases/case-response-review-inputs.mjs +371 -0
- package/packages/cases/case-response-values.mjs +85 -0
- package/packages/cases/case-review-package.mjs +45 -0
- package/packages/cases/case-selection.mjs +46 -0
- package/packages/cases/case-storage-model.mjs +31 -2
- package/packages/cases/response-route-freshness.mjs +16 -0
- package/packages/comparison/capture-context.mjs +61 -0
- package/packages/comparison/comparison-ledger-bulk.mjs +13 -11
- package/packages/comparison/page-similarity.mjs +5 -2
- package/packages/comparison/relationship-evidence.mjs +85 -8
- package/packages/comparison/relationship-provenance.mjs +93 -0
- package/packages/contracts/analyst-interchange.mjs +216 -0
- package/packages/contracts/analyst-review-state-contract.mjs +11 -0
- package/packages/contracts/analyst-review-state.mjs +5 -4
- package/packages/contracts/case-portability.mjs +366 -83
- package/packages/contracts/case-views-contract.mjs +12 -0
- package/packages/contracts/case-views.mjs +26 -0
- package/packages/contracts/cli-command-semantics.mjs +94 -0
- package/packages/contracts/cli-lookup.mjs +0 -1
- package/packages/contracts/domain-control-flight-recorder.mjs +80 -42
- package/packages/contracts/domain-control-manifest.mjs +127 -73
- package/packages/contracts/domain-control-monitor.mjs +48 -45
- package/packages/contracts/domain-control-review.mjs +179 -121
- package/packages/contracts/domain-name.mjs +21 -0
- package/packages/contracts/external-observation-interchange.mjs +2 -1
- package/packages/contracts/extracted-domain-lifecycle.mjs +11 -32
- package/packages/contracts/http-url.mjs +2 -0
- package/packages/contracts/investigation-package-limits.mjs +24 -0
- package/packages/contracts/investigation-portability.mjs +56 -27
- package/packages/contracts/investigation-run.mjs +16 -0
- package/packages/contracts/ip-address.mjs +34 -0
- package/packages/contracts/lookup-evidence.mjs +35 -0
- package/packages/contracts/offline-comparison.mjs +1 -2
- package/packages/contracts/page-fingerprints.mjs +15 -0
- package/packages/contracts/risk-calibration.mjs +15 -11
- package/packages/contracts/schema-compatibility.mjs +1 -1
- package/packages/contracts/schema-lifecycle.mjs +83 -153
- package/packages/contracts/selected-file-limits.mjs +6 -0
- package/packages/contracts/vulnerability-identifiers.mjs +5 -0
- package/packages/contracts/web-capture.mjs +10 -0
- package/packages/contracts/workspace-portability.mjs +183 -211
- package/packages/evidence/artifact-integrity.mjs +8 -2
- package/packages/evidence/artifact-structure.mjs +105 -0
- package/packages/evidence/decision-fact.mjs +4 -1
- package/packages/evidence/domain-control-runtime.mjs +201 -33
- package/packages/evidence/domain-posture-context.mjs +79 -0
- package/packages/evidence/image-regions.mjs +56 -0
- package/packages/evidence/latest-observations.mjs +28 -0
- package/packages/evidence/lookup-target.mjs +104 -0
- package/packages/evidence/observation.mjs +16 -1
- package/packages/evidence/passphrase-encryption.mjs +44 -0
- package/packages/evidence/record-identity.mjs +72 -0
- package/packages/evidence/registry-dates.mjs +190 -0
- package/packages/evidence/retained-file.mjs +69 -0
- package/packages/evidence/review-age.mjs +14 -0
- package/packages/interchange/bagit.mjs +342 -0
- package/packages/interchange/bounded-zip-extraction.mjs +278 -0
- package/packages/interchange/crc32.mjs +17 -0
- package/packages/interchange/external-findings-import.mjs +92 -51
- package/packages/interchange/web-capture-import.mjs +382 -0
- package/packages/investigation/bulk-mail-exposure.mjs +2 -1
- package/packages/investigation/investigation-bagit.mjs +14 -0
- package/packages/investigation/investigation-capsule.mjs +33 -5
- package/packages/investigation/investigation-manifest.mjs +200 -0
- package/packages/investigation/investigation-package-crypto.mjs +98 -0
- package/packages/investigation/investigation-package.mjs +200 -0
- package/packages/investigation/lookup-asset-graph-inputs.mjs +38 -0
- package/packages/investigation/lookup-asset-graph.mjs +193 -165
- package/packages/investigation/lookup-claim-readiness.mjs +18 -0
- package/packages/investigation/lookup-investigation-brief.mjs +3 -3
- package/packages/investigation/lookup-task-guidance.mjs +58 -0
- package/packages/monitoring/analyst-review-state.mjs +38 -90
- package/packages/workspace/brand-profile-model.mjs +276 -22
- package/packages/workspace/bulk-columns.mjs +17 -0
- package/packages/workspace/bulk-review-model.mjs +23 -11
- package/packages/workspace/bulk-session-model.mjs +100 -24
- package/packages/workspace/bulk-sort.mjs +1 -0
- package/packages/workspace/case-views.mjs +102 -0
- package/packages/workspace/detection-rule-model.mjs +70 -22
- package/packages/workspace/hostile-input.mjs +29 -8
- package/packages/workspace/investigation-template-model.mjs +19 -4
- package/packages/workspace/page-baseline.mjs +18 -15
- package/packages/workspace/relationship-observation-model.mjs +41 -23
- package/packages/workspace/watchlist-history.mjs +2 -2
- package/packages/workspace/watchlist-store.mjs +8 -2
- package/packages/workspace/website-snapshot-model.mjs +164 -26
- package/packages/workspace/workspace-archive-crypto.mjs +41 -61
- package/packages/workspace/workspace-archive.mjs +87 -21
- package/third-party-notices.txt +29 -2
- package/cli/evidence-command-arguments.mjs +0 -156
- package/packages/investigation/bulk-review-export.mjs +0 -63
package/docs/cli-reference.md
CHANGED
|
@@ -12,20 +12,8 @@ contains the exhaustive recipient, retention and export metadata.
|
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
package on Node.js 26:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm exec --yes --ignore-scripts --package=@slicedearth/whoisleuth-cli -- whoisleuth --help
|
|
21
|
-
npm install --global --ignore-scripts @slicedearth/whoisleuth-cli
|
|
22
|
-
whoisleuth doctor
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The scoped package and application share one semantic version. The package
|
|
26
|
-
requires no dependency lifecycle scripts and does not call the hosted
|
|
27
|
-
WHOISleuth deployment. From a repository checkout, replace `whoisleuth` with
|
|
28
|
-
`node bin/whoisleuth.mts`.
|
|
15
|
+
Use the [installation guide](cli.md#installation) for runtime requirements,
|
|
16
|
+
installation and updates. The CLI runs locally without a hosted account.
|
|
29
17
|
|
|
30
18
|
## Find and inspect commands
|
|
31
19
|
|
|
@@ -46,6 +34,13 @@ command position as Lookup shorthand. Use explicit `lookup` where input needs
|
|
|
46
34
|
supported URL-like normalisation. Credentials, paths, queries, fragments, ports
|
|
47
35
|
and unsupported special-use targets are rejected by the shorthand.
|
|
48
36
|
|
|
37
|
+
Explicit `lookup` normally uses only a pasted URL's hostname. Add
|
|
38
|
+
`--deep --exact-url` to collect that page's path and query instead of the
|
|
39
|
+
homepage; fragments are not sent. `--plan` discloses this scope without making
|
|
40
|
+
requests or copying the URL into the plan. Use stdin to keep a sensitive URL
|
|
41
|
+
out of shell history. Saved request provenance omits queries, but paths and
|
|
42
|
+
page-derived text still require review before sharing.
|
|
43
|
+
|
|
49
44
|
`registry-scaffold` has a separate fixture contract: its `--profile` selects one
|
|
50
45
|
fixed fixture profile and shared `--config` profiles are rejected. It produces
|
|
51
46
|
sanitised local fixture material and makes no registry request.
|
|
@@ -63,6 +58,9 @@ disclosures without collecting. Fast is the Lookup default. Deep adds the
|
|
|
63
58
|
applicable registration, DNS, HTTP, TLS, page, technology and network context.
|
|
64
59
|
Optional browser providers are not implicit CLI actions.
|
|
65
60
|
|
|
61
|
+
The [message-header review](cli.md#message-header-review) is offline and reports
|
|
62
|
+
publisher claims, not independent DNS or cryptographic validation.
|
|
63
|
+
|
|
66
64
|
`dnssec-validate` and `mail-transport` are isolated authorised actions. Both
|
|
67
65
|
require a selected literal public resolver, a local trust-anchor document and
|
|
68
66
|
`--owned-or-authorized`; mail transport also requires `--active-probe`. Mail
|
|
@@ -70,6 +68,8 @@ transport handles at most three selected MX hosts sequentially, sends `EHLO`
|
|
|
70
68
|
and uses `STARTTLS` only when advertised. It does not send mail, authenticate,
|
|
71
69
|
test relay, enumerate recipients or retry automatically. DNSSEC, TLSA/DANE,
|
|
72
70
|
PKIX, STARTTLS and SMTP transport remain separate evidence states.
|
|
71
|
+
STARTTLS detection uses the full bounded reply. If the retained capability
|
|
72
|
+
inventory is shortened, the report remains partial and names the omission.
|
|
73
73
|
|
|
74
74
|
The repository-only rendered-capture package is outside hosted and distributable
|
|
75
75
|
collection. It executes remote page JavaScript only for an explicitly
|
|
@@ -84,11 +84,20 @@ refused. Output goes to the terminal unless a command supports `--output`.
|
|
|
84
84
|
Private output is written atomically and an existing path is refused unless
|
|
85
85
|
replacement is explicit.
|
|
86
86
|
|
|
87
|
+
`--` ends option processing. All later arguments are literal positional inputs,
|
|
88
|
+
including names such as `--help`. Use `./-evidence.json` for a hyphen-prefixed
|
|
89
|
+
filename when completing paths across shells. Options must precede `--`.
|
|
90
|
+
|
|
87
91
|
Terminal text is the default. JSON, JSONL, CSV, Markdown, HTML and domain-only
|
|
88
92
|
formats are available only where the installed command declares them.
|
|
89
93
|
Redirected and machine output contains no ANSI or progress text. Diagnostics
|
|
90
94
|
and optional target-free `--events` output use standard error.
|
|
91
95
|
|
|
96
|
+
For `bulk` and `discover-scan`, `--csv-with-metadata` adds the source schema and
|
|
97
|
+
version, observation and report times, collection origin, scan mode, diagnostic
|
|
98
|
+
version and source-health states. Missing clocks remain `unknown`; a null
|
|
99
|
+
source state is unmeasured, not a negative result. `--csv` keeps the compact columns.
|
|
100
|
+
|
|
92
101
|
`--fail-on` and `--strict-exit` expose selected evidence states to automation
|
|
93
102
|
without changing the result document. Review focused help for the policies a
|
|
94
103
|
command supports.
|
|
@@ -109,16 +118,18 @@ Readers accept only their declared public and current versions. Unknown,
|
|
|
109
118
|
unreleased historical and future schemas fail before partial interpretation;
|
|
110
119
|
an invalid import is not treated as an empty document.
|
|
111
120
|
|
|
112
|
-
`inspect-archive` reads current workspace archive
|
|
121
|
+
`inspect-archive` reads current workspace archive v9 and exact versions 5–8. It
|
|
113
122
|
reports section metadata and digest-only search results unless `--reveal` is
|
|
114
123
|
explicitly selected. It never searches notes, contacts or arbitrary raw fields.
|
|
115
124
|
|
|
116
125
|
`export` reads supported saved Lookup v1 or v2 and writes current Lookup
|
|
117
|
-
evidence schema
|
|
118
|
-
readable. Versions 27
|
|
126
|
+
evidence schema 29. Published v2 schemas 27 and 28 and exact v1 schema 26 remain
|
|
127
|
+
readable. Versions 27–29 exclude raw registration payloads, expanded
|
|
119
128
|
contacts, credentials, complete query-bearing URLs and provider payloads;
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
schemas 28 and 29 also retain the bounded registrar-standing projection.
|
|
130
|
+
Schema 29 identifies the hostname used for DNS, TLS and web observations,
|
|
131
|
+
separately from the registrable domain used by registration sources. Older
|
|
132
|
+
evidence retains its original collection scope.
|
|
122
133
|
|
|
123
134
|
`verify-artifact` checks a recognised structure and its applicable integrity
|
|
124
135
|
contract. `interchange-report` describes retained and omitted fields.
|
|
@@ -126,6 +137,45 @@ contract. `interchange-report` describes retained and omitted fields.
|
|
|
126
137
|
validity and signer trust separate. None of these checks establishes that
|
|
127
138
|
evidence is accurate, current, safe to share or attributable to a person.
|
|
128
139
|
|
|
140
|
+
### Signer trust
|
|
141
|
+
|
|
142
|
+
Use `verify-signature package.json --trust-store-file trust.json --json` to
|
|
143
|
+
check an explicitly selected fingerprint policy offline. The result contains
|
|
144
|
+
the ordinary signature verification and a separate current trust decision.
|
|
145
|
+
Only a matching `trusted` entry succeeds; unknown, `retired`, `revoked` or
|
|
146
|
+
future-reviewed entries return exit code 4, including with `--quiet`.
|
|
147
|
+
Malformed files return 2. Without this option, the existing verification
|
|
148
|
+
output is unchanged. A supplied `--public-key-file` must also match.
|
|
149
|
+
|
|
150
|
+
The trust file contains no keys. For example:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"schema": "whoisleuth.evidence-signer-trust-store",
|
|
155
|
+
"version": 1,
|
|
156
|
+
"entries": [{
|
|
157
|
+
"keyIdSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
158
|
+
"label": "Evidence reviewer",
|
|
159
|
+
"status": "trusted",
|
|
160
|
+
"updatedAt": "2026-09-01T00:00:00.000Z",
|
|
161
|
+
"note": "Fingerprint confirmed through the established contact channel."
|
|
162
|
+
}]
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Replace the example fingerprint with the SHA-256 fingerprint of the signer's
|
|
167
|
+
SPKI DER public-key bytes, confirmed through an authenticated channel—not
|
|
168
|
+
merely copied from the package being checked. Review rotation and revocation
|
|
169
|
+
updates through that channel. On rotation, mark the old entry `retired` and
|
|
170
|
+
optionally record `successorKeyIdSha256`; independently confirm and add the
|
|
171
|
+
replacement entry. Use `revoked` for a withdrawn trust decision. Neither a
|
|
172
|
+
successor link nor a claimed signing date overrides current status.
|
|
173
|
+
|
|
174
|
+
Files support 1,024 distinct entries within 4 MiB. Labels and single-line notes
|
|
175
|
+
allow 160 and 2,048 characters respectively. Reports include only the matching
|
|
176
|
+
entry and the exact file digest. Keep the file and any saved reports under your
|
|
177
|
+
own retention policy. No automatic key discovery, key storage or trust refresh occurs.
|
|
178
|
+
|
|
129
179
|
## Command-family boundaries
|
|
130
180
|
|
|
131
181
|
- Evidence collection commands retain separate source states. A failed or
|
|
@@ -137,17 +187,20 @@ evidence is accurate, current, safe to share or attributable to a person.
|
|
|
137
187
|
- Bulk applies one declared collection contract per target. Fast accepts up to
|
|
138
188
|
500 targets and Deep up to 50; each target remains a separate request.
|
|
139
189
|
- Respond commands package browser-created Cases and prepare local packets,
|
|
140
|
-
reports and sharing reviews.
|
|
141
|
-
|
|
190
|
+
reports and sharing reviews. The offline [`case` workflow](cli.md#local-case-files)
|
|
191
|
+
also creates and updates ordinary local Case files through explicit, conflict-checked
|
|
192
|
+
output. Neither workflow submits, publishes, notifies or grants recipient authorisation.
|
|
142
193
|
- Assurance, comparison and calibration commands describe supplied or retained
|
|
143
194
|
evidence. They do not tune the running model, change infrastructure or turn an
|
|
144
195
|
analyst label into observed truth.
|
|
145
196
|
- `workflow-plan` lists fixed installed recipes without executing them.
|
|
146
197
|
`workflow-run` executes only installed steps, requires approval for network
|
|
147
198
|
work and pauses at unresolved analyst selections. Repeat
|
|
148
|
-
`--select <step-id>=<path-or-value>`
|
|
149
|
-
|
|
150
|
-
selections
|
|
199
|
+
`--select <step-id>=<path-or-value>` for remaining placeholders in order, or bind
|
|
200
|
+
a compatible earlier output with `--use-artifact <step-id>:<input-number>=<earlier-step-id>`.
|
|
201
|
+
Checkpoints retain exact selections and bindings and distinguish incomplete
|
|
202
|
+
collection from retryable failures; see [resuming a fixed workflow](cli.md#resuming-a-fixed-workflow)
|
|
203
|
+
for the supported versions and resume behaviour.
|
|
151
204
|
|
|
152
205
|
Use the installed focused help for positional inputs, exact ceilings, options,
|
|
153
206
|
network effects, outputs and command-specific exit behaviour.
|
package/docs/cli.md
CHANGED
|
@@ -35,6 +35,10 @@ dependency lifecycle scripts. From a repository checkout, replace `whoisleuth`
|
|
|
35
35
|
with `node bin/whoisleuth.mts`; maintainers can verify the exact package closure
|
|
36
36
|
with `npm run cli:package:check`.
|
|
37
37
|
|
|
38
|
+
Rendered-page collection uses the separate [optional capture companion](https://github.com/slicedearth/whoisleuth/tree/main/packages/web-capture#install-a-local-candidate),
|
|
39
|
+
not the main CLI. It can be installed from a verified local archive; browser
|
|
40
|
+
installation and each authorised capture remain explicit actions.
|
|
41
|
+
|
|
38
42
|
## First commands
|
|
39
43
|
|
|
40
44
|
Inspect the installed command set and plan one Lookup before collecting:
|
|
@@ -56,6 +60,11 @@ whoisleuth lookup example.test --deep --browse
|
|
|
56
60
|
whoisleuth lookup example.test --deep --markdown --output lookup.md
|
|
57
61
|
```
|
|
58
62
|
|
|
63
|
+
Pasted URLs normally select only their hostname. To collect one particular
|
|
64
|
+
page, use `whoisleuth lookup 'https://portal.example.test/review' --deep --exact-url`.
|
|
65
|
+
This sends the path and query to the website, without the fragment. Review
|
|
66
|
+
retained paths and page-derived text before sharing the result.
|
|
67
|
+
|
|
59
68
|
To continue a reviewed terminal Lookup in the browser, save the completed
|
|
60
69
|
private document from the interactive view:
|
|
61
70
|
|
|
@@ -65,16 +74,21 @@ whoisleuth lookup example.test --deep --browse --save-lookup lookup.json
|
|
|
65
74
|
|
|
66
75
|
In Console Lookup, open **Replay exported evidence**, select the file, verify
|
|
67
76
|
its digest and source states, then create or update a browser-local Case. The
|
|
68
|
-
file is not uploaded. Case classification, exact incident links
|
|
69
|
-
actions
|
|
77
|
+
file is not uploaded. Case classification, exact incident links and response
|
|
78
|
+
actions remain deliberate analyst steps. Ordinary Case files also support the
|
|
79
|
+
offline CLI workflow below.
|
|
80
|
+
When several incident Cases share a domain, select the intended Case before
|
|
81
|
+
retaining replay evidence. Case packs preserve each current Case ID separately;
|
|
82
|
+
trusted and public packs exclude analyst-entered incident titles.
|
|
70
83
|
|
|
71
84
|
Process selected local input:
|
|
72
85
|
|
|
73
86
|
```bash
|
|
74
|
-
whoisleuth bulk domains.txt --csv
|
|
87
|
+
whoisleuth bulk domains.txt --csv-with-metadata
|
|
75
88
|
whoisleuth discover example.test --preset common --jsonl
|
|
76
89
|
whoisleuth verify-artifact lookup.json --json --strict-exit
|
|
77
90
|
whoisleuth compare lookup.json --json
|
|
91
|
+
whoisleuth mail-headers message.eml --json
|
|
78
92
|
whoisleuth brief lookup.json
|
|
79
93
|
```
|
|
80
94
|
|
|
@@ -82,17 +96,15 @@ One strict domain, IP address or ASN can occupy command position as Lookup
|
|
|
82
96
|
shorthand. URL-like or ambiguous input requires the explicit `lookup` command.
|
|
83
97
|
Only `bulk` accepts multiple targets.
|
|
84
98
|
|
|
85
|
-
|
|
99
|
+
`discover` accepts a brand label or registrable domain and supports multi-part
|
|
100
|
+
public suffixes in `--tlds` (for example, `co.uk,com.au`). It preserves the full
|
|
101
|
+
suffix and does not collect candidate evidence; use `discover-scan` only after
|
|
102
|
+
reviewing its separate network plan. Subdomains and URLs are not generation seeds.
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
application:
|
|
104
|
+
## Command groups
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
| Investigate | `lookup`, `bulk`, `discover`, `ct-search`, `posture`, `http`, `tls`, `compare`, `brief` |
|
|
93
|
-
| Respond | `case-pack`, `change-packet`, `sharing-review`, `export` (local handoff from browser-created Cases) |
|
|
94
|
-
| Assure | `dnssec-validate`, `mail-transport`, `domain-control`, `assurance`, `workflow-plan`, `diff`, `inspect-archive`, `verify-artifact` |
|
|
95
|
-
| Utilities | `doctor`, `commands`, `completion`, `manual`, `registry-scaffold` |
|
|
106
|
+
The installed catalogue groups commands under Investigate, Respond, Assure and
|
|
107
|
+
Utilities, with each command's inputs, output and network boundary.
|
|
96
108
|
|
|
97
109
|
Filter the canonical index without running the selected commands:
|
|
98
110
|
|
|
@@ -103,12 +115,14 @@ whoisleuth commands --json
|
|
|
103
115
|
whoisleuth manual | man -l -
|
|
104
116
|
```
|
|
105
117
|
|
|
106
|
-
`registry-scaffold` has a separate fixture bootstrap contract: its `--profile`
|
|
107
|
-
selects one fixed fixture profile and it rejects shared `--config` profiles.
|
|
108
|
-
It creates sanitised local fixtures and does not contact a registry.
|
|
109
|
-
|
|
110
118
|
## Collection boundaries
|
|
111
119
|
|
|
120
|
+
For an explicit inherited-policy and direct parent-delegation review, use
|
|
121
|
+
`whoisleuth posture example.test --include-inherited-dns --json`. Without that
|
|
122
|
+
option, posture collection keeps its existing exact-name scope. The extra
|
|
123
|
+
results distinguish recursive policy publication from sampled parent referrals;
|
|
124
|
+
they do not establish name existence, message authentication or DNSSEC validity.
|
|
125
|
+
|
|
112
126
|
| Mode | Behaviour |
|
|
113
127
|
| --- | --- |
|
|
114
128
|
| Fast Lookup | Registration-first triage without WHOIS or deeper website and TLS collection. |
|
|
@@ -122,13 +136,265 @@ their focused help. They do not use the hosted login or hosted usage controls.
|
|
|
122
136
|
`lookup --plan` lists planned source families and disclosure targets before
|
|
123
137
|
collection. `doctor` is offline unless `--network` is selected.
|
|
124
138
|
|
|
139
|
+
### Message-header review
|
|
140
|
+
|
|
141
|
+
`mail-headers` parses only the bounded header block from a selected message file
|
|
142
|
+
or standard input. It extracts domain-only identity, reported SPF, DKIM, DMARC
|
|
143
|
+
and ARC states, exact-domain alignment, and the bounded `Received` route in its
|
|
144
|
+
reported order. It makes no request and does not retain address local parts,
|
|
145
|
+
display names, subject, body, attachments, or raw header values in its output.
|
|
146
|
+
Authentication states are header claims, not an independent DNS or
|
|
147
|
+
cryptographic validation, and alignment differences can be legitimate.
|
|
148
|
+
|
|
125
149
|
## Output and automation
|
|
126
150
|
|
|
151
|
+
### Local Case files
|
|
152
|
+
|
|
153
|
+
Create a working file, inspect its Case IDs, then append a note:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
whoisleuth case open --domain example.test --title "Review the selected form" --output cases.json
|
|
157
|
+
whoisleuth case show cases.json
|
|
158
|
+
whoisleuth case note cases.json --note-file note.txt --output cases.json --force
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Use `--case-id` when the file contains several Cases. `open` reuses the selected
|
|
162
|
+
Case; `--new-incident --title "Another incident"` creates a distinct ID for the
|
|
163
|
+
same domain. It does not open a browser or collect anything.
|
|
164
|
+
|
|
165
|
+
`pin`, `assess` and `recheck` read a selected JSON file with `--input`:
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
whoisleuth case pin cases.json --input pin.json --output cases.json --force
|
|
169
|
+
whoisleuth case assess cases.json --input assessment.json --output cases.json --force
|
|
170
|
+
whoisleuth case recheck cases.json --input recheck.json --output cases.json --force
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
A pin describes the supplied observation, not a new collection. For example:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"label": "Selected page observation",
|
|
178
|
+
"value": "A form was retained in the supplied capture.",
|
|
179
|
+
"source": "Analyst supplied capture",
|
|
180
|
+
"observedAt": "2026-09-01T12:00:00.000Z",
|
|
181
|
+
"completeness": "complete",
|
|
182
|
+
"sourceState": "complete",
|
|
183
|
+
"observationHostname": "example.test"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Supply an observation time only when known; use `null` otherwise. Describe
|
|
188
|
+
partial or unavailable evidence honestly. IDs and creation times are allocated
|
|
189
|
+
locally. Unknown fields, truncated values and unsupported formats are rejected.
|
|
190
|
+
|
|
191
|
+
An assessment includes a reviewed disposition and reason, a summary, a rationale,
|
|
192
|
+
and evidence relationships. Replace `selected-pin-id` with an ID from `case show`:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"disposition": "suspicious",
|
|
197
|
+
"reviewReasonCode": "other_reviewed",
|
|
198
|
+
"summary": "Review the apparent credential request",
|
|
199
|
+
"rationale": "The supplied observation needs independent corroboration.",
|
|
200
|
+
"evidence": [{ "pinId": "selected-pin-id", "stance": "supports" }]
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Each fact selects one retained `pinId` or a new `pin` object. Stances are
|
|
205
|
+
`supports`, `contradicts` or `unresolved`; at least one must support the decision.
|
|
206
|
+
Counterevidence and unresolved evidence remain linked, not discarded. Assessment
|
|
207
|
+
summary and rationale use single-line text; note files can contain paragraphs.
|
|
208
|
+
|
|
209
|
+
A recheck input contains `state`, `observedAt`, `completeness`, `source` and
|
|
210
|
+
`comparisonSummary`, with optional limitations and follow-up time. For example,
|
|
211
|
+
use `state: "unavailable"` and `completeness: "partial"` when a supplied capture
|
|
212
|
+
did not complete. `not_reproduced` requires a saved recheck question from the
|
|
213
|
+
Case's console workflow, its exact `recheck` context, the target
|
|
214
|
+
`observationHostname`, a complete later observation where a baseline exists,
|
|
215
|
+
and `conditionsMatch: "comparable"`. It never means global removal or takedown.
|
|
216
|
+
|
|
217
|
+
Mutations require an explicit output path and write the complete current Case
|
|
218
|
+
export. They never prune old evidence to fit. Input formatting may use up to
|
|
219
|
+
16 MiB; the canonical store remains limited to 4 MiB and 500 Cases. `show --json`
|
|
220
|
+
can export a selected subset to a **different** path. Ordinary Case imports also
|
|
221
|
+
allow 16 MiB for formatting and export metadata; the stored-data limit remains
|
|
222
|
+
4 MiB. Case packs retain their separate 25-Case selection and 4-MiB source-file
|
|
223
|
+
limits, and include generated reports within the bounded import allowance.
|
|
224
|
+
|
|
225
|
+
`show` reports the exact file digest. Add `--expect-file-digest sha256:<digest>`
|
|
226
|
+
to reject a file changed since that review. Source/output locks and atomic
|
|
227
|
+
replacement also detect changes during execution. After an interrupted process,
|
|
228
|
+
inspect its adjacent `.workflow.lock` before deliberately removing it. Validation
|
|
229
|
+
or conflict failures leave the Case file unchanged and return 2. Filesystem
|
|
230
|
+
publication failures return 3.
|
|
231
|
+
|
|
232
|
+
Working files contain private analyst content and file references, not attachment
|
|
233
|
+
bytes. Use `case-pack` for a reviewed audience projection and a separate evidence
|
|
234
|
+
package for selected original files. Nothing is uploaded or reported automatically.
|
|
235
|
+
|
|
236
|
+
### Portable evidence files
|
|
237
|
+
|
|
238
|
+
Package selected files without changing their bytes, then verify the ZIP offline:
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
whoisleuth manifest evidence.json screenshot.png --workflow "Evidence review" \
|
|
242
|
+
--package --output evidence.zip
|
|
243
|
+
whoisleuth verify-artifact evidence.zip --package --json --strict-exit
|
|
244
|
+
whoisleuth manifest evidence.json screenshot.png --workflow "Evidence review" \
|
|
245
|
+
--folder ./evidence-project
|
|
246
|
+
whoisleuth verify-artifact --folder ./evidence-project --json --strict-exit
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Packages admit the 128-file, 64-MiB original selection plus one bounded Case
|
|
250
|
+
export, with a separate manifest allowance. Original-file limits remain unchanged.
|
|
251
|
+
`verify-artifact` uses the same exact ordinary Case reader as `case show`,
|
|
252
|
+
without repairing content. Package verification also reports original-reference
|
|
253
|
+
completeness for each Case file; `--strict-exit` returns 4 when a referenced original is missing.
|
|
254
|
+
An ordinary Case JSON file alone provides structural validity, not a checksum.
|
|
255
|
+
They use generated entry names, not original paths. Ordinary ZIPs and folders
|
|
256
|
+
are private and unencrypted; packaging does not redact selected files. The report distinguishes
|
|
257
|
+
file identity, supported source formats, opaque content, exact capsule/source
|
|
258
|
+
links and capture-manifest attachment matches. Include the capture manifest and
|
|
259
|
+
its screenshot/DOM-digest files together to check their declared bytes; original
|
|
260
|
+
filenames are not needed to establish a match. It does not import files or establish source truth, signature trust or a
|
|
261
|
+
trusted timestamp. Unsupported or rejected entries produce a partial report;
|
|
262
|
+
`--strict-exit` returns 4. Without `--package` or `--folder`, `manifest` produces a
|
|
263
|
+
standalone JSON manifest; exact public version-2 manifests remain readable.
|
|
264
|
+
|
|
265
|
+
For [BagIt 1.0](https://www.rfc-editor.org/rfc/rfc8493.html) interchange, use
|
|
266
|
+
`--bagit` with `--package` or `--folder` on both commands:
|
|
267
|
+
|
|
268
|
+
```sh
|
|
269
|
+
whoisleuth manifest evidence.json screenshot.png --workflow "Evidence review" \
|
|
270
|
+
--bagit --package --output bag.zip
|
|
271
|
+
whoisleuth verify-artifact bag.zip --bagit --package --json --strict-exit
|
|
272
|
+
whoisleuth manifest evidence.json --workflow "Evidence review" --bagit --folder ./bag
|
|
273
|
+
whoisleuth verify-artifact --bagit --folder ./bag --json --strict-exit
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
BagIt output contains unchanged files under `data/`, SHA-512 payload and tag
|
|
277
|
+
manifests, and the existing source-declaration manifest as a tag file. It is
|
|
278
|
+
unencrypted and cannot be combined with `--passphrase-file`. Verification also
|
|
279
|
+
accepts SHA-256. It checks every manifest, reports absent files and unsupported
|
|
280
|
+
algorithms, and never downloads `fetch.txt` locations. A valid result establishes
|
|
281
|
+
declared byte integrity, not source-format validity, authenticity or factual
|
|
282
|
+
accuracy. Unchecked tags remain explicit; reported entry names are generated.
|
|
283
|
+
|
|
284
|
+
The bounded reader accepts UTF-8 tags, safe relative paths up to 1,024 UTF-8
|
|
285
|
+
bytes and 16 levels, and the same payload byte/file allowances as evidence
|
|
286
|
+
packages. Tags have a separate allowance of 32 files, 512 KiB each and 2 MiB
|
|
287
|
+
combined. Symbolic links, special files, path collisions and unsupported ZIP
|
|
288
|
+
features are refused. BagIt itself does not impose these implementation limits.
|
|
289
|
+
|
|
290
|
+
For an encrypted ordinary package, supply a local passphrase file:
|
|
291
|
+
|
|
292
|
+
```sh
|
|
293
|
+
whoisleuth manifest evidence.json screenshot.png --workflow "Evidence review" \
|
|
294
|
+
--package --passphrase-file ./package-passphrase.txt --output evidence.wlep
|
|
295
|
+
whoisleuth verify-artifact evidence.wlep --package \
|
|
296
|
+
--passphrase-file ./package-passphrase.txt --json --strict-exit
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The file contains one UTF-8 line of at least 12 characters, at most 1,024 bytes.
|
|
300
|
+
Keep it private and separate from the package. Neither command uploads it or
|
|
301
|
+
includes it in its report. Version-1 encrypted packages protect the entire ZIP,
|
|
302
|
+
including its manifest. Unlocking authenticates the container before validating
|
|
303
|
+
file identities. The report's package digest identifies the decrypted ZIP;
|
|
304
|
+
its input byte count identifies the encrypted file. Wrong passphrases, corrupted
|
|
305
|
+
containers and unsupported versions exit 3 without a verification report.
|
|
306
|
+
Encryption does not establish authorship, factual accuracy or redaction, and
|
|
307
|
+
does not apply to folder exports or separately downloaded JSON backups.
|
|
308
|
+
|
|
309
|
+
Folders contain `manifest.json` and generated `artifacts/artifact-N` files.
|
|
310
|
+
Creation requires a new destination and never replaces an existing folder.
|
|
311
|
+
Failed writes can leave partial private output; inspect or remove it before
|
|
312
|
+
choosing another destination. Verification rejects symbolic links, unexpected
|
|
313
|
+
trees and unlisted files. Its package digest and byte count describe the
|
|
314
|
+
canonical stored-ZIP representation, not filesystem metadata. These are
|
|
315
|
+
selected evidence exports, not complete workspace backups.
|
|
316
|
+
|
|
317
|
+
### Resuming a fixed workflow
|
|
318
|
+
|
|
319
|
+
All recipes listed by `workflow-plan --list` can run through `workflow-run`.
|
|
320
|
+
Planning remains offline. Execution emits a checkpoint; terminal output shows
|
|
321
|
+
retained steps, output identities, missing inputs and the next required action.
|
|
322
|
+
A partial collection
|
|
323
|
+
pauses for review; resuming keeps that observation and does not collect it
|
|
324
|
+
again. Later steps can finish without making the earlier evidence complete:
|
|
325
|
+
the run still exits with code 4. Validation, usage and export failures remain
|
|
326
|
+
failures and are retried on resume. Step diagnostics stay on stderr, separate
|
|
327
|
+
from checkpoint JSON. New network steps still need `--approve-network`.
|
|
328
|
+
|
|
329
|
+
New runs connect compatible earlier outputs for domain triage, registry review,
|
|
330
|
+
historical comparison and handoff linting. For a complete domain-triage hand-off:
|
|
331
|
+
|
|
332
|
+
```sh
|
|
333
|
+
whoisleuth workflow-run domain-triage example.test --approve-network \
|
|
334
|
+
--json --output run.json
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Bindings accept Lookup outputs for export, diff, timeline, comparison, source
|
|
338
|
+
reports and briefs; evidence exports for verification; and Case-pack output
|
|
339
|
+
for sharing review. Remaining placeholders use `--select` in order;
|
|
340
|
+
for example, `--select diff=previous.json` keeps the current observation as the
|
|
341
|
+
second input. Supply every input for an uncompleted step to use files instead,
|
|
342
|
+
or override a connection with `--use-artifact <step-id>:<input-number>=<earlier-step-id>`.
|
|
343
|
+
Input numbers start at 1 and refer to the fixed recipe's placeholders.
|
|
344
|
+
`diff` compares saved observations of the same or different domains; `timeline`
|
|
345
|
+
orders observations of one domain. Candidate and domain-control intent inputs
|
|
346
|
+
remain analyst selections. No external file is inferred or extracted automatically.
|
|
347
|
+
`reconcile` lists each observation time and declared observer/vantage, keeping
|
|
348
|
+
disagreement and unavailable evidence separate. Distinct labels do not verify
|
|
349
|
+
independent collection; timing and shared caches can affect the comparison.
|
|
350
|
+
|
|
351
|
+
For example, registry review can reuse its collection without extracting files:
|
|
352
|
+
|
|
353
|
+
```sh
|
|
354
|
+
whoisleuth workflow-run registry-disagreement example.test --approve-network \
|
|
355
|
+
--json --output registry-run.json
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
The evidence-handoff recipe pauses before any human-review declaration. Review
|
|
359
|
+
the selected material and the listed declarations, then use
|
|
360
|
+
`--confirm-review package` or `--confirm-review lint` for that particular step.
|
|
361
|
+
Confirmation applies only to the current invocation and is not inferred from
|
|
362
|
+
the checkpoint. A completed recipe means its commands ran, not that an
|
|
363
|
+
investigation is resolved or sharing is authorised.
|
|
364
|
+
|
|
365
|
+
Optional `--interactive` asks for missing paths or values on terminal stderr,
|
|
366
|
+
keeping checkpoint JSON on stdout or in the selected output file. A blank answer
|
|
367
|
+
pauses. Prompts do not grant network approval or confirm review. Redirected input
|
|
368
|
+
and unattended runs use `--select` instead. Resuming a checkpoint preserves its
|
|
369
|
+
recorded connections; new defaults are not applied to old checkpoints.
|
|
370
|
+
|
|
371
|
+
Checkpoint version 3 reads versions 1 and 2. Older installations reject version
|
|
372
|
+
3. Checkpoints retain exact output schemas, content digests and input bindings;
|
|
373
|
+
changed identities or completed inputs are rejected. Digests identify content,
|
|
374
|
+
not source authenticity, truth or freshness. The checkpoint can contain
|
|
375
|
+
selected local paths and evidence; review it before sharing.
|
|
376
|
+
|
|
377
|
+
Use `--json --output state.json` for a resumable file, and add `--force` when
|
|
378
|
+
replacing it. File output holds private adjacent `.workflow.lock` files for
|
|
379
|
+
the selected resume and output paths until publication. Another writer is
|
|
380
|
+
refused; changes to either file during execution prevent replacement. State
|
|
381
|
+
files must be regular files without symbolic or additional hard links.
|
|
382
|
+
|
|
383
|
+
Locks contain only a local process ID and are removed after the run. Following
|
|
384
|
+
an interrupted process, confirm that its owner has stopped before removing its
|
|
385
|
+
abandoned lock. Locks have no automatic expiry. Shell redirection and external
|
|
386
|
+
editors do not participate in this cooperative file-ownership protocol.
|
|
387
|
+
|
|
388
|
+
### Formats and exit behaviour
|
|
389
|
+
|
|
127
390
|
Terminal text is the default. Commands expose JSON, JSONL, CSV, Markdown, HTML
|
|
128
391
|
or domain-only output only where declared by the installed registry. Redirected
|
|
129
392
|
and machine output contains no ANSI or transient progress text.
|
|
130
393
|
|
|
131
394
|
- `--summary` and `--verbose` change presentation, not collection.
|
|
395
|
+
Verbose Lookup includes retained technology signals and library advisory
|
|
396
|
+
identifiers. Their source times are separate; ages are measured at output
|
|
397
|
+
generation, not at a later replay.
|
|
132
398
|
- `lookup --browse` provides an interactive terminal view; press `?` for keys.
|
|
133
399
|
- `--events` writes versioned lifecycle events to stderr.
|
|
134
400
|
- `--strict-exit` and `--fail-on` expose selected evidence states to automation.
|
|
@@ -140,17 +406,26 @@ concurrency and observer labels. They cannot add targets, enable Deep
|
|
|
140
406
|
collection, choose output paths or approve network work. Explicit command
|
|
141
407
|
options override profile defaults.
|
|
142
408
|
|
|
409
|
+
`source-report` summarises collector-owned health envelopes in saved Lookup
|
|
410
|
+
and Bulk output. Raw publications and extension fields are not interpreted as
|
|
411
|
+
diagnostics, and missing health metadata remains unmeasured.
|
|
412
|
+
|
|
413
|
+
`mail-review` keeps failed input targets, incomplete DNS coverage and original
|
|
414
|
+
collection times visible. Source-output and review-generation times do not
|
|
415
|
+
stand in for missing observation times. `domain-change` and
|
|
416
|
+
`domain-change-packet` retain authority, resolver and certificate observation
|
|
417
|
+
times; previously published version-2 packets remain verifiable.
|
|
418
|
+
|
|
143
419
|
## Exit codes
|
|
144
420
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
| 143 | The process received SIGTERM. |
|
|
421
|
+
See the [exit-code reference](cli-reference.md#files-output-and-automation).
|
|
422
|
+
A completed command can still contain partial sources; use the selected
|
|
423
|
+
command's strict-exit policy when automation requires complete evidence.
|
|
424
|
+
|
|
425
|
+
For scripts, use `whoisleuth verify-artifact evidence.json --json --strict-exit`.
|
|
426
|
+
An incomplete verification returns **4** with that option. Without it, **0**
|
|
427
|
+
means a report was produced, not that the artefact passed verification; inspect
|
|
428
|
+
the report's state and checks.
|
|
154
429
|
|
|
155
430
|
## Command details
|
|
156
431
|
|
package/lib/abort.mjs
CHANGED
|
@@ -10,7 +10,10 @@ function abortable(operation, signal) {
|
|
|
10
10
|
const aborted = () => reject(abortReason(signal));
|
|
11
11
|
signal.addEventListener('abort', aborted, { once: true });
|
|
12
12
|
Promise.resolve()
|
|
13
|
-
.then(
|
|
13
|
+
.then(() => {
|
|
14
|
+
signal.throwIfAborted();
|
|
15
|
+
return operation();
|
|
16
|
+
})
|
|
14
17
|
.then(resolve, reject)
|
|
15
18
|
.finally(() => signal.removeEventListener('abort', aborted));
|
|
16
19
|
});
|