Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Research budgeting and funding operations — study budget construction, cost per participant and per insight, burn against milestones, and portfolio prioritisation by decision value. Use when costing, tracking, or ranking research.
.claude/skills/borghei-research-finance/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 216% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 191% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 197% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 80% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 201% | 0% |
The money side of research operations: building a study budget that funds what the study will actually consume, tracking spend against delivery rather than against the calendar, and deciding which research to fund when the portfolio asks for more than the budget holds.
scrutinised line by line and a missing line item becomes unfunded work
finance partner, and sponsor asks first
buying delivery or just buying time
need supplementary funding
available
centre and needs to see decision value
planned versus actual spend by period
and the probability it changes that decision
Before generating, confirm these inputs. If any is unknown or vague, ASK — do not assume:
Stop rule: ask only the 2-3 that most change the output. If the user says "just draft it," proceed and list your assumptions at the top of the artifact.
and fixed. Most under-budgeting comes from costs sitting in the wrong block — site coordination billed as fixed rather than per site-month is the classic.
enrolled participants. Screening is charged on everyone screened.
8% is the floor below which every protocol amendment becomes a change request.
insight — those are the two numbers the funding conversation turns on.
fail. They are all cases of work the study will do and thebudget does not fund.
bashpython3 research-ops/research-finance/scripts/study_budget_builder.py \ --input research-ops/research-finance/assets/sample_budget.json \ --format text
Enrolment usually carries 40-50% of the weight; setup milestones feel important and are cheap.
the estimate at completion.
A programme at 36% spent and 24% delivered is heading for a 50% overrun, and the monthly finance report showing "on budget" will not tell you that.
bashpython3 research-ops/research-finance/scripts/burn_vs_milestone_tracker.py \ --input research-ops/research-finance/assets/sample_burn.json \ --format text
that decision wrong, and the probability the study changes the choice.
reversibility, zeroes out studies that arrive too late or inform decisions already made, and allocates the budget greedily by value per unit cost.
fail findings to the portfolio review directly. "This study informsa decision that has already been made" is a conversation worth having out loud, and the ranking alone will not force it.
bashpython3 research-ops/research-finance/scripts/portfolio_prioritizer.py \ --input research-ops/research-finance/assets/sample_portfolio.json \ --budget 400000 --format text
| Omission | Consequence | Fix | |----------|-------------|-----| | Screen failure | Screening work on non-enrolled participants is unfunded | Gross participant costs up by 1/(1 − failure rate) | | Site coordination as fixed | Understates cost of a long study | Charge per site-month for the full duration | | Close-out and reporting | Runs out of money at the least recoverable moment | Budget close-out, database lock, and the final report explicitly | | Data management | Absorbed into "IT" and then contested | Separate line, sized against participant count | | Statistics beyond the plan | Analysis is charged as an overrun | Fund the analysis plan and one round of additional analysis | | Protocol amendments | Every change becomes a change request | 10% contingency minimum | | Currency and inflation on multi-year studies | Real cost drifts above the award | Explicit escalation line on studies over 24 months |
| CPI | Meaning | Action | |-----|---------|--------| | Above 1.05 | Delivery is running ahead of spend | Verify the milestone weights are honest before celebrating | | 0.95 – 1.05 | On plan | Continue monitoring | | 0.85 – 0.95 | Drifting | Identify the driver now; it rarely self-corrects | | 0.70 – 0.85 | Materially over | Descope or seek funding — decide deliberately | | Below 0.70 | Forecast overrun above 40% | Stop and re-plan. Continuing spends the remaining budget on the same inefficiency. |
PROVEN] The single most useful number in research finance is the gap between percent spent and percent delivered. A gap above 20 points is the reliable early signal of a supplementary funding request, and it appears months before the calendar-based view shows anything wrong.
A study is worth funding to the extent that it changes a decision, and a decision is worth informing to the extent that getting it wrong is expensive.
expected decision value = decision value × P(research changes the decision)
× reversibility multiplier| Reversibility | Multiplier | Reasoning | |---------------|-----------|-----------| | Reversible in a sprint | 0.15 | A wrong choice costs one sprint to undo — information is nearly worthless | | Reversible in a quarter | 0.45 | Correctable, but at real cost | | Costly to reverse | 0.85 | Most of the decision value is genuinely at stake | | One-way door | 1.0 | Full decision value at stake |
Two studies are automatically worth zero regardless of their inputs: one informing a decision already made, and one answering after the decision deadline. Both are common, and both survive portfolio review because nobody asks the question directly.
Cost per insight is a blunt instrument and a useful one — it forces a comparison across methods that otherwise get evaluated in isolation.
| Method | Typical cost per decision-ready insight | Notes | |--------|----------------------------------------|-------| | Support ticket / call analysis | Lowest | Evidence already paid for; only analysis time | | Instrumentation analysis | Low | Assumes instrumentation exists | | Interview round (6-8 sessions) | Moderate | Recruiting and incentives dominate | | Survey (400 completes) | Moderate | Panel cost dominates; falls sharply with an owned list | | Experiment | Moderate | Engineering time is the real cost, and it is usually uncounted | | Multi-site clinical study | Highest by orders of magnitude | Regulatory and site infrastructure dominate |
RECOMMENDED] Count engineering time in experiment costs. It is the most frequently omitted research cost in product organisations, and omitting it makes experiments look free relative to studies that carry an explicit invoice.
Mistake: Building the participant budget on the enrolment target when the protocol will screen substantially more people to reach it. Why it happens: The enrolment number is the one in the protocol and the one everyone quotes. The screen failure rate lives in a different section, if it is written down at all. Instead: Gross every screening-stage cost up by 1/(1 − screen failure rate). At a 25% failure rate that is a third more screening assessments than the enrolment target implies — and screening is real clinical work on real people that someone has to pay for.
Mistake: A monthly report showing spend versus planned spend, with no delivery measure alongside it. Why it happens: Spend and calendar are both easy to measure and both come from finance systems automatically. Delivery requires someone to assess milestone completion honestly. Instead: Weight the milestones, assess completion each period, and report the spend-delivery gap as the headline. A study spending exactly to plan while enrolling at half rate looks perfectly healthy on a calendar view and is heading for a large overrun.
Mistake: Assigning heavy weights to setup milestones — protocol approved, ethics obtained, first site activated — so the programme shows 40% delivered before a single participant is enrolled. Why it happens: Setup milestones are discrete, visible, and satisfying to complete. Enrolment is a long grind with no natural checkpoints. Instead: Weight by share of actual work and cost. Enrolment typically deserves 40-50% of the total weight. Front-loaded weights hide exactly the problem earned-value tracking exists to expose, and they hide it during the window when descoping is still possible.
Mistake: Funding the cheap studies first because more of them fit in the budget. Why it happens: Cost is known precisely and decision value is an estimate, so the ranking gravitates to the number that feels solid. Instead: Rank by expected decision value per unit cost. A rough estimate of decision value beats no estimate — it at least surfaces the studies costing more than the decision is worth. Funding by cost systematically starves the expensive studies attached to the largest decisions, which is precisely backwards.
Mistake: A study that will report after the choice has been committed, kept in the portfolio to validate it. Why it happens: The work was scoped when the decision was still open, and cancelling it feels like admitting the decision was made prematurely. Instead: Ask directly, at every portfolio review, whether each study's decision is still open and what result would change it. If nothing would, cut the study and redirect the money. This is documentation, and it should be funded as documentation if it is funded at all.
| File | Purpose | |------|---------| | scripts/study_budget_builder.py | Expands unit costs into line items, applies screen-failure grossing, contingency, and overhead; reports unit economics | | scripts/burn_vs_milestone_tracker.py | Earned-value tracking of spend against milestone delivery, with completion forecast and overrun warning | | scripts/portfolio_prioritizer.py | Ranks studies by expected decision value per unit cost and allocates a fixed budget | | references/research-cost-models.md | Cost structures by method, unit-cost drivers, cost-per-insight modelling, common omissions | | references/funding-and-portfolio-allocation.md | Funding sources, grant budget conventions, value-of-information method, portfolio governance | | assets/study-budget-template.md | The budget document a funding request ships in | | assets/sample_budget.json | Runnable input for the budget builder | | assets/sample_burn.json | Runnable input for the burn tracker | | assets/sample_portfolio.json | Runnable input for the portfolio prioritiser |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 33,010 | 23,653 | -28% | 1 | 1 | 0% | 2,225 | 7,020 | +216% | 0 | 0 | — |
case-02 | pass→pass | 15,290 | 21,593 | +41% | 1 | 1 | 0% | 3,108 | 7,198 | +132% | 0 | 0 | — |
case-03 | fail→pass | 16,841 | 30,700 | +82% | 1 | 1 | 0% | 3,193 | 9,279 | +191% | 0 | 0 | — |
case-04 | pass→pass | 11,874 | 9,890 | -17% | 1 | 1 | 0% | 2,098 | 4,788 | +128% | 0 | 0 | — |
case-05 | pass→pass | 13,201 | 11,329 | -14% | 1 | 1 | 0% | 2,185 | 4,867 | +123% | 0 | 0 | — |
case-06 | pass→pass | 14,509 | 11,661 | -20% | 1 | 1 | 0% | 2,045 | 4,724 | +131% | 0 | 0 | — |
case-07 | pass→pass | 11,916 | 11,968 | +0% | 1 | 1 | 0% | 2,028 | 4,929 | +143% | 0 | 0 | — |
case-08 | pass→pass | 11,429 | 9,401 | -18% | 1 | 1 | 0% | 1,958 | 4,332 | +121% | 0 | 0 | — |
case-09 | fail→pass | 8,712 | 13,538 | +55% | 1 | 1 | 0% | 1,802 | 5,349 | +197% | 0 | 0 | — |
case-10 | pass→pass | 5,647 | 5,478 | -3% | 1 | 1 | 0% | 1,011 | 3,905 | +286% | 0 | 0 | — |
case-11 | fail→fail | 15,678 | 14,212 | -9% | 1 | 1 | 0% | 2,309 | 5,276 | +128% | 0 | 0 | — |
case-12 | pass→pass | 9,354 | 7,094 | -24% | 1 | 1 | 0% | 1,374 | 4,145 | +202% | 0 | 0 | — |
case-13 | fail→pass | 13,129 | 4,626 | -65% | 1 | 1 | 0% | 2,093 | 3,773 | +80% | 0 | 0 | — |
case-14 | pass→pass | 10,741 | 11,903 | +11% | 1 | 1 | 0% | 1,848 | 4,848 | +162% | 0 | 0 | — |
case-15 | pass→pass | 11,847 | 9,631 | -19% | 1 | 1 | 0% | 1,700 | 4,472 | +163% | 0 | 0 | — |
case-16 | pass→pass | 14,153 | 13,379 | -5% | 1 | 1 | 0% | 2,095 | 4,974 | +137% | 0 | 0 | — |
case-17 | pass→pass | 10,387 | 2,759 | -73% | 1 | 1 | 0% | 1,557 | 3,410 | +119% | 0 | 0 | — |
case-18 | fail→fail | 15,861 | 29,511 | +86% | 1 | 1 | 0% | 2,903 | 8,563 | +195% | 0 | 0 | — |
case-19 | fail→fail | 14,287 | 13,342 | -7% | 1 | 1 | 0% | 2,243 | 5,070 | +126% | 0 | 0 | — |
case-20 | fail→fail | 14,237 | 18,384 | +29% | 1 | 1 | 0% | 2,465 | 6,051 | +145% | 0 | 0 | — |
case-21 | fail→pass | 8,848 | 5,556 | -37% | 1 | 1 | 0% | 1,269 | 3,816 | +201% | 0 | 0 | — |
case-22 | fail→pass | 10,004 | 3,035 | -70% | 1 | 1 | 0% | 1,485 | 3,560 | +140% | 0 | 0 | — |
case-23 | pass→pass | 13,916 | 11,759 | -16% | 1 | 1 | 0% | 2,015 | 4,742 | +135% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 22 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +26 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.