experiment
Skill64 starsChanged 7 months agoApache-2.0View on GitHub
Design, run, and evaluate a controlled A/B test (split test) on your ad accounts with evidence discipline — one variable, a falsifiable hypothesis, a fixed window, and a per-variant outcome verdict. Use when the user asks to run an A/B test, split test, or experiment, to 'test whether X beats Y', to validate a creative-refresh or learning hunch properly, to validate a breakdown exclusion or reallocation hypothesis before acting on it, or requests A/Bテスト / スプリットテスト設計 / 実験を回したい / どちらが勝ったか評価して / 仮説を検証したい. Forces a designed experiment instead of an ad-hoc change, records the baseline in action_log, and forbids peeking-based decisions before the window closes.
27 other projects use a version of this.
Adopted by
Most recently taken up by
- SethGammon/Citadeltheir own version, first seen Nov 4, 2026
- DaeSeokSong/oh-my-ouroborostheir own version, first seen Nov 1, 2026
- Anglesite/anglesite-skillstheir own version, first seen Oct 27, 2026
- simota/agent-skillstheir own version, first seen Oct 23, 2026
- akasecurity/preflight-skillstheir own version, first seen Oct 20, 2026
- DoKu67/claude-code-skilstheir own version, first seen Oct 16, 2026
Used with
Projects with it also use cost, eval and 8 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
maxvaegaSkillcost
Estimate what Claude Cowork / Claude Code conversations would cost if run on the pay-per-token Claude API instead of the subscription. Reports token counts and cache-aware API cost in USD and EUR, for the current conversation or for the whole history (cost per conversation). Trigger when the user asks things like "how much would this conversation cost on the API", "API cost of my Cowork conversations", "token usage / token count", "cost per conversation", "/cost", or wants to compare subscription vs API pricing.
Also in 3 projects that use this
qtzx06Skilleval
Evaluate trained YOLO model accuracy with mAP metrics and per-class error analysis. Identifies failure cases for targeted improvement. Use after training.
Also in 4 projects that use this
dirienSkilldecide
Three-agent adversarial debate protocol for strategic decisions. Two advocates steelman opposing positions while a moderator identifies risks and synthesizes a binding consensus. Use when choosing between alternatives, evaluating tradeoffs, or making high-stakes decisions.
Also in 3 projects that use this
javatarzSkillwiki
Access and manage the local GitHub Wiki clone. Use this skill when you need to read wiki content (architecture, design docs, guides), update wiki documentation, check wiki status, or push wiki changes. The wiki contains high-level system design and architectural documentation.
Also in 3 projects that use this
HeshamFSSkillloop
Run a command or check on a recurring interval
Also in 3 projects that use this
VercelSkillworkflow
Creates durable, resumable workflows using Vercel's Workflow SDK. Use when building workflows that need to survive restarts, pause for external events, retry on failure, or coordinate multi-step operations over time. Triggers on mentions of "workflow", "durable functions", "resumable", "workflow sdk", "queue", "event", "push", "subscribe", or step-based orchestration.
Also in 3 projects that use this
Other versions27 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 27
- rohanpsingh/LearningHumanoidWalking★ 1.2ksame name
- SethGammon/Citadel★ 927same name
- menkesu/awesome-pm-skills★ 441same name
- ai-analyst-lab/ai-analyst★ 304same name
- simota/agent-skills★ 96same name
- sunnnybala/Rstack★ 69same name
- Kastalien-Research/thoughtbox★ 64same name
- alirezarezvani/gaios★ 37same name
- skyf0xx/gambit★ 29same name
- SethGammon/Armory★ 19same name
17 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository30 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- ad-fatigue-checkSkill
- audience-reviewSkill
- budget-pacingSkill
- budget-rebalanceSkill
- competitive-scanSkill
- creative-generateSkill
- creative-refreshSkill
- daily-checkSkill
- goal-reviewSkill
- incident-postmortemSkill
- lead-form-createSkill
- learnSkill
- monthly-reportSkill
- _mureo-amazon-adsSkill
- _mureo-google-adsSkill
- _mureo-learningSkill
- _mureo-meta-adsSkill
- _mureo-pro-diagnosisSkill
- _mureo-report-persistSkill
- _mureo-sharedSkill
- _mureo-state-schemaSkill
- _mureo-strategySkill
- onboardSkill
- rescueSkill
- search-term-cleanupSkill
- sync-stateSkill
- tracking-healthSkill
- weekly-reportSkill
The file
We split this skill into the rules it gives an agent
3 rules. 0 are common, 1 is distinctive, and 2 are very specific to this project.
0
Common
Most of the 25 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
Read ../_mureo-learning/SKILL.md first — its Observation Windows and Minimum Sample Sizes tables set the duration and sample floor this …
- Very specific: line 23
Before you start: Run the Diagnostic preamble from ../_mureo-shared/SKILL.md — load learning insights (mureo_learning_insights_get) and …
- Distinctive: line 43
If neither caveat is acceptable, recommend not running the Google Ads experiment rather than shipping a test the operator will over-trust.
“Common” is measured: kept by at least 6 in 10 of the 25 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Experiment
PREREQUISITE: Read
../_mureo-shared/SKILL.mdfor auth, security rules, output format, and Tool Selection (Read/Write on Code,mureo_strategy_*/mureo_state_*MCP on Desktop / Cowork).
Tool names below refer to the built-in platforms; a namespaced variant (see
_mureo-shared→ Namespaced built-in variants) is used with its prefix substituted.
Turn an ad-hoc change into a designed experiment. Most "we tried X and CPA moved" claims are noise — one variable was never isolated, the window was never fixed, and the decision was made by peeking. This skill enforces the discipline: a falsifiable hypothesis, exactly one variable, a success metric tied to a Goal, a pre-committed duration and sample floor, no peeking, and a per-variant verdict where inconclusive is a valid outcome.
Read ../_mureo-learning/SKILL.md first — its Observation Windows and Minimum Sample Sizes tables set the duration and sample floor this skill commits to, and its evidence lifecycle is the rulebook for the no-peeking rule below.
Prerequisites
- STRATEGY.md and STATE.json must exist (run the
onboardskill first)
Steps
Before you start: Run the Diagnostic preamble from ../_mureo-shared/SKILL.md — load learning insights (mureo_learning_insights_get) and consult advisors (mureo_consult_advisor) before drawing conclusions.
- Establish today: call
mureo_state_getfirst, on every host (including Claude Code, where you would otherwiseReadthe file) and takeserver_nowfrom its response — ISO 8601 with UTC offset, e.g.2026-07-28T10:12:33+09:00. Its date is the only source of the current date for this run: the designed window'sstart_time/end_time, theobservation_dueyou commit to in step 7, and the "has the window closed?" gate in step 9 are all measured from it. A stale date is not cosmetic here — it is how a test gets evaluated early, which is precisely the peeking failure step 8 forbids. Do not shell out (this skill must run in Bash-less headless hosts) and do not read the date off STATE.json —last_synced_at,reports.*.periodandaction_logtimestamps are history, never evidence of what day it is now. Never writeserver_nowinto STATE.json: it is a response field, and a persisted copy becomes tomorrow's stale "today". - Hypothesis intake — force a falsifiable statement. Take the hypothesis from the operator, from a
/creative-refreshfinding, or from a VALIDATED learning insight, and rewrite it into a single testable sentence with three explicit parts: variable (the ONE thing that differs), expected effect (direction + rough magnitude), and success metric (the number that decides it). Reject vague inputs ("make it better") — push back until it is falsifiable, e.g. "Video creative (variable) will lower CPA by ≥15% (effect) vs the current static image, measured on cost_per_conversion (metric)." If two things would differ, split into two experiments or drop one. - Design — one variable, tied to a Goal. Confirm exactly one variable changes between variants (creative, headline, audience, placement, bid — not several at once; confounded designs are unattributable). Set the variant count (2 is the default; more variants need proportionally more sample and duration). Bind the success metric to a specific STRATEGY.md Goal so the winner means something (a CTR win that doesn't move the Goal's CPA/CV is not a win). Derive the minimum duration and sample floor from
../_mureo-learning/SKILL.md: creative/targeting changes need a 14-day window; the metric's sample floor (CPA: ≥30 conversions/variant; CTR: ≥1,000 impressions/variant; CVR: ≥200 clicks/variant) must be reachable within the window at current traffic — if it is not, say so and either extend the window or advise against running (an underpowered test wastes spend). - Discover platforms. Identify configured platforms from STATE.json
platforms. Include any hosted official-MCP connector present in the session (e.g. TikTok, keytiktok_ads) andmcp__mureo__<plugin>_*plugin platforms — but note honestly that a true randomized split-test tool only exists for Meta below; on other platforms the experiment is a manual/approximate construction (see../_mureo-shared/SKILL.md→ Hosted-connector platforms and Plugin platforms). mureo BYOD data lives in the workspacebyod/directory and is reachable only through mureo MCP tools — do not look for raw CSVs in the project directory. - Setup — Meta (native split test). Meta has a real experiment engine. The variants are ad sets — the split-test tool references pre-existing ad sets and does not create them, so first make sure each variant exists as its own ad set (identical except for the one variable) via
meta_ads_ad_sets_list/meta_ads_ad_sets_create. In BYOD mode the list response is wrapped as{"source": "byod_import", "as_of": <import time>, "data": [...]}— take the rows fromdataand treat them as ofas_of, not as live. Then, after the approval gate (step 6), create the test withmeta_ads_split_tests_create:cells: one{name, adsets:[ad_set_id]}per variant; Meta splits traffic evenly.objectives:[{type: COST_PER_RESULT | CONVERSIONS | REACH | CPC | CPM}]— pick the type matching the Goal metric from step 2.start_time(must be in the future — i.e. afterserver_now) andend_time— honor the designed window; Meta requires ≥4 days between them.confidence_level(80–99, default 95). Do not lower it just to force a faster verdict. Inspect a running test withmeta_ads_split_tests_list/meta_ads_split_tests_get. If mureo's Meta tools are unavailable (MUREO_DISABLE_META_ADS=1aftermureo providers add meta-ads-official), fall back to the officialmeta-ads-officialhosted MCP for whatever experiment surface it exposes, and self-apply the guardrail/confirm rules yourself (mureo's PolicyGate cannot see that call).
- Setup — Google Ads (no split-test tool — honest manual paths). mureo ships no Google Ads campaign-experiment / drafts-and-experiments tool — there is no
google_ads_experiment*in the tool surface, so do not invent one. Offer the operator the two honest alternatives and require explicit acknowledgment of their caveats before proceeding:- (a) RSA asset A/B (in-ad, lowest-risk). Add the challenger headline/description alongside the control in the same Responsive Search Ad and let Google's asset rotation gather per-asset data; read the split with
google_ads_rsa_assets_analyze(per-assetperformance_label+ CTR) andgoogle_ads_rsa_assets_audit. Caveat: this is asset-level rotation, not a randomized user split — Google serves assets non-uniformly (it favors likely winners), so it is directional, not a clean controlled test. - (b) Duplicated-campaign split (campaign-level). Duplicate the campaign (
google_ads_campaigns_create+google_ads_ads_create), change only the one variable, split budget, and compare withgoogle_ads_ad_performance_report/google_ads_ad_performance_compare. Caveats: the two campaigns compete in the same auction (they can cannibalize each other), Smart Bidding re-enters its learning phase on each, and there is no traffic-randomization guarantee — confounds are larger than a Meta split test. State these plainly and get the operator to accept them. If neither caveat is acceptable, recommend not running the Google Ads experiment rather than shipping a test the operator will over-trust.
- (a) RSA asset A/B (in-ad, lowest-risk). Add the challenger headline/description alongside the control in the same Responsive Search Ad and let Google's asset rotation gather per-asset data; read the split with
- Approval gate before ANY write. Setup steps 4–5 create/mutate platform state. Apply the Confirm Before Write Operations rule from
../_mureo-shared/SKILL.md: show the full design (variants, variable, split, budget, window, success metric, sample floor) and get explicit approval before creating any ad set, split test, or duplicated campaign. Respect Operation Mode and## Guardrails(budget caps,blocked_operations); refuse a design that breaches them. - Record the design in
action_log. After the test is created, append onemureo_state_action_log_appendentry per variant (or one entry capturing all variants) withmetrics_at_action= the baseline per variant (the control's currentcpa/conversions/ctr/impressionswith theirperiod, and the challenger's starting zero/baseline),command="/experiment", asummarynaming the hypothesis, andobservation_due= the designed end date (not a default 7/14). This is the commitment device that makes step 8's no-peeking rule enforceable and lets daily-check pick the evaluation up automatically. Give every entry a display line:display_title(at most 40 characters) anddisplay_summary(at most 120) — what this action WAS, in the operator's words, as plain text with no markdown (**bold**reaches a person as asterisks). The dashboard row shows those two and stops there; the fullsummaryis drill-down only, so keep writing it as fully as the next agent needs and let the display line be the short one. Over either bound the append is refused, never truncated. - Interim rule — NO peeking-based decisions before the window closes. While the test runs, you may report interim numbers if asked, but you must refuse to call a winner or stop a variant early on them. State why: repeatedly checking and acting on a running test inflates the false-positive rate (the sequential-testing / "peeking" problem) — a lead that looks significant mid-flight reverses far more often than the confidence level implies. If a variant is causing genuine harm (runaway spend, a policy issue), that is an incident to escalate, not an experiment result — handle it via
/rescue, and mark the experiment confounded. - Evaluation — only when the window has closed. Once
observation_duehas passed — compare it againstserver_now's date from step 0, never against anotheraction_logtimestamp:- Check sample-size adequacy FIRST. Pull per-variant results (
meta_ads_split_tests_getfor Meta;google_ads_ad_performance_report/google_ads_rsa_assets_analyzefor the Google Ads paths). If any variant is below its sample floor from step 2, the result is inconclusive-underpowered — do not read the metric delta as signal. Say so and stop here (optionally extend the window if traffic allows). - Per-variant verdict. For each challenger, call
mureo_outcome_evaluate— the deterministic verdict avoids eyeballing. When the variant has its own step-7 entry, passevaluation_of= that entry's index (itsmetrics_at_actionis the baseline, so do not passbefore: refused withevaluation_of_conflicts_with_before) andafter= the variant campaign'smetricsobject frommureo_state_get, unchanged (includingperiodandfetched_at), and then append the evaluation record viamureo_state_action_log_append:evaluation_of= the same index,evaluation= theevaluationobject the tool returned, exactly as returned, andaction="Outcome evaluated"(a neutral label — the table carries the verdict, so do not restate it inaction; do not passsummary— mureo builds it from the table). When one entry captured all variants, passbefore= the variant's baseline from step 7 andafter= its final numbers instead. Cross-read Meta's ownwinner_cell_id/confidence_intervalfrommeta_ads_split_tests_getwhere present. - Declare one of three outcomes, honestly: winner (challenger beats control on the success metric, above noise, sample-adequate), no-difference (within the noise band — a real and useful result: it means the variable doesn't matter here, stop spending attention on it), or inconclusive (underpowered or confounded). Inconclusive is a valid outcome — never manufacture a winner to close the ticket.
- Check sample-size adequacy FIRST. Pull per-variant results (
- Close out. Apply the outcome (approval gate): promote the winner (shift budget to it / adopt the winning creative or copy), and stop the losing variant (
meta_ads_split_tests_endif ending a Meta study early is warranted, or pause the losing ad set / ad). Show current-vs-proposed and confirm before each mutation. - Offer to save the finding via
/learn. A closed experiment — winner, no-difference, or inconclusive-because-underpowered — is exactly the reusable know-how the knowledge base is for. Propose the generalized lesson (e.g. "Video beat static image by 22% CPA for this Persona — prefer video-first creative briefs") and, on approval, save it through the/learnflow (mureo learn add, per that skill's conventions — do not duplicate its steps here). Never record account IDs or personal data. Persist the report summary (best-effort): Call
mureo_state_report_setwithreport="experiment"and a concisesummaryobject so the read-only dashboard can render the experiment without re-running you. Follow this convention:generated_at: ISO 8601 timestamp of this run — useserver_nowperiod: the experiment window (start_time..end_time) and its status (running / evaluated)totals: the account's headline figures, using the canonical metric vocabulary —spend,conversions,cpa,ctr,clicks,impressions. This is the block the dashboard renders as figures. Raw numbers only:773957, not"¥773,957";0.0466, not"4.66%"— one of those keys carrying a string is refused, because it sits where the view reads a figure and renders as nothing. A key outside the vocabulary may ride along: it is stored, just not shown as a headline number. Omittotalsentirely if this run gathered no account-level figures.kpis: per-variant{metric_at_baseline, metric_final, verdict}and the success metric name — the breakdown, not the headline rowflags: notable items (e.g.["underpowered_variant_B", "google_ads_manual_split_caveats_accepted"])narrative: the outcome (winner / no-difference / inconclusive, with confidence) and what you propose next, at most 400 characters — the tool refuses a longer one rather than truncating it (a sentence cut in half is worse than a long one). Do not restate the figures and do not list the findings here: numbers belong intotals, findings inflags.
Reflect the FINAL state, and persist this LAST — after every
action_logentry and any winner-promotion / loser-stop you applied this run. This is best-effort: ifmureo_state_report_setis unavailable (e.g. a pure file-mode host without the context MCP), skip it silently — the rest of this skill still works.Persist the display contract (best-effort): Call
mureo_state_display_setwith what the DASHBOARD shows. This is a different audience from the summary above — STATE.json is written for the next agent, and this small bounded section is the only thing the operator's screen reads. Write it in the SAME pass as the report, from the SAME figures, and reach no new verdict here: every value below is one you already decided, and this step only renders it.source: your own skill name — REQUIRED whenever you write any section, at most 24 characters. The contract is replaced wholesale by whoever writes it last, so this is what lets the card say whose answer it is showing.generated_atis stamped by the server — do not compute it.nav_message: the ONE line the operator should act on today — where the test stands, e.g."Variant B wins on CPA — promote it and stop the control". One line, not a summary of the report.highlights: at most 3 chips, and thetonemust match the verdict you already gave —goodfor a target met or a clear win,watchfor something to keep an eye on,badfor something deteriorating. Choose the three that matter; a fourth is refused and nothing is dropped for you. Map a finding's severity to a chip tone: action → bad / watch → watch / positive → good. info does NOT become a highlight — a neutral note would spend one of the 3 chips an action or a win needed, and it is still in the report for whoever wants it.breakdown.campaigns/.adgroups: one row per entity you judged, carrying figures you ALREADY hold —spend,mcpa(the measured CPA) andtarget_cpa— plusstatefrom the closed set (target_met/improving/watch/worsening/no_data) and anoteof at most 40 characters. Usecampaignsfor the campaigns under test andadgroupsfor per-variant ad sets / ad groups; a design-only run with no results yet omitsbreakdownrather than inventing rows. Omit a figure you do not have:0states a perfect CPA rather than the absence of one, andno_datais the state for an entity with too little delivery to judge.proposals: the recommendations you did NOT carry out, one entry each —title(what to do) plusbody(why, in one line) plusdate=server_now's date asYYYY-MM-DD. Something you DID apply this run is the same entry withstatus: "done". Record each of these as a decision too —mureo_decision_recordwithstatus: "proposed", your reasoning inrationaleand the figures you judged it on inmetrics. This section is the screen and is replaced whole by the next skill that writes it; the decision record is the one that survives, and it is what stops the next session re-proposing something the operator already turned down.stated_values: label + figure chips ONLY ({"label": "…", "value": …}) — the design and the result:{"label": "variants", "value": 2},{"label": "days run", "value": 14},{"label": "CPA lift", "value": "-18%"}. No prose notes here. A sentence lands in a numeric column and the tool refuses it; anything that needs a sentence stays in the report'snarrativeabove, exactly where it goes today.
The bounds, verbatim from the tool: The dashboard reads THIS section and nothing else — keep your reasoning where it already goes. Every bound below refuses the write rather than truncating it, because a sentence cut in half is worse than a long one. nav_message: one line, at most 80 characters. highlights: at most 3 items of {tone, text}, tone one of good/watch/bad, text at most 60 characters. proposals: {title, body, status, date}, title at most 30 and body at most 80 characters, status one of proposed/done. breakdown.campaigns / breakdown.adgroups: rows of {name, spend, mcpa, target_cpa, state, note} — the three figures are raw numbers, state is one of target_met/improving/watch/worsening/no_data, note at most 40 characters. stated_values: {label, value}, label at most 24 characters and value a raw number or a string of at most 12 characters — a sentence there is refused, because it lands in a numeric column. Do NOT write the KPI funnel or the daily chart: mureo computes both from the stored totals.
Over a bound the write is REFUSED — shorten and rewrite, do not re-send the same sentence trimmed. Lead with the point and drop the connectives; a noun phrase is fine (
CPA 12% over target, notThe CPA is currently running about 12% above the target we agreed). Trimming one character at a time and calling again spends the run's context on a bound one rewrite would have met.You may not be the first writer today.
displayis REPLACED WHOLE and the last writer wins — there is no merge. Before you write it, read the current one (mureo_state_get). Of what another skill wrote TODAY, carry exactly one thing into your own write: itsproposalsthat are still live — not yet done, and not contradicted by what you just found. Everything else you write from your own run alone, because a screen assembled from two runs shows a moment that never happened. And carry over NOTHING ELSE: never copy another skill'snav_message,highlights,breakdownorstated_values, which would put its judgement under your name when you cannot vouch for it. Name yourself insourceso the screen says whose answer it is.This is best-effort: if
mureo_state_display_setis unavailable (e.g. a pure file-mode host without the context MCP), skip it silently — the rest of this skill still works.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

