Deep entity patterns beyond the primary subject — shared boards, co-investments, common counsel, jurisdiction clustering
LAYER 2: ANALYSIS AGENT — This is a theory-building skill. You identify systemic patterns and generate hypotheses, but every hypothesis MUST produce a testable prediction queued as a research lead for Layer 1 agents. Shared attributes (same jurisdiction, same industry, same donor pool) are often coincidental at baseline — always ask "what's the base rate?" before calling something a pattern. See research/INVESTIGATIVE_METHODOLOGY.md#framework-discipline.
Analyze a group of actors as a SYSTEM — shared board memberships, co-investments, common counsel, jurisdiction clustering, coordinated donations, common grant recipients. Focus on what connects them to each other independent of the primary investigation subject.
--thread N: analyze actors in a specific investigation thread--person "Name": analyze the system around a specific person--cluster "label": analyze a tagged cluster from previous analysisWithout arguments: analyzes the highest-priority thread or the largest tagged cluster.
Load the active investigation context before executing:
uv run python tools/investigation_context.py show
This provides: primary_subject, key_persons, threads, corpus_tools, key_dates, known_addresses. Use these values instead of hardcoded names throughout this skill.
WORKDIR=$(mktemp -d /tmp/osint-XXXXXXXX)
echo "Session workdir: $WORKDIR"
uv run python -c "
from tools.analysis_export import start_analysis_run
run_id = start_analysis_run('systemic-analysis')
print(f'Analysis run #{run_id}')
"
Depending on the argument:
For --thread N:
uv run python tools/analysis_export.py findings-dump --thread-id N --output $WORKDIR/thread-findings.json
Select the top 10-15 actors by finding count in the thread.
For --person "Name":
uv run python tools/graph_tools.py neighbors "Name" --depth 2 --output $WORKDIR/ego.json
Select the person plus their top 10-15 connections by degree.
For --cluster "label":
uv run python tools/tag_manager.py find --type cluster --value "label" --output $WORKDIR/cluster.json
Extract the distinct target_names from the tagged findings.
For each member of the target group, search external sources. Use --output $WORKDIR/... on all searches:
a) LittleSis — Relationship mapping
uv run python tools/query_littlesis.py search "MEMBER_NAME" --output $WORKDIR/littlesis-MEMBER.json
# If found, get full relationships:
uv run python tools/query_littlesis.py relationships ENTITY_ID --output $WORKDIR/littlesis-rels-MEMBER.json
b) SEC EDGAR — Board and financial connections
uv run python tools/query_edgar.py search "MEMBER_NAME" --output $WORKDIR/edgar-MEMBER.json
uv run python tools/query_edgar.py company CIK_NUMBER --output $WORKDIR/edgar-co-MEMBER.json
c) IRS 990 — Nonprofit board overlap
uv run python tools/query_990.py search "MEMBER_NAME" --output $WORKDIR/990-MEMBER.json
uv run python tools/query_990.py officer-search "MEMBER_NAME" --output $WORKDIR/990-officer-MEMBER.json
d) FEC — Political donation patterns
uv run python tools/query_fec.py donor "MEMBER_NAME" --output $WORKDIR/fec-MEMBER.json
e) OpenSanctions — Sanctions/PEP status
uv run python tools/query_opensanctions.py search "MEMBER_NAME" --output $WORKDIR/sanctions-MEMBER.json
From gathered data, build a matrix showing which patterns are shared:
| Pattern | Member A | Member B | Member C | ... |
|---|---|---|---|---|
| Board: Company X | Yes | Yes | ||
| Donor: PAC Y | Yes | Yes | ||
| Attorney: Firm Z | Yes | Yes | ||
| Jurisdiction: USVI | Yes | Yes | Yes | |
| Grant: Charity W | Yes | Yes |
Focus on patterns shared by 3+ members — these indicate systemic behavior, not coincidence.
For each member, investigate their activities INDEPENDENT of the primary subject:
This reveals the SYSTEM — the pre-existing or parallel structure that the primary subject operated within.
For each systemic pattern:
uv run python tools/findings_tracker.py add \
--target "SYSTEM_NAME (e.g., 'philanthropy network' or 'board overlap cluster')" \
--type relationship \
--summary "SYSTEMIC PATTERN: N members share X" \
--detail "Members: A, B, C. Pattern: DESCRIPTION. Significance: IMPLICATION." \
--confidence medium \
--claim-type synthesis \
--evidence "analysis-run-{RUN_ID}; littlesis:ID1; edgar:CIK" \
--source-quote "SPECIFIC DATA POINTS from external sources"
uv run python tools/tag_manager.py bulk-tag --table findings --ids ID1,ID2,ID3 \
--type systemic --value "GROUP_NAME" --created-by "agent:systemic-analysis"
For system-level coordination patterns. Every hypothesis MUST include:
uv run python tools/hypothesis_tracker.py add \
--title "SYSTEMIC HYPOTHESIS" \
--pattern-type operational \
--description "SYSTEM PATTERN: N actors share X, suggesting Y. INNOCENT EXPLANATION: [best alternative]. FALSIFICATION: [what would disprove this]." \
--predicted-evidence "If coordinated, expect shared Z" \
--search-plan "1. Check registry for shared agents 2. Search emails for inter-member communication 3. Cross-ref financial flows" \
--originated-from "analysis:systemic-analysis"
For unexplored system nodes (e.g., the shared attorney, the common board, the co-investment vehicle):
uv run python tools/lead_tracker.py add \
--target "SYSTEM_NODE_NAME" \
--category connection \
--priority medium \
--description "Systemic node: shared by N members of GROUP. Roles: DESCRIPTION." \
--source "analysis:systemic-analysis" \
--thread-id THREAD_ID
Create connections between system members that aren't already recorded:
uv run python tools/findings_tracker.py connect \
--person-a "MEMBER_A" \
--person-b "MEMBER_B" \
--type board_membership \
--description "Both serve on BOARD_NAME" \
--finding-id FINDING_ID
Write to $WORKDIR/report-systemic-analysis.md:
# Systemic Analysis Report — [DATE]
## Target Group
- Scope: [thread/person/cluster]
- Members (N): [list]
## System Patterns Found
### 1. [PATTERN NAME]
**Members involved:** A, B, C, D
**Evidence:** [external source data]
**Significance:** [what it implies]
### 2. [NEXT PATTERN]
...
## Comparison Matrix
[Table of shared patterns]
## Non-Subject System Structure
[What connects these actors to each other independent of the primary subject]
## Systemic Hypotheses
[Generated hypotheses with IDs]
## New Leads
[Leads for unexplored system nodes]
## Connections Mapped
[New connections created]
uv run python -c "
from tools.analysis_export import complete_analysis_run
complete_analysis_run(RUN_ID, findings_created=N, hypotheses_created=M,
leads_created=L, tags_created=T,
report_path='$WORKDIR/report-systemic-analysis.md')
"
claim_type=synthesis, max confidence medium