Graam is a document repository, analysis and structuring system for structured-credit teams. Upload a prospectus, a collateral tape or a whole data room; Graam turns them into a searchable institutional record and uses that record to produce cited answers, validated cashflows, structuring analyses and portable deal files.
A language model decides which operations to run. A deterministic, source-available engine performs the financial calculations. Hard provenance rules prevent model-authored figures from being presented as engine results.
Inputs & Extraction
Analysis & Modeling
Collateral Analysis
Build projection curves from rating-agency vintage cohorts and shelf performance data.
Historical Performance
Time series from agency and EDGAR datasets across vintages and issuers.
Interactive Analysis
Drop into Python on any tape; compose typed primitives, not free-form scripting.
Model Training
Build default models on historical data with GAM and logistic regression.
Rating Criteria
S&P and Fitch RMBS criteria encoded as canonical, loan-level methodologies.
Structuring & Pricing
Deal Structuring
Extract a structure, or clone a known-good one, swap the collateral and resize.
Cashflow Projection
Deterministic waterfall execution across scenarios via the Flows engine.
Reverse Structuring
From a pool and a term sheet back to a maximum purchase price.
Rate Sheets
Base price by note rate and an LLPA grid where every cell is a securitization.
Staged, isolated calls — each stage fails safe
One cell at a time, against real output
A separate, colder model — disposes, never proposes
Prose over figures it did not author
Typed, provenance-tiered results
S&P and Fitch RMBS criteria, canonical
Collateral projection, waterfall, bond analytics
Every query takes this path. The shaded upper band is the only place a language model authors anything; the lower band contains no model at all. A figure in a deliverable can only have come from the lower band.
Phase 1 — Inputs & Extraction
Document Intelligence
Every document becomes a typed, page-cited profile
A document is converted into a reusable structured profile: typed fields with page citations and per-field confidence. Downstream analysis works from that consistent record rather than repeatedly interpreting the source from scratch. Upload a prospectus and it is recognized as a modelable deal on arrival; point Graam at a whole data room and it profiles every document in it.
Many narrow extractors, not one sweeping call
Extraction runs as many narrowly-scoped passes — the single biggest lever on hallucination, because a small extractor asked for one table on known pages has very little room to invent. Twenty-one extractor modules cover the structures that matter: RMBS, CRT and CLO priority-of-payments, tranches, triggers, coverage tests, pool composition, annex stratifications, expenses and WAL tables.
Extraction and assembly fail differently
Extraction turns a document into fields. Assembly turns fields into a deal. Keeping them separate makes a tie-out break diagnosable — an extraction failure is a reading problem, an assembly failure is a mechanical one, and the pipeline can tell you which occurred.
Citation-linked answers
Every answer includes page-level citations pointing back to the source document. Click through to the exact passage that supports the response, and to the per-field confidence the extractor recorded.
Versioned, org-scoped profiles
Both stages write into the same artifact: a profile per document, versioned, page-cited and org-scoped. You cannot run an analytic across two hundred PDFs, but you can run one across two hundred profiles.
Deal Library
Search and analytics across every document you own
Graam turns a repository of past transactions into a comparable, cited deal library. A sweep takes conditions and a projection: the conditions filter the corpus, and the projection pulls named fields out of every matching document. Those fields are the columns of the table you are building — which is what makes this an analytic rather than a search.
# every deal whose minimum CE test sits under 5%, # with the columns you want to chart search_profiles( where=["$..threshold_pct < 5", "deal.closing_date exists"], select=["deal.name", "$..threshold_pct", "tranches[].initial_ce"], name_contains="stacr", )
The evidence contract
The result is not a list of matches. A sweep partitions the corpus into five outcomes, not two, around a single principle: absent is not false.
Swept
What the sweep learned
matchedHit the predicate. Values plus citations back to the source page.
not_matchedCarried the field and came out false — and hands back the value it actually holds, so 4.2 against your 5 is visible.
silentNever extracted the field you asked about. It did not fail your test, and calling it a non-match would be a claim about a deal that nothing supports.
Not read
What it could not learn, named file by file
unprofiledNamed filenames. We looked, and no profile exists.
unreadableNamed filenames. The read errored — we never looked.
A profile that is silent on one path and false on another is reported as SILENT. We cannot claim a document failed a test we never found in it.
graam.bridge · profile_search.py
Reach a field without knowing where it was filed
Profiles for a CRT deal, a non-QM shelf and a CLO are not shaped alike — each extractor files its fields under the domain they belong to. Paths support recursive descent, so $..threshold_pct finds that leaf wherever it was filed. You do not need to hold three extraction schemas in your head to ask a question that spans them.
The denominator is reported, never assumed
Twelve deals matched means nothing until you know whether that was twelve of twelve or twelve of two hundred. The sweep returns documents in scope, documents actually searched, and names every unprofiled or unreadable file — because a store that returns nothing for a document it has no profile for and a store that returns nothing because the read threw produce the identical empty answer.
Units are as stored, and nothing is rescaled
A field holding 4.2 for a threshold means 4.2 percent. Deciding that > .05 meant five percent rather than five basis points is a guess, on a corpus where both scales genuinely occur — so the predicate runs exactly as you wrote it, and the sweep warns when the values the corpus actually holds at that path disagree with its shape.
The projection is the analytic
Credit enhancement by vintage across a shelf, every deal carrying a structural feature you care about, trigger thresholds compared across issuers. Each row carries citations back to the page in its source document, so any number in the chart can be walked back to the paragraph it came from.
A primitive that silently multiplies a predicate by 100 is a ×100 bug generator wearing a helpful face, and the reader has no way to see it happened.
graam.bridge · profile_search.py
Tape Stratification
Pool composition at a glance
Upload a loan tape and get instant stratification across FICO, LTV, rate, term, geography, and asset type. Each FICO bucket joins to historical CDR, CPR, and CNL performance from comparable cohorts, so pool composition lands with built-in context. Weighted averages, concentration metrics, and risk flags.
Stratification Tables
Stratifies across FICO, LTV, rate, term, geography, and asset type. Computes WFICO, WAC, WALT, and balance-weighted concentration metrics. Identifies risk concentrations that drive structuring decisions.
Weighted Averages & Concentrations
Computes weighted-average FICO, coupon, LTV, original term, and remaining term. Flags geographic and issuer concentrations that exceed typical thresholds and may require additional credit enhancement.
Risk Flags
Automatically identifies outlier loans, missing data fields, and concentration risks. Surfaces issues that affect pool classification and stress assumptions before they propagate into structuring.
Phase 2 — Analysis & Modeling
Collateral Analysis
Build projection curves from agency and shelf data
Match the pool against rating-agency vintage cohorts and shelf performance data. Build empirical CDR, CPR, severity, and CNL curves from comparable deals, with vintage-over-vintage overlay and stress multipliers feeding directly into the projection chain.
Agency + Shelf Cohort Matching
Filter by FICO range, vintage, originator, term, and rate band. Graam matches the current pool against rating-agency vintage cohorts (Freddie Mac SFLLD for resi) and EDGAR shelf filings, and pulls period-by-period CDR, VPR, DQ60, DQ90, and CNL straight from the source.
Vintage Comparison Across Issuers
Overlay performance curves across vintages and issuers to identify relative value and emerging trends. Compare CDR, severity, and CNL trajectories side by side.
CDR / Severity / CNL Milestones
Extract cumulative net loss, default rate, and severity milestones at 12, 24, 36, 48, and 60 months of seasoning. Use these benchmarks to calibrate forward projections.
Bull / Base / Bear Scenario Comparison
Apply stress multipliers to base empirical curves to produce bull, base, and bear scenarios. Compare projected performance across assumptions to size credit enhancement.
Historical Performance
Time series from agency and EDGAR datasets
Access loan-level residential mortgage performance from the GSE datasets and period-by-period deal performance from EDGAR shelf filings. Analyze CDR, CPR, severity, and delinquency trends across vintages and issuers.
EDGAR Time Series
Period-by-period CDR, VPR, DQ60, DQ90, and CNL from shelf filings. Filter by issuer, vintage, and deal to build custom benchmarks and track performance over time.
Freddie Mac SFLLD Vintage Cohorts
Loan-level performance data from Freddie Mac's Single Family Loan-Level Dataset. Analyze default and prepayment behavior by origination vintage, FICO band, LTV bucket, and geography.
S-Curve Analysis
Prepayment rates by refinancing incentive bucket. Visualize the classic S-curve relationship between rate incentive and voluntary prepayment speed across vintages and loan types.
Sponsor / Shelf-Level Queries
Query performance at the sponsor or shelf level. Compare how different issuers' deals have performed across market cycles and identify platform-specific risk factors.
Interactive Analysis
Built to be argued with
Graam runs as a conversation. Push back on its assumptions, write your own pandas code on the pre-loaded tape, splice cohorts to build a custom curve, then feed any of it into the projection chain. Every step is auditable; nothing is locked behind a button.
Drop into Python on any tape
Every uploaded loan tape and historical performance file is pre-loaded as a pandas DataFrame in a sandboxed Python environment. Ask Graam to weight CDR by FICO bucket, build a custom severity vector, splice cohorts at month 24, plot loss timing — it writes the code, runs it on your data, and renders charts and tables inline.
Typed primitives, not free-form scripting
Generated code does not run as free-form scripting over a raw file. It executes in a constrained REPL seeded with typed primitives: pool metrics, stratifications, delinquency roll rates, performance curves, empirical CPR and CDR histories, loss projection. The agent composes those primitives rather than reimplementing them per query — which is what makes two runs of the same question agree.
Build performance curves with the agent
Start with empirical data: "Pull the 2022 non-QM vintage loss curves." Adjust: "Stress severity to 90% for the first 24 months." Splice: "Use the stressed curve through year 2, then revert to the issuer's base case." Compare: "Run the deal with both curves and show me the breakeven." Each step lands in the same projection state — no rebuilding, no reuploading.
Override and re-run the chain
Disagree with the empirical multiplier? Override it. Want to swap the waterfall convention? Swap it. Graam re-runs the entire chain — collateral projection, waterfall, bond analytics — and shows you what changed. The leverage isn't automation; it's a partner that ships work in a fraction of the time.
Bridges into the engine
Custom Python code calls the same bridges the engine uses — graam.store_curve, graam.get_deal, graam.chart, graam.empirical_severity. Any analysis can flow directly into a projection, waterfall, or bond-analytics run. No exports, no copy-paste between tools.
Your own output views
Define the columns and conventions you want once, as a reusable skill, and every subsequent run returns in that shape without re-prompting.
Sealed deliverables
A result becomes visible only by being sealed. A computation that ran but was never sealed does not silently appear in a report — the absence is the safe failure.
Model Training
Build default models on historical data
Train GAM and logistic regression models on loan-level historical performance data. Generate feature importance rankings, out-of-sample validation metrics, and model-derived CDR curves for projection. Not a black box you license — a model you watched get built and can back-test yourself.
Auto-Derived Cohorts from Tape Characteristics
Graam segments the tape into cohorts based on FICO, LTV, term, and geography. Each cohort is matched against historical performance data to calibrate default probabilities.
GAM and Logit Model Types
Train generalized additive models (GAMs) for nonlinear feature relationships or logistic regression for interpretable coefficient-based models. Both produce loan-level default probabilities.
AUC Validation (Minimum 0.65 Threshold)
Every model is validated on an out-of-sample holdout. Models below the 0.65 AUC threshold are flagged, and Graam surfaces the validation metrics so you can assess discriminatory power.
Model-Derived CDR Vectors for Cashflow Projection
Convert loan-level default probabilities into aggregate CDR vectors that feed directly into the cashflow engine. Bridge the gap between statistical models and waterfall execution.
Rating Criteria
S&P and Fitch RMBS criteria, encoded as canonical methodologies
Give the system a pool and a target rating and it sizes the capital stack against published criteria rather than against an impression of them. The computation is loan-level, and it produces a required credit-enhancement ladder by rating.
A ladder per rating, computed loan by loan
S&P runs the loan-level frequency-of-foreclosure computation against the archetypal pool, combined with loss severity. Fitch runs its Origination PD model and loss-severity framework — PD × LS = expected loss, balance-weighted and floored to the rating case's pool loss floor. Each produces the credit-enhancement level a class needs to carry its rating.
Dual-purpose criteria skills
Without a tape, the skill answers factual questions directly from the transcribed methodology — a documentation adjustment factor, an occupancy or property-type factor, a credit-enhancement floor. With a tape, it runs the loan-level computation through the canonical engine function against your actual pool.
One source file, so nothing drifts
Both paths read the same criteria YAML. The factors quoted back to you in a fact lookup are rendered from the same file the engine computes against, so the number you are told and the number that gets applied cannot diverge.
The agent cannot write a ladder in prose
The skill declares which function is permitted to produce the foreclosure-frequency ladder, and the reporting layer rejects any deliverable that states that ladder without a figure minted by it. A plausible ladder written in text, with the canonical function never called, is the most dangerous possible output — because it is the one nobody checks — so it is made impossible to ship.
No tape, still a real run
Asked to estimate required credit enhancement for a pool described only by stated composition, the system builds a representative tape from that composition and runs the real engine over it, rather than hand-authoring a ladder that looks right.
Published gaps are disclosed, not filled
Where a criteria model's continuous coefficients are proprietary and the published document prints only "varies," the encoded approximation is marked as such with its basis noted, and calibrated to reproduce the published categorical impacts. The faithful published values and the disclosed approximations are never mixed together silently.
Agency CRT has no criteria step
Phase 3 — Structuring & Pricing
Deal Structuring
Extract a structure, or clone one and change it
Parse a prospectus to extract the capital stack, tranches, waterfall rules, and triggers into a validated deal model. Or start from a deal that already works, change something material about it, and determine what it is now worth — without rebuilding the deal or committing changes until the analysis is complete.
Reuse a verified structure on new collateralProspectus Extraction
Parses the prospectus to extract the capital stack, tranche definitions, coupon types, subordination levels, and structural triggers into a validated deal model. Supports sequential, pro-rata, and hybrid structures.
Clone, then change one thing
The starting point is a deal already modeled from its own offering document and reconciled against its published tables — its waterfall, triggers, exchangeables and coupon conventions are known-good. Cloning that and changing one thing is a far shorter path to an answer than authoring a structure from nothing, and it is how the deals on a shelf actually get made.
Substituting collateral
Swap the tape and the deal keeps its structural grammar — the priority of payments, the trigger definitions, the class conventions — while the pool underneath it changes. That is the difference between re-modeling a deal and re-running one: everything the offering document established stays put, and only the collateral moves.
Edits are functional, so exploring is free
An edit returns a new in-memory deal and writes nothing; persistence is a separate, explicit verb. Vary a parameter across dozens of candidates, project and price each one, and commit only the winner — at no database cost for the ones you discarded. Each edit carries a change log recording what moved and from what to what, and an edit that could not be applied comes back flagged as an error rather than as a silent no-op.
Iterative validation
Every structure is submitted to the cashflow engine for validation. The agent checks WAL ranges, payment priority, trigger fire-points, and cashflow conservation. If validation fails, it diagnoses the issue, modifies the deal model, and re-runs until the structure passes — or surfaces the discrepancy for review.
Break-evens on two axes
Price — the maximum collateral price an existing deal supports — and credit, the default rate at which a given class first takes a loss. Proceeds come from the typed sources-and-uses, never a hand-sum of the rows, so reported proceeds can never exceed what the structure actually raised.
The resize runs the deal twice, on purpose
Coupons are an output of pricing and an input to the waterfall. A single pass cannot satisfy both, so a resize runs the structure, prices it, stamps the solved coupons back on, and runs it again.
Pass 1
Pass 2
The first pass learns the cashflows the bonds will be priced off. The second runs the same structure with the coupons that pricing actually solved for.
This is enforced rather than left to judgment because the shortcut fails quietly. Price the stack off a coupon placeholder anchored to the pool's own WAC and the bond coupons consume nearly all the spread, leaving the excess-spread strip with almost no cashflow to price. Every number in that chain is arithmetically correct and the answer is still wrong — so the structuring path always prices off the stated spread ladder, and real excess spread survives to the residual.
Where it refuses
Cashflow Projection
Deterministic waterfall execution across scenarios
Run CDR/CPR/severity scenarios through the open-source Flows engine. Produce tranche-level yield, WAL, duration, and discount margin. Solve for breakeven CDR at target yields. The engine's full source is published, and it runs standalone.
Waterfall Engine
Executes payment waterfalls exactly as specified — sequential, pro-rata, and hybrid structures. Supports interest and principal priority rules, exchangeable classes, coupon ladders and step-ups, OC and reserve triggers, writedown allocation, excess spread mechanics, day-count conventions, clean-up calls, and redemption to any date you name.
Bond Analytics
Computes yield (IRR), weighted average life, modified duration, and discount margin for each tranche at any given price. Supports price-to-yield and yield-to-price solving, breakeven CDR analysis, and multiple day count conventions.
Scenarios & Solvers
Projects defaults (CDR), prepayments (CPR/ABS), and severity from scalar values, ramp vectors, or month-by-month arrays. Vectors are not a fixed menu — a curve can be uploaded from the spreadsheet it already lives in, or pasted straight into the conversation, and it runs the same way as a published scenario. Solvers run break-evens across them, such as the CDR at which a given class first attaches under a fixed severity and speed.
The Deal File
A modeled deal is a JSON document — the analog of a CDI file, and the reason there is no lock-in. It holds the tranches, the priority of payments, the triggers, the collateral. Hand it to the Flows engine inside your own infrastructure and it runs, with no call to Graam and no dependency on a subscription remaining current. The DSL covers the full range of RMBS, CRT and CLO features: multi-class stacks, exchangeable classes, floating-rate coupons with SOFR spreads, and time-varying vectors.
Reverse Structuring
From a pool and a term sheet to a purchase price
An issuer's question is rarely what is this structure worth. It is what can I pay for the collateral. Reverse structuring starts from the collateral and a term sheet and works backward: size the stack to criteria, price it at the stated spreads, value the retained strip, and read off the maximum purchase price.
The inputs are the ones a desk actually has on the day: a tape, the intended capital stack with its target ratings, the spread ladder each rated class is expected to sell at, and the collateral assumptions. What comes back is a fully assembled, priced deal and the sources-and-uses that follow from it.
Foreclosure-frequency ladder
The loan-level rating-criteria computation, run over the actual tape — a required credit-enhancement level per rating.
Sized stack
Each rated class sized to its criteria level; the first-loss and excess-spread strip fall out as the residual.
Coupons and pricing
Rated classes priced off the stated spread ladder, coupons solved and stamped back, the structure re-run at those coupons — the two-pass discipline above.
Retained strip valuation
The excess-spread strip's actual waterfall cashflows, valued to a target yield, so the retained piece is worth what its cashflows are worth.
Sources and uses
Rated proceeds, retained value, fees and any vertical retention slice, giving the maximum cash purchase price and the total economic value of the pool.
Two numbers, two questions
The maximum cash purchase price is what the rated bonds raise, and it does not move with the note rate — criteria-sized balances at spread-priced coupons are independent of it. The economic value adds the retained strip, and it does move, because that is where the coupon lives. A desk comparing bids wants the first; a desk pricing its own origination wants the second.
Or solve the price directly
The same chain runs in the other direction: sell the rated classes at par, retain the residual and first-loss, and root-find the collateral price at which the retained piece earns a target IRR. The purchase price is wired into the day-one equity outflow — equity is what you paid less what the sold bonds raised — so the retained IRR genuinely moves as price moves.
Retention and fees are inputs
A vertical retention slice and deal fees enter the sources-and-uses explicitly, so a risk-retention structure prices as one rather than as a footnote.
Why it is one call
The whole chain runs as a single procedure with every step bound to the function that must produce it: the ladder from the criteria engine, the deal from the assembler, the proceeds from the typed sources-and-uses. The steps that are easy to skip when a chain is assembled by hand cannot be skipped, because there is no hand-assembled version to skip them in.
Where it refuses
Rate Sheets
Rate sheets and loan-level pricing
For an originator or forward-flow buyer, the deliverable is a rate sheet: a base price by note rate, and a grid of loan-level price adjustments by FICO and LTV, with further adjustments by documentation, occupancy, property type, purpose and DTI. Graam builds one from the securitization economics above, prices loans and whole tapes against it, and re-prices it week over week.
Every cell is a securitization
A cell on the sheet is not a lookup. Each is a representative loan with that cell's attributes, run through the full reverse-structuring chain — criteria-sized stack, stated spreads, retained strip — so a price adjustment for a 680 FICO at 85 LTV is the difference in what that loan is worth once securitized, not an assumption about what it should cost.
Decomposed, not enumerated
Base price is priced along the note-rate axis at the best-case borrower, and the FICO × LTV adjustments are priced at a reference rate, so a full sheet costs a few dozen structures rather than the full cross-product. Any loan's price reconstructs as base price plus adjustments, to the sheet's rounding grain.
Price is economic value, not cash price
The base price keys on the loan's total economic value — rated proceeds plus the retained excess-spread strip. The cash price the rated bonds raise does not change with the note rate, so a sheet keyed on it would print the same price at every rate. The value of a higher note rate lives in the strip, and the sheet has to price the strip to show it.
Categorical adjustments come from criteria
Documentation program, occupancy, property type, loan purpose and DTI each become an adjustment column by the same method: hold the borrower fixed, vary one attribute, take the price difference. Those factors are the rating-criteria tables themselves — a bank-statement program or an investor property is priced through the criteria engine's own multiplier, not a house guess.
Quote a loan
Note rate, FICO, LTV and the categorical attributes, against a named sheet: base price plus each adjustment, itemized. Bands are tiers, not nearest grid points — a 720 FICO prices in the 700 tier, an 82 LTV in the 85.
Price a tape
Every loan on a tape quoted off the sheet, rolled up to total balance, weighted net price and total proceeds, with loan-level detail retained. Pass several sheets and the tape is priced across them — a yield sweep in one table.
Export the workbook
A five-tab Excel file — rate sheet, adjustments, capital stack, assumptions, and a loan pricer whose formulas are live, so a desk can quote from the workbook without Graam in the loop.
Stated spreads are checked, not trusted
The spread ladder you state is compared, basis point for basis point, against the ladder the built stack actually carries. A transcription slip surfaces as a named discrepancy rather than a slightly wrong sheet.
Weekly re-price, then the diff
# derive this week's sheet from last week's — only the rungs that moved rate_sheet(base="wk-36", spreads={"AAA": 150, "AA": 205}, name="wk-37") # what moved: base price by rate, LLPA by cell, the ladder compare_rate_sheets("wk-36", "wk-37")
A built sheet is saved under a name, with its inputs, its computed grids and its capital stack, and everything downstream keys on that name. The published sheet is authoritative for the grid and for every rung that did not move; a re-price supplies only the changes, and the comparison prices nothing — so the diff is exact and runs on any two saved sheets on any later day.
Where it refuses
Phase 4 — Why the numbers can be trusted
The Forgery Boundary
A model cannot author an engine number
This is the load-bearing mechanism. Every value returned by the bridge carries a provenance tier, and two of the three tiers cannot be constructed by agent-authored code at all. A forged result raises before it exists.
DETERMINISTICThe return value of a typed engine function — a waterfall result, a metric, a projection.
No — raisesCANONICALA constant bound to a source in the repository, such as a rating-criteria table.
No — raisesDERIVEDComputed at runtime from other results. Provenance-tracked and assessor-checked.
Yes — softDETERMINISTIC/CANONICAL are hard (a vetted engine fn / a repo source; the LLM may not author them). DERIVED is soft (computed at runtime; provenance-tracked + assessor-checked, but not structurally proven).
graam.primitives · contract.py
The guard closes every construction path
Not just the constructor: __init__, model_copy() and model_construct() all check the same flag. Copying a legitimate result and editing the number in it fails the same way as fabricating one outright. Generated analysis code cannot access or override that guard.
What this buys, stated precisely
A number in a Graam deliverable can be traced to the function that produced it. A model cannot compute a figure in its head, write it into prose, and have it carry the authority of an engine result — the type it would need in order to do so is one it cannot construct.
And the honest limit
DERIVED is soft. Runtime compositions are tracked and reviewed but not structurally proven, which is why the tier exists as a separate name rather than being quietly folded in with the other two.
Applied to rating criteria
A skill can declare what it must produce and which function is permitted to produce it — a canonical foreclosure-frequency ladder, minted only by the criteria engine function. The reporting layer then rejects any deliverable that states that ladder without a figure minted by that function.
The Writer Loop
The model that proposes completion is not the model that grants it
The common failure mode in agent systems is self-termination: the model declares success and the system believes it. Graam removes that by construction — the component that proposes completion and the component that grants it are different models, and neither owns the loop.
findings not set
Write the next cell. The loop continues.
findings set
The assessor is a separate, cold model that disposes rather than proposes. Keep-going feeds its review back into the writer's next cell. Fail is the honest-empty path — it returns the diagnostic rather than a fabricated answer.
Before a line of code is written
Decomposition is a fixed sequence of isolated calls, not a reasoning loop — resolve referents, classify, select methodology, check sufficiency, refuse on a false premise, extract typed assumptions. Each stage fails safe: an error degrades to a smaller result, never to a wrong one.
One cell at a time
The writer is a pure function: given a spec and the history, it returns the next cell. It sees the result of the previous cell before writing the next, so it inspects real column names, shapes and values rather than guessing at them. It signals that it believes the work is done by populating a findings variable. It does not get to act on that belief.
An unrecognized verdict is not success
An assessor response the system cannot validate is treated as repair-and-rethink, never as done. The ambiguous case fails toward more work, not toward shipping.
Repair is the loop, not a branch off it
A cell that raises is rolled back and its traceback becomes the next observation — so the writer's next cell is the fix, written against the actual error rather than a summary of it.
Every path is bounded
Executed cells are capped, assessor bounces are capped separately, and a writer that returns prose without runnable code repeatedly fails closed on a stall detector well before either bound.
Budgets count work, not turns
Cells that execute nothing are not charged against the execution budget — a response carrying no runnable code is re-asked without cost, up to a limit.
The Tie-Out
Reconciled against the tables printed in the deal's own prospectus
A modeled deal is validated against the sensitivity and decrement tables printed in its own offering document — every published scenario, weighted average life and yield per class, to maturity and to redemption.
The strength is in whose numbers they are
Those printed tables are the output of the three-way tie-out performed at issuance between the issuer, the accounting firm and the lead bank. Reconciling to them is a comparison against three parties with no interest in Graam being right — independent verification, not a self-graded exercise.
Explicit pass or fail on every row
The output is a per-scenario workbook with an explicit pass or fail on every row. A scenario that does not reconcile is reported as a break. Nothing is smoothed, and nothing is omitted for not agreeing.
The question to ask any vendor
A validation report that always comes back clean is telling you less than one that shows you its breaks. The correct question is not does it tie out, but show me what it does when it doesn't.
Outputs
What comes out
Everything a run produces is portable. The deal file runs on the engine with no call to Graam; the workbooks open in Excel; every figure traces back to the function that minted it or the page it was read from.
Cited answers
Page-level citations back to the source document.
Analytics tables and charts
Projections across a corpus, with the coverage behind them.
Scenario cashflows
Per-scenario tranche cashflows and bond analytics.
Tie-out results
Per-scenario pass/fail against the printed tables.
Portable JSON deal files
The full structure, runnable on the engine standalone.
Rate sheets and priced tapes
Named, saved, comparable week over week.
Excel workbooks
Including the five-tab rate sheet with a live loan pricer.
Prospectus documents
Preliminary offering prose generated from a validated deal model, in Markdown or DOCX.
Evaluate Graam on a deal you already know
Provide an offering document and, optionally, a collateral tape. Graam will reconstruct the transaction, run the published scenarios, return an explicit tie-out, and show the source or computation behind every material figure.
Book a demo