skills/58-charlescoverdale-econstack/cost-benefit/SKILL.md
Cost-benefit analysis. Produces economic NPV and financial NPV side by side, with BCR, optimism bias (with mitigation), Marginal Excess Tax Burden, real-terms rebasing, WELLBY / QALY / VPF wellbeing valuation, sensitivity, switching values, EANC for unequal-life options, validation gate, and a one-line headline verdict (socially worthwhile vs financially self-sustaining). Backed by the greenbook R package (HM Treasury Green Book primitives) when available, with graceful fallback. Supports HMT Green Book, EU Better Regulation, World Bank, ADB, and Victorian HVHR. Reads a longlist markdown file directly via --from.
npx skillsauth add brycewang-stanford/Awesome-Agent-Skills-for-Empirical-Research cost-benefitInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Only stop to ask the user when: project description is missing, there are fewer than 2 options (including do-nothing), or cost / benefit magnitudes cannot be estimated. Never stop to ask about: perspective, additionality rates, stakeholder tagging, sensitivity method, output filename, or formatting. Pick sensible defaults and keep moving.
<!-- preamble: update check -->Before starting, run this silently. If it outputs UPDATE_AVAILABLE, tell the user:
"A new version of econstack is available. Run cd ~/.claude/skills/econstack && git pull to update."
Then continue with the skill normally.
~/.claude/skills/econstack/bin/econstack-update-check 2>/dev/null || true
<!-- preamble: project learnings -->
After the update check, run this silently to load prior learnings for this project:
eval "$(~/.claude/skills/econstack/bin/econstack-slug)"
~/.claude/skills/econstack/bin/econstack-learnings-read --limit 3 2>/dev/null || true
If learnings are found, apply them. When a prior learning influences a decision, note: "Prior learning applied: [key]".
Capturing new learnings: After completing this skill, log new insights via:
~/.claude/skills/econstack/bin/econstack-learnings-log '{"skill":"...","type":"...","key":"...","insight":"...","confidence":N,"source":"observed|user-stated|inferred"}'
Types: framework (preferred appraisal framework), parameter (custom overrides), data-source (preferred data), output (past report references), operational (tool/env quirks), preference (formatting/style). Confidence: 9-10 observed/stated, 6-8 strong inference, 4-5 weak. User-stated never decays; observed/inferred lose 1 point per 30 days. All data stored locally. Nothing transmitted.
After the update check, verify the parameter database is available and check staleness:
PARAMS_DIR="$HOME/econstack-data/parameters"
if [ -d "$PARAMS_DIR" ]; then
PARAM_COUNT=$(find "$PARAMS_DIR" -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
echo "PARAMS: $PARAM_COUNT files loaded from $PARAMS_DIR"
# Check for stale files (last_verified > 2 years ago)
STALE=$(find "$PARAMS_DIR" -name "*.json" -mtime +730 2>/dev/null | wc -l | tr -d ' ')
if [ "$STALE" -gt 0 ]; then
echo "PARAMS_WARNING: $STALE file(s) not updated in 2+ years. Run: cd ~/econstack-data && git pull"
fi
else
echo "PARAMS: not found. Using built-in defaults. For full parameter support: git clone https://github.com/charlescoverdale/econstack-data.git ~/econstack-data"
fi
If PARAMS_WARNING appears, tell the user which parameter files may be stale and recommend updating. Continue with the skill normally using whatever parameters are available.
<!-- preamble: safety hooks -->Safety rules for this skill:
Parameter database is read-only. Never write to, modify, or delete files in ~/econstack-data/parameters/. These are shared, versioned parameters maintained separately. If a parameter needs updating, tell the user to update the econstack-data repo.
Confirm before overwriting. Before writing an output file, check if a file with the same name already exists. If it does, ask the user: "A file named [filename] already exists. Overwrite it, or save with a new name?" Do not silently overwrite.
At the end of every skill run, report one of these statuses:
Format: STATUS: [status] | [one-line reason]
Produces a Green Book-style economic case (NPV, BCR, optimism bias, sensitivity) alongside a parallel financial case (cash flow to the sponsor, Financial NPV, payback, DSCR if debt is involved), with a one-line headline verdict telling you whether the project is socially worthwhile and financially self-sustaining.
/longlist = "Brainstorm benefits and costs"
↓
/cost-benefit = "Now monetise and compute NPV" (this skill)
↓
/business-case = "Wrap in the Five Case Model"
Default output: one clean deliverable with headline verdict, options, costs, benefits, economic case, financial case, sensitivity, and recommendation. Power users can grab just one section via --section.
/cost-benefit [project description] [options]
Examples:
/cost-benefit "New secondary school in Leeds, GBP 40m capex, 60-year appraisal"
/cost-benefit --from longlist-italy-city-greening-2026-04-10.md
/cost-benefit "Rural water project, Indonesia" --framework adb
/cost-benefit "Victorian level crossing removal" --framework au-vic
Options:
--framework <name> : uk-gb (default), eu-brg, wb, adb, or au-vic. Auto-detected from context if not set.--from <file.md> : Import project, options, costs, benefits, and Cash flow tags from a /longlist markdown file. Skips the interactive entry.--sponsor <type> : government (default), private, blended, philanthropic. Drives the financial case discount rate. Carried through from the longlist if --from is used.--section <name> : Emit only one sub-component. Options: full (default), headline, costs, benefits, economic, financial, sensitivity, stakeholder, validation. Combinable with commas.--format <type> : Output format(s). markdown (default, always generated), xlsx, word, pptx, pdf, or all. Comma-separate for multiple.--distributional : Apply Green Book Annex A4 iso-elastic welfare weights (eta = 1.3, reference = median equivalised income). Silent if not set.--stage <name> : soc (Strategic Outline Case), obc (Outline Business Case, default), fbc (Full Business Case). Drives the optimism bias uplift.--ob-mitigation <pct> : Optimism bias mitigation factor in [0, 1]. Default 0. Use 0.3 to 0.5 once an active risk register is in place. Greenbook: gb_apply_ob(mitigation = ...).--price-base <year> : Price base year for real-terms rebasing. Default = current calendar year. All cash inputs are re-based via gb_rebase() before discounting. Greenbook: gb_deflator() / gb_real() / gb_rebase().--carbon-scenario <name> : low / central (default) / high. Pulls from the consolidated DESNZ Nov-2023 series. Greenbook: gb_carbon_value().--schedule <name> : standard (default), health (1.5% baseline for QALY/WELLBY-monetised consequences only), catastrophic (3.0% for projects where catastrophic risk dominates). Greenbook: gb_stpr(schedule = ...).--horizon <years> : Override the default appraisal period (60 infrastructure / 30 programmes / 10 IT). For horizons > 30 years the kinked STPR schedule kicks in automatically.--cea : Cost-effectiveness mode. When monetisation of the dominant benefit is impossible (low-monetisability flag from /longlist), replaces BCR with cost per output unit. Greenbook: gb_cost_per_unit().--audit / --no-audit : Auto-run /econ-audit on the produced markdown at the end. Default: --audit.--validate-only : Run the validation gate against the longlist + parameters and exit with a structured report. No NPV produced. Useful in CI.| Flag | Discount rate | Optimism bias | Carbon price | VPF / VSL | VTTS | METB | Wellbeing |
|------|--------------|---------------|--------------|-----------|------|------|-----------|
| uk-gb | Kinked STPR: 3.5% y0-30, 3.0% y31-75, 2.5% y76-125, 2.0% y126-200, 1.5% y201-300 | Mott MacDonald 2002 by project type, with --ob-mitigation | DESNZ Nov-2023 single consolidated series, low/central/high | DfT TAG v2.03FC anchor 2023 = GBP 2.474m WTP, +2% real per capita growth | DfT TAG Data Book | 20% on tax-financed costs (mandatory) | WELLBY GBP 13k (2019 prices); QALY GBP 70k (2024 prices, DHSC) |
| eu-brg | 3% advanced / 5% convergence (flat) | Not used; scenario sensitivity | EU ETS + EC shadow | EUR 3.6m (DG MOVE) | EU TEN-T values | n/a | n/a |
| wb | 6% (country-specific ERR) | Not used; scenario sensitivity | WB shadow (USD 40-80/tCO2e, rising to 50-100 by 2030) | By country income group | Local shadow wages | n/a | n/a |
| adb | 9% EIRR (6% for climate / health / education per 2017 revision) | Not used; switching values mandatory | ADB shadow (USD 36.30+/tCO2e) | Country-specific | ADB shadow wages | n/a | n/a |
| au-vic | 4% infrastructure / 7% non-infrastructure (flat) | Vic DTF ILG risk allowance, P50 + P90 | Australian shadow carbon | AUD 5.4m | ATAP PV5 | n/a | n/a |
Auto-detection rules:
au-vicadbwbeu-brguk-gbCheck whether the greenbook R package is reachable through the bridge script:
GB_VERSION="$(echo '{"action":"version"}' | ~/.claude/skills/econstack/bin/econstack-greenbook 2>/dev/null)"
GB_OK="$(echo "$GB_VERSION" | python3 -c 'import sys, json; d=json.loads(sys.stdin.read() or "{}"); print("yes" if d.get("ok") else "no")' 2>/dev/null || echo "no")"
GB_OK=yes: set BACKEND=greenbook. Use the bridge for NPV / BCR / discount factors / OB / METB / VPF / QALY / WELLBY / EANC / carbon. Stash the data_versions array for the KEY NUMBERS block. All numerical claims should match gb_economic_case() to within ±0.01.GB_OK=no: set BACKEND=skill. Compute internally using the formulas below. Add a footnote to the output: "Computed without greenbook backend; install with install.packages('greenbook') or set GREENBOOK_DEV_PATH for full reproducibility and vintage stamping."Do not narrate the backend choice to the user unless they ask. Continue with Step 1.
If --from <file.md> specified: read the longlist markdown file and parse:
Skip the interactive entry and proceed to Step 2.
Otherwise: ask the user in ONE AskUserQuestion batch:
Do NOT ask perspective, referent group, distributional weights, sensitivity method, appraisal period, optimism bias rate, or discount rate. Detect sector from the description. Default:
--horizon.--ob-mitigation is set.--price-base overrides. Real-terms rebasing applied to all cash inputs before discounting (uk-gb only; greenbook gb_rebase()).standard for the main appraisal. The health schedule is applied only to QALY / WELLBY benefit lines; do not apply 1.5% to monetary or non-health benefits.Run the computations internally. Do not narrate; show results in the output. When BACKEND=greenbook, prefer the bridge over inline math — call econstack-greenbook with action appraise (or specific action for sub-computations) and read NPV / BCR / OB-adjusted streams / METB / discount factors back from JSON.
If any cash input is in a price base year other than --price-base:
rebased_value = gb_rebase(value, from = source_year, to = price_base_year)
# bridge:
echo '{"action":"appraise", ..., "base_year": <price_base>}' | econstack-greenbook
Greenbook bundles HMT's December-2025 GDP deflator. Outputs cite the deflator vintage in the KEY NUMBERS block. For non-uk-gb frameworks, the user supplies values already in the chosen base year.
When BACKEND=greenbook (uk-gb): factors come back from the appraise action; for ad-hoc factor lookup use action discount_factor. Greenbook schedules: standard (default), health (1.5% baseline; apply only to QALY/WELLBY rows), catastrophic (3.0%).
When BACKEND=skill (uk-gb), compute cumulatively across the kinked bands:
df(0) = 1.0
For t = 1 to horizon:
r = STPR(t): 3.5% (1-30), 3.0% (31-75), 2.5% (76-125), 2.0% (126-200), 1.5% (201-300)
df(t) = df(t-1) / (1 + r)
CRITICAL: cumulative compounding only. Never apply the lower rate from year 0.
For eu-brg, wb, adb, au-vic (flat rate): df(t) = 1 / (1 + r)^t.
construction_years > 1: apply S-curve weights
5-year: [0.10, 0.20, 0.30, 0.25, 0.15]
3-year: [0.20, 0.50, 0.30]
construction_years == 1: all capex in year 0.
Lookup the project category and apply the percentage from the Mott MacDonald 2002 table (greenbook: gb_optimism_bias() then gb_apply_ob(..., mitigation = ...)). Mitigation reduces the uplift proportionally:
ob_effective = ob_raw * (1 - mitigation)
adjusted_capex = capex * (1 + ob_effective)
Default mitigation = 0. Set --ob-mitigation 0.3 to 0.5 once an active risk register is in place. Typical raw uplifts: 24-44% at SOC stage, 12-24% at OBC, 3-10% at FBC. No optimism bias on opex unless the user explicitly states a duration uplift.
For eu-brg, wb, adb: skip OB; rely on scenario sensitivity. For au-vic: use Vic DTF ILG P50/P90 in place of OB.
For tax-financed costs (any cost line where the sponsor is government or where the longlist tag indicates public funding), apply 20% METB after optimism bias. Greenbook: gb_metb(rate = 0.20). Bridge action: metb.
costs_with_metb = costs_after_ob * (1 + 0.20)
This is mandatory under Green Book 2022 §5.36. Skip METB only when sponsor is private or philanthropic (no distortion from raising the funds). Show as a dedicated row in Table 2 (Costs).
When a benefit row's quantification method is one of wellby, qaly, or vpf, route the monetisation through the dedicated greenbook function rather than generic prices. These rows are also discounted on the health schedule (1.5%) when --schedule is not overridden.
WELLBY: echo '{"action":"wellby","life_satisfaction_change":0.5,"persons":1000,"years":3}' | bridge
QALY: echo '{"action":"qaly","qalys":120,"scenario":"dhsc","base_year":2024}' | bridge
VPF: echo '{"action":"vpf","year":2026,"series":"central"}' | bridge
Vintage and base year flow through to the KEY NUMBERS block.
linear ramp over N years:
benefit(i) = full_annual_benefit * (i / N) for i = 1..N
post-ramp:
benefit(i > N) = full_annual_benefit * (1 + growth_rate)^(i - N)
Default ramp: 3 years for infrastructure, 1 year for programmes. growth_rate defaults to 0; override only for programmes with documented per-capita growth (e.g. transport demand).
For uk-gb, use the consolidated central series (DESNZ Nov-2023 collapsed the historical traded / non-traded split). Override with --carbon-scenario {low|central|high}. Bridge action: carbon_npv.
phases: 'embodied' (construction years, always a cost) and 'operational' (in-use)
For each year t:
carbon_value(t) = tCO2e(t) * carbon_price(t, scenario)
NOT adjusted for additionality (global externality).
For other frameworks: EU ETS + EC shadow (eu-brg); WB shadow USD 40-80 rising to 50-100 by 2030 (wb); ADB USD 36.30+ (adb); Australian shadow carbon (au-vic).
If the counterfactual has costs (deterioration, emergency repairs, rising congestion), compute their PV. For intervention options:
NPV = PV_benefits + PV_avoided_do_nothing_costs - PV_intervention_costs
Avoided counterfactual costs count as benefits of the intervention.
Apply to all monetised benefits except: carbon (global externality), WELLBY/QALY/VPF (already net of relevant counterfactuals when computed correctly), tax-revenue items (excluded as transfers in social CBA).
adjusted_benefit = gross_benefit * (1 - deadweight) * (1 - displacement) * (1 - leakage)
PV_costs = sum over t of [adjusted_cost(t) * df(t)]
PV_benefits = sum over t of [adjusted_benefit(t) * df(t)]
Economic_NPV = PV_benefits - PV_costs
Economic_BCR = PV_benefits / PV_costs
VfM category (uk-gb only):
BCR < 1.0 -> Poor
1.0 - 1.5 -> Low
1.5 - 2.0 -> Medium
2.0 - 4.0 -> High
> 4.0 -> Very High
--distributional)When set, weight cashflows by stakeholder income relative to median equivalised income, eta = 1.3 (Green Book Annex A4 iso-elastic). Bridge action: dist_weighted_npv. Add Table 8 (Distributionally weighted NPV by stakeholder group) to the output.
echo '{"action":"dist_weighted_npv","cashflow":[...],"recipient_income":[...],"eta":1.3}' | bridge
--cea)If the dominant benefit is flagged as low-monetisability on the longlist (or --cea is set), skip BCR and report cost per output unit. Greenbook: gb_cost_per_unit(). The economic NPV is still computed; only the BCR row is suppressed and replaced with cost per [unit].
If the longlist has Cash flow tags (cash_in / cash_out / non_cash), compute the financial case using only the cash items. Non-cash items (heat mortality avoided, WELLBYs, biodiversity, air quality, carbon unless credits are sold) are excluded entirely.
If the project was entered interactively without cash tags, auto-tag:
Financial discount rate by sponsor type (flat, not declining):
Financial computations:
For each year t:
Cash_inflow(t) = sum of cash_in items in year t
Cash_outflow(t) = sum of cash_out items in year t
Net_cash_flow(t) = Cash_inflow(t) - Cash_outflow(t)
Cumulative_cash_flow(t) = Cumulative_cash_flow(t-1) + Net_cash_flow(t)
Financial_NPV = sum over t of [Net_cash_flow(t) / (1 + r_financial)^t]
Total_funding_requirement = max over t of [-Cumulative_cash_flow(t)]
(the peak financing need: how much money the sponsor must commit before any net inflow)
Payback_period = smallest t such that Cumulative_cash_flow(t) >= 0
(if never, report "Does not pay back within appraisal period")
Financial_IRR = the r_financial value that makes Financial_NPV = 0
(compute numerically; report "Undefined" if no real positive root)
DSCR (only if project involves debt): if the user or longlist specifies debt parameters, compute DSCR per year of the debt term:
For each year t in the debt term:
Operating_cash_flow_for_debt(t) = Cash_inflow(t) - (Cash_outflow(t) excluding capex and debt service)
Debt_service(t) = scheduled interest + scheduled principal per repayment profile
DSCR(t) = Operating_cash_flow_for_debt(t) / Debt_service(t)
Minimum_DSCR = min over debt term
Average_DSCR = mean over debt term
Flag if minimum DSCR < 1.2: "Minimum DSCR of [val] is below the typical 1.2x lender covenant. The project cannot support this debt structure. Reduce gearing, extend tenor, or find non-debt funding."
economic_sign = "positive" if Economic_NPV > 0 else "negative"
financial_sign = "positive" if Financial_NPV > 0 else "negative"
If economic positive AND financial positive:
"Both cases positive. Project is socially worthwhile AND financially self-sustaining. Viable for commercial or blended funding."
If economic positive AND financial negative:
"Economic case positive, financial case negative. Project is socially worthwhile but requires public subsidy, grant, or philanthropic backing. Not viable for commercial debt on standalone cash flows."
If economic negative AND financial positive:
"Economic case negative, financial case positive. Project generates cash for the sponsor but destroys social value (often through displacement or unpriced external costs). Reconsider before proceeding."
If economic negative AND financial negative:
"Both cases negative. Do not proceed on these numbers."
Run four tests and summarise in one paragraph:
Report all four in one paragraph. No multi-table sensitivity section.
EANC for unequal-life options: if the options have different appraisal periods (e.g. 30-year vs 60-year), compute the equivalent annual net cost via greenbook gb_eanc() (bridge action: eanc) and add an extra row to Table 4. Without EANC, NPVs across options of unequal life are not directly comparable; flag this explicitly if EANC cannot be computed (e.g. BACKEND=skill).
echo '{"action":"eanc","npv":42.5,"years":60,"schedule":"standard"}' | bridge
For uk-gb and au-vic projects with a clear referent group, compute:
Efficiency_NPV = PV_all_benefits - PV_all_costs
Referent_Group_NPV = PV_referent_benefits - PV_referent_costs
Non_Referent_NPV = PV_non_referent_benefits - PV_non_referent_costs
Identity: Efficiency_NPV = Referent_Group_NPV + Non_Referent_NPV
If the identity does not hold, flag a tagging error. If Efficiency NPV is positive but Referent Group NPV is negative, note prominently that value is leaking outside the referent group.
Skip for wb and adb (distributional analysis by income decile replaces referent group for those frameworks).
Before writing anything to disk, run the validation gate. The goal is to catch the well-known broken-CBA patterns that gb_validate() and /econ-audit check for, but at the source so a malformed appraisal never produces a file.
When BACKEND=greenbook: pass the appraisal spec through bridge action validate.
In all backends, enforce these checks:
uk-gb and project is investment-type.cash_in, cash_out, non_cash.--price-base year after rebasing.health schedule applied only to QALY/WELLBY rows; not to the project as a whole.If any check fails, do not write the file. Instead, print:
STATUS: BLOCKED | validation_gate_failed
Issue: [short description]
Fix: [pointer to the longlist field or skill flag that needs to change]
Do not fall back to a "best-effort" output. A broken CBA is worse than no CBA.
Save cba-[slug]-[YYYY-MM-DD].md with this exact structure.
<!-- KEY NUMBERS
framework: [framework]
sponsor: [sponsor]
project: [project name]
preferred_option: [name]
economic_npv_m: [val]
economic_bcr: [val]
economic_eanc_m: [val or n/a]
vfm_category: [category or n/a]
pv_costs_m: [val]
pv_benefits_m: [val]
financial_npv_m: [val]
financial_discount_rate: [val]
total_funding_requirement_m: [val]
payback_years: [val or "does not pay back"]
financial_irr_pct: [val or "undefined"]
min_dscr: [val or "n/a"]
optimism_bias_pct: [val]
ob_mitigation_pct: [val]
metb_applied: [yes|no]
metb_rate_pct: [val or n/a]
additionality_factor: [val]
distributional_eta: [val or n/a]
discount_schedule: [standard|health|catastrophic]
discount_rate_baseline_pct: [val]
appraisal_period: [val]
price_base_year: [val]
carbon_scenario: [low|central|high]
backend: [greenbook|skill]
greenbook_version: [val or n/a]
stpr_vintage: [val or n/a]
deflator_vintage: [val or n/a]
optimism_bias_vintage: [val or n/a]
metb_vintage: [val or n/a]
carbon_values_vintage: [val or n/a]
vpf_vintage: [val or n/a]
qaly_vintage: [val or n/a]
wellby_vintage: [val or n/a]
date: [YYYY-MM-DD]
-->
# Cost-Benefit Analysis: [Project name]
**Framework**: [framework] · **Sponsor**: [sponsor] · **Stage**: [stage] · **Date**: [YYYY-MM-DD]
## Headline
**Economic NPV**: [currency][val]m (at [social discount rate]% [declining|flat])
**Financial NPV**: [currency][val]m (at [financial discount rate]% flat)
**Verdict**: **[one-line verdict from Step 4]**
| | Economic case | Financial case |
|---|---|---|
| NPV | [val] | [val] |
| BCR / IRR | [BCR] | [IRR]% |
| Discount rate | [social] | [financial] |
| Includes | All items | Cash in and Cash out only |
| Interpretation | Societal welfare | Sponsor cash position |
## Options
Table 1: Options considered.
| # | Option | Description |
|---|--------|------------|
| 1 | Do Nothing | [Counterfactual: what happens without intervention] |
| 2 | [Do Minimum] | [description] |
| 3 | [Preferred] | [description] |
The counterfactual is dynamic: it projects forward what happens without intervention, including existing trends and committed policies.
## Costs
Table 2: Cost streams ([currency] [price base] prices, discounted at [rate]).
| Cost category | Cash flow | Undiscounted ([currency]m) | OB raw / mitigated | METB | Adjusted ([currency]m) | PV ([currency]m) |
|--------------|:---------:|---------------------------:|-------------------:|-----:|----------------------:|------------------:|
| Capital | Cash out | [val] | [X]% / [Y]% effective | +20% | [val] | [val] |
| Operating | Cash out | [val] | 0% | +20% | [val] | [val] |
| [Other] | [tag] | [val] | [val]% | [+20% or n/a] | [val] | [val] |
| **Total** | | **[val]** | | | **[val]** | **[val]** |
The METB column is `+20%` for tax-financed (government / blended) costs and `n/a` for private / philanthropic sponsors. Set to `n/a` for non-uk-gb frameworks.
## Benefits
Table 3: Benefit streams ([currency] [price base] prices).
| Benefit category | Cash flow | Undiscounted ([currency]m) | Additionality | Adjusted ([currency]m) | PV ([currency]m) |
|-----------------|:---------:|--------------------------:|--------------:|----------------------:|------------------:|
| [Category 1] | [tag] | [val] | [X]% | [val] | [val] |
| [Category 2] | [tag] | [val] | [X]% | [val] | [val] |
| [Carbon, if applicable] | Non-cash | [val] | 100% | [val] | [val] |
| **Total monetised** | | **[val]** | | **[val]** | **[val]** |
**Non-monetised benefits** (listed qualitatively, not in the BCR):
- [Benefit with direction and estimated magnitude]
## Economic case
Table 4: Economic NPV and BCR comparison.
| Metric | Do Nothing | [Option 2] | [Option 3] |
|--------|-----------:|-----------:|-----------:|
| PV Costs ([currency]m) | 0 | [val] | [val] |
| PV Benefits ([currency]m) | 0 | [val] | [val] |
| **Economic NPV ([currency]m)** | **0** | **[val]** | **[val]** |
| **BCR** | - | **[val]** | **[val]** |
| **VfM category** | - | **[category]** | **[category]** |
[Preferred option] has an economic NPV of [currency][val]m and a BCR of [val], representing [category] value for money.
## Financial case
Only Cash in and Cash out items counted. Non-cash social benefits excluded entirely.
Table 5: Cash flow profile ([currency]m).
| Year | Cash in | Cash out | Net cash flow | Cumulative |
|------|--------:|---------:|--------------:|-----------:|
| 1 | [val] | [val] | [val] | [val] |
| 2 | [val] | [val] | [val] | [val] |
| ... | ... | ... | ... | ... |
Table 6: Financial metrics.
| Metric | Value |
|--------|------:|
| Total funding requirement (peak financing need) | [currency][val]m |
| Financial NPV | [currency][val]m |
| Financial IRR | [val]% or "Undefined" |
| Payback period | [val] years or "does not pay back" |
| Minimum DSCR (if debt) | [val] or "n/a" |
**Interpretation**: [one paragraph drawn from the verdict block, explaining the economic-vs-financial split and what it means for funding strategy]
## Sensitivity
[One paragraph covering all four sensitivity tests. Example shape: "The Economic NPV is robust under pessimistic scenario (NPV [val], BCR [val]) and remains positive at discount rates up to [X]%. The top sensitivity is [variable] (widest tornado range, [val]m span). Benefits could fall by [X]% before the NPV turns negative. The Financial NPV is [structurally negative / positive under all scenarios] and [is / is not] rescued by any plausible parameter change."]
## Stakeholder (if uk-gb or au-vic)
Table 7: Multiple account view.
| Stakeholder group | In referent group? | PV costs ([currency]m) | PV benefits ([currency]m) | Net position |
|-------------------|:-----------------:|----------------------:|--------------------------:|-------------:|
| [Local residents] | Yes | [val] | [val] | [val] |
| [Municipality] | Yes | [val] | [val] | [val] |
| [Foreign contractors] | No | [val] | [val] | [val] |
| **Referent group total** | | **[val]** | **[val]** | **[val]** |
| **Efficiency total** | | **[val]** | **[val]** | **[val]** |
Identity check: Referent Group NPV + Non-Referent NPV = Efficiency NPV. [Any deviation is a tagging error.]
## Recommendation
[One paragraph: preferred option, key conditions for proceeding (e.g. "subject to securing PNRR grant of EUR 40m"), and flags on the biggest risks from the sensitivity paragraph.]
## Next step
- `/business-case` to wrap this in the Five Case Model for a spending bid (when revived).
- `/econ-audit` to check for residual CBA errors.
That is the full default deliverable.
Alongside the markdown, write a structured cba-[slug]-[YYYY-MM-DD].json file containing the full appraisal object: every input (costs, benefits, years, framework, sponsor, schedule, base year), every parameter (OB, OB mitigation, METB, additionality, distributional eta, carbon scenario), every output (NPV, BCR, EANC, PV, optimism_bias_pct, METB applied, costs_adjusted, benefits_adjusted), and the full data_versions array from the bridge. Schema version 1.
The JSON is the structured handoff that /business-case (when revived) will consume as the Economic Case of the Five Case Model.
After Steps 7 and 7.5 complete, invoke the econ-audit skill against the produced markdown unless --no-audit is set.
Skill(econ-audit) with input: cba-[slug]-[date].md
Capture the audit's RAG counts and append to the closing message (single line: Audit: 0 RED, 1 AMBER). Do not paste the full audit into the chat. The user can re-run /econ-audit cba-[slug]-[date].md for the full report.
If RED count > 0, change the closing status from DONE to DONE_WITH_CONCERNS and include the first RED issue's headline.
Sub-component selection (via --section): emit only the requested parts. Always include the KEY NUMBERS comment and header block.
full (default): the whole structure above.headline: header + headline block only.costs: header + costs table only.benefits: header + benefits table only.economic: header + economic case only.financial: header + financial case only.sensitivity: header + sensitivity paragraph only.stakeholder: header + stakeholder table only.--section headline,financial,sensitivity.Format exports (multi-format via --format):
cba-[slug]-[date].md.xlsx in --format): invoke the xlsx skill. Workbook with sheets: Summary (headline and key numbers), Costs, Benefits, Cash flow (year-by-year), Sensitivity, Stakeholder. Blue input cells for key assumptions so the user can re-run scenarios. Save as cba-[slug]-[date].xlsx.word in --format): invoke the docx skill. One document, the full structure with cover page and hyperlinked references. Save as cba-[slug]-[date].docx.pptx in --format): invoke the pptx skill. 8 slides: (1) Problem and options, (2) Headline verdict, (3) Costs, (4) Benefits, (5) Economic NPV, (6) Financial case, (7) Sensitivity, (8) Recommendation. Action titles. Save as cba-[slug]-[date].pptx.pdf in --format): render markdown through econstack Quarto template. Save as cba-[slug]-[date].pdf.all: expand to all five formats.Tell the user (listing only files actually produced):
CBA complete. [Preferred option] NPV [val], BCR [val], VfM [category]. METB applied: [yes|no]. Backend: [greenbook|skill]. Audit: [N] RED, [N] AMBER.
Saved:
cba-[slug]-[date].md
cba-[slug]-[date].json
[other formats if requested]
Next: /econ-audit cba-[slug]-[date].md for the full audit report.
If --no-audit was set, omit the Audit: field from the headline. If BACKEND=skill, append a one-line note recommending install.packages('greenbook') for full reproducibility and vintage stamping.
uk-gb (UK HMT Green Book)gb_stpr()).--ob-mitigation is set; typical 30-50% reduction once an active risk register is in place.--price-base.health schedule (1.5% baseline) on QALY/WELLBY rows only. Monetary benefits stay on standard (3.5%).low / central / high); historical traded vs non-traded split has been retired.--distributional.eu-brg (EU Better Regulation)wb (World Bank)adb (ADB)au-vic (Victorian HVHR)--risks. Otherwise reset to 0.Cash in or Cash out on the longlist count for Financial NPV. Non-cash items are excluded entirely, no matter how large.health schedule is applied only to QALY and WELLBY rows. Do not run a whole appraisal at 1.5% just because it has a health benefit.--price-base year before discounting. Mixing 2020 and 2024 prices without rebasing is a validation-gate failure./longlist. Do not re-add them here.BACKEND=skill, mark the affected vintages as n/a and note the loss of reproducibility./longlist produces the markdown file this skill reads via --from. The Cash flow column drives the financial case; quantification methods route benefits to WELLBY / QALY / VPF / monetary./business-case (when revived in v0.15.0) will consume the sidecar JSON as the Economic Case of the Five Case Model./econ-audit runs automatically at the end (Step 8) unless --no-audit. The validation gate (Step 6.5) catches structural errors before writing; econ-audit catches presentational and methodological errors after writing.install.packages("greenbook") (CRAN) or set GREENBOOK_DEV_PATH to a local clone of https://github.com/charlescoverdale/greenbook. Provides STPR, GDP deflator, OB lookups, METB, carbon, VPF, QALY, WELLBY with bundled vintage metadata.~/.claude/skills/econstack/bin/econstack-greenbook — JSON in/out wrapper around greenbook. Returns {"ok": false, "error": "greenbook_not_installed"} cleanly when greenbook is unavailable; the skill falls back to BACKEND=skill (LLM computes the math, with reduced reproducibility).tools
Recommend AND run open-source AI tools, agents, Claude Code / Codex skills, and MCP servers for any stage of a literature review — searching, reading, extracting, synthesizing, screening, citation-checking, and paper writing. Use when the user asks "what tool should I use to..." OR "install/run/use <tool> to ..." for research/lit-review work: automating a survey or related-work section, PDF→Markdown extraction for LLMs (MinerU/marker/docling), PRISMA / systematic review (ASReview), citation-backed Q&A over PDFs (PaperQA2), wiring papers into Claude/Cursor via MCP (arxiv/paper-search/zotero servers), or chatting with a Zotero library. Ships a launcher (scripts/litrun.py) that installs each tool in an isolated venv and runs it. Curated catalog of 70+ vetted projects. 支持中英文(用于「文献综述工具选型」与「一键安装/运行」)。
development
Route empirical-research requests through the Auto-Empirical Research Skills catalog when this whole repository is installed as one skill in Codex, CodeBuddy, Claude Code, or another IDE. Use to choose and load the right vendored AERS skill for causal inference, econometrics, replication, data acquisition, manuscript writing, peer review and referee responses, citation checking, de-AIGC editing, or full empirical-paper workflows without reading the entire repository at once.
documentation
Use when the project collects primary data or runs a field, lab, or survey experiment, before the intervention begins — write the pre-analysis plan, size the sample from a power calculation, and register with the AEA RCT Registry. Apply after the design is chosen in aer-identification and before any outcome data are seen.
tools
Guide economists to authoritative data sources with explicit, confirmed data specifications before retrieval; interfaces with Playwright MCP to navigate portals and extract real data, not articles about data.