Search sub-skill for the Client Opportunity Scout. Defines the full search process, output format, dedup protocol, and validation rules. Preloaded into client-scout-search-agent via skills declaration.
Find funding opportunities that match a specific client's profile but aren't yet in Meridian's database. You search one source-type wave with a chunk of 3-5 project needs. Report structured findings — do NOT write to any database.
Quality standard: Every finding must be a REAL funding opportunity (not news, not a blog post, not a general information page). Include enough detail for the orchestrator to assess match quality and for the ingestion phase to locate the program.
Read the search strategies reference before doing anything else:
Read: .claude/skills/client-scout-search/SEARCH-STRATEGIES.md
This file contains query templates, site navigation patterns, DSIRE techniques, PDF handling, and source-type-specific guidance you need for execution.
Your prompt from the orchestrator contains these fields. Parse them before searching:
| Field | Description |
|---|---|
wave | Source type: utility, county, state, federal, foundation |
sources | Specific entities to search (e.g., "Southern California Edison", "Los Angeles County") |
needs_chunk | Array of 3-5 project needs (e.g., ["HVAC Systems", "Solar Panels", "Battery Storage"]) |
client_type | Client's type (e.g., "K-12 School Districts") |
expanded_types | Expanded type list (synonyms + hierarchy + cross-categories) |
state_code | Client's state (e.g., "CA") |
county | Client's county (e.g., "Los Angeles County") |
city | Client's city (e.g., "Redondo Beach") |
dac | Whether client is in a Disadvantaged Community (true/false) |
dedup_titles | Existing opportunity titles in Meridian (for dedup) |
dedup_urls | Existing opportunity URLs in Meridian (for dedup) |
For each project need in your needs_chunk, execute the search strategies
appropriate to your wave type (defined in SEARCH-STRATEGIES.md).
dedup_titles and dedup_urlsSame as the extraction skill — hierarchical fallback:
HTML pages:
browser_navigate + browser_snapshot)PDF documents:
curl -sL -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" "PDF_URL" | python3 -c "
import sys, fitz
doc = fitz.open(stream=sys.stdin.buffer.read(), filetype='pdf')
for page in doc[:20]: print(page.get_text())
"
Login-gated pages: Flag and skip — do not attempt to bypass.
Include:
Exclude:
Before including any finding in your output:
dedup_urls?dedup_titles? (fuzzy — account for slight naming differences)already_in_db list with the matching title/URL.The orchestrator uses the already_in_db list to detect matching anomalies (Category 2 in the report).
For each finding, assess whether it would plausibly match the client using these criteria
(mirrors the 4-criteria matching algorithm in evaluateMatch.js):
| Criterion | What to Check |
|---|---|
| Location | Does the program cover the client's geography? (utility territory, county, state, national) |
| Applicant Type | Does the program accept the client's type or any of the expanded types? |
| Project Needs | Does the program fund at least one of your assigned project needs? |
| Activities | Does the program involve construction/installation/renovation type activities? |
Assign a confidence level:
Return your findings as a structured report. The orchestrator will parse this.
=== WAVE REPORT: [wave_type] ===
Agent: [agent_name]
Needs chunk: [need1, need2, need3]
Queries executed: [N]
URLs evaluated: [N]
--- NEW FINDINGS ---
FINDING 1:
title: [Official program name]
url: [Primary URL]
source_name: [Funding entity name]
source_type: [Utility/County/State/Federal/Foundation]
source_website: [Entity's main website]
state_code: [XX]
funding_type_guess: [Grant/Incentive/Rebate/Tax Credit/Loan]
status_guess: [Open/Upcoming/Rolling/Closed-Recurring/Unknown]
confidence: [high/medium/low]
match_reasoning: [1-2 sentences: why this matches the client]
matched_needs: [which project needs from your chunk this covers]
program_urls: [array of URLs: main page, application page, PDF links]
is_pdf: [true/false — whether primary content is a PDF]
FINDING 2:
...
--- ALREADY IN DB ---
EXISTING 1:
found_title: [What you found]
found_url: [URL you found]
existing_match: [Title/URL from dedup list that matches]
note: [Why you think this should/shouldn't be matching the client]
--- BONUS FINDS ---
BONUS 1:
title: [Program name]
url: [URL]
source_name: [Entity name]
note: [Why this is interesting even though it doesn't match THIS client]
best_for: [What client types/geographies would benefit]
=== END WAVE REPORT ===