Skip to content
Back to skills

Investigative Reasoning

ASecurity

Use this skill when investigating complex multi-source problems requiring entity resolution, cross-dataset linking, or public records correlation. Adapts OpenPlanter's methodology for Agent Zero investigations — joining disparate data sources through fuzzy matching and relationship inference. Triggers: 'investigate', 'find connections between', 'link these entities', 'cross-reference', 'entity resolution', 'follow the money'.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
ai-agentspythongoshelltestingapidatabasesecurity

Works with

  • api

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add Stranglehold/Exocortex --skill investigative-reasoning --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Investigative Reasoning?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Investigative Reasoning
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/stranglehold-investigative-reasoning/badge)](https://www.skillsdirectory.com/skills/stranglehold-investigative-reasoning)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "investigative-reasoning"
description: "Use this skill when investigating complex multi-source problems requiring entity resolution, cross-dataset linking, or public records correlation. Adapts OpenPlanter's methodology for Agent Zero investigations — joining disparate data sources through fuzzy matching and relationship inference. Triggers: 'investigate', 'find connections between', 'link these entities', 'cross-reference', 'entity resolution', 'follow the money'."
version: "1.0.0"
author: "Exocortex Adaptation Team"
tags: ["investigation", "entity-resolution", "cross-linking", "public-records", "forensics"]
trigger_patterns:
  - "investigate connections between"
  - "find links across"
  - "correlate these datasets"
  - "follow the money trail"
  - "resolve entity identity"
  - "cross-reference public records"
---

# Investigative Reasoning

## Purpose

This skill guides complex investigations requiring **entity resolution** and **cross-dataset correlation**. It adapts OpenPlanter's methodology — used to link Boston city councilors to campaign finance donors via vendor relationships — for Agent Zero's tool surface.

**Core capability:** Join disparate data sources (WHOIS, corporate registries, financial filings, DNS records) through fuzzy entity matching and relationship inference. Build connected graphs of ownership, funding flows, or infrastructure sharing.

**Key pattern:** When investigating X, ask: What other datasets might contain information about the same entities? How can I join them on names, addresses, phone numbers, email domains, or tax IDs?

## When to Use

Use this skill when:
- **Multi-source correlation required**: Needing to link entities across different databases (e.g., matching a domain registrant's name against campaign finance donors)
- **Identity resolution needed**: Same entity appears under slightly different names in different sources (fuzzy matching: "John Smith" vs. "J. Smith")
- **Graph construction required**: Building relationship networks between people, companies, domains, and infrastructure
- **Public records investigation**: Analyzing corporate registries, campaign finance data, contracts databases, or DNS records together

Do NOT use for:
- Single-source lookups (e.g., "Who owns this domain?") — use `domain_collector` directly
- Simple fact-checking without cross-referencing multiple datasets
- Tasks not requiring entity resolution or multi-dataset joins

---

## Methodology

### Phase 1: Define the Investigation Core

Start by identifying your **seed entities** (people, companies, domains) and the **hypothesis** you're testing.

```python
# code_execution_tool — document investigation scope
investigation = {
    "seed_entities": ["target_domain.com", "Suspect Name"],
    "hypothesis": "The domain registrant is connected to campaign finance contributions",
    "datasets_needed": ["WHOIS data", "Campaign Finance DB", "Corporate Registry"],
    "join_keys": ["name", "address", "phone_number"]  # Fields for fuzzy matching
}
```

### Phase 2: Multi-Source Data Acquisition

Collect relevant datasets from multiple sources. OpenPlanter demonstrates joining:
1. **Boston City Council candidate list** (CPF IDs, names, offices)
2. **OCPF campaign finance data** (donors, employers, contributions)
3. **Open Checkbook vendor registry** (company names, addresses)
4. **Corporate filings** (MA Secretary of State for corporate officers)

For Agent Zero investigations:
- Use `domain_collector` to extract WHOIS registrants and DNS records
- Use `company_collector` for business registrations
- Use `people_collector_enhanced` for data breach and social footprint data
- Acquire external datasets via browser_agent or document_query if available locally

**Example**: Extract email domains from WHOIS, then join against corporate registry to find other companies owned by the same registrant.

### Phase 3: Entity Resolution (The Core Step)

This is where you **normalize names and addresses** across sources before joining. OpenPlanter's approach:

```
1. Extract CPF IDs from candidates.txt → load into dict {cpf_id -> full_name}
2. Load OCPF contributions with donor names
3. Fuzzy-match candidate names to donor names using Levenshtein distance or simple substring matching
4. Link on CPF ID when exact match found, link on name similarity otherwise
```

For Agent Zero:
- Normalize names: Remove suffixes (Jr., III), expand initials, standardize punctuation
- Normalize addresses: Standardize street abbreviations (St vs Street), remove directionals (N vs North)
- Extract join keys: Parse phone numbers to E.164 format, extract email domains, parse tax IDs

**Example Entity Resolution Code Pattern:**

```python
# code_execution_tool — fuzzy matching logic from OpenPlanter adapted for A0
import difflib
from collections import defaultdict

def normalize_name(name):
    """Remove suffixes and standardize."""
    name = name.replace("'s", "")  # Remove possessive
    return name.lower().strip()

def find_best_match(target_name, candidate_list, threshold=0.75):
    """Find best fuzzy match across list."""
    target = normalize_name(target_name)
    for candidate in candidate_list:
        if difflib.SequenceMatcher(None, target, normalize_name(candidate)).ratio() >= threshold:
            return candidate
    return None
```

### Phase 4: Cross-Linking Analysis

Once entities are resolved across datasets, **build relationship edges**.

OpenPlanter's approach:
- **Primary link**: Candidate CPF ID → Campaign contributions (direct)
- **Secondary link**: Donor employer name ↔ Vendor company name (fuzzy match on names and addresses)
- **Tertiary link**: Corporate officer names ↔ Registrant names (identity resolution across registries)

For Agent Zero, construct relationships:
1. **Ownership edges**: Domain registrant → Company owner (same name/address)
2. **Infrastructure edges**: Domain A → Domain B (shared WHOIS email or DNS server)
3. **Financial edges**: Person X → Campaign donor to Candidate Y (via campaign finance data)
4. **Employment edges**: Person X → Employer Z (from corporate registry)

**Example Relationship Inference:**
```
IF domain registrant.name == campaign_donor.name AND 
   domain registrant.address ~= campaign_donor.address (within 50 chars) THEN
   Create relationship: Domain —[REGISTERED_BY]→ Person —[DONATED_TO]→ Candidate
```

### Phase 5: Finding Synthesis

Generate **investigative findings** by identifying high-value paths in the graph:
- **Cycles**: A → B → C → A (ownership loops indicating shell companies)
- **Shared infrastructure**: Multiple domains with same registrant email (likely related)
- **Temporal patterns**: Registrations clustered around campaign finance filing deadlines
- **Geographic clusters**: Entities sharing city/zip codes indicating physical proximity

---

## Agent Zero Tool Mapping

| OpenPlanter Capability | Agent Zero Equivalent |
|------------------------|---------------------|
| Load Boston candidates from TSV | `domain_collector` (WHOIS extraction) + `document_query` (local data files) |
| Fuzzy name matching across datasets | Python `difflib.SequenceMatcher` or custom entity resolution in `code_execution_tool` |
| Link donors to vendors via employer names | `company_collector` + manual join logic |
| Corporate officer lookup | Browser scraping of Secretary of State sites OR local database joins |

**Key difference:** OpenPlanter uses bulk file loads (TSV/CSV). Agent Zero typically queries APIs or individual lookups. For bulk analysis, download datasets first via `browser_agent`, then use `code_execution_tool` for pandas-style operations.

---

## Example Investigation: Domain to Political Connection

**Hypothesis**: A suspicious domain is registered by someone connected to local politics.

1. **Collect WHOIS data** → Extract registrant name ("Acme Corp") and address ("123 Main St, Boston")
2. **Query Campaign Finance DB** → Search for donors named "Acme" or located at "Main St, Boston"
3. **Entity Resolution** → Fuzzy match "Acme Corporation" with "ACME CORP" in campaign finance data
4. **Cross-Link** → Found: Acme donated $50k to Councilor X; same address matches vendor in city contracts
5. **Synthesis** → Finding: Domain registrant is a major political donor and city vendor, potential conflict of interest.

---

## Security Rules — Non-Negotiable

1. **No PII retention**: Do not store personally identifiable information beyond the scope of this investigation session.
2. **Public records only**: Use only publicly available data sources. Do not access password-protected systems or private databases without explicit authorization.
3. **Data provenance tracking**: Always document source URLs and extraction timestamps for legal defensibility.
4. **Fuzzy match confidence scoring**: When fuzzy matching names across datasets, report the similarity score (e.g., "85% match on address"). Do not treat low-confidence matches as definitive.

---

## What This Skill Does NOT Do

- Does not perform automated entity resolution without human review — always verify fuzzy matches
- Does not scrape behind paywalls or login walls — uses only public, freely accessible data
- Does not claim legal conclusions (e.g., "this proves corruption") — reports factual connections only
- Does not replace the need for `domain_collector`, `company_collector`, etc. — orchestrates their output

---

## Example Invocation

> "Investigate whether the registrant of suspicious-domain.com appears in Massachusetts campaign finance records as a donor or vendor. Use entity resolution to link across datasets."

**Expected workflow:**
1. Call `domain_collector` on suspicious-domain.com → extract registrant name/address/email
2. Check local OCPF campaign finance dataset (or fetch via browser_agent if not cached)
3. Normalize names and fuzzy-match against donor list and vendor list
4. Report any matches with similarity scores and full entity details
5. Synthesize findings into a relationship graph description.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.