Skip to content

Scenarios

Plan-scenario tools: create, apply, and compare scenarios against a base plan.

A scenario is a named, ordered list of typed overrides (a delta) applied against a base UserState (design dev_docs/tasks/scenario-storage-design.md). These tools are thin wrappers over finplan_core.scenarios: the numbers are always re-derived server-side by running the whole-plan projection per scenario — never narrated between tool calls.

The base is identified by a BaseRef: a mandatory state_hash (the content hash manage_state returns) plus an optional state_ref accelerator (the st_… handle from the ephemeral state store) so the full document need not be re-sent through model context mid-session. An inline state_json always works and takes precedence.


Create a plan scenario: a named, validated delta of typed overrides against a base plan.

ParameterTypeDefaultDescription
baseobjectrequiredBaseRef the scenario is authored against: {‘state_hash’: ‘sha256:…’ (required, from manage_state), ‘state_ref’: ‘st_…’ (optional in-session accelerator). The response returns base_state_ref for reuse as base.state_ref while live.
namestringrequiredHuman label, e.g. ‘Retire at 60’.
overrideslistrequiredOrdered, typed overrides (the delta), each tagged by ‘kind’: retirement_age, return_assumption, inflation, tax_rate, monthly_contribution, account_balance, income_change, expense_change, goal_target. Amounts are in cents. E.g. [{‘kind’: ‘retirement_age’, ‘age’: 60}].
descriptionstringnullWhat question this scenario explores (e.g. ‘does retiring at 60 still fund college?’). Defaults to a generated summary of the overrides.
state_jsonobjectnullThe base UserState document inline. Optional when base.state_ref is still live; takes precedence when both are given.

Returns: scenario, display_label, input_diff, base_state_hash, base_state_ref, and warnings.


Resolve a scenario’s state-shaped overrides against the base and return a state_ref to the resolved (hypothetical) UserState — plus the resolved state_json inline when return_state_json=True — for inspection or handing to other tools.

ParameterTypeDefaultDescription
baseobjectrequiredBaseRef: {‘state_hash’: ‘sha256:…’ (required), ‘state_ref’: ‘st_…’ (optional)}.
scenarioobjectrequiredThe scenario to apply: a create_scenario document, or a minimal {‘name’: …, ‘overrides’: […]} sketch.
state_jsonobjectnullThe base UserState document inline. Optional when base.state_ref is still live; takes precedence when both are given.
return_state_jsonboolfalseWhen True, also return the resolved hypothetical UserState inline as ‘state_json’. Use it with run_projection (which takes state_json); project_plan also accepts the returned state_ref directly.

Returns: scenario_id, display_label, state_ref, state_hash, warnings — plus the resolved state_json inline when return_state_json=True.


Compare plan scenarios against a base plan: one server-side operation that projects every scenario’s whole plan and diffs the outcomes — never narrated arithmetic.

ParameterTypeDefaultDescription
baseobjectnullBaseRef shared by the scenarios: {‘state_hash’: ‘sha256:…’ (required), ‘state_ref’: ‘st_…’ (optional)}. Required with ‘scenarios’; ignored in favor of the set-level base when ‘scenario_set’ is given. The response returns base_state_ref for reuse as base.state_ref while live.
scenarioslistnullScenarios to compare against the base: create_scenario documents or minimal {‘name’: …, ‘overrides’: […]} sketches. Mutually exclusive with scenario_set.
scenario_setobjectnullA portable finplan_scenario_set document ({‘base’: BaseRef, ‘scenarios’: […]}); its set-level base is authoritative. Mutually exclusive with scenarios.
state_jsonobjectnullThe base UserState document inline. Optional when the base’s state_ref is still live; takes precedence when both are given.
time_horizon_monthsint360Months to project (default 360 = 30 years). Shared by the base and every scenario so outcomes land on one comparable grid.
assumptions_presetstring"standard"Capital-market assumptions preset the scenarios vary from: ‘standard’ (stocks 7%/15%), ‘conservative’ (5%/18%), or ‘optimistic’ (10%/15%).
inflationfloat0.025Baseline annual inflation rate as a decimal (e.g., 0.03 = 3%; default 2.5%); an inflation override in a scenario replaces it for that scenario. When > 0, values are in today’s purchasing power; 0 gives nominal dollars.
percentileslistnullPercentiles to compute (default: [10, 25, 50, 75, 90]).
marginal_ordinary_ratefloat0.22Household marginal ordinary income tax rate for after-tax values; a tax_rate override in a scenario replaces it for that scenario.
ltcg_ratefloat0.15Household long-term capital gains tax rate for after-tax values; a tax_rate override in a scenario replaces it for that scenario.
methodstring"closed_form"Projection method (closed_form is recommended).
iterationsint1000Monte Carlo iterations (only used for method=‘monte_carlo’).
seedintnullRandom seed, pinning which Monte Carlo draw runs (only used for method=‘monte_carlo’). Omitting it is still reproducible — monte_carlo falls back to a fixed default seed.
compute_income_taxbooltrueCompute each year’s federal, state, local and payroll tax from the base state’s person and each scenario’s income, and subtract it from the surplus (default true), as project_plan does, so a scenario’s delta includes its tax consequence. Computed tax replaces hand-entered TAXES expenses; false keeps them and invests the pre-tax surplus.

Returns file URLs + a compact inline summary; the per-month timelines live in the data file only (see the returned schema URL and jq examples). The summary inputs include base_state_ref: reuse it as base.state_ref while it remains live instead of inlining the full state again.