Research · Audit

Off-Balance-Sheet Commitments Audit — How Much Has This Company Promised That Its Balance Sheet Doesn't Show?

Builds the series of what a filer has promised but not recorded — leases not yet commenced, purchase commitments, VIEs — and files it as a cited dossier.

An audit, not a chat answer: a fixed procedure over one filer's lease, commitments, and venture notes that builds the time series of what has been promised but not yet recorded — leases signed but not commenced, non-cancelable purchase commitments, unconsolidated ventures and guarantees — reconciles it against the recorded balance sheet, and files the result as a cited dossier with create_report. Built for the credit or equity analyst who suspects reported leverage understates what the company has agreed to pay, and for the forensic reader who wants the recorded-versus-committed chart with every cell cited.

Every number this audit finds is disclosed exactly where US GAAP requires — and none of it is in numeric XBRL facts. It lives in text blocks, so ratio screens cannot see it, and single-period readers miss the only thing that matters: the rate of change. Meta's not-yet-commenced leases went $34B → $104B → $183B → $279B across four consecutive filings. Microsoft's went $92.7B → $329.1B across the four filings of one fiscal year. No single filing shows that arc.

Why this works with edgar.tools MCP

The discriminating capability is full-text search over XBRL text blocks across a filer's whole filing history, joined to the as-filed statements and ending in a report object the server validates:

  • company_filings — establish which periodic filing is actually newest (the 10-K often post-dates the latest 10-Q).
  • financial_statements — the recorded side: balance sheet at both annual and quarterly, annual cash flow.
  • disclosure_search — the whole audit rides on this: topic names an accounting requirement (leases not yet commenced, contractual commitments, VIE maximum exposure) and series: true returns that disclosure from every recent 10-K / 10-Q in one call, one row per filing, oldest first. The series is one call per requirement.
  • filing_section — read a note by tag when search misses; the wrong-tag error returns the filing's full tag list, which is how you discover a filer's non-standard note names.
  • create_report — files the dossier. The server enforces the citation contract: every block carries sources, every external source is an SEC URL.

How to use

Copy the procedure below into your Claude / ChatGPT / Gemini conversation with edgar.tools MCP connected, then ask:

Audit off-balance-sheet commitments for [TICKER].

The output is a report you can open, hand to a PM or a compliance file, and (on the Analyst plan) share as a frozen link — not a summary of a chat.

Prompt — paste this into Claude, ChatGPT, or Gemini

The audit (v0.2)

You are running a reconciliation audit on one filer: what has it committed to pay that its balance sheet does not yet record, and how fast is that figure moving? Follow the steps in order. Step labels are fixed (R resolve · G gather · A analyze · W widen · D deliver). The deliverable is a create_report dossier, not a chat summary.

Non-negotiables

  • No invention. Every dollar amount, date, and quoted phrase comes from a tool result tied to an accession. If a value is not in the filings, write UNKNOWN.
  • Executory contracts are not debt. Never write "debt," "borrowing," or "hidden liabilities" for something the filing calls a commitment or a lease. Say what the filing says, label the recorded and unrecorded columns, and let the reader draw the ratio.
  • A zero-match search is a fact about the query, not the filer. A topic walks its own phrase ladder and, on a miss, returns topic_miss with every phrase tried and the tags the filing carried. A free-text query ANDs every term and gives no diagnostic. Exhaust the topic, then the fallback ladder, then a tag read before writing "not disclosed," and even then write "not disclosed in this filer's XBRL text blocks."
  • Keep results bounded. Series calls are bounded by design (one passage per filing). For a free-text query, use max_results ≤ 8 and context: true; a quoted phrase without context returned 60K characters on one filer.
  • Sums are upper bounds. Filings do not say whether disclosed totals overlap. Never present a sum of note-only rows as a measurement.
  • File before you summarize. Invoking this audit is the request to file it. Run D1 and D2, then answer in chat with the report URL and the Assessment. Do not ask whether to file, and do not offer create_report as a next step — the report is private to the owner and costs nothing to discard. Offer follow-ups (the RPO series, peer audits) after the report exists, never instead of it.

Procedure

