Skip to content

GOOG/GOOGL multi-class shares overcount — opposite direction to PR #257 allowlist (Alphabet aggregate-only filer) #261

@dackclup

Description

@dackclup

Symptom

On the 2026-05-23 production cron (90157482, commit 9015748), both GOOG (Class C) and GOOGL (Class A) tickers store Alphabet's 12.12B total shares (sum across all classes) instead of the per-class breakdown — making each ticker appear to have a $4.6T market cap.

Ticker Stored shares_outstanding Stored market_cap Real (per-class) Overcount
GOOG (Class C) 12,116,000,000 $4,596.6B ~$1,048B (5.9B shares × ~$178) 4.4×
GOOGL (Class A) 12,116,000,000 $4,640.1B ~$1,057B (5.9B shares × ~$179) 4.4×
Combined (storing 2 × 12.12B = 24.24B) $9,236B ~$2,105B (real Alphabet MC) 4.4×

fair_price.median = $85.29 against actual price ~$379 → mos_pct = -344.8% / -349.0%. Value pillar contaminated (15.94 / 11.59 — appears expensive on every ratio because each per-class ticker is reported at ~$4.6T).

Root cause

compute/ingest/fundamentals.py reads shares_outstanding from SEC companyfacts for Alphabet's CIK (0001652044). The companyfacts aggregate API returns the total common-shares outstanding across all classes (~12.12B) — Alphabet files non-dimensionally for the EntityCommonStockSharesOutstanding concept, so both GOOG and GOOGL tickers receive the same aggregate. The same aggregate × the per-class price = a market cap that double-counts the company.

This is the opposite direction of the V/NWS/NWSA/FOX/FOXA/BRK-B/STZ allowlist pattern fixed by PR #257:

Defense gap

NONE of the current defense flags catch it:

Suggested fix path

Three options (deferred to methodology-scientist Mode B verdict):

  1. Reverse-allowlist per-class extraction — for known multi-class non-dimensional filers (GOOG/GOOGL/possibly DISCK-style historic patterns), explicitly extract the per-class share count from per-filing XBRL using a different XBRL fact name or ticker-CIK-class mapping. Adds a second allowlist + extraction path opposite to PR feat(ingest): Issue #248 PR2b — multi-class XBRL dimensional override (V/NWS/NWSA/FOX/FOXA/BRK-B/STZ) #257.
  2. Class-aware downscaling — for the GOOG/GOOGL pair, divide the aggregate by the known voting-equivalent class ratio. Risk: data-driven heuristic; needs methodology Mode B sign-off.
  3. Defense annotate — fire a new multi_class_aggregate_shares_suspected flag when one ticker's CIK matches another ticker's CIK in the universe (Alphabet GOOG/GOOGL share CIK 0001652044). Annotate-only, no scoring veto, surfaces the pattern at cohort-audit time.

Reproduction

python -c "
import json
for t in ('GOOG', 'GOOGL'):
    with open(f'frontend/public/data/stocks/{t}.json') as f:
        d = json.load(f)
        print(f'{t}: shares={d[\"raw_metrics\"][\"shares_outstanding\"]:,} '
              f'mc=\${d[\"raw_metrics\"][\"market_cap\"]/1e9:.1f}B '
              f'mos={d[\"fair_price\"][\"mos_pct\"]:.1f}%')
"

Expected output (current state):

GOOG:  shares=12,116,000,000  mc=$4596.6B  mos=-344.8%
GOOGL: shares=12,116,000,000  mc=$4640.1B  mos=-349.0%

Surfaced by

15-parallel-agent self-audit on claude/eager-bohr-12bQi (2026-05-26). stock-detail-auditor Step 3 LLM verdict: broken_data (not cron_pre_fix_state because GOOG/GOOGL are NOT in PR #257's MULTI_CLASS_SHARE_ALLOWLIST — they're a distinct error class). Filed as a separate issue (rather than expanding PR #257's allowlist) because the underlying mechanism is opposite to PR #257's.

Cross-references

Severity / priority

MEDIUM — visible to users on /stock/GOOG + /stock/GOOGL (both show absurd $4.6T market cap and -345% MoS). Composite rank impact is real but Top-5 rotation Rule 16 invariant is intact (GOOG / GOOGL are not currently in any top-5 contention because the value pillar tanks them to low ranks). No safety violation. Q3 2026-08-19 cohort audit is the natural decision gate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions