The problem
What problem does Ad campaign runbook solve?
A good blog post with a real offer in it deserves paid traffic. On LinkedIn the usual plan is a funnel: awareness, consideration, conversion, a campaign for each. At a small B2B budget that plan cannot run. The platform's daily minimum leaves money for one campaign, and a tag that records page views cannot report a conversion, however the plan words it.
So the plan has to start from the sums and from what the site can actually measure, not from the funnel someone would like to draw. Then the ads have to say only what the post says, and a marketer has to be able to run the campaign without the author in the room.
This skill gives an agent the runbook we write for every post we promote: it checks what the site measures, sizes the campaign to the budget, writes ads whose every sentence traces back to the post, and adds an organic companion post, tracking links, conversions and click-by-click Campaign Manager steps. It reads the ad account but changes nothing without a yes.
The tool
What does the skill do?
This skill adds no module to your app: your agent runs it as a tool. What Ad campaign runbook does:
- 1. A probe of what the site actually measures
- 2. A campaign structure sized by the budget and the platform minimum
- 3. Ad copy traceable to the post
- 4. An organic companion post with author-only slots
- 5. UTMs, conversions and click-by-click Campaign Manager steps
Provenance
Where do the rules come from?
This skill was written by the engineer who has shipped this work. The earlier implementation it was audited against was a LinkedIn ads runbook for a B2B marketing site with consent-gated analytics and a sign-in wall between the ad click and the conversion. The procedure holds the properties a runbook has to hold: a campaign count that follows from the budget and the platform minimum, a dated record of what the site measures, every ad claim traceable to a sentence in the post, personal facts left as slots for the person whose name goes on them, an ad account the agent reads but never changes without a yes, and a finished file with no placeholder and no fact older than the day it was handed over. `references/provenance.md` has the record.
The engineering ledger for this skill: what the audit of the earlier implementation changed and how the procedure holds it, what was kept on purpose with the reason it is safe, and what was designed here and has never been run. It is written for the person editing the skill, not for the reader of the README. Read it before simplifying anything.
The ledger separates what the audit changed, what was kept on purpose, and what has not run in production yet.
Fixed
- A funnel the budget could not feed The first plan had four campaigns, two cold audiences, a sponsored founder post and retargeting, sized for several times the budget that existed. Each would have sat near the platform's daily minimum, where a campaign cannot bid its way to a judgeable sample. Held by: campaign count is arithmetic on the daily minimum, and the default is one post, one campaign. See strategy.md.
- Tracking taken on trust The tag was installed, so conversions were taken to work. The probe found a base tag and nothing else: no conversion event anywhere, no UTM stored, tag and analytics both behind consent, and an auth redirect that rebuilt the URL before any page rendered. Held by: the probe is a mandatory step and its findings are a dated section of every runbook. See host-probe.md.
- An ad blocker read as a site defect The tag reported an error and one request failed in about a millisecond, too fast for a network round trip. The cause was the tester's own ad blocker, confirmed when the ad platform's UI showed its warning banner and rendered blank pages. Held by: the failure mode table, and the rule that all ad account work happens in a browser profile without a blocker.
- An organic post that read as a company pitch The first draft carried the link in the body, no named or dated moment, no number with a referent, three stacked lists of three, a close that pitched the link, and an instruction for colleagues to reshare at once. Held by: author slots the agent must not fill, the first-comment link rule, staggered comments in place of reshares, and an audit step before publication. See creative.md.
- Hooks that spent the visible characters on nothing One ad opened on a quoted line of jargon, so the 140 characters a phone shows carried no reason to care. Another used a "not X, your Y" contrast frame in both intro and headline. Held by: the copy rules and the 140-character print check in the creative audit.
Show 2 moreShow fewer
- Facts that went stale inside one session The sections describing the ad account and the site's code aged as conversions were created and code shipped the same day, and the post's length was written from memory and was wrong by more than a tenth. Held by: the preflight reports measured facts, and the verification step rereads the runbook against them before it is handed over.
- A page-load conversion id nearly used in a track call The account's only conversion was a URL rule, whose id an event-specific track call cannot use. Held by: the distinction, and the instruction to copy only the number an event-specific conversion issues, in conversion-tracking.md.
Non-negotiables
What are the 6 rules the module never breaks?
Every module built from this skill holds these, whoever builds it. The same list is in the skill's README and SKILL.md, so the agent reads it before it writes a line.
Never run without the post file.
Which content gets the budget is the user's decision. The preflight exits
2on a missing, non-file or non-markdown argument, and the skill stops there and asks.Never write a claim the post does not make.
Every ad sentence names the post sentence it comes from, and the post's own caveats bind the ads. The creative audit drops what has no source.
Never invent a budget, a benchmark or a fact about the author.
Budgets come from the user, planning numbers are labelled as assumptions until a post-mortem replaces them, personal facts stay as slots the author fills before publication, and an input nobody gave takes its documented default and is listed as open.
Never assume tracking works.
An installed tag records page views. The probe reads the code and one live page, dates its findings, and what is missing becomes a ticket rather than a promise.
Never change the ad account without an explicit yes for that action.
Reading a signed-in session is fine. Creating a conversion, audience or campaign accepts the advertising agreement on the user's behalf, so the skill fills the form, stops at the review step and shows what will be created.
Never leave a placeholder or a stale fact in the finished runbook.
The verification step greps for
{{and rereads the tracking, creative and build sections against what is true on the day it is handed over.
Fit
When should you use it, and when not?
Use it for
- A post with a real offer in it should get paid LinkedIn traffic.
- The host already has one campaign runbook and the next post needs the same.
- Someone asks for ad copy, UTMs or Campaign Manager steps for a specific post.
Not for
- Writing and publishing organic LinkedIn posts or commentsInsteadThe
linkedin-marketingskill. This skill drafts one companion post and hands it to that skill's audit - Boosting a Company Page post (Engagement objective, link in the first comment)InsteadThe
linkedin-boostskill - Writing the blog post itselfInstead
blog-markdownand the host's content workflow. A post with no offer in it is not a paid candidate - Meta, Google or X campaignsInsteadNot covered. The build steps are LinkedIn's, and another channel needs its own minimums, objectives and formats established first
- Creating campaigns through an ads APIInsteadThis skill produces a document for a human to execute in Campaign Manager
- Reporting on a campaign that has already runInsteadSection 9 of the template, the post-mortem, which feeds its actuals into the next runbook
Install
How do I install it?
One command. The skills.sh CLI installs the skill into every skills-compatible agent it finds.
$ npx skills add timerise-ai/ad-campaign-runbookClaude Code
Invoke with /ad-campaign-runbook
Codex CLI
Invoke with $ad-campaign-runbook
Gemini CLI
Invoke with /skills
Name the agents instead with -a, for example npx skills add timerise-ai/ad-campaign-runbook -a claude-code -a codex. Or clone the repository into your agent's skills folder. Nothing in it is agent-specific.
What is inside the repository (17 entries)
SKILL.mdEntry point: the required input, architecture, eight critical facts, six hard rules, quick start, and the reference directoryreferences/adaptation.mdThe seam with the host app: what it must provide, the rename table, integration points, where the runbook lives, another channelreferences/inputs.mdThe required post and the preflight, the inputs to ask for in one batch, and every placeholder in the templatereferences/host-probe.mdWhat the site can and cannot measure: tag, consent, conversion events, UTMs, redirects, CSP, the live check, failure modes, reading an ad accountreferences/strategy.mdBudget to structure, the budget bands, planning assumptions, audience, decision rules, cadencereferences/creative.mdOffer, proof points, angles, the five ads and their copy rules, the organic companion post with author slots, the pre-publication auditreferences/conversion-tracking.mdThe UTM convention, the conversions to create, the client-side event in TypeScript, the engineering tickets, reporting without UTM capturereferences/campaign-manager.mdClick-by-click build: account preflight, conversions, audiences, campaign group, the campaign, pre-launch checklist, gotchasreferences/runbook-template.mdThe document to produce, with fixed section numbers and every placeholderreferences/provenance.mdThe engineering ledger: what the audit changed and how the procedure holds it, what was kept on purpose, what was added hereassets/preflight.pyStdlib Python: enforces the required post and reports the measured facts the runbook is built from. Exit2means stopREADME.mdThis fileCHANGELOG.mdRelease history, newest firstCLAUDE.mdThe editing conventions, for an agent editing this repositoryLICENSEMITevals/The prompts an operator types after installing (prompts.md) and one file per agent eval: the skill installed into an empty Next.js app, one prompt carrying the post, no help, then type-checked, built and tested.github/workflows/agent-eval.ymlThe caller of the index's reusable eval workflow, run on every published release and on a maintainer's dispatch
Recent releases
- v0.1.4October 7, 2026
A wording release, from scoring the prompt-1 agent eval runs of 0.1.3.
- v0.1.3October 7, 2026
A fix release, from scoring the prompt-1 agent eval runs of 0.1.2.
- v0.1.2October 7, 2026
A fix release, from scoring the prompt-1 agent eval runs of 0.1.1 against a fidelity rubric.
After installing
What do I tell my agent?
Say what you need in your own words; the skill supplies the how. These are starting points, and the ones we tested say how it went.
Save the post below as content/blog/en/stop-confirming-bookings-by-phone.md, then write the LinkedIn ads runbook for it. We have 2,000 EUR a month, we sell to clinic and studio owners in Germany and Poland, and I will post the organic companion myself. --- title: Stop confirming bookings by phone date: 2026-09-01 author: Head of Product --- Most small clinics and studios still confirm every appointment by phone the day before. A receptionist works down a list, leaves voicemails, and marks the ones who answered. It feels like care. It is mostly lost time. [Try automatic confirmations free for 14 days](/signup). ## Where the first hour goes We looked at how front desks using our booking software spend the first hour of the day. The confirmation calls were the largest single block, larger than check-ins and larger than rescheduling. The calls also reached the fewest people: a client who books online rarely answers an unknown number at work. ## What we changed So we replaced the call with a message the client can answer in one tap. Two days before the visit they get a text and an email with three buttons: keep, move, or cancel. Keep does nothing. Move opens the calendar at the same service and the same staff member. Cancel frees the slot at once, and the waiting list gets the offer within a minute. Three things changed for the clinics that switched. The front desk got its first hour back. Cancellations arrived two days out instead of at the door, which is early enough to fill the slot. And the clients who never answered calls started answering, because a button is easier than a conversation. ## What it does not fix A client who has decided not to come will not tell you, whatever the channel. A deposit or a cancellation fee is the tool for that, and we do not think a reminder should pretend otherwise. If most of your no-shows come from new clients booking free first visits, start there. Setting it up takes about ten minutes. You choose when the message goes out, write the text in your own words, and decide whether a cancellation opens the slot to the waiting list or to everyone. Nothing changes for clients who prefer to call: the phone still works, it just stops being the only way. If your desk still starts the day with a call list, try it for two weeks and compare the first hours. [Start the free trial](/signup).
Write LinkedIn ads for our latest blog post. We can spend about 1,500 EUR a month.
No data storeHere is a short post of ours; save it as content/blog/en/new-calendar-view.md and give me the LinkedIn ad copy and the Campaign Manager steps to promote it on 600 EUR a month. --- title: A new calendar view date: 2026-09-15 --- The calendar now has a week view for each staff member. Drag an appointment to move it, and the client gets a message with the new time. [See it in the demo](/demo).
No data store
Tested
How does it do in each agent?
We install the skill into an empty Next.js app, give the agent one of the prompts above and no further help, then type-check, build and run the tests it left behind. Nothing is fixed by hand before the checks, and a failing run is published like a passing one. The procedure and every result are public, and the first prompt runs again before each release.
- Built, checks pass
Gemini CLI0.63.0
gemini-3.8-flash
Save the post below as content/blog/en/stop-confirming-bookings-by-phone.md, then write the LinkedIn ads runbook for it. We have 2,000 EUR a month, we sell to clinic and studio owners in Germany and Poland, and I will post the organic companion myself. --- title: Stop confirming bookings by phone date: 2026-09-01 author: Head of Product --- Most small clinics and studios still confirm every appointment by phone the day before. A receptionist works down a list, leaves voicemails, and marks the ones who answered. It feels like care. It is mostly lost time. [Try automatic confirmations free for 14 days](/signup). ## Where the first hour goes We looked at how front desks using our booking software spend the first hour of the day. The confirmation calls were the largest single block, larger than check-ins and larger than rescheduling. The calls also reached the fewest people: a client who books online rarely answers an unknown number at work. ## What we changed So we replaced the call with a message the client can answer in one tap. Two days before the visit they get a text and an email with three buttons: keep, move, or cancel. Keep does nothing. Move opens the calendar at the same service and the same staff member. Cancel frees the slot at once, and the waiting list gets the offer within a minute. Three things changed for the clinics that switched. The front desk got its first hour back. Cancellations arrived two days out instead of at the door, which is early enough to fill the slot. And the clients who never answered calls started answering, because a button is easier than a conversation. ## What it does not fix A client who has decided not to come will not tell you, whatever the channel. A deposit or a cancellation fee is the tool for that, and we do not think a reminder should pretend otherwise. If most of your no-shows come from new clients booking free first visits, start there. Setting it up takes about ten minutes. You choose when the message goes out, write the text in your own words, and decide whether a cancellation opens the slot to the waiting list or to everyone. Nothing changes for clients who prefer to call: the phone still works, it just stops being the only way. If your desk still starts the day with a call list, try it for two weeks and compare the first hours. [Start the free trial](/signup).
Typecheck: passBuild: passTests: not run- Time
- 6 min
- Changed
- 6 files, +685 lines
- Stack
- No data store
- Skill
- v0.1.4
- Run
- Oct 7, 2026
What we saw
Rubric 8/8, scored from the final summary. There are two campaigns, with ads
SI-01toSI-05andRT-01toRT-02. Retargeting usesutm_campaign=retargetingandutm_content=rt-01. The split is 66 EUR a day to the post campaign until the audience reaches 300, then 41 and 25. URLs are paths, the live check is recorded as not done with ticket T7, and the baseline is counted by hand. The handover ends with a list headed "Open inputs", one line per input. The post-mortem file it created up front is an extra that is not scored. - Built, checks pass
Codex CLIcodex-cli 0.161.0
gpt-6.1-sol
Save the post below as content/blog/en/stop-confirming-bookings-by-phone.md, then write the LinkedIn ads runbook for it. We have 2,000 EUR a month, we sell to clinic and studio owners in Germany and Poland, and I will post the organic companion myself. --- title: Stop confirming bookings by phone date: 2026-09-01 author: Head of Product --- Most small clinics and studios still confirm every appointment by phone the day before. A receptionist works down a list, leaves voicemails, and marks the ones who answered. It feels like care. It is mostly lost time. [Try automatic confirmations free for 14 days](/signup). ## Where the first hour goes We looked at how front desks using our booking software spend the first hour of the day. The confirmation calls were the largest single block, larger than check-ins and larger than rescheduling. The calls also reached the fewest people: a client who books online rarely answers an unknown number at work. ## What we changed So we replaced the call with a message the client can answer in one tap. Two days before the visit they get a text and an email with three buttons: keep, move, or cancel. Keep does nothing. Move opens the calendar at the same service and the same staff member. Cancel frees the slot at once, and the waiting list gets the offer within a minute. Three things changed for the clinics that switched. The front desk got its first hour back. Cancellations arrived two days out instead of at the door, which is early enough to fill the slot. And the clients who never answered calls started answering, because a button is easier than a conversation. ## What it does not fix A client who has decided not to come will not tell you, whatever the channel. A deposit or a cancellation fee is the tool for that, and we do not think a reminder should pretend otherwise. If most of your no-shows come from new clients booking free first visits, start there. Setting it up takes about ten minutes. You choose when the message goes out, write the text in your own words, and decide whether a cancellation opens the slot to the waiting list or to everyone. Nothing changes for clients who prefer to call: the phone still works, it just stops being the only way. If your desk still starts the day with a call list, try it for two weeks and compare the first hours. [Start the free trial](/signup).
Typecheck: passBuild: passTests: not run- Time
- 3 min
- Changed
- 5 files, +438 lines
- Stack
- No data store
- Skill
- v0.1.4
- Run
- Oct 7, 2026
What we saw
Rubric 8/8, scored from the transcript (gpt-6.1-sol, reasoning effort none). The handover now ends with a list headed "Open inputs / assumptions", one line per input, after what blocks launch, the live check, the author slots and the 0 to 6 range. Nothing has regressed. There are two campaigns: retargeting is built paused, then 31 EUR a day with 35 for the post campaign once past 300. The ads are named
SI-01andRT-01, withutm_campaign=retargetingandutm_content=rt-01. URLs are paths, the index entry is present, the preflight ran with--cta, and no test script was added. - Built, checks pass
Claude Code2.1.293
claude-opus-5-5
Save the post below as content/blog/en/stop-confirming-bookings-by-phone.md, then write the LinkedIn ads runbook for it. We have 2,000 EUR a month, we sell to clinic and studio owners in Germany and Poland, and I will post the organic companion myself. --- title: Stop confirming bookings by phone date: 2026-09-01 author: Head of Product --- Most small clinics and studios still confirm every appointment by phone the day before. A receptionist works down a list, leaves voicemails, and marks the ones who answered. It feels like care. It is mostly lost time. [Try automatic confirmations free for 14 days](/signup). ## Where the first hour goes We looked at how front desks using our booking software spend the first hour of the day. The confirmation calls were the largest single block, larger than check-ins and larger than rescheduling. The calls also reached the fewest people: a client who books online rarely answers an unknown number at work. ## What we changed So we replaced the call with a message the client can answer in one tap. Two days before the visit they get a text and an email with three buttons: keep, move, or cancel. Keep does nothing. Move opens the calendar at the same service and the same staff member. Cancel frees the slot at once, and the waiting list gets the offer within a minute. Three things changed for the clinics that switched. The front desk got its first hour back. Cancellations arrived two days out instead of at the door, which is early enough to fill the slot. And the clients who never answered calls started answering, because a button is easier than a conversation. ## What it does not fix A client who has decided not to come will not tell you, whatever the channel. A deposit or a cancellation fee is the tool for that, and we do not think a reminder should pretend otherwise. If most of your no-shows come from new clients booking free first visits, start there. Setting it up takes about ten minutes. You choose when the message goes out, write the text in your own words, and decide whether a cancellation opens the slot to the waiting list or to everyone. Nothing changes for clients who prefer to call: the phone still works, it just stops being the only way. If your desk still starts the day with a call list, try it for two weeks and compare the first hours. [Start the free trial](/signup).
Typecheck: passBuild: passTests: not run- Time
- 5 min
- Changed
- 3 files, +603 lines
- Stack
- No data store
- Skill
- v0.1.4
- Run
- Oct 7, 2026
What we saw
Rubric 8/8, scored from the final summary, which quotes what earlier summaries left as doubt. There are two campaigns, with ads
SI-01toSI-05andRT-01toRT-02, and the UTMs areutm_campaign=post-confirming-bookings&utm_content=si-01andutm_campaign=retargeting&utm_content=rt-01. Retargeting is built and left off until the first Monday check past 300 members. Then it gets 25 EUR a day and the post campaign 40. URLs are paths, the live check is a ticket, the baseline is counted by hand, and nothing was wired intonpm test. The final message ends with a list of the assumed and open inputs, one line each.
Generated from the skill's own files at commit f2b0337. Every rule above links to where the repository says it. All skills