AugmentClaude

CTI Expert

Conduct cyber threat intelligence and OSINT investigations with analyst-grade sourced findings.

Installation

  1. Make sure Claude is on your device and in your terminal.

    Skills load from ~/.claude/skills/ when Claude Code starts up β€” so you need it on your machine first. If you don't have it yet, install it once with the command below, then run claude in any terminal to verify.

    One-time setup
    npm i -g @anthropic-ai/claude-code

    Already have it? Skip ahead.

  2. Paste into Claude Code or into your terminal.

    This copies the whole skill folder into ~/.claude/skills/cti-expert-7onez/ β€” the SKILL.md plus any scripts, reference docs, or templates the skill ships with. Safe default: works for every skill.

    Faster alternative (instruction-only skills)

    Skips the clone and grabs only the SKILL.md file. Don't use this if the skill ships Python scripts, reference markdowns, or asset templates β€” they won't be downloaded and the skill will fail when it tries to load them.

    Quick install (SKILL.md only)
    Sign up to copy
  3. Restart Claude Code.

    Quit and reopen Claude Code (or any other agent that loads from ~/.claude/skills/). New skills are picked up on startup.

  4. Just ask Claude.

    Skills auto-activate when your request matches the skill's description β€” no slash command needed. Trigger phrases live in the skill's own frontmatter; you can read them in the β€œWhat this skill does” section above.

Prefer to read the source first? Open on GitHub.

When Claude uses it

Cyber threat intelligence and OSINT analysis toolkit. Runs structured investigations and delivers analyst-grade intelligence products with sourced, trust-scored findings. Use for OSINT and CTI cases, digital-footprint and exposure review, domain/subdomain/DNS/certificate recon, web-infrastructure pivoting (favicon hashes, tracker IDs, TLS certs, phishing-kit fingerprinting, campaign clustering), username/email/phone enumeration, breach and infostealer-log triage, image forensics, geolocation, crypto-wallet and IBAN/bank-account tracing, darknet search, M365/Azure and SaaS tenant recon, China/Sinophone recon (ICP filings, PRC corporate registries, Baidu/FOFA/Quake/ZoomEye), vulnerability and ransomware lookup, threat modeling, PII redaction, and structured reporting. Commands include /case, /sweep, /query, /webpivot, /username, /phone, /email-deep, /breach-deep, /icp, /cn-corp, /iban, /stealer-log, /exposure, /threat-model, /report, /brief, /redact, /apikeys.

What this skill does

CTI Expert

Cyber threat intelligence and open-source intelligence skill. Turns Claude into a trained CTI/OSINT analyst. Generates precision search queries, interprets public data, builds case timelines, and delivers structured intelligence products β€” no API keys, no paid subscriptions.

Runs anywhere. Works in Claude Code (Desktop & CLI) and in OpenAI Codex / ChatGPT and other AGENTS.md-aware agents β€” see AGENTS.md for the cross-agent runtime contract. Throughout this file, $SKILL_DIR = the directory containing this SKILL.md (Claude Code: ~/.claude/skills/cti-expert; Codex/manual clone: the repo you are working in). Resolve it by locating SKILL.md β€” never hard-assume ~/.claude. Detect the OS once (Windows/macOS/Linux) and prefer uv for all Python β€” see Β§13 Tool Auto-Install Policy.

Collection method: agent-browser when available (JavaScript-heavy sites, infinite-scroll, screenshot evidence), with automatic fallback to web search / web fetch / direct URL fetch. Tool limitations are logged as collection gaps β€” never as case blockers.


1. Quick Start

# Full autonomous case β€” runs every applicable technique
/case target.com

# Guided flow for first-time investigators
/flow person

# Summary of what's been found so far
/brief

Append --yolo to any command to skip all interactive prompts and confirmations. The analyst makes every decision autonomously.


2. AEAD Case Lifecycle

Every investigation follows four phases:

PhaseWhat Happens
AcquireCollect raw data β€” /sweep, /query, /username, /phone, /email-deep, /subdomain, /webpivot + /icp (domain/URL targets), /cn-corp Β· /iban Β· /hash-id on discovery
EnrichRecursive pivot loop β€” the pivot orchestration engine treats every discovered identifier as a new seed and expands the graph hop-by-hop (/branch, /crossref, /link-subjects, /signatures) automatically until the frontier is exhausted, no approval prompts (autonomy=auto). Acquire↔Enrich iterate, not run once.
AssessScore and verify β€” /exposure, /threat-model, /validate, /coverage, /verify-finding. Judgments carry likelihood terms, coverage gets the 5W1H pass, attributions get an ACH matrix (handbook/analytic-standards.md)
DeliverPackage output β€” /report, /brief, /render, /workspace save β€” auto-saves .md + .html + .json + .csv + IOC bundle

Run /progress at any point to see which phase you're in and what's pending.

/case and web-infra pivoting. For a domain or URL target, /case includes web-infrastructure pivoting (/webpivot) in the Acquire phase. It runs keyless by default (crt.sh + passive DNS + anonymous urlscan) and upgrades automatically when premium keys are set via /apikeys (Shodan/Censys/FOFA/DNSLytics/SecurityTrails/urlscan-PRO/WhoisXML). Because /webpivot can fetch the target directly, for hostile infrastructure it prefers passive capture (urlscan/Wayback) β€” see techniques/web-pivot.md. It is not run for username/phone/person targets.

Archive IOC harvest runs by default too. For domain/URL targets the Acquire phase also runs wayback_harvest.py <domain> --indicators (add --urlscan when URLSCAN_API_KEY is set), harvesting emails, phones, crypto wallets, tracking/verification IDs, SaaS-operator IDs, and socials from the entire Wayback history β€” not just the live page β€” with first-seen/last-seen per selector. It writes case-schema indicators[] to <case>/raw/harvest.indicators.json, which merge into the case and flow into the auto-saved IOC bundle at Deliver. This is the step that recovers selectors a network later scrubbed β€” across the whole snapshot corpus, not just the live page. Passive by construction β€” only web.archive.org (+ urlscan.io if keyed), never the target.

