Module: intel-financial-public
SPOKE MODULE. Runs only for public companies. If the company has no ticker
(is_private=True or ticker=None), skipped=True is returned immediately with
zero API calls. Surfacing executive quotes from earnings calls is the highest-value
output — gold for sales personalization.
Identity
| Field |
Value |
| Name |
intel-financial-public |
| Version |
0.1.0 |
| Layer |
Intelligence (Wave 1) |
| Wave |
1 (runs in parallel with other spoke modules after intel-company) |
| Description |
Financial intelligence for publicly traded companies via Yahoo Finance (market data + analyst consensus), SEC EDGAR (10-K/10-Q filing metadata and excerpts), and Perplexity-powered investor presentation analysis with executive quote extraction. |
| LLM Tier |
Claude via Instructor (structuring SEC insights, investor presentations, comparative summary) + Perplexity sonar (investor presentation research) |
| Timeout |
300 seconds (5 minutes) |
| Max Retries |
2 (module level) |
| Gate Module |
NO. Failure degrades financial context but does not abort the audit. |
Dependencies
| Module |
Field Read |
Why |
| intel-company |
ticker (via ExecutionContext) |
Required to pull Yahoo Finance and SEC EDGAR data — no ticker = skip |
| intel-company |
company_name |
Used in SEC EDGAR full-text search and Perplexity investor presentation queries |
| intel-company |
is_private |
Skip gate: if True, module returns skipped=True immediately |
| intel-company |
competitors (via ExecutionContext) |
Competitor tickers extracted for comparative financial data (TODO: implemented once DB read is wired) |
Hub-and-Spoke Position
intel-financial-public is a spoke module. It reads from intel-company and writes
its output to module_executions. Downstream synthesis modules (intel-competitors,
audit-report) consume its output when building the ROI business case and financial narrative.
| Field |
Type |
Required |
Description |
| domain |
str |
yes |
Website domain to analyze, e.g. "dell.com" |
| ticker |
str |
yes |
Stock ticker symbol, e.g. "DELL" |
Additionally reads from ExecutionContext at runtime:
| Context Field |
Type |
Used For |
| is_private |
bool |
Skip gate — returns skipped=True if True |
| ticker |
str or None |
Drives all Yahoo Finance and SEC EDGAR calls |
| company_name |
str |
SEC EDGAR search + Perplexity investor presentation queries |
| audit_id |
str |
Structured logging |
Output Schema: FinancialPublicOutput
Top-Level Fields
| Field |
Type |
Required |
Description |
| domain |
str |
yes |
Primary website domain, e.g. "dell.com" |
| ticker |
str |
yes |
Stock ticker symbol, e.g. "DELL" |
| skipped |
bool |
yes |
True if module was skipped (private company or no ticker) |
| skip_reason |
str or None |
no |
Reason the module was skipped, if applicable |
| annual_financials |
list[AnnualFinancials] |
no |
Up to 3 years of annual financial data from Yahoo Finance |
| market_data |
MarketData or None |
no |
Current market snapshot (price, market cap, P/E) |
| analyst_data |
AnalystData or None |
no |
Analyst consensus (recommendation, target price, analyst count) |
| sec_insights |
list[SECInsight] |
no |
Enriched insights from recent 10-K and 10-Q filings |
| investor_presentations |
list[InvestorPresentation] |
no |
Executive quotes and priorities from investor presentations |
| competitor_financials |
list[CompetitorFinancials] |
no |
Basic Yahoo Finance data for competitor tickers |
| comparative_summary |
str |
no |
Narrative comparing company financial position to competitors |
Sub-Schema: AnnualFinancials
| Field |
Type |
Required |
Description |
| fiscal_year |
str |
yes |
Fiscal year label, e.g. "FY2025" |
| revenue |
float or None |
no |
Annual revenue in USD as float, e.g. 88400000000.0 |
| net_income |
float or None |
no |
Annual net income in USD as float |
| gross_margin_pct |
float or None |
no |
Gross margin as a percentage, e.g. 23.5 for 23.5% |
| operating_margin_pct |
float or None |
no |
Operating margin as a percentage, e.g. 6.2 for 6.2% |
| revenue_growth_pct |
float or None |
no |
Year-over-year revenue growth as a percentage |
Sub-Schema: MarketData
| Field |
Type |
Required |
Description |
| market_cap |
float or None |
no |
Market capitalization in USD |
| stock_price |
float or None |
no |
Current stock price in USD |
| fifty_two_week_high |
float or None |
no |
52-week high stock price in USD |
| fifty_two_week_low |
float or None |
no |
52-week low stock price in USD |
| pe_ratio |
float or None |
no |
Trailing price-to-earnings ratio |
| forward_pe |
float or None |
no |
Forward price-to-earnings ratio |
Sub-Schema: AnalystData
| Field |
Type |
Required |
Description |
| recommendation |
str or None |
no |
Analyst consensus, e.g. "Buy", "Hold", "Sell" |
| target_price |
float or None |
no |
Mean analyst target price in USD |
| number_of_analysts |
int or None |
no |
Number of analysts covering the stock |
Sub-Schema: SECInsight
| Field |
Type |
Required |
Description |
| filing_type |
Literal["10-K", "10-Q"] |
yes |
Annual (10-K) or quarterly (10-Q) filing |
| filing_date |
str |
yes |
Filing date in YYYY-MM-DD format |
| filing_url |
str or None |
no |
URL to the filing on SEC EDGAR |
| digital_revenue_pct |
float or None |
no |
Digital revenue as % of total, if disclosed |
| technology_mentions |
list[str] |
no |
Technology keywords mentioned: "search", "AI", "personalization", etc. |
| key_excerpts |
list[str] |
no |
Notable excerpts relevant to digital/tech strategy |
| management_discussion_summary |
str |
no |
Summary of Management Discussion & Analysis section |
Sub-Schema: InvestorPresentation
| Field |
Type |
Required |
Description |
| title |
str |
yes |
Presentation title |
| date |
str |
yes |
Presentation date in YYYY-MM-DD or approximate format |
| url |
str or None |
no |
URL to the presentation or IR page |
| strategic_priorities |
list[str] |
no |
Strategic priorities mentioned |
| digital_commitments |
list[str] |
no |
Commitments to digital transformation or e-commerce |
| technology_roadmap |
list[str] |
no |
Technology roadmap items mentioned |
| search_mentions |
list[str] |
no |
Any mentions of search, discovery, or recommendation technology |
| key_quotes |
list[str] |
no |
Verbatim executive quotes about strategy or technology |
Sub-Schema: CompetitorFinancials
| Field |
Type |
Required |
Description |
| company_name |
str |
yes |
Competitor company name |
| ticker |
str |
yes |
Competitor stock ticker symbol |
| revenue |
float or None |
no |
Most recent annual revenue in USD |
| revenue_growth_pct |
float or None |
no |
Year-over-year revenue growth as a percentage |
| market_cap |
float or None |
no |
Market capitalization in USD |
| gross_margin_pct |
float or None |
no |
Gross margin as a percentage |
Collection Strategy
Source 1: Yahoo Finance (yfinance library)
| Aspect |
Detail |
| Adapter |
yfinance Python library (direct, no adapter abstraction yet) |
| Data |
3-year revenue trend, net income, margin percentages, market cap, stock price, 52-week high/low, P/E ratio (trailing + forward), analyst recommendation and target price |
| Input |
Ticker symbol |
| Evidence Tier |
VERIFIED |
| Method |
direct_api |
| Retry |
Module-level max_retries=2 |
| Cost |
Free (no API key required) |
Source 2: SEC EDGAR (EFTS API)
| Aspect |
Detail |
| Adapter |
Direct httpx calls to EFTS full-text search API |
| Endpoint |
https://efts.sec.gov/LATEST/search-index?q={company_name}&dateRange=custom&startdt={one_year_ago}&forms=10-K,10-Q |
| Data |
Recent 10-K and 10-Q filing metadata: dates, URLs, accession numbers |
| Evidence Tier |
VERIFIED |
| Method |
direct_api |
| Cost |
Free (no API key required) |
Source 3: Perplexity API (investor presentations)
| Aspect |
Detail |
| Adapter |
Perplexity sonar model (same adapter as intel-company) |
| Model |
sonar ($0.25/M input tokens) |
| Input |
Query: "{company_name} investor presentation annual report earnings call transcript 2024 2025 site:ir.{domain} OR site:sec.gov" |
| Output |
Raw text with citations, passed to Claude (Instructor) for structuring |
| Evidence Tier |
WEBSEARCH |
| Method |
llm_extraction |
| Retry |
3 attempts with exponential backoff |
Source 4: Claude via Instructor (structuring)
| Aspect |
Detail |
| Usage |
Structures raw Perplexity text into InvestorPresentation Pydantic models; enriches SEC filing metadata with technology analysis; generates comparative_summary |
| Models |
Configured via settings.get_enricher_provider() (typically claude-3-5-haiku) |
| Evidence Tier |
ESTIMATE (for comparative_summary) / WEBSEARCH (for investor presentations) |
| Method |
llm_extraction |
| Max Retries (Instructor) |
3 per completion call |
Enrichment Strategy
The module uses a two-phase approach:
Phase 1 — Deterministic collection (Yahoo Finance + SEC EDGAR)
Raw structured data is pulled via API with no LLM involvement. Yahoo Finance returns typed numerical data. SEC EDGAR returns filing metadata (accession numbers, dates, form types).
Phase 2 — LLM enrichment (Perplexity + Claude/Instructor)
- Perplexity searches for investor presentations and earnings call transcripts by IR page domain
- Claude/Instructor structures the raw search results into InvestorPresentation objects
- Claude/Instructor enriches SEC filing metadata with technology keyword extraction and MDA summaries
- Claude generates a comparative_summary narrative from the competitor financial data
Why This Matters for Sales
The InvestorPresentation.key_quotes field captures verbatim CEO/CFO statements about digital strategy from earnings calls. These are the highest-value output of this module — enabling AEs to open discovery calls by reflecting the prospect's own language back at them.
Validation Rules (9 Checks)
| # |
Rule |
Severity |
Threshold |
| 1 |
If skipped=True, skip_reason must be set |
required |
Early return pass if both true |
| 2 |
annual_financials has at least 2 years |
required |
>= 2 AnnualFinancials entries |
| 3 |
market_data is not None |
required |
market_data != None |
| 4 |
market_data.market_cap > 0 |
required |
market_cap > 0 |
| 5 |
At least 1 SEC insight present |
warning |
len(sec_insights) >= 1 |
| 6 |
domain matches expected input |
required |
Case-insensitive match |
| 7 |
ticker matches expected input |
required |
Case-insensitive match |
| 8 |
At least 1 source provenance record |
warning |
len(sources) >= 1 |
| 9 |
comparative_summary not empty when competitors present |
warning |
Not empty string when competitor_financials populated |
Required failures -> status "partial". Warning failures -> logged but passed.
Evidence Requirements
| Field |
Minimum Tier |
Rationale |
| annual_financials |
VERIFIED |
Yahoo Finance direct API — not modeled or estimated |
| market_data |
VERIFIED |
Yahoo Finance direct API — real-time data |
| analyst_data |
VERIFIED |
Yahoo Finance direct API — institutional analyst consensus |
| sec_insights |
VERIFIED |
SEC EDGAR direct API — regulatory filings |
| investor_presentations |
WEBSEARCH |
Perplexity + LLM extraction — acceptable for narrative quotes |
| comparative_summary |
ESTIMATE |
LLM synthesis — clearly labeled as narrative, not raw data |
| competitor_financials |
VERIFIED |
Yahoo Finance direct API |
Persistence
intel-financial-public writes only to module_executions (not the accounts table directly). Synthesis modules read from module_executions.output JSONB.
Columns Written to module_executions
module_name="intel-financial-public"
module_version="0.1.0"
status # "success" | "partial" | "failed"
output # FinancialPublicOutput.model_dump() -> JSONB
sources # list[Source] -> JSONB array
duration_ms # int
llm_calls # int (Perplexity + Claude calls combined)
llm_cost_usd # float
Cost Profile
| Metric |
Expected Value |
| LLM Calls |
3-6 (1-2 Perplexity + 2-4 Claude/Instructor for structuring) |
| Yahoo Finance Calls |
1 (ticker lookup, all data in one call) |
| SEC EDGAR Calls |
1-2 (EFTS search + optional filing fetch) |
| Estimated Cost |
~$0.05-0.15 per audit (Perplexity + Claude enrichment) |
| Expected Duration |
30-90 seconds |
| External API Calls |
3-5 total |
Retry Architecture (Two Layers)
Layer 1: Collector Retries (network errors)
| Trigger |
Retry |
Backoff |
| Timeout |
3 attempts |
Exponential (2^attempt seconds) |
| Rate limit (429) |
3 attempts |
Exponential |
| Connection error |
3 attempts |
Exponential |
| Other HTTP error |
No retry |
Fail immediately |
Layer 2: Module Retries (data quality)
| Trigger |
Retry |
Backoff |
| Instructor validation failure |
3 attempts per completion |
Instructor native retry |
| Module-level failure |
max_retries=2 |
Module level |
If all retries exhausted: return ModuleExecutorResult with status="failed". Module failure is non-fatal to the audit — other modules continue.
Skip Logic
The skip check runs before any API calls:
if context.is_private or context.ticker is None:
return ModuleExecutorResult(status="success", output=FinancialPublicOutput(skipped=True, ...))
Skip costs: 0 LLM calls, 0 API calls, ~1ms duration. The skip result is recorded in module_executions so downstream modules know this module ran but found no applicable data.
Runtime Notes
SaaS Runtime (Temporal/Python)
- Module:
prism_platform/v2/modules/intel_financial_public/module.py
- Collector:
prism_platform/v2/modules/intel_financial_public/collector.py
- Enricher:
prism_platform/v2/modules/intel_financial_public/enricher.py
- Validator:
prism_platform/v2/modules/intel_financial_public/validator.py
- Schemas:
prism_platform/v2/modules/intel_financial_public/schemas.py
Skill Runtime (Claude Code)
- Skill file:
~/.claude/skills/algolia-intel-financial-public/SKILL.md (or algolia-audit-financials)
- Reads from:
01-company-context.json (for ticker)
- Writes to:
08-financial-profile.md, 08-financial-profile.json
- MCP tools used: WebFetch (IR pages, SEC EDGAR direct), WebSearch (Perplexity-equivalent for earnings calls)
What Makes This Production-Grade (vs a Simple Prompt)
| Aspect |
Simple Prompt |
PRISM Module |
| Skip logic |
Runs always, wastes money on private companies |
Hard gate: skip if is_private or no ticker, zero API calls |
| Financial data |
"Research their revenue" |
Yahoo Finance direct API — 3 years, typed numeric fields |
| Market data |
LLM estimates stock price |
Real-time yfinance: price, market cap, P/E, 52-week range |
| Analyst consensus |
Not captured |
yfinance analyst recommendation + target price + analyst count |
| SEC filings |
LLM doesn't know about EDGAR |
EFTS API search: actual 10-K/10-Q metadata with URLs |
| Executive quotes |
Fabricated or generic |
Perplexity searches IR pages for actual earnings call transcripts |
| Structuring |
Hope for good JSON |
Instructor + Claude with Pydantic retry on each structured extraction |
| Source provenance |
None |
Every field has EvidenceTier (VERIFIED/WEBSEARCH/ESTIMATE) |
| Validation |
Trust the LLM |
9-point checklist: market cap > 0, 2+ years of data, domain/ticker match |
Evolution: v1 → v2
v1 (Current — Implemented)
- Yahoo Finance via yfinance library (direct Python import)
- SEC EDGAR via EFTS full-text search API (httpx)
- Perplexity sonar for investor presentation discovery
- Claude/Instructor for structuring all LLM-returned data
- Competitor financials read: TODO (DB integration incomplete)
- Module pattern: v2 agentic (config.py + playbook.md + schemas.py + ModuleExecutor harness)
v2 (Planned — Agentic Module Pattern)
- Becomes a playbook-based agent following the unified module architecture
- Config:
intel_financial_public/config.yaml (API endpoints, timeouts, thresholds)
- Playbook:
intel_financial_public/playbook.md (step-by-step agent instructions)
- Schema:
intel_financial_public/schema.py (unchanged Pydantic models)
- Executor:
intel_financial_public/executor.py (runs Claude agent against playbook)
- Sources split across 3 structured APIs:
- SEC EDGAR API (structured endpoint, not just EFTS full-text search)
- Yahoo Finance (unchanged)
- Perplexity for earnings call research (unchanged)
- Executive quotes from earnings calls become a first-class output with their own sub-schema
- Competitor ticker lookup wired to accounts table (removes the TODO)
- No code changes to skip logic or validation contract
Changelog
| Date |
Change |
Reason |
| 2026-04-14 |
Module spec written to vault |
Knowledge extraction for v2 planning |
| 2026-03-30 |
Initial implementation |
Backend phase 1 |
- Module-Catalog -- all 20 modules overview
- Intel-Company -- foundation hub this module depends on
- Intel-Financial-Private -- the private company counterpart
- Module-Spec-Template -- the template this spec follows
- Evidence-Tier-Spec -- evidence tier system
- Adapter-Interfaces -- PerplexityAdapter and WebFetchAdapter