R1 — Resolve the filer and the as-of. Resolve the ticker with search_companies if ambiguous. Then company_filings({ company, form: "10-K", limit: 2 }) and company_filings({ company, form: "10-Q", limit: 4 }). Anchor on whichever periodic filing is later and record its accession — for June- and May-fiscal-year filers read in July–September the 10-K is newer than any 10-Q, and anchoring on the 10-Q silently drops the latest quarter. Never call company_filings unfiltered (on filers with active insider selling the first 40 rows are Forms 4 and 144). Ignore is_stale on these listings; it measures the filer's cadence, not index freshness.

G1 — Pull the recorded side. financial_statements({ company, statement: "balance_sheet", period: "annual" }) and period: "quarterly". Compare each source_accession with the R1 anchor and use the later one; the structured statements can lag the newest 10-Q by a quarter with no warning. If they lag, say so in the A2 table and take latest-quarter lease figures from the G2 note. Do not use period: "ttm" as a repair. Capture long-term debt, total liabilities (derive from current + non-current if no total row, and label it derived), total assets, equity, restricted cash, deferred revenue, and the lease captions — expecting the lease captions to be incomplete: many filers fold current operating-lease and all finance-lease liabilities into "other" liabilities and break them out only in the note. Then financial_statements({ company, statement: "cash_flow", period: "annual" }) (never ttm): CFO, capex, debt issuance and repayment, buybacks, dividends, and from the supplemental section the right-of-use assets obtained in exchange for lease liabilities (the per-year measure of leases commencing) and capital expenditures incurred but not yet paid.

G2 — The lease series. disclosure_search({ company, topic: "leases-not-yet-commenced", series: true, max_results: 8 }). One row per filing searched, oldest period first. A status: "hit" row carries the winning rung and phrase, the best passage, and parsed figures[]; a status: "miss" row says the filing was searched and no rung matched, with tags_seen listing the topic's tags it carried. Capture, per row: the not-yet-commenced amount, commencement window, term range, any conditionality clause, and every sentence describing amounts excluded from the headline with its figure. Then disclosure_search({ company, topic: "commitments-excluded-from-headline", series: true, max_results: 8 }): the excluded tier ("Not included in the preceding amounts…", "subject to a contractual maximum") is often the single largest commitment, and this topic finds it wherever the filer put it. For the maturity schedule (undiscounted, imputed interest, present value) and weighted-average term and discount rate, read the anchor filing's lease note by the tag the series row names: filing_section({ accession: <R1 anchor>, section: "note:<row.tag>" }). Filers who consolidate disclosure into the lease note put the commitment satellites and the unconsolidated-VIE paragraph in the same block, so read it before spending calls on G3 and G4.

G2b — Fallback when the topic misses. A row comes back status: "miss", or the call returns topic_miss: walk the ladder by hand on that filing, first hit wins, each with context: true, max_results: 8: "not yet commenced" (quoted) → "not reflected on our consolidated balance sheet" → "additional lease commitments". If that also misses, read filing_section({ accession, section: "note:LesseeOperatingLeasesTextBlock" }); when the tag is absent the error carries the filing's full available_tags, so pick the lease or commitments tag and re-call. Tags differ between a filer's 10-K and 10-Q and between consecutive 10-Qs (Oracle uses three tags across four filings), so budget one wasted call per filing here. A status: "unavailable" row means the filing could not be read: say so in the series, and never count it as "not disclosed."

G2c — A passage that announces a figure it does not show. If a row's passage ends on a sentence that introduces what follows ("…are the following lease arrangements", "…as follows:") and no figure comes after it, read that filing's note by its tag (filing_section, note:<row.tag>) and take the figure from the full text. The excluded amount is usually the finding, so do not let a cut passage decide the series.

G3 — The contractual-commitments series. disclosure_search({ company, topic: "contractual-commitments", series: true, max_results: 8 }). Capture the total, the year-by-year schedule (10-K) or near-year due amounts (10-Q), and the satellites: contingent capacity obligations, escrow or restricted-cash movements in either direction, unquantified energy PPAs, guarantees of a lessor's borrowing, subsequent-event additions. The commitment may not live in a commitments note: it can sit in the lease note as an excluded amount (G2 already has it), in the property-and-equipment note as a construction commitment, or in a combined leases-and-commitments note. A hit is not a schedule. A low rung (committed, commitments) can land on a Commitments note that holds only letters of credit and indemnifications. If the row's figures[] carry no money amount tied to a commitment, record "the Commitments note carries no quantified schedule" as a finding: it is a fact about the filer, distinct from "the company has no commitments."

