en un clic
generate-bounds
// Use when the user wants to generate low/base/high assumption ranges (bounds) for missing or uncertain variables in a validated extract-parameters-from-full JSON, in preparation for deterministic scenarios or Monte Carlo
// Use when the user wants to generate low/base/high assumption ranges (bounds) for missing or uncertain variables in a validated extract-parameters-from-full JSON, in preparation for deterministic scenarios or Monte Carlo
Use when the user wants to extract parameters from a PlanExe extraction-input digest (the markdown produced by experiments/napkin_math/prepare_extract_input.py — the 137-recommended section bundle, with the four "Keep or compress" sections compressed) instead of the full PlanExe HTML report
Use when the user wants to extract parameters, modelling values, or key variables from a PlanExe report (HTML or text) for napkin math, triage, or Monte Carlo simulation
Use when the user wants to run the napkin-math pipeline end-to-end on a PlanExe report, or resume a partially populated output directory by filling in only the missing stages. Orchestrates digest preparation, parameter extraction, validation, bounds, calculations, scenarios, Monte Carlo, and assessment rendering. Never copies artifacts forward from prior runs, and never re-runs a stage whose output is already on disk.
Use after the napkin_math pipeline has produced parameters/bounds/scenarios/montecarlo JSON to generate a plan assessment (assessment.md) — a thin interpretation layer over the intermediary artifacts. Emits a JSON manifest, a provenance map, gate verdicts (Critical / Fragile / Marginal / Robust), failure drivers, confidence and trust boundaries, scenario sanity check, and suggested next actions. The artifact is a navigation/judgment file, not a copy of the raw simulation data.
Use after the napkin_math pipeline has produced parameters.json (from extract-parameters-from-digest or extract-parameters-from-full) to validate it against the 16 structural checks the rest of the pipeline assumes. Writes validation.json next to parameters.json. Deterministic Python — no LLM call.
Use when the user wants to turn a validated extract-parameters-from-full JSON into a Python module of deterministic functions implementing the formula_hint expressions for downstream scenario runs and Monte Carlo
| name | generate-bounds |
| description | Use when the user wants to generate low/base/high assumption ranges (bounds) for missing or uncertain variables in a validated extract-parameters-from-full JSON, in preparation for deterministic scenarios or Monte Carlo |
Wraps the bounds-estimator system prompt at system-prompt.txt (next to this file) and applies it to a parameter JSON produced by extract-parameters-from-full (and ideally already passed validate-parameters). Output is a strict JSON object keyed by variable id, with low / base / high / unit / rationale / source for every variable that needs an assumption range.
Stage 4 of the pipeline described in planexe_simulator/README.md.
missing_values_to_estimate and uncertain key_values before running deterministic scenarios or Monte Carlovalidate-parameters (passes clean) and generate-calculations / run-scenariosNot for: regenerating the parameter JSON (use extract-parameters-from-full), validating the JSON (use validate-parameters), or producing Python code (use generate-calculations).
system-prompt.txt (sibling of this SKILL.md). Its selection rules and spread heuristics are authoritative.validate-parameters; if it visibly hasn't, tell the user and offer to validate first.rationale (Risk N, Issue N, Decision N) refers to content that substantively supports the claim — not just lexically present.source: "data" entries name an explicit anchor in the rationale.<input-basename>.bounds.json next to the input.Generate one bounds entry for every id that meets ANY of:
missing_values_to_estimatekey_value with value_type ∈ {inferred, missing_but_needed}key_value with value == nullkey_value with uncertainty == highkey_value with uncertainty == medium AND modelling_priority ∈ {critical, high}Skip: explicit/derived key_values with low uncertainty, derived_questions, recommended_first_calculations, and formula LHS-only outputs that are not declared as inputs.
| Uncertainty | Spread around base |
|---|---|
| low | ±10–20% |
| medium | ±25–50% |
| high | ≥±50%, up to a 2–5× factor when genuinely speculative |
Always low ≤ base ≤ high. Fractions stay in [0, 1]. Counts of discrete things (people, kits, centers, months) use integer bounds.
{
"<variable_id>": {
"unit": "fraction",
"low": 0.10,
"base": 0.20,
"high": 0.30,
"rationale": "Short, ≤50 words. Include required disclosures when applicable.",
"source": "data" | "assumption",
"sampling_discipline": "fraction",
"non_negative": true,
"default_pass_probability": null
}
}
Top-level is a single object keyed by variable id. Order keys roughly by importance (critical → high → medium → remaining missing values). Use "source": "data" only when the range is anchored in a citable real-world reference for similar programs; otherwise "assumption".
Each entry MUST carry a sampling_discipline chosen by the LLM based on the variable's nature. Downstream consumers (run-scenarios, monte-carlo runner) read this tag directly and do not pattern-match on unit strings — so the LLM is the single authority for this classification.
| Value | Meaning | Downstream behavior |
|---|---|---|
"fixed" | low == base == high; genuinely pinned | Always return that value |
"bernoulli_gate" | Binary pass/fail (staged funding, permit toggle, regulatory pass, conditional release). Requires default_pass_probability ∈ [0, 1] | Bernoulli draw; low on fail, high on pass |
"integer" | Countable units — people, households, sites, kits, days, … | Sample continuously, round, re-clamp to [low, high] |
"fraction" | Bounded fraction in [0, 1] | Clamp draws to [0, 1] |
"continuous" | Real-valued; no rounding, no extra clamping beyond [low, high] | Plain triangular/uniform draw |
non_negative is independent of discipline: set true when the variable cannot legitimately go below zero (continuous monetary amounts, counts, capacities); set false only when negative values are physically meaningful (a delta or net change variable).
default_pass_probability is required (a number in [0, 1]) when sampling_discipline == "bernoulli_gate" and MUST be null for every other discipline.
If no variable needs bounds, return {}.
| Mistake | Fix |
|---|---|
| Bounding every variable, including known explicit facts | Skip explicit/derived key_values with low uncertainty — they are facts, not assumptions |
Returning low == base == high for variables with real uncertainty | Give a real range; identical bounds are only for genuinely pinned KPI commitments |
Wrapping output in ```json fences | Raw JSON only |
Including derived_questions or recommended_first_calculations ids | Those are outputs/questions, not bounded inputs |
| Inventing ids that are not declared in the parameter JSON | Every key must correspond to a declared id in key_values or missing_values_to_estimate |
Picking fractions outside [0, 1] (e.g. base 1.5 for a rate) | Clamp to the unit's natural range |
Ignoring the parameter's uncertainty and giving everything the same ±20% spread | Anchor the spread on the parameter's stated uncertainty level |
| Rationale cites a numbered artifact (Risk N, Issue N, Decision N) that does not substantively support the claim | Re-read the cited artifact. The number must match content, not just exist in the report. If you cannot find a substantively correct citation, drop the citation and mark source: "assumption". |
Shifting actual_X base past the X_target threshold without a report-internal anchor | Center base at the committed value unless a named Risk / Issue / Decision / premortem / expert-criticism passage forecasts a gap between commitment and reality. "Realistic execution" and "operational drift" are not anchors. |
Generating bounds for a threshold or target variable (ids ending in _threshold, _target, _ceiling, _floor, _limit) | Thresholds enter the simulation as their stated single value. Randomising them silently changes what pass_rate measures and breaks the threshold_basis = report_explicit contract. Skip these variables. |
Triangular bounds with base = high = target on a >= target gate variable (ring-fenced reserve, segregated escrow, allocation share, KPI floor that physically cannot overshoot) | The continuous triangular CDF has zero probability mass at the exact peak — the >= 0 margin gate fails ~100% of runs even when the commitment is intact. The Critical verdict you report is a property of the bound shape, not the plan. Switch to sampling_discipline: "bernoulli_gate" with low = shortfall floor (e.g. 0 or partial-segregation amount), high = the target, and default_pass_probability = realistic execution probability of the commitment (e.g. 0.95 for a signed escrow, 0.75 for a sponsor-committed reserve, 0.5 for a contested allocation). Bernoulli returns high on pass and low on fail, so the gate cleanly tests whether the commitment was executed. |
system-prompt.txt../../README.md, Stage 4../extract-parameters-from-full/SKILL.md, ../validate-parameters/SKILL.md/tmp/extract-params-heatwave-v8.json (passes validate-parameters with valid: true)