---
name: source-router
description: evidence-plan을 읽고 source capability 기반 source-call-plan, validation, unresolved gaps를 작성하는 스킬
---

# source-router

## When to Use

- `${ACTIVE_WORKSPACE}/00_evidence/evidence-plan.md`가 존재하고, source capability에 맞춘 후보 소스와 fallback을 정해야 할 때 사용한다.
- `/market-intel` 또는 `/source-audit` thin command가 source routing 또는 audit handoff를 요청할 때 사용한다.

## Required Inputs

- `${ACTIVE_WORKSPACE}/00_evidence/evidence-plan.md`
- 기준 문서: `docs/harness/invest/research-layer/source-capability-registry.md`
- 기준 문서: `docs/harness/invest/research-layer/validation-gates.md`
- 기준 문서: `docs/harness/invest/research-layer/claim-boundary-policy.md`
- 템플릿: `docs/harness/invest/templates/source-call-plan.md`
- 템플릿: `docs/harness/invest/templates/source-validation.md`
- 템플릿: `docs/harness/invest/templates/unresolved-data-gaps.md`

## Output Paths

- `${ACTIVE_WORKSPACE}/00_evidence/source-call-plan.md`
- `${ACTIVE_WORKSPACE}/00_evidence/source-validation.md`
- `${ACTIVE_WORKSPACE}/00_evidence/unresolved-data-gaps.md`
- 선택 출력: `${ACTIVE_WORKSPACE}/00_evidence/api-call-log.md`

## Rules

- Select sources by `required_evidence_types` and source capability.
- Do not select sources by fixed use-case labels.
- Include fallback sources and source limitations.
- Include validation checks before analyst fan-out.
- Rank selected sources by evidence trust tier before availability convenience: T0 company official/regulator disclosure, T1 official market/statistical sources, T2 vendor snapshots, T3 discovery/context.
- For reported company facts, financial statements, guidance, segment data, risk factors, share count, and issuer identity, select Company IR, SEC EDGAR, DART/KRX, or local regulator filings before yfinance/FMP/Alpha Vantage/Web Search.
- Runtime availability can force a fallback, but it cannot promote T2/T3 evidence above T0 for material company claims. If T0 is unavailable, stale, or not fetchable, record the data gap before using lower-tier evidence.
- Treat FRED, Alpha Vantage, FMP, EDGAR, DART-KRX, yfinance, KOSIS, customs trade, Google Trends, Naver DataLab, KOTRA, G2B, and ECOS as capabilities, not mandatory sources.
- Read each registry source's `connection_status` as repo-evidence status only, not live runtime proof.
- Before analyst fan-out, record live runtime proof separately as `Runtime Availability` and `Live Tool Probe` in `${ACTIVE_WORKSPACE}/00_evidence/source-call-plan.md`.
- If `yfinance` is documented in repo contracts but unavailable in the live tool inventory, do not block the run. Mark it unavailable, prefer T0 company IR, SEC EDGAR, DART/KRX, or local regulator filings for reported company facts, then select FMP/Alpha Vantage only when actually callable. Use Web Search + Fetch for source discovery and source retrieval support.
- Valid `connection_status` values are `connected`, `documented_only`, `planned`, and `external_manual`.
- If a needed source is `documented_only`, `planned`, or `external_manual`, record the missing callable tool/endpoint in `${ACTIVE_WORKSPACE}/00_evidence/unresolved-data-gaps.md` instead of inventing a retrieval path.
- Select the best live callable access mode for the source: MCP, repo helper, direct API, browser, or Web Fetch. Reuse existing yfinance and DART-KRX/korea-stock tool contracts when applicable, but do not require MCP when a validated API-key/helper path is available. For SEC EDGAR, use `scripts/sec/Invoke-SecEdgarApi.ps1` when the live probe succeeds. Represent FRED, Alpha Vantage, and FMP as source capability contracts unless concrete callable repo evidence exists.
- For public web evidence, use Web Search only to discover candidate URLs. If search returns only summary snippets, require Web Fetch/browser/PDF reading of the candidate URL body before using the source as evidence.
- Search finds links; Fetch reads the article, document, or PDF body. Do not cite or validate claims from search snippets alone.
- Web Search + Web Fetch does not require a separate scraping infrastructure for ordinary public articles, documents, or PDFs, but body retrieval failures must be recorded as data gaps.
- Keep API execution outside this thin planning contract unless another skill explicitly owns retrieval.

## Workflow

