{"contract_version":"1.0","distributions":{"constant":{"name":"constant","description":"A constant value that never changes","parameters":{"value":{"type":"float","description":"The constant value to return","constraints":null}}},"normal":{"name":"normal","description":"Normal (Gaussian) distribution","parameters":{"mean":{"type":"float","description":"The mean (average) of the distribution","constraints":null},"std":{"type":"float","description":"The standard deviation (spread) of the distribution","constraints":"positive"}}},"uniform":{"name":"uniform","description":"Uniform distribution between low and high values","parameters":{"low":{"type":"float","description":"Lower bound of the distribution","constraints":null},"high":{"type":"float","description":"Upper bound of the distribution","constraints":null}}},"beta":{"name":"beta","description":"Beta distribution for modeling probabilities and proportions","parameters":{"alpha":{"type":"float","description":"The alpha shape parameter (α)","constraints":"positive"},"beta":{"type":"float","description":"The beta shape parameter (β)","constraints":"positive"}}},"gamma":{"name":"gamma","description":"Gamma distribution for modeling waiting times","parameters":{"shape":{"type":"float","description":"The shape parameter (k)","constraints":"positive"},"scale":{"type":"float","description":"The scale parameter (θ)","constraints":"positive"}}},"exponential":{"name":"exponential","description":"Exponential distribution with scale parameter","parameters":{"scale":{"type":"float","description":"Scale parameter (mean) of the distribution","constraints":"positive"}}},"poisson":{"name":"poisson","description":"Poisson distribution for modeling count data","parameters":{"lambda_val":{"type":"float","description":"The rate parameter (λ)","constraints":"positive"}}},"bernoulli":{"name":"bernoulli","description":"Bernoulli distribution for binary outcomes","parameters":{"p":{"type":"float","description":"The probability of success","constraints":"between 0 and 1"}}},"triangle":{"name":"triangle","description":"Triangle distribution with minimum, maximum, and mode parameters","parameters":{"min_val":{"type":"float","description":"The minimum value of the distribution","constraints":null},"max_val":{"type":"float","description":"The maximum value of the distribution","constraints":null},"mode_val":{"type":"float","description":"The mode (peak) of the distribution","constraints":null}}},"log_normal":{"name":"log_normal","description":"Log-normal distribution for modeling skewed, positive-valued data","parameters":{"mu":{"type":"float","description":"Mean of the underlying normal distribution (log-scale)","constraints":null},"sigma":{"type":"float","description":"Standard deviation of the underlying normal distribution (log-scale)","constraints":"positive"}}},"discrete_lognormal":{"name":"discrete_lognormal","description":"Discrete log-normal: sample log-normal then round to nearest integer (zero allowed)","parameters":{"mu":{"type":"float","description":"Mean of the underlying normal distribution (log-scale)","constraints":null},"sigma":{"type":"float","description":"Standard deviation of the underlying normal distribution (log-scale)","constraints":"positive"}}},"categorical":{"name":"categorical","description":"Categorical distribution for discrete outcomes with custom probabilities","parameters":{"values":{"type":"list[float]","description":"List of possible values to sample from","constraints":null},"probabilities":{"type":"list[float]","description":"List of probabilities for each value (must sum to 1)","constraints":"sum to 1"}}},"discrete_gamma":{"name":"discrete_gamma","description":"Discrete gamma: sample gamma then round to nearest integer (zero allowed)","parameters":{"shape":{"type":"float","description":"The shape parameter (k)","constraints":"positive"},"scale":{"type":"float","description":"The scale parameter (θ)","constraints":"positive"}}},"binomial":{"name":"binomial","description":"Binomial distribution for modeling the number of successes in n independent trials","parameters":{"n":{"type":"int","description":"Number of trials","constraints":"positive integer"},"p":{"type":"float","description":"Probability of success in each trial","constraints":"between 0 and 1"}}},"dirichlet":{"name":"dirichlet","description":"Dirichlet distribution for modeling correlated probabilities that sum to 1","parameters":{"alpha":{"type":"list[float]","description":"Concentration parameters for each category","constraints":"all positive"}}},"constant_array":{"name":"constant_array","description":"Constant array distribution for deterministic array values (used internally for scenarios)","parameters":{"values":{"type":"list[float]","description":"Array of constant values to return","constraints":null}}},"discrete_normal":{"name":"discrete_normal","description":"Discrete normal distribution for integer-valued data with normal characteristics","parameters":{"mean":{"type":"float","description":"The mean (average) of the distribution","constraints":null},"std":{"type":"float","description":"The standard deviation (spread) of the distribution","constraints":"positive"}}},"multivariate_normal":{"name":"multivariate_normal","description":"Multivariate normal (correlated inputs): draws a vector of correlated values per trial from a mean vector + correlation matrix + per-component standard deviations. Array-valued — feed multiple downstream calc nodes by INDEXing component k (1-based): INDEX({edge}, k).","parameters":{"mean":{"type":"list[float]","description":"Mean vector (one entry per correlated component)","constraints":null},"stds":{"type":"list[float]","description":"Per-component standard deviations (same length as mean)","constraints":"all positive"},"correlation":{"type":"list[list[float]]","description":"Square correlation matrix (NxN for N components); diagonal 1.0, symmetric, entries in [-1, 1]","constraints":null}}}},"formula_functions":{"abs":{"name":"abs","kind":"formula","description":"Absolute value.","arity":"1"},"and":{"name":"and","kind":"formula","description":"Logical AND of its arguments.","arity":"1..N"},"average":{"name":"average","kind":"formula","description":"Arithmetic mean of its arguments.","arity":"1..N"},"binomial":{"name":"binomial","kind":"formula","description":"Sample a binomial outcome.","arity":"2"},"ceil":{"name":"ceil","kind":"formula","description":"Round up to the nearest integer.","arity":"1"},"discount":{"name":"discount","kind":"formula","description":"Discount factor 1 / (1 + rate) ** n. n is the 1-based {time_period}. Pairs with the 1-based per-period convention; the post-sim 'npv' aggregation is 0-based — don't combine them on one series.","arity":"(rate, n)"},"exp":{"name":"exp","kind":"formula","description":"e raised to the argument.","arity":"1"},"floor":{"name":"floor","kind":"formula","description":"Round down to the nearest integer.","arity":"1"},"if":{"name":"if","kind":"formula","description":"Ternary: if(cond, then, else).","arity":"3"},"index":{"name":"index","kind":"formula","description":"Element at a position in an array argument.","arity":"2"},"length":{"name":"length","kind":"formula","description":"Number of elements in an array argument.","arity":"1"},"ln":{"name":"ln","kind":"formula","description":"Natural logarithm.","arity":"1"},"log":{"name":"log","kind":"formula","description":"Base-10 logarithm.","arity":"1"},"max":{"name":"max","kind":"formula","description":"Largest of its arguments.","arity":"1..N"},"mean":{"name":"mean","kind":"formula","description":"Arithmetic mean of its arguments (alias of average).","arity":"1..N"},"min":{"name":"min","kind":"formula","description":"Smallest of its arguments.","arity":"1..N"},"not":{"name":"not","kind":"formula","description":"Logical negation.","arity":"1"},"or":{"name":"or","kind":"formula","description":"Logical OR of its arguments.","arity":"1..N"},"pow":{"name":"pow","kind":"formula","description":"Raise the first argument to the power of the second.","arity":"2"},"product":{"name":"product","kind":"formula","description":"Product of its arguments.","arity":"1..N"},"pv":{"name":"pv","kind":"formula","description":"Present value of a cash flow discounted by 'rate' over 'period' periods: value / (1 + rate) ** period. period is the 1-based {time_period}; the first period is discounted by ^1. Do NOT also request an aggregation 'npv' on the same series (it is 0-based and would double-shift period 1).","arity":"(rate, value, period)"},"round":{"name":"round","kind":"formula","description":"Round to the nearest integer (or to N decimals).","arity":"1..2"},"sqrt":{"name":"sqrt","kind":"formula","description":"Square root.","arity":"1"},"sum":{"name":"sum","kind":"formula","description":"Sum of its arguments.","arity":"1..N"},"cagr":{"name":"cagr","kind":"aggregation","description":"Compound annual growth rate from the first to the last period of the series.","arity":"series"},"cumsum":{"name":"cumsum","kind":"aggregation","description":"Terminal value of the cumulative sum across periods (sum_t series[t]).","arity":"series"},"discounted_payback":{"name":"discounted_payback","kind":"aggregation","description":"Like payback, but on the rate-discounted cumulative series. Requires a 'rate' param.","arity":"series, rate"},"irr":{"name":"irr","kind":"aggregation","description":"Internal rate of return per trial (the per-period rate where NPV is zero; series index 0-based).","arity":"series"},"mirr":{"name":"mirr","kind":"aggregation","description":"Aggregation metric 'mirr'.","arity":null},"npv":{"name":"npv","kind":"aggregation","description":"Net present value per trial: sum_t series[t] / (1+rate)**t with a 0-BASED series index (period 0 undiscounted). Requires a 'rate' param. Model an up-front outlay as a negative period-0 cash flow.","arity":"series, rate"},"payback":{"name":"payback","kind":"aggregation","description":"Number of periods until the cumulative (undiscounted) series turns non-negative.","arity":"series"},"prob":{"name":"prob","kind":"aggregation","description":"Aggregation metric 'prob'.","arity":null},"terminal_value":{"name":"terminal_value","kind":"aggregation","description":"Aggregation metric 'terminal_value'.","arity":null}},"time_period_indexing":"{time_period} is 1-BASED in ALL per-period formulas: the first period is {time_period} == 1, not 0. The post-simulation aggregation series index (npv/irr/payback/...) is 0-BASED (first period undiscounted). WARNING: a formula mask written as `{time_period} == 0` NEVER fires for any real period — it silently evaluates to zero every period (the silent-zero trap). Use `{time_period} == 1` for the first period."}