Scenarios and run configurations
A compiled model (IR) is evaluated under a run configuration — so the same model answers base case, stress case, and sensitivity questions without editing the model file.
Base + stress in one run
run.json:
{
"deterministic": {
"annual_discount_rate": 0.10,
"parameters": { "inputs.market.new.ti_psf": 80.0 }
},
"scenarios": {
"stress": {
"annual_discount_rate": 0.12,
"parameters": { "inputs.market.new.ti_psf": 40.0, "inputs.market.renewal.rent_share": 1.0 }
}
}
}cfdl run my-deal/ir.json --config run.json --out results.jsonResults carry the deterministic block plus one summary per scenario. Each
summary carries the scenario's metrics, directly comparable with the base
run's, and its own series, annual rollup, journal, transitions, trace,
slices and statements, and its own ledger_hash, so two scenarios are told
apart by what came out. A declared metric the scenario could not evaluate is
listed under omitted with the reason, not published as a number. The
results also publish the run configuration as run, each inputs file's
content in place of its path, so a reader of the results sees what each
scenario was asked.
Other run configuration keys
annual_discount_rate, orannual_discount_curvenaming a series-shaped assumption the model declares, never both. With neither, the run publishes nomodel.npv.as_of— the date discounting measures from.valuation_grain— omitted, each cash flow discounts at the annual rate raised to its fractional year;"annual"first groups a finer model's cash by calendar year.arithmetic— omitted, expressions evaluate in decimal;"excel_compat"evaluates in float64 to reconcile against a workbook. A scenario cannot set it.
Override keys
inputs.<name>— an assumption, by its full name; a set's field isinputs.<set>.<field>. A value is replaced and a distribution is fixed. An assumption derived from an overridden one reads the override, because the run's values land before any assumption is evaluated.- Nothing else. A stream's amount moves through an assumption it reads
(
amount = inputs.rent). Thestream.<name>:amountkey is not accepted and is refused with a hint.
The run is refused before any period exists when a key goes wrong:
E5033— a key that matches nothing the model declares or reads, or a malformed setting; the message names the nearest name.E5041— a supplied value outside the assumption type's domain or itswithin.E5045— a bodiless assumption the run did not supply.
The inputs file
A bodiless assumption (assume sofr : cre.base_rate) is the run's to
supply. inputs in the deterministic case or a scenario names a JSON file,
relative to the run configuration, keyed by full assumption name; each entry
states one shape — a value, a series with points, or a quantile — and
may cite its own source, which the review page then shows. A series or a
quantile entry replaces the model's body; a value entry is an ordinary
override. A scenario's file is a different snapshot and nothing else.
Sensitivity sweeps
Generate configurations programmatically (they are plain JSON) or drive sweeps from
the Python SDK, where results.scenarios() lands each
scenario as a DataFrame row.
Monte Carlo
The monte_carlo section (trial_count, seed, and distributions,
which override distributions the model declares, by full name)
turns the same IR into a distribution — see
Stochastic modeling and the
run-config reference.