The five v2.6 commands are in the pipeline too β€” no flags. /icp runs for every domain/URL/org target (and an IP's resolved hostname); /cn-corp, /iban and /hash-id fire the moment a company name/USCC, payment detail, or hash appears β€” and all three feed their yields back into the recursive pivot loop as new seeds, so an ICP licence serial or a reused bank account expands the graph like any other node. /redact is the exception: it is opt-in (--redact), because a redacted report is a weaker artifact and that should always be a deliberate choice. Full trigger table: Β§Technique Activation Matrix. Narrow with --no-cn.

Two layers, one skill: broad collector β†’ deep pipeline. cti-expert is the broad collector β€” the wide net of Acquire/Enrich commands (/webpivot, /sweep, /subdomain, /icp, /username, /email-deep, /breach-deep, …) that pull artifacts from anywhere. The intel_engine engine is now vendored in-repo under intel_engine/ (intel_engine/harness/, intel_engine/tools/, intel_engine/WebPivot/, intel_engine/IntelGraph|IntelReport|BinaryPivot|IntelAnalysis/) and supplies the pipeline chains + deeper pivoting logic: a persistent knowledge base (intel_engine/knowledge/), versioned cases (cases/), cross-case correlation, calibrated assessment, and rendering.

The chain: broad collection (cti-expert) β†’ the pipeline (/pipeline, /harness) ingests it, then applies the deep logic β€” "seen this operator before?" (/recall), whole-KB clustering (/kb --cluster, /cert-overlap), false-positive control (/reference), risk scoring (/risk), hypothesis generation, confidence calibration, and a versioned Assessment. The pipeline drives cti-expert's own scripts/webpivot/pivot_extract.py collector, so the broad and deep layers share one artifact shape end-to-end.

Self-contained & self-resolving. /backend resolves to SELF (in-repo) β€” no external setup. Deps: uv venv && uv pip install -r requirements.txt (harness SDK/MCP + IntelGraph renderers; the collector + KB + deterministic pipeline are stdlib and need none). An explicit $INTEL_HOME still overrides for a shared external KB. Full architecture, the op map, and the evidence-envelope schema: connectors/intel-backend.md.


2.5. Pivot Priority & False-Positive Control (CRITICAL)

Two failure modes ruin a cluster: asserting a link that isn't there, and missing one that is. This section governs both. Apply it in Enrich, before anything reaches a report.

Pivot priority ladder

Work down this ladder. Never assert same-operator on a lower rung when a higher rung is available or contradicts it. Tag every asserted link in the report with the rung it rests on.

RungIndicatorStrength
1Registrant email / phone / org β€” including historic WHOISdecisive
2One domain carrying two identities across its own WHOIS historydecisive β€” proves an alias
3Site-verification token (Google Search Console, etc.)decisive β€” proves account control
4Shared TLS certificate / SAN cross-coverstrong
5Nameserver delegation to a host the operator runs themselvesstrong β€” proves zone control
6APK signing certificatestrong
7Distinctive favicon / analytics / tracker / backend tenant IDmoderate β€” verify below
8Co-tenancy on a dedicated host (few tenants)moderate
9Site template / framework / kitweak β€” kit-level, never operator-level
10Co-tenancy on shared/reseller hosting; managed-provider nameserversinformation, not a link

Reverse-WHOIS is the highest-yield pivot here. Always mode=preview first β€” the count is free. A term returning hundreds is shared boilerplate; do not purchase it.

Mandatory false-positive control

Before any indicator becomes a cluster edge, run /reference check <value>. If it returns UNKNOWN, decide and record it with /reference add so the next case inherits the judgement.

Six traps, all of which have produced real false clusters:

TrapWhy it fools youTest
Commodity site kitA template sold to hundreds of unrelated fraud operatorsSearch the template path in urlscan/FOFA β€” a large population means kit-level
Privacy-proxy contactsThe registrar's boilerplate phone/email, shared by every customer of that serviceReverse-WHOIS it; a spread of unrelated domains means noise
Shared/reseller hosting IPA 20+-tenant cPanel box links nothingCount tenants before clustering
Managed-provider nameserversCloudflare/GoDaddy/Gandi/Wix NS are shared by millionsSelf-hosted NS is rung 5; provider NS is rung 10
Org-name collisionA registrant org string that also matches a real, unrelated companyReverse-WHOIS the org; inspect what comes back before attributing
Shared analytics / tag containerOften one web developer reusing a container across unrelated clientsCheck domain creation dates β€” a decade-old business sharing a tag with a new fraud domain is a third party

Never put an unvalidated indicator into a report that recommends abuse reporting. Naming an uninvolved business is the most damaging error this skill can produce. When a cluster rests on a single rung-7-or-below indicator, label it candidate, single-indicator β€” not a cluster member.

Never submit the case's own sample to a public sandbox (CRITICAL)

/anyrun is lookup-only. It reads detonations that already happened; it has no submit path, and the submission endpoint is deliberately absent from BinaryPivot/references/anyrun.json. tests/test_no_sample_submission.py enforces that as a gate, so it cannot regress quietly.

Do not work around it. Uploading the case's own APK / installer / archive to ANY.RUN β€” or VirusTotal, or any public sandbox β€” is an outbound, irreversible act:

  • A public task is world-readable: the file, its hash, screenshots and full network log.
  • Operators watch for their own samples. The standard response is to rotate the backend, revoke the signing key and re-skin the front β€” destroying the infrastructure the case is built on, often days before a takedown or referral can land.
  • It cannot be recalled. Unlike a query from the wrong egress, there is no cleanup.

If detonation is genuinely necessary, stop and put it to the analyst in plain terms β€” what becomes public, and that it is permanent β€” and let them do it themselves in the sandbox UI on a private plan. Never as a side effect of a pivot, and never on standing permission inferred from an earlier approval. The same reasoning governs --submit (urlscan/Wayback): a public urlscan scan of a live scam funnel is visible to the operator too.

A permuted email is a hypothesis, never a finding (CRITICAL)

When a case yields a real person's name or a username, and you already hold a domain that matters to the case, run /email-permute. An operator's mailbox is almost never published, but it is usually derivable β€” mail hosts use a small set of local-part conventions, and the operator's own domain is the highest-yield thing to permute against.

That value comes with a matching hazard, so this rule is absolute:

  • Permute against the case's own domains. Name Γ— the operator's domain is a narrow, high-prior question. Name Γ— gmail.com is volume with no prior behind it β€” --free exists, is capped, and should be a deliberate choice, not a reflex.
  • Never ingest a candidate into the KB, cite one in a report, or contact one. A fabricated address that reaches kb_ingest becomes a shared indicator, and a shared indicator merges two operator clusters. A permutator wired straight into correlation does not enrich a case β€” it silently names an innocent party. This is the same failure RULE 5 exists to prevent.
  • Candidates are not seeds. They never enter the spider-map frontier. Only an address in the tool's promote list β€” corroborated by independent evidence (Gravatar registration, breach corpus, a GitHub commit, a page/DOM hit, a dork) β€” may be treated as a real email seed, and that promotion is an analyst decision.
  • Never validate over SMTP. RCPT TO probing connects to the target's mail server, which the egress posture exists to prevent on a hostile case; and a catch-all domain answers 250 for every address ever tried, so it manufactures confidence instead of measuring it. Use --verify, which gates on MX (RFC 7505 null MX included) and checks Gravatar β€” both keyless, neither touching the target.

State the status in the turn. "12 candidates, 0 corroborated" is an honest result; presenting those 12 as discovered addresses is not.

Dead seed? Do not stop

Zero pivots, a parked page, or NXDOMAIN is not an answer. Run /fallback <domain> β€” crt.sh, the full Wayback timeline, archive.today, and the local KB. A parked apex frequently has live subdomains: enumerate CT and the Wayback CDX host histogram before writing a seed off. Report an empty result as empty; a collector that returned nothing is a finding, not something to omit.


3. Command Reference

3.0 Entry point & registered commands

/cti <target> is the single entry to this skill. It routes any target type β€” domain, IP, email, username, phone, wallet, hash, APK β€” through recall β†’ collect β†’ cluster β†’ assess. Plain English works identically ("analyze example.com and pivot the infrastructure"); the command form just removes ambiguity.

Eight commands are registered with Claude Code by bash scripts/register.sh and work from a cold prompt in any project:

CommandDoesEquivalent T2 opEquivalent T1 tool
/cti <target>entry point β€” routes by target type(whole chain)(whole chain)
/cti-recall <seed>seen before? run first, alwaysrecalldomain_verdict, which_cases
/cti-case <ID> <seeds>full deterministic pipelinepipeline open(none β€” CLI only)
/cti-pivot <url|ip>collect one targetpivot-extractpivot_extract
/cti-cluster <domain>correlate & expandkb, cert-overlapkb_cluster, cert_overlap
/cti-check <indicator>false-positive controlreference checkreference_check, reference_add
/cti-report <ID>render graph + PDF/DOCXgraph, reportrender_diagram, render_report
/cti-statusbackend / MCP / credits healthbackend.py statusapi_usage

Every other /command in Β§3 is a convention read from this file, not a registered command. Once the skill is loaded they are unambiguous instructions; typed at a cold prompt they do nothing. When in doubt use /cti and describe the goal.

Three layers, one operation. The same capability is reachable three ways and the names differ by layer β€” T0 uses kebab-case after a slash, T2 uses kebab-case ops, T1 uses snake_case tools. The table above is the canonical mapping; when you add a capability, add a row here in the same commit or the layers drift apart again.

Capabilities that are not registered commands still carry their layer mapping inline in the Β§3 tables. The engine's WebPivot/BinaryPivot collectors add these: /capabilities (T2 capabilities, T1 capability_check), /impersonate (T2 impersonate, T1 impersonation_hunt), /search-pivot (T2 search-pivot, T1 search_pivot), /censys (T2 censys, T1 censys), /intelx (T2 intelx, T1 intelx_search) and /anyrun (T2 anyrun, T1 anyrun_lookup).


Commands grouped by AEAD phase.

Acquire

CommandWhat It DoesExample
/case [target]Full pipeline β€” runs every applicable technique/case example.com
/sweep [target]Multi-vector recon on any target type/sweep @username
/query [subject]Builds 12–15 advanced search operator queries/query example.com
/username [handle]Enumerate handle across 3000+ platforms/username johndoe
/phone [number]Carrier, line type, reputation, public associations/phone +84901234567
/email-deep [email]Accounts, breach history, infrastructure/email-deep u@domain.com
/subdomain [domain]CT logs, brute-force, passive enumeration; flags admin/sensitive subdomains (admin,adm,kef,ador,panel…) per handbook/admin-endpoint-indicators.md/subdomain example.com
/breach-deep [email]Multi-source breach lookup with context/breach-deep u@domain.com
/traffic [domain]Traffic estimation, ranking, audience data/traffic example.com
/visitors [domain]Full visitor intelligence: tech, geo, sources, analytics/visitors example.com
/techstack [domain]Technology fingerprint (CMS, analytics, CDN, server)/techstack example.com
/competitors [domain]Competitor & related site discovery/competitors example.com
/secrets [target]Exposed credentials in repos and paste sites/secrets github.com/org
/github-osint [target]GitHub user/org/repo recon: profiles, repos, code search, commits, forks/github-osint github.com/org/repo
/threat-check [target]IP/domain/URL/hash threat intelligence/threat-check 185.1.1.1
/scam-check [domain]Phishing/scam/malicious domain check/scam-check susp-site.xyz
/webpivot [url]Web-infra pivoting β€” extract favicon mmh3 / GA-GTM-AdSense / wallet / SaaS-operator artifacts from a page's DOM β†’ ranked pivot queries (Shodan/PublicWWW/urlscan/FOFA). Flags: --render, --crawl, --history (Wayback GA), --fetch (pull archived page content β€” WebFetch can't reach Wayback), --harvest (full-IOC harvest across whole archive history β†’ emails/phones/wallets/IDs/socials), --whois, --graph (cluster), --rank (score same-operator relations), --cert (cert-fingerprint pivot), --suggest, --wallets, --paths. See techniques/web-pivot.md (reverse-lookup engines per artifact β†’ handbook/pivot-services.md)/webpivot https://scam-site.top
(automatic β€” no flag)Four layers now run on every collection and need no command. Asset layer: fetches the page's own JS bundles and re-runs every extractor over the source β€” the fix for SPA/white-label kits where the shell HTML is empty; yields off-apex api_endpoint/websocket_endpoint (the backend survives a front-end re-skin), build_env:<KEY> tenant tokens, js_bundle_sha256, and via sourceMappingURL the operator's own dev_username/dev_project. SPA route table: reads the app's router literals β€” spa_route:admin, spa_route:funnel, and a spa_route_signature that survives a re-skin. Zero extra requests, routes are leads only and are never fetched. Well-known/policy files: a fixed standards list (never a wordlist, no path brute-forcing) β†’ adstxt_publisher, apple_team_id, security_contact. JARM: TLS-stack fingerprint of the server. Suppress with --no-assets / --no-well-known; cap fetches with --assets-max N(runs inside /cti-pivot)
/capabilitiesRun this first, and again before reporting any "nothing found". Which optional API keys are configured, and for each absent one the evidence class that went unqueried plus the free path that substitutes. A keyless run extracts every artifact but cannot reverse most of them β€” so "no sibling domains" with no FOFA/urlscan key is a fact about the credentials, not about the operator. Every collection also records this in meta.capability; carry the limitation statement into the assessment and cap confidence accordingly. T2: capabilities Β· T1: capability_check/capabilities
/impersonate [domain]Hunt lookalike / typosquat domains of a seed β€” typosquat permutations (omission, insertion, adjacent-key, transposition, homoglyph, hyphenation, combosquat) + a curated scam-heavy TLD sweep + a crt.sh keyword hunt, then existence-checked by live DNS. Output separates confirmed registered lookalikes (each an impersonation:candidate β€” run /cti-pivot on it and compare) from an unregistered monitoring watchlist. FREE (crt.sh + DNS); --fofa / --urlscan add the metered sweeps. Never live-fetches the lookalike infra. Tune the TLDs/affixes per campaign in intel_engine/WebPivot/references/impersonation.json. T2: impersonate Β· T1: impersonation_hunt/impersonate example.com
/search-pivot [indicator]Multi-engine search-engine pivot β€” the general-web complement to FOFA/PublicWWW, which only see served HTML. Takes any indicator (domain, slogan, tracking ID, wallet, Telegram/Zalo handle) and emits ready-to-open, URL-encoded dork queries across Google/Yandex/DuckDuckGo/Bing/Brave. It does not scrape: fire the queries with WebSearch, or WebFetch the DuckDuckGo html URL, then feed new hosts back into /cti-pivot. FREE, no keys. T2: search-pivot Β· T1: search_pivot/search-pivot "distinctive slogan"
/censys [mode] [value]Censys Platform β€” the server-side view FOFA/urlscan don't give. cert <sha256> returns every hostname on that exact leaf certificate (near-decisive cross-brand same-operator evidence, and it works on a free plan); host <ip>, webproperty <host> also free-plan. query <kind> <value> builds the CenQL offline and keyless; budget reports the balance. ⚠️ 100 credits/MONTH per account, no rollover β€” a lookup is 1, a search 5, and running the emitted CenQL in the web UI costs the same 5. Prefer handing the analyst the query over spending a search. Needs CENSYS_PAT. T2: censys Β· T1: censys/censys cert 1a2b3c…
/intelx [selector]Intelligence X β€” search ONE strong selector across a corpus nothing else here indexes: breach dumps, infostealer logs, pastes, darknet mirrors, historical WHOIS. Takes an email / domain (*.apex wildcard ok) / URL / IP / phone / wallet / IBAN β€” never a brand or person name (soft terms are refused and still cost a unit; classify_selector() blocks them locally). --phonebook <domain> inventories every email, subdomain and URL under an apex β€” the highest-value call, PAID-only. Grading is not optional: a hit in a breach dump or stealer log is EXPOSURE, flagged NOT clusterable β€” two addresses in one combolist share victims, not an operator. Only whois / pastes / darknet hits may carry a same-operator edge. Keyless β‰ˆ 50%: it still types the selector and hands you the intelx.io URL. T2: intelx Β· T1: intelx_search/intelx registrant@example.com
/anyrun [indicator]ANY.RUN TI Lookup β€” READ-ONLY. What samples carrying this indicator did when other people detonated them: contacted domains/IPs/URLs/ports, family label, Suricata context, public task links. Run it after /binary on the sample's sha256, backend host or ip:port. It is the only way to recover a packed sample's real endpoints β€” those exist only at runtime, so a thin string sweep plus a binary:protection finding is exactly the cue. A shared family is same-KIT, never attribution on its own. Keyless β‰ˆ 50%: composes the query + UI link. ⚠️ This tool never submits a sample β€” see the box below. T2: anyrun Β· T1: anyrun_lookup/anyrun <sha256>
/cert-pivot [domain]Cert-fingerprint pivot β€” other hosts serving the same TLS cert + SAN siblings (keyless; Shodan/Censys with keys)/cert-pivot scam-site.top
/sensitive-paths [list]Classify a Wayback/URL list for exposed paths (.git/.env/backups/configs) β€” severity + per-year timeline/sensitive-paths waymore_index.txt
/email-hygiene [email]Grade an email domain 0–100 + A–F (disposable/MX/free/role)/email-hygiene admin@site.top
/vuln-check [query]CVE/vulnerability lookup (CIRCL + NVD)/vuln-check CVE-2024-1234 or /vuln-check apache/httpd
/ransomware-check [org]Check if org is a ransomware victim/ransomware-check "Acme Corp"
/stealer-log [folder]Triage an infostealer-log folder β€” stealer-family attribution, victim-vs-operator profiling, cross-log actor correlation, IOC extraction (raw passwords/cookies/autofill/history shown)/stealer-log ./logs
/gdoc [url]Extract metadata/owner from Google document/gdoc https://docs.google.com/...
/msftrecon [domain]M365/Azure tenant recon β€” tenant ID, federation, MDI, SharePoint/msftrecon example.com
/icp [domain|serial]ICP filing (ε·₯δΏ‘ιƒ¨ε€‡ζ‘ˆ) β†’ registered PRC entity + licence number; reverse the licence serial to sibling domains under the same filing (same-operator, HIGH). See techniques/china-recon.md/icp scam-site.top
/cn-corp [name|USCC]PRC corporate registry chain β€” GSXT (ground truth) β†’ TianYanCha/QCC/Aiqicha β†’ 俑用中国 blacklist β†’ UBO; officers, shareholders, subsidiaries, revoked-status flags/cn-corp ζ·±εœ³εΈ‚ζŸζŸη§‘ζŠ€ζœ‰ι™ε…¬εΈ
/iban [value]Validate + decompose a bank account as a selector β€” mod-97 checksum, country, BBAN split, bank code, jurisdiction-mismatch signals. See techniques/fiat-payment-osint.md/iban GB29NWBK60161331926819
/hash-id [hash]Identify a hash's algorithm before lookup β€” separates file hashes from credential material (32 hex = MD5 or NTLM) so it routes to the right service/hash-id 5f4dcc3b5aa765d61d8327deb882cf99
/appliance-scan [domain|ip]Fingerprint internet-facing edge/VPN appliances (Citrix/F5/Cisco/Ivanti/Forti/PAN/Exchange) + exposed services β†’ CISA KEV/CVE mapping. Passive-first (Shodan InternetDB/Censys); feeds /vuln-check + /threat-model. See techniques/fx-edge-appliance-recon.md/appliance-scan vpn.example.com
/saas-map [domain]Map SaaS tenancy + identity fabric β€” DNS-TXT tenancy tokens, non-Microsoft IdP fingerprint (Okta/Auth0/OneLogin/Ping/Keycloak/ADFS), unauth API/GraphQL/spec discovery. See techniques/fx-saas-identity-recon.md/saas-map example.com
/sharelink [url]Extract sharer identity from share link/sharelink https://vm.tiktok.com/ABC
/binary [file|url]Built-in. Static IOC extraction from a scam/fraud binary (sideloaded APK, desktop trading .exe/.dmg, bundled .jar) via the in-repo BinaryPivot/ β€” signing-cert SHA-256, package name/permissions, embedded C2/backend hosts, Firebase/S3 tenants, wallets, Telegram/WhatsApp handles. Output is WebPivot-shaped β†’ clusters the app with web infra in the shared KB. See connectors/intel-backend.md Β§7/binary ./trader.apk
<!-- dork-integration:phase-05 start -->

