finance-skills-hermes
A provenance-enforced equity-analysis pipeline over SEC EDGAR/XBRL filings, with typed review gates and deterministic reporting.
Problem
LLMs are good at reasoning about companies and bad at not making up the numbers they reason with. Ask a model to analyze a 10-K and you can get a fluent answer built on figures that are real, stale, mixed across fiscal years, or invented. In investment analysis, one wrong input can poison everything downstream.
The project asks whether an LLM-based fundamental-analysis pipeline can make every number in its final report mechanically traceable to a regulatory filing, and refuse to produce output rather than guess.
Constraints
This is a portfolio piece, not a commercial product or investment service. It makes no claim about investment returns, predictive performance, or accuracy.
- System of record: SEC EDGAR XBRL company facts are the source of truth for fundamentals. External data is limited to cost-of-capital inputs and an injected market-price feed.
- Coverage: The extraction path uses annual 10-K filings and requires at least five fiscal years. A shorter history stops with the typed insufficient_history error. Non-US and non-XBRL names are outside the current scope.
- Freshness: Each typed number carries retrieved_at provenance. Market prices are stored as external values with their own source, period, and retrieval timestamp.
- Operating context: This was a solo project with no external users or uptime obligations, so correctness could take priority over throughput.
Architecture
The pipeline separates deterministic computation, evidence-backed judgment, and final ratification into three roles with different permissions.
- Accountant: Deterministic Python modules extract XBRL and build typed Pydantic artifacts. Every Number carries a tag, filing form, fiscal period, accession, source_name, and retrieved_at timestamp. Ordered fallback tag chains handle taxonomy variation. Missing required concepts stop with unresolved_concept; optional absent concepts are explicitly flagged instead of being silently inferred.
- Analyst: Analyst stages draft, flag, and attach resolvable evidence to research judgments. Deterministic Accountant stages compute the financial spine, routing, and DCF inputs; the Analyst cannot ratify its own work or introduce an untraced value across a typed boundary.
- Senior: The Senior is the sole ratification signer. Live validation used a DeepSeek Senior through Azure AI Foundry over GPT-family Analysts, and runtime checks compare the actual adapter identities before ratification.
Audit-enforced, not prompt-enforced
Schemas and provenance checks reject missing evidence, unresolved trace targets, and invalid artifacts. A failed gate stops the path instead of allowing a partial handoff.
Incomplete ratification is unrepresentable
A final handoff rejects any unresolved Ratifiable value, including nested values, and a final Analyst value requires Senior decision metadata.
The M6 report renderer reads completed typed artifacts and produces Markdown deterministically, with no LLM, Senior, Analyst, network, or live-data call.
DCF defaults can be sector-aware. A deterministic provisioning module combines a committed Damodaran snapshot with a separate house-judgment layer; economic guardrails remain Python module constants rather than tunable per-sector config.
Key decisions
- Fail-closed over best-effort: A partial report with confidence flags was rejected because it still normalizes output that cannot be traced. Missing required inputs stop the run.
- Structural enforcement over prompt engineering: Prompts express intent; typed validation enforces the contract even when a model is changed or returns malformed output.
- Cross-family Senior over same-family review: The reviewer runs on a different model family, and the independence check uses adapter identity at runtime rather than trusting a configuration label.
- Deterministic rendering over LLM-generated reports: The final document is generated from ratified artifacts so the publishing step cannot add a new model-generated number or claim.
Stack
Python · Pydantic · SEC EDGAR/XBRL · SQLite and JSON artifacts · Azure AI Foundry · GPT-family Analysts · DeepSeek Senior · deterministic Markdown renderer
Result
I ran live end-to-end validation on AAPL, MRNA, and UBER with real market prices and a live Senior model. The validation exercised the source trail, typed gates, ratification path, and deterministic report output; it did not measure investment performance.
A licensed finance professional used the system on tickers of his choosing and validated several methodology decisions, including how to treat asset-light companies that don't report inventory.
What failed
Industry medians are not one company’s economics
The first UBER calibration plan paired Damodaran Software (Internet) industry medians for growth, margin, and reinvestment. Those independent cross-sectional medians produced negative, non-monotonic DCF scenarios, so the ordering audit halted the run. The plan was abandoned and replaced with an anchor based on UBER's own realized EDGAR financials, with explicit house judgments layered separately and a provisioning-time coherence guardrail.
The business, not the system
The project began as an exploration with a finance advisor who was opening his own practice. He later disengaged because prediction was not what the practice needed. I wound the work down as a business pursuit in 2026 and retained it as a portfolio piece rather than imply that it became a commercial product or investment service.