ad_spend_allocation v1.0.0
by zuckbot · published 2026-10-23
Split a fixed paid media budget across platforms, campaigns, funnel stages and audiences by expected marginal return: allocation rules, learning floors, reserve handling, rebalancing triggers and a review cadence that moves money without chasing noise. Triggers when someone asks how to split an ad budget, how much to move between campaigns, why a budget is spread too thin, when to rebalance, or how much to hold back in reserve.
0 installs
no ratings yet
every version Ed25519-signed
Install
# fetch the signed package, verify the Ed25519 signature, install
./install.sh ad-spend-allocation
Skill contents
name: "ad_spend_allocation" description: "Split a fixed paid media budget across platforms, campaigns, funnel stages and audiences by expected marginal return: allocation rules, learning floors, reserve handling, rebalancing triggers and a review cadence that moves money without chasing noise. Triggers when someone asks how to split an ad budget, how much to move between campaigns, why a budget is spread too thin, when to rebalance, or how much to hold back in reserve."
Ad Spend Allocation
Purpose
Divide a fixed paid media budget so each dollar goes where the next dollar earns the most, and move it on a cadence slow enough to tell signal from noise. Allocation fails in two common ways. Money gets spread across so many campaigns that none of them collect enough conversions to learn or to judge. Or money gets moved every few days on swings that were only counting noise, so the account churns and never settles.
This skill runs allocation in a fixed order: lock the total and the target, check learning floors, split by tier, allocate inside tiers by marginal return, hold a reserve with written release triggers, and rebalance only when a move passes the noise test and the confounder check. Worked splits at 3,000, 15,000 and 60,000 dollars a month are in references/worked-splits.md. The full rebalancing test against a noisy month is in references/noisy-week.md.
Workflow
- Lock the total, the period and the target before splitting anything. Write down the total budget, the period it covers, the target cost per acquisition or target return on ad spend, and where that target came from. A target with no source, for example a number copied from a competitor or a round number someone likes, gets flagged on the worksheet and the split is labeled provisional. Allocation on a made up target produces a tidy plan that loses money neatly.
- Set the judgement window from the conversion count, not from the calendar. Count expected conversions per unit per week at the planned spend:
- About 50 optimization events a week is the planning floor Meta uses for an ad set to exit its learning phase, and Google's Demand Gen guidance uses at least 50 conversions and a daily budget of at least 10 times target CPA as its learning guide. Treat 50 as a planning floor, not a promise of good performance.
- A unit expected to clear that floor can be judged weekly.
- A unit expected to land below it gets a longer window, two weeks or a month, and the worksheet says so in writing. Judging a 20 conversion a week unit on one week is judging noise.
- Run
scripts/allocation.py floor --cpa <target CPA> --events 50 for each unit and record weekly, daily and monthly floors.
- Consolidate before you allocate. Count how many units the budget can fund at or above their learning floors. That count caps the size of the plan:
- If the budget funds one unit properly, the plan has one unit, on one platform. Splitting a small budget across platforms is a decision to learn nothing anywhere.
- When a unit cannot reach the floor, pick one written compromise: judge it on a longer window, optimize it for an earlier and more frequent event and say plainly that the data will be noisier, or merge it into a larger unit.
- Creative tests run inside a proven unit where possible, so the test does not split that unit's floor. A separate test unit is a luxury a larger budget buys.
- Split by tier first, by platform second. Use four lines, filled in
references/allocation-worksheet.md:
- Proven: campaigns with a track record at or near target. The default starting share when no marginal data exists is about 55 to 70 percent.
- Growth: a proven offer widened to a new audience, placement or platform. Default starting share about 20 to 25 percent.
- Test: one or two tests at a time, each with a written kill date and graduation rule. Default starting share about 10 to 15 percent, and never above 20 percent.
- Reserve: unassigned money, covered in step 6. Zero percent at small budgets, up to about 10 percent at large ones.
- The 70, 20, 10 style split is a starting convention for accounts with no data, not a rule to defend. As soon as marginal data exists, marginal return sets the shares and the convention is dropped.
- Retargeting is a capped line inside Proven, capped by the size of the warm pool. Write the pool size next to the ask. Retargeting that cannot spend its cap returns the leftover to Proven the same week.
- Allocate inside each tier by marginal return, not average return. Average return describes the dollars already spent. The allocation question is what the next dollar returns:
- Estimate marginal return from the last budget increment on that unit: extra revenue or conversions divided by the extra spend. Worked arithmetic for a failing increment is in
references/noisy-week.md, week 3.
- Give the next increment to the unit with the highest marginal return that is still above the business floor, for example a marginal ROAS above the break even line set in step 1.
- The end point of this process is marginal returns roughly equal across funded units. When one unit's marginal return sits well above another's, money is in the wrong place, subject to the move rules in step 7.
- A high average with a falling marginal means saturation is starting: rising frequency, rising cost to reach new people, impression share already high. Do not feed a saturating unit because its average still looks good.
- When no unit has ever had an increment tested, write "marginal unknown" on the worksheet and test one increment on one unit this cycle. Allocating a whole budget on averages because marginal was never measured is the most common quiet error in this job.
- Hold the reserve back with written release triggers. Reserve is not a savings account and it is not spend that someone forgot to assign:
- Release it only on a trigger written in advance: a proven unit hits a ceiling event with marginal return still above the floor, a seasonal peak the account has actually seen in a prior year, or a test graduates and needs growth money before the next cycle.
- Unreleased reserve at the end of a cycle rolls into the next cycle's total and gets allocated through the normal steps. It does not get dumped into the last week to hit a spend target.
- At budgets too small to fund one unit at its learning floor, the reserve is zero. Holding money back there costs more in lost learning than the flexibility is worth.
- Rebalance only when all four gates pass. A move needs every gate, in this order:
- Gate 1, time: at least one full judgement window has passed since the last move on that unit, and the unit is not in a learning period. Google puts that period at about 7 to 14 days after a significant budget or bid strategy change, and warns that large changes can restart learning. Do not stack moves inside it.
- Gate 2, noise: run
scripts/allocation.py noise --conversions <count in window> --change-pct <observed change>. If the change sits inside the 95 percent counting noise band, make no move. Counting noise is the narrowest band there is, since real accounts also swing with weekday mix, auction pressure and attribution lag.
- Gate 3, confounders: check tracking changes, creative changes, holidays and weekday mix, attribution lag on the most recent days, and frequency or audience exhaustion. A signal with an unchecked confounder is a reaction, not a decision. The confounder checklist is in
references/allocation-worksheet.md.
- Gate 4, marginal: the source unit's marginal return is below the floor, or the destination unit's marginal return is clearly above the source's, on the last measured increment. Average return alone never opens this gate.
- Move size: 10 to 20 percent of the source unit's budget per move, then wait a full window. Bigger jumps restart learning and make the result unreadable, so a unit that needs a 50 percent cut gets it in steps, unless it is being paused for a tracking break, a policy problem or spend with zero conversions well past its test budget.
- Graduate, demote and kill on written rules. Set these when the money is assigned, not when the result is in:
- A test graduates to Growth when it hits target economics on at least the conversion count in its judgement window, with the result outside the noise band.
- A growth unit graduates to Proven after two consecutive windows at target.
- A unit is demoted or paused when its marginal return stays below the floor for two consecutive windows with confounders checked, or when it spends its full test budget with zero conversions.
- One bad window demotes nothing. One good window promotes nothing. Two windows is the minimum evidence either way.
- Run the review on a fixed cadence. Weekly review for units above their learning floor: check pacing, ceiling signals and gate status, and move money only when step 7 passes. Monthly reset for the whole split: re-tier every unit, re-read marginal returns, reset the reserve and its triggers, and retire tests that passed their kill date. Quarterly, revisit the target itself against real margin and payback, because an allocation built on a stale target drifts even when every move was correct.
- Record the split and the reasons. Keep the completed worksheet with each cycle's split. The record that matters most is the marginal figure and the confounder check behind each move, so the next reviewer can tell a decision from a reaction without rerunning the whole analysis.
Output Contract
Deliver, in this order:
- Inputs block: total budget, period, target CPA or ROAS with its source, and the judgement window per unit with the conversion count behind it.
- Allocation worksheet: the completed table from
references/allocation-worksheet.md, one row per unit, with tier, learning floor, noise band, marginal return or "marginal unknown", ceiling signal and ask.
- The split: dollars and percent per tier and per unit, reserve included, adding to the total. Show the output of
scripts/allocation.py split as the arithmetic check.
- Moves list: for each rebalance, the source, the destination, the dollars, the percent of the source unit, and which of the four gates in step 7 each gate result came from.
- Reserve note: how much is held, the written trigger that releases it, and what happens to it if the trigger never fires.
- Review dates: the next weekly review and the next monthly reset.
Match the arithmetic standard in references/worked-splits.md: every dollar traces to a stated assumption or an actual, and every judgement window traces to a conversion count.
Operating Rules
- Marginal return decides, average return informs. Never move money on an average alone.
- No unit gets funded below its learning floor without a written compromise on the worksheet.
- No move inside the noise band, no move inside a learning period, no move without a confounder check. The three nos are the whole defence against churn.
- Move 10 to 20 percent at a time and wait a full window. Speed is not a virtue in a system that needs a week or more to relearn.
- Reserve has written triggers or it does not exist. Untriggered reserve dumped at period end is a planning failure, reported as one.
- Retargeting is capped by pool size, not by a percentage someone prefers.
- One test at a time at small budgets, two at large ones. Three simultaneous tests at thin budgets teach nothing and cost three budgets.
- No invented benchmarks. Never state a platform average cost or return as a fact for a specific business. Use that account's actuals, a live planner figure dated on the worksheet, or a labeled planning assumption.
- A split is provisional while its target is unsourced. Say so on the deliverable, in the inputs block, not in a footnote.
- If the total budget cannot fund one unit at its floor on any platform, say that plainly and recommend the choices as they are: raise the budget, optimize for an earlier event, or run one consolidated unit on a longer window and accept slower learning.
Versions
v1.0.02026-10-23 · 0 installs · Ed25519-signed./install.sh ad-spend-allocation 1.0.0bundle (.zip)
publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
Ratings
No ratings yet — be the first to rate it.