| /dork-sweep [target] [--telegram\|--docs\|--filetype\|--all] [--after DATE] [--clean] | Zero-auth dork sweep: Telegram ecosystem, 18 doc-hosts, filetype families; 4-tier fallback cascade | /dork-sweep example.com --filetype | | /docleak [target] [--platform list] [--severity high] | 18-platform document leak hunt with severity classification (CRITICAL/HIGH/MEDIUM/LOW) | /docleak "Acme Corp" |

<!-- dork-integration:phase-05 end -->

| /dns-history [domain] | Historical DNS record changes (A, NS, MX) via passive DNS | /dns-history example.com | | /cert-history [domain] | SSL/TLS certificate timeline from CT logs (crt.sh) | /cert-history example.com | | /email-permute [name] [domain] | Generate email permutations from name + domain | /email-permute "John Smith" company.com | | /proton-check [email] | Proton Mail account creation date via PGP key | /proton-check user@proton.me | | /pgp-lookup [email] | PGP key search β€” creation date, UIDs, signatures | /pgp-lookup dev@example.com | | /wifi [ssid] | WiFi SSID geolocation via Wigle.net | /wifi "HomeNetwork" | | /wifi --bssid [mac] | Exact AP lookup by MAC address | /wifi --bssid AA:BB:CC:DD:EE:FF | | /register [name] | Add a subject to the case workspace | /register JohnDoe | | /snapshots [url] | List/fetch archived Wayback snapshots. Note: WebFetch is blocked from web.archive.org (robots.txt) β€” use scripts/webpivot/wayback_fetch.py to list captures and pull archived content. See analysis/archive-explorer.md | /snapshots example.com |

Enrich

CommandWhat It DoesExample
/branch [data]Expand a discovered identifier laterally/branch john@mail.com
/pivot-suggestRank "what to pivot on next" from findings β€” leet/variant/reuse/temporal/domain clusters/pivot-suggest
/email-permute [name|handle]Derive email candidates from a person name or username against case domains. VN/CN/KR family-name-first aware; folds diacritics Unicode won't. --verify = MX gate + Gravatar. Output is hypotheses β€” see the rule below/email-permute "Nguyen Van A" --domain example.com --verify
/rank-relationsScore + rank same-operator relations across analyzed pages (noise-filtered, clustered)/rank-relations
/crypto-balance [addr]On-chain balance + lifetime flow for a wallet, valued at spot/crypto-balance 1A1z…
/timeline [subject]Assemble dated event sequence/timeline Company Inc
/crossrefDetect shared identifiers across subjects/crossref
/link-subjects [A] [B]Define a connection between two subjects/link-subjects John Jane
/show-connectionsDisplay all logged connections/show-connections
/show-trail [subject]Show the evidence chain for a subject/show-trail JohnDoe
/watch [subject]Add subject to active tracking list/watch example.com
/record-findingLog a finding with source and confidencePaste data after command
/show-findingsList all recorded findings/show-findings
/graphFull ASCII subject relationship map/graph
/pathfind [A] [B]Discover connection path between subjects/pathfind A B
/diff [url]Diff archived versions of a URL/diff example.com/page

Assess

CommandWhat It DoesExample
/exposure [target]Composite exposure score (0–100)/exposure domain.com
/threat-modelBuild threat model from findings; every attribution claim carries an ACH matrix (competing hypotheses scored by inconsistency, runner-up named) per handbook/analytic-standards.md Β§3. Backend hook (Assess): if /backend is up, calibrate confidence on your own priors first β€” intel.py operators list + intel.py risk --case <id> + read knowledge/{calibration.jsonl,analyst_profile.md} β€” instead of scoring from scratch. See connectors/intel-backend.md Β§6/threat-model
/signaturesSurface recurring behavioral patterns/signatures
/validateQuality audit β€” score 0–100/validate
/coverageCoverage matrix with identified gaps β€” technique matrix plus the 5W1H substantive pass (Why/How unanswered blocks Deliver-ready)/coverage
/verify-finding [id]Re-check a specific finding's sources/verify-finding 12
/subject [name]View or create subject record/subject JohnDoe
/lookup [name]Retrieve a registered subject/lookup JohnDoe
/modify [name]Update a subject record/modify JohnDoe
/archive-subject [name]Remove subject from active tracking/archive-subject JohnDoe
/find [query]Search across all subjects/find domain:example.com
/show-trail [subject]Full evidence trail/show-trail JohnDoe
/blind-spotsPrioritized investigation gap analysis/blind-spots
/source-checkBatch source URL accessibility check/source-check
/drift [subject]Temporal risk score tracking/drift example.com
/clarify [finding]Plain-language finding explanation/clarify fnd-003

Deliver

CommandWhat It DoesExample
/reportFull report β€” auto-saves .md + .html + .json + .csv + IOC bundle/report
/report htmlInteractive self-contained HTML report (primary deliverable)/report html
/report briefSingle-page executive brief/report brief
/report jsonRaw data as JSON/report json
/report csvSpreadsheet-compatible export/report csv
/report docxWord document (rich charts/diagrams) β€” on request/report docx
/report legalEvidence-formatted for legal proceedings (adds DOCX/PDF)/report legal
/report journalistSource-citation-heavy format/report journalist
/briefPlain-language summary (non-technical)/brief
/render entitiesASCII subject relationship diagram/render entities
/render timelineChronological event chart/render timeline
/render riskExposure heatmap/render risk
/render networkNetwork topology of connections/render network
/statsCounts and coverage statistics/stats
/workspace save [name]Persist case state/workspace save mycase
/workspace open [name]Resume a saved case/workspace open mycase
/workspace listShow saved cases/workspace list
/workspace diff [a] [b]Diff two saved workspaces/workspace diff case1 case2
/render threat-pathASCII attack path flow diagram/render threat-path
/render attack-surfaceASCII attack surface exposure map/render attack-surface
/report iocExport IOCs as STIX 2.1 or flat list/report ioc --format stix
/redact [file]Shareable variant of a report β€” stable numbered placeholders ([EMAIL_1]) + reversible JSON map; .md/.json/.csv. Opt-in β€” the default export set stays unredacted; request with /redact or --redact/redact REPORT.md

UX & Navigation

CommandWhat It DoesExample
/flow [type]Guided step-by-step case workflow/flow person
/template listBrowse pre-built case templates/template list
/template run [name]Run a pre-built template/template run security-audit
/noviceToggle simplified, low-jargon mode/novice
/termsOSINT term glossary/terms
/progressCurrent case phase and coverage/progress
/opsecOPSEC checklist for current task/opsec
/onboardInteractive first-time onboarding guide/onboard
/qualityInvestigation quality composite score/quality

Configure