1. Read evidence plan requirements.
2. For each evidence type, select candidate source, trust tier, `source_id`, `connection_status`, runtime availability, live tool probe evidence, reason selected, required parameters, fallback sources, expected output, validation checks, and source limitations.
3. Write claim boundaries for each source.
4. If required inputs are missing, write unresolved data gaps.
5. If the selected source is not `connected`, or is `connected` in repo evidence but unavailable in the live runtime, write the unavailable tool/endpoint and fallback path as a data gap before analyst fan-out.
6. If a lower-trust source is used because T0/T1 evidence is unavailable, write the missing higher-trust evidence and affected claim in unresolved data gaps.
7. For web sources, include both the search query/link-discovery step and the fetch/body-read step in the source-call plan.
8. If retrieval was performed by another role, summarize evidence IDs, fetched URL/body status, and validation status.
9. Run the **Coverage Self-Check** below before declaring the source-call-plan complete.
10. Write outputs under `${ACTIVE_WORKSPACE}/00_evidence/`.

## Coverage Self-Check (Phase C, Wave 7)

source-router는 source-call-plan.md를 emit하기 직전에 자기 출력에 대해 다음 완전성 self-check를 수행하고 결과를 source-call-plan.md 본문 끝에 inline 블록으로 기록한다.

```text
# === Source Routing Coverage Self-Check ===
schema_version: 1
evidence_plan_path: ${ACTIVE_WORKSPACE}/00_evidence/evidence-plan.md
checked_at: 2026-05-21T09:14:55Z
coverage:
  - evidence_type: financial_statement
    primary_source_id: sec_edgar
    fallback_source_ids: [yfinance, fmp]
    has_primary: true
    has_fallback: true
  - evidence_type: macro_series
    primary_source_id: fred
    fallback_source_ids: [alpha_vantage]
    has_primary: true
    has_fallback: true
unresolved_evidence_types: []   # primary 또는 fallback이 한 개도 없는 evidence_type
```

규칙:

- 위 블록은 evidence-plan.md의 모든 `evidence_type`(role slice의 합집합)에 대해 항목을 가져야 한다.
- 각 항목에 대해 `has_primary=true`이고 `fallback_source_ids`가 ≥ 1이면 통과.
- primary 또는 fallback이 한 개도 없는 evidence_type은 `unresolved_evidence_types`에 모은다. 이 배열이 비어 있어야 본 source-call-plan은 "완전(complete)"으로 간주된다.
- 누락 evidence_type이 있으면 source-router는 그것을 `${ACTIVE_WORKSPACE}/00_evidence/unresolved-data-gaps.md`에도 `data_gap`으로 기록한다.
- 본 self-check는 결정성 백업으로 post-hoc 검증되며, `scripts/test_evidence_layer_structure.py`가 워크스페이스 모드에서 동일 항목을 재검증한다(self-check + post-hoc 양립).
- block의 marker(`# === Source Routing Coverage Self-Check ===`)는 문자 그대로 emit한다.

## Live Probe 결과 병합 (Phase D, Wave 11)

Stage 1 Preflight 단계에서 본 SKILL은 다음 절차로 live probe 결과를 source-call-plan.md에 병합한다.

1. `source-capability-registry.md`에서 `connection_status=connected`로 등록된 모든 source_id를 수집한다.
2. `python scripts/probe/run_live_probe.py`(또는 wrapper `scripts/probe/Run-LiveProbe.{ps1,sh}`)를 실행한다. 인자는 source_id 목록과 `--mock` 옵션(실제 호출 없이 schema-valid 결과만 emit). 표준 probe command 매핑은 `docs/harness/invest/research-layer/source-capability-registry.md`의 "Live Probe Standard Commands" 절을 따른다(예: `sec_edgar` → 기존 helper의 `-DryRun` 호출, `dart_krx_korea_stock` → `get_today_date()`).
3. probe runner의 stdout YAML 블록을 그대로 `${ACTIVE_WORKSPACE}/00_evidence/source-call-plan.md` 본문 끝에 append한다. block marker는 `# === Live Probe Results ===`이며 문자 그대로 유지한다.
4. probe 결과가 `error` 또는 `timeout`인 source는 `runtime_unavailable` 배열에 모은다.

primary route 선택 규칙:

- `runtime_unavailable`에 포함된 source_id는 evidence_type primary 후보에서 제외한다.
- declared fallback이 있으면 fallback으로 라우팅한다.
- fallback이 없으면 해당 evidence_type을 `${ACTIVE_WORKSPACE}/00_evidence/unresolved-data-gaps.md`에 `data_gap`으로 기록한다.

기존 "Connection Status는 repo-evidence 상태이지 live runtime proof가 아니다" 정책은 그대로 유지된다. live_probe 블록은 그 정책을 기계 판독 가능 형태로 보강한다.

## Prohibited

- Do not store API keys.
- Do not implement API clients or databases.
- Do not average conflicting sources without explaining the conflict.
- Do not treat relative search interest as sales or market size.
- Do not treat customs trade as company revenue.
- Do not treat public procurement as total market demand.
