Inspiration
A covenant breach is usually the first domino of a default. Before a company misses a payment, it typically trips a leverage or coverage test in its credit agreement.
The terms are public. Credit agreements are filed on SEC EDGAR as EX-10 exhibits, along with every amendment. In practice they are unusable: 150 to 300 pages each, with bespoke definitions like "Consolidated EBITDA" stacked with capped addbacks. Companies rarely report the covenant ratio, and they never show the working. Analysts read them by hand, pay for limited coverage, or find out from the waiver announcement.
We asked: can you compute covenant headroom from public filings alone, prove every number, and put AI agents on top that an analyst can actually trust?
What it does
Covenant Watch turns a company's credit agreement into a live covenant monitor. It reads the contract, compiles the covenant definitions into executable logic, runs them against the company's own XBRL financials every quarter, and shows how much room is left before a breach, with an audit trail behind every number. Three Claude agents then investigate, explain and stress-test the results.
The core insight came from real data: the definition is the number. For companies that report their own covenant ratio, we recomputed it from plain GAAP numbers. GAAP came out higher every single time:
- Dine Brands: 4.58x reported vs 7.25x plain GAAP
- OUTFRONT Media: 4.80x vs 5.99x
- Vishay: 3.14x vs 4.18x
- Concentra: 3.60x vs 4.15x
- MSCI: 2.70x vs 3.28x
A naive tool overstates leverage for all five, by as much as 2.67 turns. Any serious answer has to come from the contract itself.
How one covenant becomes one number. Take a typical maximum leverage covenant: Consolidated Total Debt divided by Consolidated EBITDA may not exceed 4.50 to 1.00, stepping up to 5.25 after an amendment and back down a year later. Covenant Watch extracts that limit schedule with its effective dates, then the definition of Consolidated EBITDA: net income, plus interest, taxes, depreciation and amortization, plus non-cash charges, plus restructuring charges capped at 15% of EBITDA. Each of those terms is matched to a line in the company's filings, the formula is evaluated on trailing twelve months, and the result is compared to the limit in force that quarter.
Honest answers, not false precision. When a contract addback has no public figure, the engine do not guess. It carries a range from zero to the contractual cap all the way through to the ratio. A covenant reads breach only if even the best case is past the limit, indeterminate if the range straddles it, warning within 10% of it, and refused, with a stated reason, when something cannot be verified, such as a redacted threshold or a missing filing.
What you see in the app
- Portfolio dashboard: every covenant every quarter stacked by status, so you can watch a portfolio deteriorate; a live status gauge; accuracy and early-warning tiles; the covenants closest to breach, each with a headroom trend line; the waivers and defaults companies actually disclosed; and every refusal grouped by reason.
- Company pages: the tightest covenant's worst-case headroom up front, then one card per covenant with the computed ratio range against its limit, headroom over the last twelve quarters, and an exact cushion from the engine, such as "EBITDA can fall 42.1% before the worst case breaches" or "already past the limit; EBITDA must rise 22.3%".
- Headroom timeline: the limit drawn as a step line that moves when amendments land, the computed ratio as a band where inputs are uncertain, real waiver and default dates overlaid, and the company's own reported ratios plotted against ours, so the story of a breach reads in one picture.
- Provenance drawer: click any quarter to see the ratio and headroom, why it is a range, the exact covenant clause and the amendment sentence that set that quarter's limit, the contract's definition compiled into a formula, and every input with its XBRL concept, value, period, mapping confidence and a link to the filing it came from.
- Evaluation page: a scatter of reported against computed ratios, a lead-time chart showing how many quarters ahead real waivers and defaults were flagged (misses included), a matched-peer control group for false alarms, refusals by reason and a per-company breakdown.
Three Claude agents, all read-only and fully auditable
Each agent works through tools over the same API the app uses, and every tool call appears beside its answer.
- Analyst: a chat panel on every page. Ask "which companies had a waiver?" or "why is this quarter a range?" and it searches companies, reads timelines, opens quarter provenance and checks refusals, then answers with the exact quarters, ratios and clauses it found.
- Risk briefing: autonomous. With no question asked, it scans the portfolio for the most at-risk covenants, reads each one's history, opens the filings behind the latest quarter, and writes a ranked memo: where each stands, the trend, the drivers, the warning signs and what to watch next.
- Company agent with stress testing: on every company page. In Ask mode it answers questions about that company. In Stress test mode it runs scenarios such as EBITDA down 25%, rates up, or a recession through the engine, which computes exact breakevens and reruns each scenario through the contract's own definition tree, caps included. Claude chooses the scenarios and explains which covenant trips first and why; the engine does all of the math.
How we built it
Covenant Watch is a five-stage pipeline behind a read-only API, with a Next.js front end and three Claude agents on top. Python (FastAPI, Pydantic) on the back end, TypeScript and Next.js on the front, Claude Opus 5.5 and Sonnet 5.5 for language, and SEC EDGAR plus XBRL as the only data source. Every stage reads and writes one frozen, typed schema, so each piece can be tested and trusted on its own.
1. Contract understanding. EDGAR full-text search over EX-10 exhibits finds a company's credit agreement and every amendment, ordered by date, with redaction markers detected up front. Each document is segmented into articles and sections with exact character offsets back to the original filing. Claude Sonnet 5.5 then extracts, against a strict schema, every financial covenant (kind, direction, test period), its threshold schedule with effective dates and step-downs, and the full recursive definition tree behind each term: sums, subtractions, ratios, caps and floors, down to atomic line items. Extraction runs twice over two different document layouts. Where the two disagree, a verifier pass decides, hard definitions escalate to Claude Opus 5.5, and anything still unresolved becomes a refusal coded by reason (redacted, ambiguous definition, missing filing, unmapped term, pro forma adjustment). Every field must be an exact substring of the filing at its recorded offsets. Amendments are applied in order: replaced definitions, changed thresholds with their effective windows, and temporary relief that reverts on schedule. Every model call is reserved against a hard budget before it is sent, and every response is checkpointed with a checksum, so an interrupted run resumes without paying twice.
2. Financial data layer. The SEC companyfacts API is turned into clean quarterly and trailing-twelve-month series. Restated periods take the latest filing. Missing quarters are derived from year-to-date facts (Q2 = 6M minus Q1, Q4 = full year minus 9M), items reported only year to date are rolled into TTM as YTD plus prior year minus prior YTD, four quarters must be contiguous to form a TTM, and balances such as debt are read as point-in-time values. The layer survives filers that switch tags between years, lines split across two tags (summed only where both are reported), and net interest that flips to income. Each contract term is then mapped to a financial concept. Claude proposes a match from the concepts this company actually reports; a rule table proposes independently; and a deterministic validator checks units, duration versus instant, sign and availability before anything is used. Broader contract terms such as "non-cash charges" map only as partial proxies that count toward the low case, and every mapping carries a confidence score.
3. Covenant compiler and interval engine. Each definition tree compiles into an executable graph, ordered so every cap is evaluated after the term it references, with cycle detection. The base items a definition is built on, like net income under EBITDA or debt in a leverage ratio, are required; a quarter missing one is refused. Every other addback is bounded: if it has no source, it becomes the interval from zero to its cap. The engine runs interval arithmetic end to end, including division, so uncertainty flows honestly from a single unsourced line to the ratio, the headroom and the status. The same algebra gives closed-form breakevens (how far earnings can fall, or debt and interest can rise, before the worst case hits the limit) and scenario reruns, so every number the agents cite matches what the app shows. Every result carries provenance per input: the concept, the filing accession, the period and the mapping confidence.
4. Evaluation harness. Ground truth comes straight from SEC filings. Sentences in 10-Ks and 10-Qs where companies state their own covenant ratio ("our Consolidated Leverage Ratio was 3.2 to 1.00") yield 387 reported ratios across 156 companies, and 8-K disclosures yield 157 waivers, defaults, loosening amendments and accelerations across 119 companies, classified and de-duplicated. Every number must appear verbatim in its quoted span, and all 544 quotes are re-verified against their source documents. Each event company gets matched peers with the same industry code and similar total assets and no covenant event, forming a 250-company universe. The scorer aligns fiscal quarters, allows for two-decimal rounding in reported ratios, and measures ratio accuracy, threshold agreement, early-warning hit rate and lead time against the peer false-alarm rate. Extraction precision and recall are scored against gold labels: 20 agreements are drafted, each field backed by an exact quote, and await sign-off.
5. Agent layer. The three agents are Claude Opus 5.5 tool loops over seven read-only tools: search_companies, portfolio_overview, covenant_timeline, quarter_provenance, company_refusals, and two engine tools, covenant_breakeven and stress_test. Their instructions forbid estimating or recalling numbers: every figure must come from a tool result and be quoted as given. The arithmetic stays in the engine, every tool call is returned to the interface beside the answer, and server-side refusal fallback keeps an answer coming if a request is declined. Every successful answer is stored, so a failed live call falls back to the last real answer instead of an error.
The product. A Next.js App Router front end with server-rendered pages, hand-built SVG charts, a canvas-rendered landing scene and a single dark design system, served by a FastAPI API with endpoints for the portfolio, each company, covenant timelines, quarter provenance, breakevens, evaluation and the three agents. The provenance view locates each clause in the original filing and highlights it in context. 127 automated tests cover the stack, including a golden test that reproduces every expected ratio, headroom and status from a reference contract, and tests for each agent's tool loop.
Challenges we ran into
- Definitions differ per contract and are recursive. One defined term references others, so we compile trees instead of matching keywords.
- Addbacks with no public data. Rather than invent a number, we carry a range from zero to the cap, all the way through to the ratio, the headroom and the stress tests.
- XBRL quirks: companies switching tags, items reported only year to date, split tags, and net interest flipping to income.
- Redline amendments where deleted and inserted text run together in the filed exhibit.
- Cost control. An early unbudgeted extraction run taught us to enforce strict budgets and checkpoints.
- Rounded ground truth. Companies report ratios to two decimals, so the scorer needed an explicit tolerance.
- Making agents trustworthy in finance. We kept them read-only, made them quote tool results exactly, showed every step, and moved all math into the engine so the model never computes a number itself.
- Agent latency. A full risk briefing takes about a minute of tool calls, so we save every live answer and replay it if a later call fails.
Accomplishments that we're proud of
- Governed AI that is still load-bearing. Claude reads contracts, maps terms and runs three agents, but code checks every output: exact quotes, validators, ranges instead of guesses, and refusals with reasons.
- Agents an analyst can audit. Every answer comes with the trail of tool calls behind it, and the stress tester's numbers come from the same engine as the rest of the app.
- A real, verified ground-truth set: 387 reported ratios and 157 covenant events, with every quote re-checked against the source filing.
- A pilot on a real agreement (Paycom) where the reader conservatively refused what it could not verify. Saying "I don't know" with a reason is a feature in credit.
- Provenance end to end: every number traces to a clause and a filing.
What we learned
- In credit, the definition is the number. Generic financial ratios are confidently wrong.
- The best use of an LLM here is as a reader, proposer and explainer whose work deterministic code verifies, not as the final source of truth.
- Agents earn trust when they show their steps and leave the arithmetic to code.
- Ranges and refusals build more trust than precise-looking guesses.
- Building the evaluation set first keeps you honest about what you have proven.
What's next for Covenant Watch
- Run the contract reader end to end across the full 250-company universe.
- A real early-warning backtest against the 157 disclosed covenant events.
- Alerts when headroom crosses a line, written up by the risk briefing agent.
Log in or sign up for Devpost to join the conversation.