CommandWhat It DoesExample
/apikeysManage premium/pro API keys (Shodan, Censys, FOFA, SecurityTrails, DNSLytics, urlscan-PRO, WhoisXML, Hudson Rock, IntelX, GitHub, SerpAPI…) β€” status/set/unset/test/unlocks. Keys upgrade existing techniques (especially /webpivot); keyless/free stays the default. Stored chmod-600 in $SKILL_DIR/.env (gitignored), env-var override. See handbook/api-keys.md/apikeys set shodan <KEY>
/backendDetect/report the optional persistent-intelligence backend and pick the tier β€” Tier 1 typed MCP (intel-harness) β†’ Tier 2 CLI β†’ Tier 3 stateless. Runs scripts/backend/backend.py to resolve $INTEL_HOME (env β†’ .mcp.json β†’ sibling dir β†’ symlink) and print the tier line. All the backend commands below dispatch through scripts/backend/intel.py <op> at Tier 2 (or the typed MCP tool at Tier 1). intel.py list maps all 69 engine ops (full CLI parity β€” CDN ranges, graph-build, hypothesize, calibration, evidence-report, case-store, cost, deterministic pipeline, …); intel.py mcp prints/writes the .mcp.json that enables Tier 1 ("the server"). See connectors/intel-backend.md/backend Β· /backend check
/kb [query]Built-in. Query the shared knowledge base. T2: intel.py kb --stats/--entity <v>/--cluster <domain>/--shared --min N; intel.py operators list. T1: kb_entity/kb_cluster/kb_query_shared/kb --entity example.com
/recall [seed]Built-in. "Have I seen this before?" β€” check a seed against every prior case before collecting. T1: which_cases/domain_verdict (typed MCP). T2: intel.py recall <seed> (query.py --entity; which_cases/domain_verdict are MCP-only). Surfaces known operators up front/recall scam-site.top
/risk [case]Built-in. Score a case's hosts for NRD / bulletproof-hosting / money-trail red flags. T2: intel.py risk --case <id> (or --file <pivot.json>). T1: risk_signals/risk CASE-0001
/reverse-whois [email|name]Built-in. Reverse-WHOIS a registrant identity β†’ only high-value pivots; refuses privacy/registrar terms, flags bulk resellers as noise. T2: intel.py reverse-whois --reverse-email <e> --search-type historic --json. T1: reverse_whois/reverse-whois owner@x.com
/cert-overlap [d1 d2 …]Built-in. KB-aware TLS/SAN same-operator verdict (SHARED-CERT / SIBLING-OVERLAP / NO-CT-OVERLAP) across 2+ domains β€” corroborates a cluster at the TLS layer. Complements the keyless /cert-pivot. T2: intel.py cert-overlap a.com b.com. T1: cert_overlap/cert-overlap a.com b.com
/reference [check|add|list]Built-in. Curated false-positive control ledger β€” is a fingerprint BENIGN (common logo/CDN β†’ don't cluster), SIGNAL (distinctive, prior-case β†’ pivot), or UNKNOWN. T2: intel.py reference check <value>. T1: reference_check/reference_add/reference check favicon:123
/pipeline [open|status] <case> <domains-file>Built-in. The deterministic chain (no LLM key) β€” the bread-and-butter handoff: broad collect (cti-expert's pivot_extract) β†’ ingest β†’ prior-overlap β†’ risk β†’ shared-cluster β†’ ICD-203 assessment, persisted under cases/<case>/. Prints collector: cti-expert. T2: intel.py pipeline open <case> seeds.txt [--no-graph]/pipeline open case1 seeds.txt
/harness [open|continue|status]Built-in. The LLM-driven whole-case orchestration (IntelHarness) β€” persistent, versioned, cross-case Collectβ†’Correlateβ†’Assess to convergence (needs the venv deps + an LLM key for continue). T2: intel.py harness open CASE-0001 <seeds…> Β· continue CASE-0001 --depth 4 Β· status [CASE-0001]. Persists to cases/; status needs no key/harness status CASE-0001
/graph --renderBuilt-in. IntelGraph publication-quality render of a case graph β†’ PNG/SVG (distinct from the ASCII /graph). T2: intel.py graph <case_graph.json> <out-stem> --legend. T1: render_diagram/graph --render case_graph.json out
/report pdfBuilt-in. IntelReport pandoc render of an assessment .md β†’ polished PDF/DOCX (editorial house style, cover/TOC/figures, VN-safe). Complements /report docx. T2: intel.py report <assessment.md> <out-stem> --pdf --docx. T1: render_report/report pdf assessment.md out
/clusters [case]Built-in. Partition a case into same-operator clusters before judging it β€” the unit of judgment is the cluster, not the case. Shows each binding indicator's KB-wide prevalence, so an indicator that binds 3 domains here but sits on 400 KB-wide reads as noise. Pure KB read. T2: intel.py clusters <case>. T1: case_clusters/clusters CASE-0001
/frontier [case]Built-in. The case's unresolved gaps β€” free next seeds already discovered (crt.sh SAN, passive-DNS co-host, TLS co-SAN, CORS, reverse-WHOIS) plus the deferred metered leads held for approval. reopen re-opens a converged case on new seeds. T2: intel.py frontier <case> Β· intel.py reopen <case> <seed…>. T1: case_frontier/case_reopen/frontier CASE-0001
/loop [case]Built-in. Collect β†’ assess repeatedly until the case converges, instead of stopping at an arbitrary depth. T2: intel.py loop <case>. T1: case_loop/loop CASE-0001
/scope [case]Built-in. Case intake: the no-touch class, victim ownership and the egress gate, derived up front rather than assumed mid-run. A defaulted value is never rendered as an answer. T2: intel.py scope <case>. T1: case_scope/scope CASE-0001
/liveness [domain]Built-in. Is it actually alive? A 200 parking/default/suspended/soft-404 page is not live and a 404/403/5xx/bot-wall is not dead β€” only NXDOMAIN reports dead, and every still-controlled name sets reuse_watch. T2: intel.py liveness <domain>. T1: domain_liveness/liveness scam-site.top
/pssl [domain|cert]Built-in. Passive SSL β€” the historical cert β†’ IP direction that recovers an origin from behind a CDN, with the base-rate rail that keeps a shared CDN certificate out of the clustering. Free (same CIRCL account as passive DNS), so it is on by default in the pipeline. T2: intel.py pssl <target>. T1: passive_ssl/pssl example.com
/paths [url]Built-in. The URL path as a clustering indicator (path_kit:) β€” for an operator who rotates disposable hosts and selects the branded template by directory instead. A generic path (/login, /assets) emits nothing; the base-rate denylist is the whole reason this is safe. T2: intel.py paths <url>. T1: url_paths/paths https://host/kitname/
/serp [domain]Built-in. The advertising layer β€” Google Ads Transparency (who paid: a verified, billed advertiser identity) plus the cloaking probe with its falsification control. Opt-in per run: it spends a SerpApi search per host. T2: intel.py serp <domain>. T1: serp_ads/serp scam-site.top
/docmeta [url|file]Built-in. Document/image metadata β€” PDF /Info + XMP, EXIF (incl. GPS), PNG chunks β€” the author string an operator forgot to strip. Base-rate filtered on both the pivot and ingest paths. T2: intel.py docmeta <target>. T1: doc_metadata/docmeta https://site/brochure.pdf
/victims [case]Built-in. Infer the access vector from the victim set, plus demography (country + sector) β€” who was hit tells you how. T2: intel.py victims --case <id>. T1: victim_profile/victims CASE-0001
/case-timeline [case]Built-in. IntelGraph infrastructure-lifecycle timeline β€” registration/expiry spans, registrant eras, IP hosting windows, cert validity, archive visibility β€” with an evidence ledger citing every dated fact to an online source. T2: intel.py timeline <case>. T1: case_timeline/case-timeline CASE-0001
/tool-calls [case]Built-in. Audit what the model actually called during a run, including the denied calls β€” intel.py dashboard serves the same data as a loopback-only inspector (cost, trace, tool pairing). T2: intel.py tool-calls <case> Β· intel.py dashboard. T1: tool_calls/tool-calls CASE-0001
/login-detect [url]Built-in. Engage (detection half β€” passive and free): find the login form, the password field and the registration page, and classify by fields (a confirm-password means register; an invite code is a pivot, not an OTP). T2: intel.py login-detect <url>. T1: detect_login/login-detect https://scam-site.top
/engage [url]Built-in. GATED β€” outbound, attributable, irreversible. Create a synthetic-persona account and log in to read the members area (panel, deposit/withdraw flow, affiliate tree, support handles). Refuses without explicit confirmation, refuses a non-synthetic persona or direct egress, and stops at a CAPTCHA. Same gate class as a sandbox submission β€” ask first, always. T2: intel.py persona β†’ intel.py engage <url> β†’ intel.py engage-harvest β†’ intel.py engage-report. T1: make_persona/engage_account/harvest_authenticated/engage_report/engage https://scam-site.top

4. Subject & Connection Model

Reference: engine/case-schema.json, engine/subject-registry.md

Subject Types

TypeEmojiExamples
PersonπŸ‘€Full name, alias
Username@Social handle
EmailπŸ“§Address, domain
Domain🌐Site, subdomain
IP AddressπŸ–₯IPv4, IPv6
Organization🏒Company, group
PhoneπŸ“±E.164 format
LocationπŸ“GPS, address
AssetπŸ“¦Document, image
EventπŸ“…Dated occurrence
DeviceπŸ–₯️IoT device, server, workstation
ImageπŸ–ΌοΈPhotograph, screenshot
Crypto AddressπŸ’°Bitcoin, Ethereum wallet
Bank Account🏦IBAN, local account no., BIC
ICP FilingπŸ“‹PRC licence serial (one registrant, many sites)
Custom🏷️User-defined entity type

Connection Types

owns         β€” domain, email, or asset ownership
uses         β€” platform account or tool usage
works_at     β€” employment or affiliation
linked_to    β€” general association
alias        β€” same identity, different handle
communicated_with β€” observed contact

Finding Trust Scores

ScoreLabelMeaning
5PRIMARYAuthoritative or official source
4DERIVEDConfirmed by 2+ independent sources
3CONFIRMEDSingle reliable source, verified
2ANECDOTALReported but unverified
1CONTESTEDConflicting data exists

Source Reliability Scale

Complements numeric trust scores with source-level grading. Trust score rates finding content; source reliability rates the source itself.

GradeLabelTypical Sources
ACompletely ReliableOfficial registries, government records
BUsually ReliableEstablished outlets, corporate sources
CFairly ReliableKnown blogs, industry publications
DNot Usually ReliableAnonymous forums, unverified claims
EUnreliableKnown disinformation, fabricated content
FCannot Be JudgedInsufficient information to assess

Confidence Levels

LevelLabelUse When
VERIFIEDDirect observation, primary source
STRONGMultiple corroborating sources
MODERATESingle reliable source
WEAKCircumstantial or inferred
TENTATIVEAnalyst deduction only
CHALLENGEDContradicted by other findings

Likelihood Language (judgments, not findings)

The three scales above grade evidence. An analytic judgment built on that evidence β€” an attribution, a motive, a forecast β€” carries a probability-anchored likelihood term instead. Without an anchor, "MODERATE" routinely means a 30-point-different thing to writer and reader.

TermBandTermBand
Almost no chance1–5%Likely / probable55–80%
Very unlikely5–20%Very likely80–95%
Unlikely20–45%Almost certain95–99%
Roughly even chance45–55%

Likelihood and confidence are orthogonal β€” report both:

The operator is very likely based in Guangdong (moderate confidence β€” single registry record, unverified).

Never 0% or 100%. One term per judgment. Never attach a likelihood term to a directly observed fact. findings[].confidence in the report JSON stays an integer describing evidence quality β€” likelihood lives in the narrative.

Attribution claims additionally require an ACH matrix (competing hypotheses, scored by inconsistency, runner-up named). Full rules β€” likelihood, the 5W1H coverage overlay, and ACH: handbook/analytic-standards.md.

Map Rendering (ASCII Mandatory)

ALL visualization commands produce ASCII box-drawing art by default. This includes /graph, /render entities, /render network, /render timeline, /render risk, /pathfind, and /show-connections. Mermaid available only with explicit --mermaid flag.

Why ASCII-first: Universal terminal compatibility, renders correctly in .md and .docx exports, no external renderer dependency.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   owns   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ πŸ‘€ John Doe          [3/5] │══════════▢│ 🌐 example.com     [4/5] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚ works_at                       β”‚ hosted_on
         β–Ό                                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 🏒 Acme Corp         [4/5] β”‚  β”‚ πŸ–₯ 203.0.113.10    [4/5] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Connection arrows: ═══▢ owns Β· ───▢ confirmed Β· Β·Β·Β·β–Ά inferred Β· ←─▢ bidirectional Β· ─·─▢ alias Β· β•Œβ•Œβ–Ά works_at Box styles: β”Œβ”€β”€β” confirmed Β· β”Œ ─ ┐ unverified Β· ╔══╗ target Badge: [n/5] trust score Β· emoji prefix = entity type


5. Finding Framework

Reference: engine/finding-framework.md, engine/conflict-resolver.md

Every finding logged via /record-finding captures:

Source URL / method
Collection method (browser | search | fetch | manual)
Trust score (1–5)
Confidence level (VERIFIED β†’ CHALLENGED)
Timestamp
Linked subjects

Conflict detection (engine/conflict-resolver.md): When two findings about the same subject contradict each other, the system flags a CONTESTED state. Both findings are preserved. Resolution options: accept one, mark both TENTATIVE, or log the conflict as its own finding.

Deviation detection (analysis/deviation-detector.md): Automatically flags behavioral anomalies β€” account creation gaps, platform presence inconsistencies, metadata mismatches.

Weight engine (analysis/weight-engine.md): Aggregates trust scores across findings to compute subject-level confidence.


6. Technique Catalog

Reference directory: techniques/

FileCovers
fx-metadata-parsing.mdEXIF, email headers, document metadata analysis
fx-image-verification.mdImage authenticity and provenance workflow
fx-breach-discovery.mdBreach database methods and paste site search
fx-geolocation.mdGPS extraction, W3W, Plus Codes, MGRS, Street View
fx-social-topology.mdSocial graph construction and topology
fx-email-header-analysis.mdHeader analysis, SPF/DKIM, SMTP routing
fx-document-forensics.mdDocument forensics and metadata extraction
fx-http-fingerprint.mdHTTP fingerprinting and server signature analysis
fx-leak-monitoring.mdLeak and breach monitoring, paste site search
<!-- dork-integration:phase-05 start -->

| fx-dork-sweep.md | Zero-auth Google/Bing dork sweeps β€” Telegram ecosystem, doc-hosts, filetype families + 4-tier fallback cascade (WebSearch β†’ Bing β†’ DDG β†’ agent-browser) | | fx-document-leak-hunt.md | 18-platform document leak discovery with severity classification, paywall handling, auto-snapshot |

<!-- dork-integration:phase-05 end -->

| username-osint.md | 3000+ platform enumeration with pivot extraction | | phone-osint.md | Carrier lookup, VoIP detection, spam databases, FreeCNAM CallerID, WhoCalld, USPhoneBook reverse lookup | | email-osint.md | Full email investigation: accounts, breaches, infra, Proton API, PGP keys, permutation, manual reference tools | | fx-dns-cert-history.md | Historical DNS records (passive DNS, A/NS/MX changes), SSL certificate timeline (crt.sh CT logs) | | threat-intel.md | AbuseIPDB, GreyNoise, OTX, VirusTotal, URLScan.io, CIRCL CVE, NVD API, ransomware.live | | web-traffic-analysis.md | SimilarWeb/Semrush estimation, audience data | | secret-scanning.md | Credential/secret detection in repos and pastes | | github-osint.md | GitHub user/org/repo profiling, code search, commit metadata, forks, collaboration networks | | domain-advanced.md | Subfinder, Amass, CT log enumeration | | social-media-platforms.md | Twitter/X Snowflake IDs, Discord, Strava, BlueSky, ShareTrace share link analysis | | advanced-geolocation-techniques.md | Overpass Turbo, road sign analysis, reflected text | | web-dns-forensics.md | Zone transfers, Tor lookups, GitHub, Telegram, WHOIS, Xeuledoc Google doc intel | | fx-visitor-intelligence.md | Visitor stats, tech stack, geo, traffic sources, analytics/AdSense/advertising ID cross-domain linking, competitors | | wifi-ssid-osint.md | WiFi SSID/BSSID geolocation via Wigle.net, encryption analysis, travel patterns | | scam-check.md | Phishing/scam domain verification and detection | | cloud-audit.md | Cloud infrastructure security (AWS/GCP/Azure): IAM, network, storage, compute, logging, secrets | | microsoft-tenant-recon.md | M365/Azure tenant enumeration β€” federation, tenant ID, Azure AD config, MDI detection | | china-recon.md | China/Sinophone layer β€” ICP filing β†’ PRC entity + licence-serial sibling pivot, GSXT/俑用中国/TianYanCha/QCC/Aiqicha registry chain, USCC validation, Quake/ZoomEye/FOFA cyberspace engines, Baidu dorking, CJK pinyin + Traditional variant generation, CN social platforms, access-reality gaps | | fiat-payment-osint.md | Bank accounts as selectors β€” IBAN mod-97 validation + BBAN decomposition, BIC, VN/SEA non-IBAN rails (VietQR/NAPAS BIN), account-reuse pivot, mule-pattern signals | | fx-edge-appliance-recon.md | Edge/VPN appliance fingerprint β†’ CISA KEV/CVE catalog (Citrix/F5/Cisco/Ivanti/Forti/PAN/Exchange) + exposed-service port-risk matrix (Shodan InternetDB, passive-first) | | fx-saas-identity-recon.md | SaaS tenancy + identity-fabric mapping β€” DNS-TXT tenancy tokens, IdP fingerprinting (Okta/Auth0/OneLogin/Ping/Keycloak/ADFS/Entra), unauthenticated API/GraphQL/OpenAPI-spec discovery | | dependency-audit.md | Supply chain security: CVE audit, framework-specific vulns, typosquatting, CI/CD security | | disk-forensics.md | Digital evidence analysis: image integrity, Sleuth Kit, file carving, artifact recovery, timeline | | incident-triage.md | Security incident response: NIST 800-61 methodology, containment, evidence preservation, IOC extraction | | owasp-audit.md | OWASP Top 10 (2021) source code audit with grep patterns and CWE references | | prompt-injection-audit.md | AI/LLM security: prompt injection classes, agent/MCP security, permission boundary audit | | stealer-log-analysis.md | Infostealer-log triage: family fingerprinting (RedLine/Vidar/StealC/Lumma/META/traffer), victim-vs-operator profiling, cross-log actor correlation, IOC + attribution extraction (uv run parser, raw artifacts shown) | | agent-browser.md | Interactive browser collection & evidence capture via vercel-labs/agent-browser (CDP, accessibility-tree @eN snapshots, screenshots; primary interactive collector, complementary to Scrapling) |


7. Workflow Guides

Reference directory: workflows/

GuideIntended UserFile
Journalist Source VerificationJournalists verifying claimswf-journalist.md
HR ScreeningHR professionals running background checkswf-hr-screening.md
Cyber Threat IntelligenceSecurity analysts tracking adversarieswf-threat-analyst.md
Private InvestigatorLicensed PIs running person caseswf-private-investigator.md

Activate via /flow [type] β€” interactive guided prompts walk through each step.


8. Output Formats

Reference: output/reports/, connectors/

Conversational domain table β€” show this in chat on every collection turn (CRITICAL)

Whenever a collection command (/cti, /case, /sweep, /webpivot, /subdomain, or the pipeline) returns one or more domains, the reply's first element β€” before any prose β€” is a markdown table summarizing each domain, so the operator sees the yield at a glance in the conversation. The Β§8 file exports are the durable record; this table is the live view and is never skipped, even for a single domain.

DomainResolvesTop pivotsRiskCluster / peersSeen before
site-a.exampleβœ“favicon:123456789 Β· G-XXXXXXXXXXNRD, BPH3 peersCASE-0001 (Operator A)
site-b.exampleβœ“registrant@example.comβ€”3 peersnew

Columns: Resolves βœ“/βœ— (collector got a host); Top pivots the 1–3 highest-rung indicators (Β§2.5 ladder) as kind:value; Risk the risk_signals flags (NRD / BPH / money-trail, or β€”); Cluster / peers shared-indicator peer count from the KB; Seen before the prior case + operator from /recall, or new. Keep to these columns β€” detail goes in the prose below. One row per domain; for a large sweep show the top 20 by risk and note how many rows were omitted.

Mandatory File Export (CRITICAL)

Every /report, /brief, and /case command MUST auto-save the default export set to disk at the end of delivery:

#FormatFileRole
1MarkdownCTI-REPORT-[CASE-ID]-[YYYY-MM-DD].mdDiffable, greppable source of truth; also the input to the HTML/DOCX generators
2Interactive HTMLCTI-REPORT-[CASE-ID]-[YYYY-MM-DD].htmlPrimary human-facing deliverable β€” self-contained, OFFLINE; charts + 2D entity graph + topology + timeline + indicator panel + search
3JSONCTI-REPORT-[CASE-ID]-[YYYY-MM-DD].jsonStructured case data (the report JSON below); feeds the generators and downstream tooling
4CSVCTI-REPORT-[CASE-ID]-[YYYY-MM-DD].csvFindings (and indicators, via the IOC export) for spreadsheets / SIEM lookups
5IOC / selector bundleIOC-[CASE-ID]-[YYYY-MM-DD].{stix.json,txt,csv}Comprehensive indicators & selectors β€” STIX 2.1 + flat + CSV
Save location: Current working directory, or ./osint-reports/ subdirectory if it exists.

The default set is unredacted β€” it is the analyst's working record. A shareable variant is opt-in, never automatic, so nothing is ever quietly weakened. Request it with /redact or /case … --redact:

S="$SKILL_DIR/scripts"; R="CTI-REPORT-[CASE-ID]-[YYYY-MM-DD]"
for f in md json csv; do
  uv run "$S/redact.py" "$R.$f" -o "$R.redacted.$f" --map "$R.map.json"
done

One --map across all three files keeps a selector's placeholder identical everywhere. Infrastructure (URL/domain/IP) stays visible even then β€” in a CTI report the actor's infrastructure is the analysis, not incidental PII; add --all-types to cover it too. Never ship the .map.json β€” it reverses the redaction.

  • --yolo: save the five-format default set with no prompt.
  • Interactive mode: save the default set, then ask the user at the end whether they also want DOCX (Word) or PDF.
  • DOCX is NOT in the default set (heaviest, most failure-prone toolchain). Generate it on request (/report docx) or automatically for /report legal (evidentiary, where a fixed Word/PDF artifact is expected). HTML "Print β†’ Save as PDF" covers most PDF needs for free.
  • Explicit machine-format subcommands always emit that format directly: /report json, /report csv, /report ioc.

The HTML, JSON, CSV and IOC outputs all derive from one report JSON. Build it once, then run the generators below.

Step 1 β€” Build the report JSON file. The generators expect a SPECIFIC flat format (NOT the engine case-schema.json). You MUST construct the JSON matching this exact structure before calling the scripts. Reference: scripts/sample-cti-report-data.json.

{
  "case": {
    "id": "CTI-2026-001",          // string, case identifier
    "label": "Case Title",         // string, human-readable name
    "classification": "OPEN SOURCE", // string
    "analyst": "AI-Assisted CTI",  // string
    "date": "2026-04-08",          // ISO date
    "subject": "target.com",       // string, primary subject
    "status": "active",            // string
    "exposure_score": 72           // integer 0-100 (optional, enables risk gauge)
  },
  "executive_summary": "Full paragraph summarizing investigation findings...",
  "subjects": [
    {
      "id": "SUB-001",            // string ID (not UUID)
      "label": "target.com",      // human-readable name β€” REQUIRED for display
      "type": "domain",           // lowercase: domain, person, ip, organization, email, username
      "confidence": 95,           // INTEGER 0-100 (not string like "VERIFIED")
      "verified": true,           // boolean
      "aliases": ["alias1"],      // string array
      "first_seen": "2025-01-15", // ISO date string
      "notes": "Primary domain"   // string
    }
  ],
  "findings": [
    {
      "id": "FND-001",            // string ID
      "subject_id": "SUB-001",    // links to subject
      "type": "infrastructure",   // credential, infrastructure, identity, exposure, behavioral, legal
      "weight": "HIGH",           // CRITICAL, HIGH, MEDIUM, LOW, INFO β€” drives severity colors
      "description": "Full description of the finding...",
      "source_url": "https://...",
      "collected_at": "2026-04-08T10:00:00Z",
      "confidence": 88,           // INTEGER 0-100 (not string)
      "tags": ["tag1", "tag2"]
    }
  ],
  "connections": [
    {
      "id": "CON-001",
      "from_id": "SUB-001",       // subject ID
      "to_id": "SUB-002",         // subject ID
      "relationship": "owns",     // string describing relationship
      "strength": "confirmed"     // confirmed, probable, possible
    }
  ],
  "timeline": [
    {"date": "2025-01-15", "event": "Domain registered"}
  ],
  "sources": [
    {"name": "Source Name", "url": "https://...", "date": "2026-04-08"}
  ],
  "intelligence_gaps": [
    "Gap description string"
  ],
  "recommendations": [
    "Action item string"
  ],
  "visitor_stats": {              // optional β€” enables visitor intelligence charts
    "domain": "target.com",
    "monthly_visits": 150000,
    "traffic_sources": {"direct": 42, "search": 28, "referral": 15, "social": 10, "paid": 5},
    "top_countries": [{"country": "Vietnam", "share": 60}, {"country": "US", "share": 20}]
  },
  "caveats": ["Caveat string"]   // optional β€” overrides default methodology notes
}

CRITICAL FORMAT RULES:

  • confidence on subjects and findings MUST be an integer (e.g., 85), NOT a string (e.g., "VERIFIED")
  • findings MUST be a flat top-level array, NOT nested inside subjects
  • label is REQUIRED on each subject (this is what displays in the report β€” not value or display_name)
  • weight on findings drives severity coloring β€” use CRITICAL/HIGH/MEDIUM/LOW/INFO
  • recommendations must be an array of strings (not objects with priority/action keys)
  • All fields shown above should be populated with actual data β€” empty strings or "N/A" defeat the purpose
  • Populate executive_summary with a full paragraph β€” this is the most-read section of the report

Optional enrichment fields (backward-compatible β€” used by the HTML report & IOC export when present):

  • subjects[].role β€” actor | victim | infrastructure | associate | witness (drives the role chips and actor↔victim attribution; otherwise inferred from type/links)
  • subjects[].selectors[] β€” contact/social points attached to a person/org: {type, value, platform, url} (e.g. a victim's phone, an actor's Telegram or LinkedIn) β€” surfaced in the Indicators panel and IOC export
  • indicators[] β€” analyst-curated indicators to force into the export verbatim: {type, value, category, role, confidence, source_url}

Step 2 β€” Generate the interactive HTML report (PRIMARY human-facing deliverable). Self-contained, OFFLINE, zero toolchain to view β€” opens in any browser:

S="$SKILL_DIR/scripts"     # $SKILL_DIR = dir containing SKILL.md
uv run "$S/generate-cti-html.py" "REPORT.json" "REPORT.html"   # any OS, zero setup
# no uv installed: python3 "$S/generate-cti-html.py" "REPORT.json" "REPORT.html"   (Windows: py …)

It injects the report JSON into cti-report-template.html and renders, entirely client-side and offline (no CDN, no network calls): KPI cards, an exposure gauge, a finding-type pie, severity bars, a draggable/zoomable 2D entity graph, infrastructure topology, an event timeline, and the comprehensive Indicators & Selectors panel (network IOCs + contacts + identities + social/messaging handles + wallets + actor↔victim attribution) β€” with global search, category menus, dark/light themes and a print-to-PDF stylesheet.

Step 3 β€” Generate the comprehensive IOC / selector bundle.

uv run "$S/generate-cti-iocs.py" "REPORT.json" "IOC-[CASE-ID]-[YYYY-MM-DD]" --format all
# single format: --format stix | flat | csv

Extracts EVERY indicator that profiles or can reach an actor/victim β€” network IOCs, emails/phones, usernames/names/aliases, social-media profiles, messaging handles, crypto wallets, and the attribution links between subjects. Full spec: techniques/ioc-export.md.

Step 4 β€” DOCX (on request, or automatically for /report legal). Word is no longer auto-generated by default. When the user asks for it (or for evidentiary reports), build it from the SAME report JSON + MD. The generators carry PEP 723 inline dependency metadata, so the simplest, most portable runner is uv run β€” it provisions the deps on the fly with zero venv/pip setup, identically on every OS. The generator is also self-healing: it forces UTF-8 output and auto-locates pandoc (including Windows %LOCALAPPDATA%\Pandoc), so no PYTHONUTF8 / PATH prelude is needed. Replace REPORT with CTI-REPORT-[CASE-ID]-[YYYY-MM-DD].

Preferred β€” uv run (any OS, any agent, zero setup):

S="$SKILL_DIR/scripts"     # $SKILL_DIR = dir containing SKILL.md (Claude Code: ~/.claude/skills/cti-expert; Codex/clone: the repo)
# Primary: HYBRID β€” full narrative from MD + charts/diagrams from JSON (zero content loss)
uv run "$S/generate-cti-docx-hybrid.py" "REPORT.md" "REPORT.json" "REPORT.docx"
# Fallback 1: JSON-only (charts + structured data; no pandoc needed)
uv run "$S/generate-cti-docx.py" "REPORT.json" "REPORT.docx"
# Fallback 2: MD-only (styled narrative, no charts)
uv run "$S/generate-cti-docx-hybrid.py" "REPORT.md" "REPORT.docx"

Windows PowerShell: set $S = "$env:USERPROFILE\.claude\skills\cti-expert\scripts" (Claude Code) or "<repo>\scripts" (Codex/clone), and use backslash paths.

Fallback β€” no uv installed. Use the OS interpreter; the script's ensure_deps() installs the libs on first run (via uv if present, else pip):

  • macOS / Linux (Bash): python3 "$S/generate-cti-docx-hybrid.py" "REPORT.md" "REPORT.json" "REPORT.docx"
  • Windows (PowerShell): py "$S\generate-cti-docx-hybrid.py" "REPORT.md" "REPORT.json" "REPORT.docx" β€” the Store python3 stub will not run; use py or the venv python
  • Last resort (no styling/charts): pandoc "REPORT.md" -o "REPORT.docx" --from markdown --to docx --standalone

How the hybrid generator works:

  1. Phase 1: pandoc converts the MD file to a base DOCX (preserving ALL narrative content β€” tables, lists, formatting)
  2. Phase 2: python-docx post-processes to add CTI professional styling, prepend cover page + TOC, and inject charts/diagrams from JSON at matching section headings

The MD file is the primary content source. It carries the full narrative (detailed person profiles, infrastructure tables, wallet addresses, corporate structure, legal history, etc.). The JSON file provides structured data for visual elements (charts, diagrams, risk gauge). Using both together produces a complete report with zero content loss.

Rich hybrid DOCX includes: Cover page titled "CTI REPORT", table of contents, all narrative content from MD (every paragraph, table, list, code block), pie chart (finding types), bar chart (severity), risk gauge (exposure score), timeline chart, entity relationship diagram, network topology diagram, traffic/geo charts, CTI-themed styling (navy headings, styled tables), header/footer with classification and page numbers.

After saving, confirm all files to the user:

πŸ“„ Report saved (default export set):
   β†’ CTI-REPORT-CASE001-2026-03-30.md
   β†’ CTI-REPORT-CASE001-2026-03-30.html   (interactive β€” open in any browser, fully offline)
   β†’ CTI-REPORT-CASE001-2026-03-30.json
   β†’ CTI-REPORT-CASE001-2026-03-30.csv
   β†’ IOC-CASE001-2026-03-30.stix.json / .txt / .csv   (indicators & selectors)

   Need a Word (.docx) or PDF too? (PDF = open the .html and Print β†’ Save as PDF)

Report Formats

FormatCommandAudience
Interactive HTML/report (default) Β· /report htmlEveryone β€” analysts to execs; the primary deliverable
Technical INTSUM/reportAnalysts, security teams
Executive Brief/report briefDecision-makers, management
Plain-Language Summary/briefNon-technical stakeholders
Legal Evidence Format/report legalAttorneys, compliance teams (auto-adds DOCX/PDF)
Journalist Format/report journalistReporters, media
JSON Export/report jsonDownstream tools, pipelines
CSV Export/report csvSpreadsheets, databases
IOC / selector bundle/report iocSIEM/TIP ingest, threat-intel sharing
Word document/report docxFormal sharing (on request)

Every narrative report auto-saves the default export set (.md + .html + .json + .csv + IOC bundle β€” see Mandatory File Export above). /report legal additionally produces DOCX/PDF. Machine-only subcommands (json, csv, ioc) emit their native format directly.

Visual Outputs

TypeCommandFormat
Subject relationship map/render entitiesASCII (default) β€” --mermaid for Mermaid
Chronological timeline/render timelineASCII Gantt
Exposure heatmap/render riskASCII
Network topology/render networkASCII

All visual outputs use ASCII box-drawing by default. Mermaid only on explicit --mermaid flag.

Diagram tradecraft: output/visuals/diagram-patterns.md β€” compile-check a Mermaid diagram before presenting it, and pick the right diagram type per CTI question (attack β†’ sequence, lifecycle β†’ state, handoffs β†’ swimlane, infra β†’ graph).

The interactive HTML report (default deliverable) renders all of these as live, explorable visuals β€” a draggable/zoomable 2D force-directed entity graph, infrastructure topology, an event timeline, and SVG charts (pie/bar/gauge/donut) β€” alongside the ASCII versions in the .md.

Connectors

ToolFileWhat It Exports
Maltegoconnectors/maltego-export.mdGraphML entity graph
Obsidianconnectors/obsidian-setup.mdLinked markdown notes
Notionconnectors/notion-schema.mdStructured database
Intel backendconnectors/intel-backend.mdOptional persistent KB + cross-case correlation via the intel_engine engine (MCP/CLI). Absent β†’ stateless as normal. Enables /backend, /kb, /recall, /binary

9. Skill Tiers & Customization

Reference: experience/skill-tiers.md, experience/layered-detail.md

Tiers

TierCommandWhat Changes
Novice/noviceJargon removed, steps explained, glossary auto-linked
Practitioner(default)Standard output, moderate detail
Specialist/novice offFull technical detail, raw findings, internal signals

Switch tiers at any point β€” output adapts immediately.

Guided Flows

experience/guided-flows/ contains step-by-step interactive flows:

  • person-investigation.md β€” Full guided person case
  • domain-reconnaissance.md β€” Guided domain sweep
  • email-investigation.md β€” Guided email tracing
  • rapid-case.md β€” 10-minute abbreviated sweep

Activate: /flow person Β· /flow domain Β· /flow email Β· /flow quick

Case Templates

experience/case-templates/ contains pre-built starting configurations:

  • due-diligence.md β€” Corporate partner vetting
  • security-audit.md β€” Organization exposure audit
  • background-check.md β€” Individual background research

Activate: /template run [name]


10. Ethics & Boundaries

This skill operates strictly within publicly available information.

Permitted

  • Journalists verifying facts about public figures or institutions
  • Security professionals auditing their own organization's exposure
  • Individuals reviewing their own digital footprint
  • Corporate due diligence on business partners
  • Academic research and educational demonstrations

Prohibited

  • Stalking, harassment, or doxing of any individual
  • Accessing accounts or systems without authorization
  • Social engineering or deception campaigns
  • Any activity violating applicable law

Ethical reminders are issued automatically when the investigation approaches sensitive territory. Public data is not a license to cause harm.


11. Autonomous Mode (--yolo)

Append --yolo to any command or activate at session start.

What changes:

  • No clarifying questions β€” analyst infers context and proceeds
  • No confirmation prompts β€” scope expands automatically on new discoveries
  • Guided flows skip Q&A β€” reasonable defaults applied
  • Both /report and /brief generated without asking

What stays the same:

  • Ethics and legal boundaries β€” always enforced
  • Trust scores on every finding
  • Source citations on every claim
  • /validate and /coverage run before final delivery

Activate per-command: /case target.com --yolo Activate for session: /cti-expert --yolo


12. Architecture Reference

cti-expert/
β”œβ”€β”€ SKILL.md                    This file
β”œβ”€β”€ README.md                   User-facing overview
β”‚
β”œβ”€β”€ engine/                     Case data model and state management
β”‚   β”œβ”€β”€ case-schema.json        Subject and finding data structures
β”‚   β”œβ”€β”€ subject-registry.md     How subjects are tracked and versioned
β”‚   β”œβ”€β”€ finding-framework.md    Finding lifecycle, trust scores, evidence chains
β”‚   β”œβ”€β”€ pivot-orchestration.md  Recursive spider-map pivot engine (BFS loop, edge matrix, gating)
β”‚   β”œβ”€β”€ workspace-format.md     Workspace serialization spec
β”‚   β”œβ”€β”€ workspace-manager.md    Save/open/list workspace logic
β”‚   └── conflict-resolver.md    CONTESTED finding resolution
β”‚
β”œβ”€β”€ analysis/                   Pattern detection and intelligence engines
β”‚   β”œβ”€β”€ deviation-detector.md   Behavioral anomaly detection
β”‚   β”œβ”€β”€ auto-branch-rules.md    Automatic pivot trigger rules
β”‚   β”œβ”€β”€ drift-monitor.md        Subject state change tracking
β”‚   β”œβ”€β”€ cross-reference-engine.md Shared identifier detection across subjects
β”‚   β”œβ”€β”€ archive-explorer.md     Wayback Machine integration and diff
β”‚   β”œβ”€β”€ signature-catalog.md    Behavioral pattern library
β”‚   β”œβ”€β”€ exposure-model.md       Exposure score calculation framework
β”‚   β”œβ”€β”€ risk-trend-tracker.md   Temporal risk score tracking (/drift)
β”‚   β”œβ”€β”€ pattern-library.md      Username, email, bot detection patterns
β”‚   └── weight-engine.md        Finding aggregation and confidence weighting
β”‚
β”œβ”€β”€ techniques/                 Collection techniques and module specs
β”‚   β”œβ”€β”€ fx-metadata-parsing.md  EXIF, headers, document metadata
β”‚   β”œβ”€β”€ fx-image-verification.md Image authenticity and provenance
β”‚   β”œβ”€β”€ fx-breach-discovery.md  Breach database and paste site methods
β”‚   β”œβ”€β”€ fx-geolocation.md       GPS, W3W, Plus Codes, Street View
β”‚   β”œβ”€β”€ fx-social-topology.md   Social graph construction and topology
β”‚   β”œβ”€β”€ fx-email-header-analysis.md Header analysis, SPF/DKIM
β”‚   β”œβ”€β”€ fx-document-forensics.md Document forensics and extraction
β”‚   β”œβ”€β”€ fx-http-fingerprint.md  HTTP fingerprinting and signatures
β”‚   β”œβ”€β”€ fx-leak-monitoring.md   Leak and breach monitoring
β”‚   β”œβ”€β”€ username-osint.md       Platform enumeration (3000+)
β”‚   β”œβ”€β”€ phone-osint.md          Phone carrier/VoIP/spam lookup
β”‚   β”œβ”€β”€ email-osint.md          Deep email investigation
β”‚   β”œβ”€β”€ threat-intel.md         Threat intelligence free lookups
β”‚   β”œβ”€β”€ web-traffic-analysis.md Traffic estimation methods
β”‚   β”œβ”€β”€ secret-scanning.md      Credential/secret detection
β”‚   β”œβ”€β”€ github-osint.md         GitHub profiles, repos, code, commits, forks
β”‚   β”œβ”€β”€ domain-advanced.md      Subdomain enumeration methods
β”‚   β”œβ”€β”€ social-media-platforms.md Platform-specific techniques
β”‚   β”œβ”€β”€ advanced-geolocation-techniques.md Overpass Turbo, road signs, reflected text
β”‚   β”œβ”€β”€ wifi-ssid-osint.md      WiFi SSID/BSSID geolocation via Wigle.net
β”‚   β”œβ”€β”€ web-dns-forensics.md    DNS, GitHub, Telegram, WHOIS
β”‚   β”œβ”€β”€ fx-visitor-intelligence.md Visitor stats, tech stack, geo analysis
β”‚   β”œβ”€β”€ scam-check.md           Phishing/scam domain verification
β”‚   β”œβ”€β”€ cloud-audit.md          Cloud infrastructure security audit
β”‚   β”œβ”€β”€ microsoft-tenant-recon.md M365/Azure tenant enumeration
β”‚   β”œβ”€β”€ china-recon.md          ICP filings, PRC registries, CN cyberspace engines, CJK variants
β”‚   β”œβ”€β”€ fiat-payment-osint.md   IBAN/BIC/bank accounts as selectors, VN-SEA rails
β”‚   β”œβ”€β”€ fx-edge-appliance-recon.md Edge/VPN appliance fingerprint β†’ KEV/CVE catalog + port-risk matrix
β”‚   β”œβ”€β”€ fx-saas-identity-recon.md SaaS tenancy + IdP fingerprint + API/GraphQL/spec discovery
β”‚   β”œβ”€β”€ dependency-audit.md     Supply chain security audit
β”‚   β”œβ”€β”€ disk-forensics.md       Digital evidence analysis
β”‚   β”œβ”€β”€ incident-triage.md      Security incident response
β”‚   β”œβ”€β”€ owasp-audit.md          OWASP Top 10 source code audit
β”‚   β”œβ”€β”€ prompt-injection-audit.md AI/LLM security audit
β”‚   β”œβ”€β”€ stealer-log-analysis.md Infostealer-log triage, actor attribution & IOC extraction
β”‚   β”œβ”€β”€ agent-browser.md        Interactive browser collection & evidence capture (vercel-labs/agent-browser)
β”‚   └── ioc-export.md           IOC export (STIX 2.1, flat list)
β”‚
β”œβ”€β”€ experience/                 UX, tiers, and guided flows
β”‚   β”œβ”€β”€ skill-tiers.md          Novice/Practitioner/Specialist spec
β”‚   β”œβ”€β”€ layered-detail.md       Progressive disclosure rules
β”‚   β”œβ”€β”€ guidance-system.md      How guided flows work
β”‚   β”œβ”€β”€ case-progress.md        Progress tracking logic
β”‚   β”œβ”€β”€ guided-flows/           Interactive step-by-step flows
β”‚   β”‚   β”œβ”€β”€ flow-person-lookup.md Person investigation guided flow
β”‚   β”‚   β”œβ”€β”€ flow-domain-sweep.md Domain reconnaissance guided flow
β”‚   β”‚   └── flow-image-check.md Image verification guided flow
β”‚   β”œβ”€β”€ case-templates/         Pre-built case configurations
β”‚   β”‚   β”œβ”€β”€ tpl-index.md        Template index and descriptions
β”‚   β”‚   β”œβ”€β”€ tpl-due-diligence.md Due diligence case template
β”‚   β”‚   β”œβ”€β”€ tpl-security-review.md Security audit case template
β”‚   β”‚   └── tpl-background-check.md Background check case template
β”‚   β”œβ”€β”€ tutorial.md             First-time onboarding guide (/onboard)
β”‚   β”œβ”€β”€ feedback-system.md      Investigation quality feedback loops
β”‚   └── accessibility/          Glossary and accessibility settings
β”‚       β”œβ”€β”€ glossary.md         OSINT term glossary
β”‚       └── accessible-mode.md  Low-jargon mode settings
β”‚
β”œβ”€β”€ output/                     Report and visualization specs
β”‚   β”œβ”€β”€ reports/                Report format templates
β”‚   β”‚   β”œβ”€β”€ format-catalog.md   Report format specifications
β”‚   β”‚   β”œβ”€β”€ leadership-brief-template.md Executive brief template
β”‚   β”‚   β”œβ”€β”€ export-specs.md     Export format specifications
β”‚   β”‚   └── citation-guide.md   Source citation standards
β”‚   └── visuals/                Chart and visualization specs
β”‚       β”œβ”€β”€ chart-templates.md  Chart rendering templates
β”‚       β”œβ”€β”€ ui-components.md    UI component library
β”‚       β”œβ”€β”€ render-engine.md    ASCII render engine spec
β”‚       β”œβ”€β”€ case-dashboard.md   Dashboard layout spec
β”‚       β”œβ”€β”€ attack-path-diagram.md  Attack path flow visualization (/render threat-path)
β”‚       └── attack-surface-map.md   Attack surface exposure map (/render attack-surface)
β”‚
β”œβ”€β”€ scripts/                    Cross-platform install + HTML / IOC / DOCX report generation
β”‚   β”œβ”€β”€ platform-setup.md            Cross-platform reference: OS detection, uv-first install matrix, gotchas
β”‚   β”œβ”€β”€ install.ps1                  Windows installer (uv-first: uv venv/pip/tool; winget + pip/pipx fallback)
β”‚   β”œβ”€β”€ install.sh                   macOS/Linux/Git-Bash/WSL installer (uv-first; brew/apt + pip/pipx fallback)
β”‚   β”œβ”€β”€ stealer_log_parse.py         Infostealer-log analyzer β€” attribution, profiling, IOCs (PEP 723 / `uv run`, zero-dep)
β”‚   β”œβ”€β”€ iban_analyze.py              IBAN validate + decompose (ISO 13616/7064) β†’ bank code, risk signals (PEP 723, zero-dep)
β”‚   β”œβ”€β”€ redact.py                    Reversible PII redaction β€” stable placeholders + exportable map; md/json/csv (PEP 723, zero-dep)
β”‚   β”œβ”€β”€ cti-report-template.html     PRIMARY: interactive HTML report template β€” self-contained & OFFLINE (charts + 2D entity graph + topology + timeline + indicator panel + search; dark/light + print-to-PDF)
β”‚   β”œβ”€β”€ generate-cti-html.py         HTML report generator β€” injects the report JSON into the template (PEP 723 / `uv run`, zero-dep, self-heals UTF-8)
β”‚   β”œβ”€β”€ generate-cti-iocs.py         Comprehensive IOC/selector exporter β†’ STIX 2.1 / flat / CSV (network IOCs + contacts + identities + social/messaging + wallets + attribution; PEP 723 / `uv run`, zero-dep)
β”‚   β”œβ”€β”€ generate-cti-docx-hybrid.py  Hybrid MD+JSON DOCX generator β€” on request / `/report legal` (PEP 723 / `uv run`; self-heals UTF-8 + pandoc)
β”‚   β”œβ”€β”€ generate-cti-docx.py         Fallback: JSON-only generator (PEP 723 / `uv run`)
β”‚   β”œβ”€β”€ cti_docx_postprocess.py      Post-processing: styling, chart injection, cover page
β”‚   β”œβ”€β”€ cti_docx_charts.py           Chart rendering (pie, bar, gauge, timeline, traffic, geo)
β”‚   β”œβ”€β”€ cti_docx_diagrams.py         Entity relationship + network topology diagrams
β”‚   β”œβ”€β”€ cti_docx_sections.py         Report section formatting (used by JSON-only generator)
β”‚   β”œβ”€β”€ cti_docx_styles.py           Document styling, colors, cover page, header/footer
β”‚   β”œβ”€β”€ requirements.txt             Python dependencies
β”‚   └── sample-cti-report-data.json  Example JSON report data
β”‚
β”œβ”€β”€ workflows/                  Professional workflow guides
β”‚   β”œβ”€β”€ wf-journalist.md
β”‚   β”œβ”€β”€ wf-hr-screening.md
β”‚   β”œβ”€β”€ wf-threat-analyst.md
β”‚   └── wf-private-investigator.md
β”‚
β”œβ”€β”€ handbook/                   Reference material
β”‚   β”œβ”€β”€ operator-queries.md     Search operator catalog
β”‚   β”œβ”€β”€ quick-report.md         Rapid reporting reference
β”‚   β”œβ”€β”€ discovery-paths.md      Per-target-type search paths
β”‚   β”œβ”€β”€ report-template.md      INTSUM format specification
β”‚   β”œβ”€β”€ admin-endpoint-indicators.md  Admin-panel / sensitive-endpoint detection vocab & rules
β”‚   β”œβ”€β”€ analytic-standards.md    Likelihood bands, 5W1H coverage overlay, ACH (competing hypotheses)
β”‚   β”œβ”€β”€ pivot-artifacts.md      Pivot-artifact catalog (favicon, trackers, wallets, certs…)
β”‚   β”œβ”€β”€ pivot-services.md       Reverse-lookup engines per artifact β€” hash algo, cost, API/key notes
β”‚   β”œβ”€β”€ api-keys.md             Premium/pro API key management and unlocks
β”‚   └── tool-cascade-reference.md Tool priority and fallback chains
β”‚
β”œβ”€β”€ guides/                     Worked case walkthroughs
β”‚   └── walkthroughs/           Step-by-step investigation examples
β”‚       β”œβ”€β”€ walkthrough-person-lookup.md
β”‚       β”œβ”€β”€ walkthrough-domain-sweep.md
β”‚       └── walkthrough-username-trace.md
β”‚
β”œβ”€β”€ validation/                 Quality assurance
β”‚   β”œβ”€β”€ coverage-matrix.md      Investigation area coverage tracking
β”‚   β”œβ”€β”€ quality-scoring.md      Scoring methodology
β”‚   └── verification-checklist.md Finding verification steps
β”‚
└── connectors/                 External tool integrations
    β”œβ”€β”€ maltego-export.md
    β”œβ”€β”€ obsidian-setup.md
    └── notion-schema.md

Technique Activation Matrix

Which techniques activate per target type in a /case run:

TechniquePersonDomainOrgUsernameEmailIP
/sweepβœ…βœ…βœ…βœ…βœ…βœ…
/queryβœ…βœ…βœ…βœ…βœ…βœ…
/usernameβœ…β€”βœ…*βœ…β€”β€”
/email-deepβœ…β€”βœ…*β€”βœ…β€”
/phoneβœ…β€”βœ…*β€”β€”β€”
/breach-deep (LeakCheck + HudsonRock)βœ…βœ…βœ…βœ…βœ…βœ…
/subdomainβ€”βœ…βœ…β€”β€”β€”
/trafficβ€”βœ…βœ…β€”β€”β€”
/threat-checkβ€”βœ…βœ…β€”β€”βœ…
/secretsβ€”βœ…βœ…βœ…β€”β€”
/github-osintβœ…*βœ…βœ…βœ…βœ…*β€”
/scam-checkβ€”βœ…βœ…β€”β€”β€”
/branchβœ…βœ…βœ…βœ…βœ…βœ…
/gdocβ€”βœ…βœ…β€”β€”β€”
/sharelinkβœ…β€”βœ…βœ…βœ…β€”
<!-- dork-integration:phase-05 start -->

| /dork-sweep | βœ… | βœ… | βœ… | βœ… | βœ… | βœ…* | | /docleak | βœ… | βœ… | βœ… | βœ…* | β€” | β€” |

<!-- dork-integration:phase-05 end -->

| Social media platforms | βœ… | β€” | βœ… | βœ… | β€” | β€” | | Metadata forensics | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | Photo verification | βœ… | β€” | βœ…* | βœ… | β€” | β€” | | Network analysis | β€” | βœ… | βœ… | β€” | β€” | βœ… | | Advanced geolocation | βœ… | β€” | β€” | βœ… | β€” | β€” | | Web & DNS forensics | β€” | βœ… | βœ… | β€” | βœ… | βœ… | | /timeline | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | /exposure | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | /threat-model | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | /wifi (SSID/BSSID) | βœ… | βœ… | βœ… | β€” | β€” | βœ… | | Visitor intelligence | β€” | βœ… | βœ… | β€” | β€” | βœ… | | Cloud audit | β€” | βœ… | βœ… | β€” | β€” | βœ… | | MSFTRecon (M365/Azure tenant) | β€” | βœ… | βœ… | β€” | β€” | β€” | | /icp (ICP filing β†’ PRC entity) | β€” | βœ… | βœ… | β€” | β€” | βœ… | | /cn-corp (PRC registry chain) | βœ…* | βœ… | βœ… | β€” | β€” | β€” | | /iban (payment-rail selector) | βœ… | βœ… | βœ… | βœ… | βœ… | β€” | | /hash-id (hash typing) | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | Dependency audit | β€” | βœ… | βœ… | β€” | β€” | β€” | | Disk forensics | β€” | β€” | β€” | β€” | β€” | β€” | | Incident triage | β€” | βœ… | βœ… | β€” | β€” | βœ… | | OWASP audit | β€” | βœ… | βœ… | β€” | β€” | β€” | | Prompt injection audit | β€” | βœ… | βœ… | β€” | β€” | β€” | | /snapshots | β€” | βœ… | βœ… | β€” | β€” | βœ… | | Archive IOC harvest (wayback_harvest.py) | β€” | βœ… | βœ… | β€” | β€” | β€” | | /diff | β€” | βœ… | βœ… | β€” | β€” | βœ… | | /drift | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | /render threat-path | β€” | βœ… | βœ… | β€” | β€” | βœ… | | /render attack-surface | β€” | βœ… | βœ… | β€” | β€” | βœ… | | /blind-spots | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | /source-check | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | /report ioc | β€” | βœ… | βœ… | β€” | β€” | βœ… | | /report + /brief | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | | Shodan InternetDB (ports/tags/vulns) | β€” | βœ… | βœ… | β€” | β€” | βœ… | | GreyNoise Community (noise/threat class) | β€” | βœ… | βœ… | β€” | β€” | βœ… | | URLScan.io passive (scan history) | β€” | βœ… | βœ… | β€” | β€” | β€” | | Disposable email check (kickbox) | βœ… | β€” | βœ…* | β€” | βœ… | β€” | | URLhaus (malware URL hosting) | β€” | βœ… | βœ… | β€” | β€” | βœ… | | ThreatFox (IOC/C2 lookup) | β€” | βœ… | βœ… | β€” | β€” | βœ… | | MalwareBazaar (hash β†’ malware family) | β€” | β€” | β€” | β€” | β€” | β€” | | ipwho.is (geo + ASN + ISP) | β€” | βœ… | βœ… | β€” | β€” | βœ… | | DMARC/SPF/DKIM check (DNS) | β€” | βœ… | βœ… | β€” | βœ… | β€” |

βœ…* β€” runs for discovered key personnel within the organization MalwareBazaar β€” reached via /hash [value], but only after /hash-id has typed the value

The five v2.6 commands in /case

Four fire automatically as part of the standard pipeline β€” no flag needed. /redact is opt-in.

CommandFiresPhase
/icpUnconditionally for every domain/URL/org target, and on an IP target's resolved hostname. One cheap passive lookup β€” and a missing filing on CN-hosted infrastructure is itself a finding, so there is no CN-nexus precondition. A discovered licence serial re-enters the pivot loop as its own node and reverse-searches to sibling domains (same operator, HIGH).Acquire
/cn-corpAutomatically on any company name or USCC the case surfaces β€” from the ICP filing, WHOIS registrant org, page footer, or personnel discovery. Runs the GSXT β†’ aggregator β†’ 俑用中国 chain; officers/shareholders/subsidiaries re-enter the loop as new nodes.Acquire β†’ Enrich
/ibanAutomatically on any payment detail that surfaces β€” page DOM, Wayback harvest, victim statement, invoice, stealer log. Validation is arithmetic on a string, so it is free and touches nothing. Valid accounts become financial/iban IOCs; a checksum-invalid account on a payment page is logged as a behavioural finding instead.Acquire β†’ Enrich
/hash-idAutomatically on every discovered hash, and always before /hash. Decides file hash (β†’ MalwareBazaar/VT) vs credential material (β†’ /breach-deep, never a public service). 64-hex is queued for both the cert-fingerprint and file-hash readings, since it is genuinely ambiguous.Acquire β†’ Enrich
/redactOpt-in, not automatic β€” pass --redact (or run /redact later). Emits REPORT.redacted.{md,json,csv} + REPORT.map.json alongside the unredacted set. A redacted report is a weaker artifact, so producing one stays a deliberate choice.Deliver

Registries needing mainland egress (TianYanCha/QCC/Aiqicha) are logged as collection gaps, never blockers (techniques/china-recon.md Β§7). Non-IBAN rails (VN transfer, VietQR/NAPAS BIN, card BIN, e-wallet) follow techniques/fiat-payment-osint.md Β§4.

Flags: --no-cn skips /icp+/cn-corp (both run by default). --redact adds the redacted variant (off by default).

Recursive pivot orchestration (the spider-map). /case is not a one-pass collector — it runs a recursive BFS pivot engine: every discovered identifier becomes a new seed, and the relationship graph expands hop by hop until the frontier is exhausted or a budget cap is hit. The state machine — identifier typing, dedup / cycle prevention, per-node depth, the identifier→pivot edge matrix, confidence gating, and per-depth checkpoints — is scripts/pivot_orchestrator.py; the full spec is engine/pivot-orchestration.md. The orchestrator plans and tracks; the agent executes each hop's technique commands and feeds results back via --ingest.

  • Defaults: posture=active (may fetch/scan targets; still passive-first for hostile infra), reach=exhaustive (pivot till the frontier empties), autonomy=auto β€” the loop runs to closure unattended, no per-depth approval prompts. Depth summaries are still printed as they happen, so the expansion stays auditable. Safety caps: max_nodes=500, max_depth=6.
  • Gating (reuses analysis/auto-branch-rules.md): exact-match links (β‰₯95% β€” shared GA ID / cert / favicon / registrant email, handle exact-match) auto-pursue unbounded; HIGH/MEDIUM capped per type; LOW held unless corroborated; PII (person/phone) auto-expands by default (hold with --authorization unconfirmed); visited nodes and past-depth-cap nodes suppressed (loop-safe).
  • Example hops: an email auto-pivots via reverse-WHOISβ†’domains, /breach-deep, /github-osint; a domain discovered from a person (high-confidence link) continues via /webpivot+wayback_harvest+whois_enrich+cert_pivot+subdomains; a shared GA ID reverse-pivots to sibling domains; a discovered document (.pdf/office) or image (.jpg/.png) is itself a node β€” metadata/authorshipβ†’person/email/org and EXIF GPS + reverse-image/faceβ†’person/domain (face matches held pending corroboration) β€” each new node re-enters the loop.
  • Control flags (all narrowing β€” the defaults are already maximal): /case <t> --passive|--passive-first, --reach balanced|focused, --checkpoint (pause for approval after each depth level), --depth N, --budget N, --authorization unconfirmed (re-hold PII), --no-cn; --redact opts in to the redacted variant.
  • Termination β†’ emit edges β†’ graph_build.py β†’ interactive HTML force-graph + topology
    • timeline; findings/indicators roll into the auto-saved report + IOC bundle.

Legacy one-hop note (still true, now a subset of the loop): if /sweep on a domain finds an email, /email-deep and /breach-deep trigger on it automatically.

GitHub OSINT auto-fire in /case:

  • Domain/Org target β†’ run /github-osint on the org name, primary domain, discovered GitHub orgs/repos, and developer-platform hits from /query or /dork-sweep.
  • Username target β†’ run /github-osint directly when the handle has a GitHub profile or GitHub search hit.
  • Person target β†’ run /github-osint only after discovering a likely GitHub handle, commit email, repo author, or developer profile link.
  • Email target β†’ run /github-osint only after discovering commit attribution, GitHub noreply patterns, profile links, or repo references.
  • Results feed into /secrets, /branch, /timeline, /crossref, /exposure, and final /report automatically.
<!-- dork-integration:phase-05 start -->

βœ…* dork coverage notes: /dork-sweep on IP runs against reverse-DNS hostname once resolved (graceful skip if no rDNS); /docleak on Username targets document-author/uploader fields on scribd, slideshare, academia.edu, researchgate.

Dork auto-fire matrix β€” every /case target type gains coverage:

  • Person β†’ /dork-sweep --telegram --docs + /docleak on full name
  • Domain β†’ /dork-sweep --filetype --docs + /docleak on domain + org name
  • Org β†’ /dork-sweep --filetype --docs --telegram + /docleak on org + primary domain
  • Username β†’ /dork-sweep --telegram --docs + /docleak (author-angle)
  • Email β†’ /dork-sweep --telegram --docs on email + @domain
  • IP β†’ /dork-sweep on rDNS-resolved hostname (skipped if no rDNS)

Adaptive fan-out: discovered emails β†’ Telegram dork; discovered personnel β†’ /docleak; discovered subdomains β†’ filetype dork; discovered usernames β†’ Telegram + doc sweep; discovered IPs β†’ rDNS β†’ dork-sweep.

<!-- dork-integration:phase-05 end -->

When /case or /sweep runs on a Domain or Org target, it inspects the MX record and SPF TXT record. If MX ends in protection.outlook.com OR SPF contains spf.protection.outlook.com, /msftrecon auto-fires as part of the Acquire phase. Results feed back into the subject registry as infrastructure findings (tenant ID, federation type, MDI presence) and into /exposure scoring.

/case pipeline walkthrough (M365-hosted Domain/Org): (a) standard DNS/WHOIS/subdomain/traffic/scam-check/breach-deep checks run first, (b) if M365 indicators present β†’ /msftrecon fires automatically with no extra flag, (c) tenant ID discovered becomes a pivot for /branch in Enrich phase (search other domains under the same tenant). No user intervention required.

Parallel enrichment (3+ subjects): When Acquire discovers 3+ subjects, enrichment commands fan out in parallel via AgentFlow DAG orchestration. Each subject's enrichment runs independently, results merge with dedup before Assess phase. Disable with --sequential flag. See techniques/agentflow-enrichment.md.


Exposure Score Bands

RangeLabelAction
0–25MinimalPassive monitoring sufficient
26–50ModeratePeriodic review advised
51–75ElevatedAddress within 30 days
76–100CriticalImmediate escalation required

Tool Priority & Fallback

Primary interactive collector: agent-browser (vercel-labs) β€” a fast native-Rust CDP browser that returns accessibility-tree snapshots (@eN element refs) + screenshots; no API key for core automation; cross-platform; also an MCP server. Full how-to + per-command usage in techniques/agent-browser.md. It is complementary to Scrapling, not in conflict (different ecosystems β€” Rust binary via npm/brew/cargo vs Python via pip β€” each manages its own browser): use agent-browser to interact with and witness a page (logins, clicks, screenshots, JS render) and Scrapling to fetch and parse pages programmatically.

  1. Check agent-browser first (agent-browser --version; load its guide via agent-browser skills get core; install per the auto-install policy if missing)
  2. Use agent-browser for: screenshot evidence, logins/interactive UI, JS-rendered/SPA pages, complex multi-step browser flows
  3. Use Scrapling DynamicFetcher for: JS-heavy sites, SPA content, auto-escalation from static (programmatic)
  4. Use Scrapling StealthyFetcher for: anti-bot bypass, Cloudflare-protected targets
  5. Use Scrapling Fetcher for: fast static page collection, HTML parsing (~2ms)
  6. Fall back to web search β†’ web fetch β†’ direct curl β€” no investigation blockers
  7. Tag each finding with collection method: [browser] Β· [scrapling-dynamic] Β· [scrapling-stealth] Β· [scrapling-static] Β· [search] Β· [fetch] Β· [manual] Β· [whois-lib] Β· [whois-cli] Β· [whois-api]

Tool Auto-Install Policy

Before running any CLI tool, detect the OS, check whether the tool exists, and if not, install it automatically and silently using the method correct for that OS. This ensures zero-friction investigation on Windows, macOS, and Linux alike β€” the analyst never stalls on a missing dependency and never runs a Linux-only command on Windows.

Full cross-platform reference: scripts/platform-setup.md β€” OS detection, $PY/shell conventions, package managers, the complete per-tool Γ— per-OS install matrix, and known gotchas. Consult it whenever this summary is not enough.

Step 0 β€” Detect the platform (once per session)

Determine the OS before running anything, and cache it for the rest of the session. In Claude Code the environment block already reports it (e.g. Platform: win32 β†’ Windows). Otherwise probe: PowerShell $IsWindows/$IsMacOS, or Bash uname -s (Darwin=macOS, Linux=Linux, MINGW*/MSYS*/CYGWIN*=Windows/Git Bash). Then fix these conventions:

WindowsmacOS / Linux
ShellPowerShellBash
Python runner ($PY)uv run (preferred) Β· else venv …\.venv\Scripts\python.exe Β· else pyuv run (preferred) Β· else venv …/.venv/bin/python3 Β· else python3
"exists?" checkGet-Command <tool> -ErrorAction SilentlyContinue (or where.exe <tool>)command -v <tool>
System pkg managerwinget (β†’ choco/scoop)brew (macOS) Β· sudo apt/dnf/pacman (Linux)

On Windows, python3/python in the Bash tool is often a non-functional Microsoft Store stub. Prefer uv (it brings its own Python and sidesteps the stub); otherwise use py via PowerShell.

Step 0.5 β€” Ensure uv (the primary Python toolchain)

uv is the preferred way to install and run everything Python in this skill. It is a single fast, cross-platform tool that replaces pip, pipx, venv, and pyenv, manages its own Python (so the Windows Store-stub problem disappears), and resolves script dependencies on the fly. Using uv also collapses the per-OS split for Python tools β€” the same command works on Windows, macOS, and Linux.

  • Check: uv --version
  • Install if missing:
    • Windows: winget install --id astral-sh.uv β€” or powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    • macOS / Linux: curl -LsSf https://astral.sh/uv/install.sh | sh β€” or brew install uv
    • Any OS that already has pip: python -m pip install uv

If uv genuinely cannot be installed, fall back to the per-OS pip/pipx/venv path β€” nothing here hard-requires uv.

Auto-Install Protocol

  1. Check: OS-correct existence test from the table above (or <$PY> -c "import <module>" for Python modules)
  2. Install: If missing, run the OS-correct install command (see dispatch below / platform-setup.md)
  3. Verify: Confirm the tool resolves before proceeding β€” re-check; on Windows a fresh install may need a new shell or a probe of its install dir
  4. Log: Note [auto-installed] in the finding's collection method tag
  5. Continue: Proceed with the investigation β€” never block on tool availability

Install Dispatch by Category

Python tools β€” uv, identical on every OS (the big win: no per-OS split). CLIs use uv tool; libraries go into the skill venv via uv pip. No-uv fallback in the last column.

Python tool(s)Install (any OS, uv)No-uv fallback
CLIs β€” maigret, sherlock-project, holehe, h8mail, waymore, xeuledocuv tool install <pkg>pipx install <pkg>
Libraries β€” cloudscraper, oletools, whoisdomain, scraplinguv pip install --python <venv> <pkg><$PY> -m pip install <pkg>
Scrapling headlessuv tool install "scrapling[fetchers]" then scrapling install<$PY> -m pip install "scrapling[fetchers]" then scrapling install
AgentFlowuv pip install --python <venv> --no-deps agentflow<$PY> -m pip install --no-deps agentflow
Git-only β€” theHarvester, msftrecon, blackbird, sharetraceuv tool install "git+https://…/theHarvester.git" Β· uv pip install "git+https://…/msftrecon.git" Β· clone + uv pip install -r requirements.txtpipx install "git+https://…" Β· clone + <$PY> -m pip install -r requirements.txt
Run a generator scriptuv run <script.py> ARGS (deps auto via inline metadata)<$PY> <script.py> ARGS

<$PY> = py (Windows) / python3 (macOS/Linux), or the venv python. On PEP-668 Linux add --break-system-packages to the pip fallback.

System binaries β€” OS package manager (uv does not manage these):

Tool(s)WindowsmacOSLinux
git, gh, jq, exiftool, pandoc, poppler/pdfinfo, qpdf, whoiswinget install <Id>brew install <pkg>sudo apt install -y <pkg>
Go toolchainwinget install GoLang.Gobrew install gosudo apt install -y golang
mat2 (metadata strip)n/a β†’ exiftool -all= -overwrite_original <file>brew install mat2sudo apt install -y mat2
agent-browser (interactive browser)npm i -g agent-browser or cargo install agent-browser β†’ agent-browser installbrew install agent-browser β†’ agent-browser installnpm i -g agent-browser (or cargo install) β†’ agent-browser install

Go tools (after Go is present β€” identical on all OSes): go install <module> for subfinder, amass, gau, gitleaks, httpx. PhoneInfoga and TruffleHog β†’ GitHub release binary per OS/arch (go install rejects TruffleHog's module for its replace directives; the PyPI trufflehog is the abandoned v2 Python tool and does not accept v3 syntax). ASN β†’ Git Bash/WSL bash <(curl -sL …/nitefood/asn/master/asn) on Windows, native bash on macOS/Linux, or RDAP/ipwho.is HTTP fallback.

The exact winget IDs, brew formulae, apt packages, uv commands, import names, and Go module paths for every tool are tabulated in scripts/platform-setup.md Β§5. To provision a fresh machine in one shot, run the bundled installer for the detected OS:

  • Windows: powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.claude\skills\cti-expert\scripts\install.ps1"
  • macOS / Linux / Git Bash / WSL: bash ~/.claude/skills/cti-expert/scripts/install.sh

(both accept --headless/-Headless, --go/-Go, --all/-All)

Behavior Rules

  • uv first (anything Python): prefer uv β€” uv tool install for CLIs, uv pip install for libraries, uv run for scripts. It behaves identically on every OS, so reach for it before per-OS pip/pipx. Fall back to <$PY> -m pip / pipx only when uv cannot be installed.
  • Detect before install (system binaries): dispatch by the OS detected in Step 0 β€” never run apt on Windows or winget on Linux.
  • Silent install: do not ask permission β€” install and proceed. Tool installation is a normal part of the investigation workflow.
  • Go tools: require Go installed. If go is missing, install it via the OS package manager (winget install GoLang.Go / brew install go / sudo apt install -y golang), or note the gap and fall back to the next tool in the cascade.
  • Linux privileges: system installs need sudo unless running as root.
  • Windows specifics: winget may prompt UAC; a freshly installed tool may not be on PATH until the shell is reopened (probe its install dir or restart the shell before declaring failure). The DOCX generator self-heals UTF-8 output and pandoc location β€” see platform-setup.md Β§6.
  • Git-based install: for tools without a PyPI package (msftrecon, blackbird, sharetrace), clone the repo and install its requirements.txt with <$PY> -m pip install -r requirements.txt.
  • Fallback on install failure: if installation fails, log a collection gap and skip to the next tool in the cascade β€” never block the investigation.

Related skills