feat(ingest): country + exchange listing metadata (PR-A1, schema 0.10.12)#347
Merged
Conversation
….12) First of a 2-PR sequence (grill-me spec) to replace the hero's sector+industry chips next to the #1 rank with a country tag (US) + exchange tag (NYSE/NASDAQ), each with a logo. PR-A1 is the compute + schema half; PR-B does the chips. compute/ingest/cross_source.py: - exchange_name(code): maps yfinance fast_info.exchange codes to display names (NMS/NGM/NCM->NASDAQ, NYQ->NYSE, ASE->NYSE American, PCX/NyseArca->NYSE Arca, BATS->Cboe BZX); unknown codes pass through verbatim. - country_for_exchange(code): "US" for all known US venues, else None. - fetch_yfinance_exchange(ticker): cache-first via the SAME yfinance_info cache as market-cap (exchange merged in, market_cap preserved); tenacity-retried _yf_fast_exchange; QR_SKIP_CROSS_SOURCE honored; graceful-degradation -> None. Schema triple (MINOR bump 0.10.11 -> 0.10.12-phase4.6): StockDetail.exchange: str|None + StockDetail.country: str|None + Metadata.exchange_coverage_pct: float|None (Rule-18 observability), added in lockstep across schemas.py + types.ts + schema-snapshot.json. config SCHEMA_VERSION + test_config pin + SKILL.md schema-table row updated. schema-sentinel verified the hand-regenerated snapshot byte-matches the generator contract (value-key order, alphabetical position, type strings, +15/-0 diff) -> CI schema guard will pass. tests/test_ingest/test_cross_source_exchange.py (test-engineer): 39 offline (pure helpers + cache merge/backward-compat + QR_SKIP path) + 1 @network drift. DISPLAY-ONLY: no ranking/scoring/valuation/defense change. Observability-before- wiring: schema fields ship first; main.py field-population is PR-A2; the hero chips (PR-B) wait for >=1 cron confirming coverage. Until PR-A2 the fields are None-default (valid, they are |None). https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Pre-merge production simulation
Diff vs main
Main baseline: Top-10 movers (sorted by |Δcomposite_score|)
|
This was referenced Jun 1, 2026
dackclup
added a commit
that referenced
this pull request
Jun 1, 2026
…(PR-A2) (#349) Populate the StockDetail.exchange / .country fields PR-A1 (#347) declared, plus the Rule-18 Metadata.exchange_coverage_pct diagnostic, from the Step-8 per-ticker cross_source loop. Display-only -- no ranking / scoring / valuation / defense-layer change; NO schema change (stays 0.10.12-phase4.6, the fields already exist from PR-A1). - Import country_for_exchange / exchange_name / fetch_yfinance_exchange. - Two {exchange,country}_by_ticker accumulators before the Step-8 loop. - Per-ticker fetch_yfinance_exchange piggybacks the cross_source market-cap block; skip-safe via QR_SKIP_CROSS_SOURCE inside the helper (no main.py branch -- confirmed no QR_SKIP_CROSS_SOURCE ref in main.py). - exchange= / country= kwargs on StockDetail (siblings of industry=). - exchange_coverage_pct via a pure _exchange_coverage_pct helper, imported by the tests (NOT copied) per the CLAUDE.md PR #310 no-verbatim-copy lesson; + "Exchange coverage" log + the Metadata kwarg. PR-B (hero country/exchange chips) waits for >= 1 cron confirming coverage (observability-before-wiring). Tests +19 (test_main.py orchestrator wiring + test_output/test_exchange_schema.py schema round-trip); full offline suite 1460 passed, 0 failures. Pre-push gate: quantrank-reviewer READY-TO-PUSH, phase-coordinator LOCKSTEP-SATISFIED, docs-reviewer DOCS-CLEAN. https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq Co-authored-by: Claude <noreply@anthropic.com>
dackclup
added a commit
that referenced
this pull request
Jun 1, 2026
Replace the stock-detail hero #rank-row sector + industry chips with a country chip (country-flag-icons flag + ISO tag) + an exchange chip (lucide Landmark generic icon + display name), reading detail.country / detail.exchange (populated by PR-A2, #347 -> #349). Display-only; no compute / schema / scoring / valuation change. - New frontend/components/ListingChips.tsx -- LedgerCraft neutral-steel chips (mirrors SectorChip), null-safe (renders nothing until a cron populates the fields), FLAG_BY_COUNTRY static per-country lookup (US today). - New dep country-flag-icons ^1.6.17 (MIT, 0 transitive, 0 install-script -- dependency-auditor + security-reviewer both SAFE). Per-country STATIC subpath import only; barrel/dynamic = 330KB footgun (new CLAUDE.md Gotcha, mirrors lucide). - frontend/app/stock/[ticker]/page.tsx -- swap SectorChip + industry span for ListingChips; drop the now-unused SectorChip import. Sector still shows in the HeroAttributeTiles Sector tile. Held Draft -- merge after the next weekly cron populates exchange/country + confirms exchange_coverage_pct (observability-before-wiring); current data has the fields null so the chips render nothing on live until then. frontend-design-reviewer 0 FAIL (D1 font-medium + D2 flag/icon height parity + F1 title a11y all fixed). tsc --noEmit clean; next build 506/506 static pages; flag tree-shaken (~2KB, no barrel bloat). https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
First of a 2-PR sequence (locked via a
/grill-mesession) to replace the hero's sector+industry chips (next to the #1 rank) with a country tag (🇺🇸 US) + exchange tag (NYSE/NASDAQ), each with a logo. PR-A1 is the compute + schema half; PR-B does the chips.The 5 grill-locked decisions
PR-A1 — compute + schema
compute/ingest/cross_source.py:exchange_name(code)— maps yfinancefast_info.exchangecodes → display names (NMS/NGM/NCM→NASDAQ, NYQ→NYSE, ASE→NYSE American, PCX/NyseArca→NYSE Arca, BATS→Cboe BZX); unknown → passthroughcountry_for_exchange(code)— "US" for known US venues, else Nonefetch_yfinance_exchange(ticker)— cache-first via the sameyfinance_info/<ticker>.jsoncache as market-cap (exchange merged in, market_cap preserved); tenacity-retried;QR_SKIP_CROSS_SOURCEhonored; graceful-degradation → NoneSchema triple (MINOR bump
0.10.11 → 0.10.12-phase4.6):StockDetail.exchange: str | None+StockDetail.country: str | None+Metadata.exchange_coverage_pct: float | None(Rule-18) — lockstep acrossschemas.py+types.ts+schema-snapshot.json+config+test_configpin +SKILL.mdtable.schema-sentinelverified the hand-regenerated snapshot byte-matches the generator contract (value-key ordertype/required/default, alphabetical position, type strings, +15/−0 diff) → the CI schema guard will PASS.Tests (
test-engineer):tests/test_ingest/test_cross_source_exchange.py— 39 offline (pure helpers + cache merge/backward-compat +QR_SKIPpath) + 1@networkAAPL drift.Observability-before-wiring
The schema fields ship first. main.py field-population is PR-A2 (deferred — the orchestrator is 2000+ lines and the session was long; fresh focus avoids a careless miss). Until PR-A2 the fields are None-default (valid —
| None). The hero chips (PR-B) wait for ≥ 1 cron confirmingexchange_coverage_pct.Scope
Compute + schema. DISPLAY-ONLY — no ranking / scoring / valuation / defense-layer change. CLAUDE.md §Phase status + AGENTS.md + SKILL.md schema row + PHASE_STATUS_INFLIGHT.md.
https://claude.ai/code/session_0148EoMmL6zakDWqHXjqQ9yq
Generated by Claude Code