G4 — The venture and VIE series. disclosure_search({ company, topic: "maximum-exposure-to-loss", series: true, max_results: 8 }). The topic searches the VIE, equity-investment, fair-value, subsequent-event and debt notes; an uncapped funding commitment to a financing counterparty reassessed as a VIE can live in the debt note, and the series shows the quarter it first appears. If the topic misses, read the debt note by tag (note:LongTermDebtTextBlock or note:DebtDisclosureTextBlock; the error lists the filing's tags when neither exists). Capture ownership %, development cost and pro-rata funding, lease commitment to the venture and commencement year, RVG threshold, carrying value, the company-stated maximum exposure to loss, funding commitment and funded portion, and the primary-beneficiary conclusion. Absence is a first-class outcome: many large filers publish no maximum-exposure figure. Report the section with "no such disclosure found" and, if one exists, the equity-method funding commitment as the only quantified exposure. Do not infer a VIE from a lease counterparty name, an equity-method investee, a related party, or a consolidated subsidiary.

A1 — Build the time series. One row per filing for each of: not-yet-commenced leases (with commencement window and term range — drift in either is a finding); contractual commitments total; near-year due amounts; venture maximum exposure. Subsequent-event additions are their own rows dated to the disclosing filing, and may land on a different line than last time. Presentation-break check: a split operating/finance figure collapsing into one combined number mid-series manufactures an apparent decline — annotate the break; never sum across it. Record the filer's own imputed-interest haircut per period (imputed interest ÷ total undiscounted) beside its discount rate.

A2 — Tabulate recorded versus committed. One table as of the R1 anchor. Recorded rows (G1, finished from the G2 note) and note-only rows (G2–G4), each labelled balance sheet / inside an "other" caption, broken out in the note / note only, and derived where you summed. State that the filings do not say whether note-only rows overlap, quote any inclusion or exclusion the filer does state, and call the sum an upper bound. If G1 served an older column than the note, say which rows sit on which date.

A3 — Coherence findings. Each as "field A says X, field B says Y, same record": near-year commitments against prior-year CFO and capex (when the R1 anchor is a 10-Q, add financial_statements({ company, statement: "cash_flow", period: "quarterly" }) for the year-to-date column, labelled as such; if it lags the anchor, a cash or debt-service figure the filer states in MD&A or Item 1A may be quoted verbatim with its accession); debt issuance and restricted cash (recorded) against the obligations they secure (not); venture maximum exposure against carrying value, quoting the company's own decomposition when it gives one; not-yet-commenced undiscounted total against the undiscounted total of recorded leases; and the commencement bridge — when the not-yet-commenced total falls, check the recorded lease liability in the same quarter before characterizing the fall: a falling note-only figure beside a rising recorded figure is commencement, not cancellation.

W1 — Universe comparison (optional; Analyst plan). For 2–25 filers, disclosure_search({ ciks: [...], topic: "leases-not-yet-commenced", series: true }), then repeat G2–G3 per filer, and produce the recorded-versus-committed table per filer.

W2 — Committed revenue beside committed rent (optional). For a take-or-pay lessee, the benign case is that contracted revenue covers the new rent. disclosure_search({ company, query: "\"remaining performance obligations\"", context: true, max_results: 8 }) gives the RPO figure per filing; put its series beside the G2 series and quote the filer's own expected-recognition window. Same caveat as the sums: the filings do not match a contract to a lease.

D1 — Write the dossier. Sections, in this order, unnumbered: Assessment (one bolded central claim, two or three pillars pointing into the evidence, a posture verdict) · Recorded side (balance-sheet table + lease maturity table; as-of split stated if G1 lagged) · Leases not yet commenced (series table with window / term / break annotations + one verbatim callout + scale check against CFO and capex) · Contractual commitments (titled in the filer's own term; series + schedule + satellites + verbatim callout, or the negative finding) · Unconsolidated ventures and guarantees (paragraph + keyValue + verbatim maximum-exposure callout, or an explicit "no such disclosure found") · Recorded versus committed (one table + overlap caveat) · Coherence (cash-flow table + numbered findings) · What would make this benign (mandatory; always state that undiscounted ≠ liability, quoting the filer's own haircut and rate, and that the new commitments may run longer than the recorded book) · Open questions · Sources · a citationNote with the method chain. The citationNote names this procedure as "Off-Balance-Sheet Commitments Audit v0.2." Every sentence quotes a filing or states a verifiable structural fact; conclusions are the questions the record raises.

D2 — File. Call create_report({ kind: "dossier", title, blocks }) now, in this turn — not as an offer. Block rules: every block carries sources: [] at minimum, headings and the citationNote included; citationNote.method is an array of strings; do not number headings (the renderer letters sections); one callout per verbatim quote, never a paraphrase inside a callout; external sources are https://www.sec.gov/…-index.htm URLs. Share links are minted on the report page (Analyst plan), never by this procedure.

Priors — what each observation is worth

  • The disclosure is standard-mandated; the wording is not. ASC 842 requires the not-yet-commenced disclosure and ASC 810 the maximum-exposure figure. Most filers use the standards' words; some do not, and the tags are less stable than the phrases. Treat each phrase as a hypothesis with a ladder behind it.
  • The rate of change is the finding; the level is context. A large commitment at a company with large operating cash flow is arguable either way. A six-fold rise in twelve months is not. Build the series before characterizing any single number.
  • The excluded amount is often the finding. The headline is frequently defined by what it leaves out. One filer's single largest commitment (up to $14.7B) is disclosed only as an amount outside the headline; a run that captured the headline alone understates the unrecorded set by ~40%.
  • Structural facts outrank accounting characterizations. Escrow demanded (or returned), a lender requiring a guarantee of a lessor's borrowing, a funding commitment "not subject to a contractual cap," megawatts undelivered — facts about what counterparties demanded. They are safe to report and they discriminate.
  • The company's own decomposition beats yours when it gives one; when it gives one sentence with one number, quote that and build nothing.
  • Undiscounted ≠ liability, and the haircut is filer-specific. Observed haircuts run from 25% at a 4.5% rate to 44% at 10%. Compute it from the filer's schedule; never carry one filer's haircut to another.
  • Subsequent events are sometimes next quarter's series point. Check every filing; record the absence rather than assuming a row.
  • Read the venture where it first appears and where it settles — in both directions. Ventures migrate from subsequent events into the equity note, and financing counterparties can become VIEs mid-quarter inside the debt note.

Stopping conditions

  • If the R1 anchor is more than a quarter older than today and the filer has a 10-Q due, say so and date the audit to the anchor.
  • If G2, G2b, G2c and G3 all return nothing, the filer discloses no lease or commitment schedule in XBRL text — file the dossier with that as the central finding and the recorded side only.
  • If the account lacks Pro, financial_statements and disclosure_search return TIER_INSUFFICIENT; call account_status and tell the user what was gated.
Then askRun this on MSFT.

What the audit finds that a screen cannot

QuestionRatio screen / base LLMThis audit
Leases signed but not commencedInvisible — no numeric fact existsdisclosure_search topic series returns the sentence and the excluded tier from every filing in one call
Purchase / capacity commitmentsInvisible, or a stale memorized figureThe topic's phrase ladder finds the note wherever the filer put it, and says what it tried when it misses
Unconsolidated venture exposureGuessed from headlinesThe company's own maximum-exposure sentence, or an explicit "not disclosed"
Recorded lease liabilitiesThe face of the balance sheet (often a fraction of the recorded total)The note's supplemental table — $88.5B where the face showed $16.5B at one filer
Direction of changeOne periodConsecutive filings, with presentation breaks and commencement bridges annotated
DeliverableA chat answerA cited dossier object the server validated, shareable as a frozen link

Worked runs (2026-09-03): Meta, Microsoft, Oracle, CoreWeave. Three of the four filers phrase the lease disclosure in ASC 842's words; Oracle does not. At none of the four does the verbatim "non-cancelable contractual commitments" query find the commitments, which is why each topic carries a ladder and the procedure keeps a tag-discovery floor. On 2026-10-14 the v0.1 hand ladder took CoreWeave in 9 calls; v0.2's topic series cover G2–G4 in four.

  • Short-Seller Forensics — when the question is "is this company hiding something?" rather than "what has it promised?"
  • F.O.R.G.E. Framework — the compounder lens; run this audit first if capex commitments are the thesis risk.
  • Form D Shell Fan-Out Audit — the family's other audit: cross-filing linkage rather than one filer's notes.