Research Sources
Populate the research cache consumed by pnpm run research <protocol>. This skill handles the web-search / source-discovery half of the pipeline entirely within Claude Code (subscription-billed) so the Anthropic API phase only pays for citations extraction.
Arguments
<protocol>— required. The protocol id, matching a key inscripts/research-config.ts.--only "A,B"— optional. Restrict discovery to the named properties. Matches the semantics ofpnpm run research --only.
Instructions
Load config. Read
scripts/research-config.tsand resolve the entry for<protocol>. Extractid,title,description,sourceUrls, andcontext. If the id is missing, list available ids and stop.Load schema. Read
src/data/schema.ts. Build the property list by filteringPROPERTY_DEFINITIONSagainst theSKIP_PROPERTIESset declared inscripts/research-config.ts(currently:Anonymity set size,On-chain gas cost: deposit,On-chain gas cost: transfer,On-chain gas cost: withdraw). If--onlywas supplied, further restrict to those names.Load rules. Read
scripts/research-prompts.tsfor the cross-cutting blocks. ApplySOURCE_SELECTION_RULESwhen choosing URLs — reject PDFs, prefer official docs over third-party blogs, reject landing/navigation pages, point at specific READMEs rather than repo roots. URL workflow (1–3 sources, two is the default): discover up to three independent sources per property (different domains where possible — e.g. official docs + L2BEAT, official docs + GitHub README, official docs + audit report). Two is the default and has been load-bearing in practice; add a third only when distinct load-bearing claims rest on distinct documents (e.g. mechanism in docs + compliance gate in contract README + dated-deployment evidence in a separate announcement). One URL is acceptable when a single source covers every claim (e.g. a license file for Open source). Every recorded URL will be ingested by the research script even if only one ends up cited (SOURCE_SELECTION_RULES #6). For per-property guidance, read.claude/skills/property-rules-{group}/SKILL.mdfor the relevant group (privacy, compliance, trust, cryptography, state-model, timing, composability). For the four compliance properties andUpgradeability, also apply theCROSS_CHECK_RULEScontract-level compliance audit — inspect the contract repository directly, not just the whitepaper.Load the existing cache if present.
scripts/research-cache/{id}.json. If it exists, treat its entries as prior work — re-use theurlsandsummaryfor any property you aren't currently refreshing. When--onlyis supplied, only the listed properties are re-discovered; all others are copied through unchanged. Legacy entries with a singleurlfield are still readable but should be upgraded tourlsnext time you touch them.For each in-scope property, use
WebSearchandWebFetchto identify 1–3 independent source URLs (two is the default):- List the docs sitemap first. Run
curl -s <docs-origin>/sitemap.xml(or WebFetch it) and read the<loc>URLs — the hand-pickedsourceUrlsare a seed, not the ceiling. The sitemap surfaces deep pages a placeholder docs root hides (the miden bridge, block time, and auth pages were all missed by an 8-URL hand-list). Then start fromconfig.sourceUrlsand the official docs. If there's no sitemap, probe/llms.txtor hand-pick. Never fall back to the marketing apex domain ({protocol}.xyz/) as a substitute — that's a SOURCE_SELECTION_RULES #1 violation. - When no single page answers the property, issue a
WebSearchscoped to the protocol's name plus keywords from the property (e.g."{protocol} upgradeability proxy admin"). - Fetch candidate URLs with
WebFetchto confirm they contain the required technical content. - For smart-contract-based protocols evaluating the four compliance properties or
Upgradeability, inspect the contract repo (look for proxy patterns,onlyOwnergates, blocklist hooks) — the correct URL may be a contract README or deployment script, not the whitepaper. - Reject URLs that fail
no-pdf-sources,official-sources-only, orspecific-technical-page. - Primary + secondary (default): find a primary source (best technical content) AND an independent secondary source (different domain — L2BEAT, audit report, GitHub README, ethresear.ch design discussion). The primary is what the LLM will likely cite; the secondary gives cross-reference.
- Add a third only when warranted: if a single property's load-bearing claims span content that no two sources cover together (e.g. mechanism in docs + compliance gate in contract README + dated-deployment evidence in an audit report), record a third URL.
- Single source is fine when one document carries every claim (e.g. a licence file for Open source, a block-explorer page for an admin classification).
- Load-bearing span requirement: for each chosen URL, identify the specific sentence(s) on that page that prove the load-bearing claim — not adjacent architecture context, not landing-page chrome. The fetched page text is what the API will extract spans from, so the source must literally contain the substantive sentence the value rests on. If a candidate page only contains adjacent context without the load-bearing sentence, look for a different page on the same site that does.
- List the docs sitemap first. Run
Compose a short factual
summary(≤400 characters) describing what those pages establish about this property. The summary will be fed into the citations phase of the API script — it should be concrete, not narrative. When the property's load-bearing claim is one specific sentence in the source, quote that sentence near-verbatim in the summary so the API biases toward extracting the substantive span (rather than adjacent architecture context). If the sources disagree on a fact, mention the disagreement in the summary so the reviewer-LLM sees both views.Write the cache file at
scripts/research-cache/{id}.json:{ "id": "<protocol>", "generatedAt": "<ISO8601>", "properties": [{ "name": "Confidentiality", "urls": ["https://primary…", "https://secondary…"], "summary": "…" }] }propertiesmust contain an entry for every non-skipped, non-filtered property.- Each entry has a
urlsarray (length 1, 2, or 3) — primary first, then secondary, then optional tertiary. Two is the default. - Preserve previously-cached entries for properties outside the current
--onlyfilter.
Output
Print a one-line summary per property while working ({property} → {url}) and a final line:
Wrote scripts/research-cache/{id}.json ({N} properties)
Next: pnpm run research {id} [--only "A,B"]
Failure modes
- No acceptable URL found for a property: write the property entry with
urls: []and a summary explaining why. The API script will flag the property asINSUFFICIENT_DATA. - Config entry missing or
sourceUrlsset to"TODO": stop and tell the user to populatescripts/research-config.tsfirst. --onlynames a property not in the schema: stop with the list of valid property names.