Scenario Lab#
The scenario lab (means.lab) is the shared application layer over means.planning.
It owns scenario validation, named hypotheses, variant generation, sensitivity ranking, and stable presentation models.
The CLI (means-plan), TUI (means-tui), and web UI (means-web) all consume one typed API – no surface-specific financial calculation forks exist.
Core concepts#
Hypotheses#
A hypothesis is a named question over the scenario with at least two named alternatives. Each alternative carries typed overrides targeting fields from the finite registry:
starting_cash– the opening cash balancereserve_floor– the minimum cash floorextra_debt_payment– the monthly extra debt paymentallocation_day– the monthly extra-allocation date
All alternative names within a hypothesis must be unique.
Variants#
The lab evaluates the Cartesian product of hypothesis alternatives.
Variant expansion fails closed above a documented bound (MAX_VARIANTS = 64).
from decimal import Decimal
from means.lab import (
Alternative,
Hypothesis,
HypothesisTarget,
LabRequest,
OverrideTarget,
ScenarioLab,
)
request = LabRequest(
scenario=scenario,
hypotheses=[
Hypothesis(
name='Starting cash',
alternatives=[
Alternative(
name='low',
targets=[
HypothesisTarget(
field=OverrideTarget.STARTING_CASH,
value=Decimal('3000.00'),
),
],
),
Alternative(
name='high',
targets=[
HypothesisTarget(
field=OverrideTarget.STARTING_CASH,
value=Decimal('8000.00'),
),
],
),
],
),
],
)
result = ScenarioLab().evaluate(request)
Sensitivity ranking#
Sensitivity is descriptive, not causal. For each hypothesis and metric, the lab measures the spread observed across the evaluated variants and reports the range with its low and high variant labels. This does not prove that a hypothesis causes the observed difference.
Fictional example#
This example uses entirely fictional data:
A scenario-lab document wraps the planning scenario under a scenario: key and adds optional hypotheses:
scenario:
name: Fictional demo scenario
as_of: 2026-01-01
through: 2026-06-30
starting_cash: '5000.00'
reserve_floor: '500.00'
flows:
- uid: income
name: Income
category: salary
kind: inflow
amount: '3000.00'
start: 2026-01-01
frequency: monthly
debts:
- uid: card
name: Card
balance: '2000.00'
annual_rate: '0.18'
minimum_payment: '150.00'
due_day: 5
extra_debt_payment: '200.00'
allocation_day: 10
hypotheses:
- name: Reserve policy
alternatives:
- name: Conservative reserve
targets:
- field: reserve_floor
value: '1000.00'
- name: Lean reserve
targets:
- field: reserve_floor
value: '250.00'
Privacy and safety#
All computation is local; no financial data is sent remotely.
Neither the TUI nor the WUI mutates a Ledger.
The WUI binds to loopback (
127.0.0.1) by default.The WUI parses no arbitrary paths from browser input.
Both interfaces label scenario math as hypotheses, not predictions or financial advice.
Optional UI dependencies do not enlarge the base installation.