audience-review
Skill64 starsChanged 7 months agoApache-2.0View on GitHub
Audit who your ads actually target and where they run, compare it against the STRATEGY.md Persona, and surface exclusions, bid adjustments, lookalikes, and placement pruning tied to that Persona. Use when the user asks to review targeting, audiences, demographics, placements, or device performance, to check whether spend matches the Persona, to find wasted placements (e.g. Audience Network with no conversions), or requests オーディエンスレビュー / 配置レビュー / ターゲティング見直し / ペルソナと配信のズレを確認 / 除外設定を提案して. Reads Persona + Target Audience from STRATEGY.md and drives the read-only targeting tools.
In this repository30 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- ad-fatigue-checkSkill
- budget-pacingSkill
- budget-rebalanceSkill
- competitive-scanSkill
- creative-generateSkill
- creative-refreshSkill
- daily-checkSkill
- experimentSkill
- 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. About 0 are common, 0 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
Before you start: Run the Diagnostic preamble from ../_mureo-shared/SKILL.md — load learning insights (mureo_learning_insights_get) and …
- Very specific: line 33
If mureo's Google Ads tools are unavailable (MUREO_DISABLE_GOOGLE_ADS=1 after mureo providers add google-ads-official), fall back to the …
- Very specific: line 39
If mureo's Meta tools are unavailable, fall back to the official meta-ads-official hosted MCP for its targeting / breakdown surface, and …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Audience Review
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.
Reconcile who you say you want (the STRATEGY.md Persona / Target Audience) with who you are actually paying to reach (the live targeting and the segments where spend lands). Accounts drift: a broad audience quietly spends on a segment the Persona excludes, a placement like Audience Network burns budget with zero conversions, or the Persona implies a lookalike that was never built. This skill inventories current targeting, scores performance by segment, flags the mismatches, and proposes Persona-anchored changes.
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: theobservation_dueyou write in step 10 isserver_now's date + 14 days. 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". - Load context: Read STRATEGY.md — especially the Persona and Target Audience (age, gender, interests, geography, device intent, exclusions the Persona implies) and each Goal's success metric — and STATE.json. The Persona is the yardstick for every judgement below; if STRATEGY.md has no Persona, say so and offer to capture one via
/onboardrather than inventing demographics. - Discover platforms: Identify configured platforms from STATE.json
platforms. Also include any hosted official-MCP connector in the session (e.g. TikTok, keytiktok_ads) andmcp__mureo__<plugin>_*plugin platforms — for those, report only the targeting surface their own tools expose and emitanalytics_not_available_for_<platform>for the segment-scoring value-adds below; do not fabricate targeting verdicts from an integration's tool schemas (see../_mureo-shared/SKILL.md→ Plugin platforms / Hosted-connector platforms). - Inventory current targeting — Google Ads (prefer mureo native):
- Demographics:
google_ads_demographic_targeting_list— explicit age / gender / parental-status / income criteria and theirnegative(excluded) flag. Remember an empty result means "all demographics, no exclusions", not "nothing targeted" — segments with no explicit criterion are targeted by default. - Audiences:
google_ads_audience_targeting_list— affinity / in-market interests, remarketing & customer-match user lists, custom / combined audiences, with theirnegativeflag. - Devices:
google_ads_device_analyzefor per-device (Desktop / Mobile / Tablet) spend, CPA, CVR and its built-in insights, plusgoogle_ads_device_targeting_get/google_ads_bid_adjustments_getfor the current device bid modifiers in place. - If mureo's Google Ads tools are unavailable (
MUREO_DISABLE_GOOGLE_ADS=1aftermureo providers add google-ads-official), fall back to the officialgoogle-ads-officialMCP for the targeting-listing surface it exposes; note the segment-scoring heuristics below still apply.
- Demographics:
- Inventory current targeting — Meta Ads (prefer mureo native):
- Custom Audiences:
meta_ads_audiences_list— id, name, subtype (WEBSITE / CUSTOM / LOOKALIKE / …), approximate_count, retention_days. - Ad-set targeting:
meta_ads_ad_sets_list— each ad set'stargeting_summary, budget, and optimization_goal (targeting lives at the ad-set level on Meta). In BYOD mode this response is wrapped as{"source": "byod_import", "as_of": <import time>, "data": [...]}— take the rows fromdataand treat them as ofas_of, not as live. - Placement & segment analysis:
meta_ads_analysis_placements(per-placement spend / CPA / CTR with keep / exclude / scale recommendations) andmeta_ads_analysis_audience(age × gender efficiency scoring). For raw slices usemeta_ads_insights_breakdownwithbreakdown=age,gender,publisher_platform,placement, ordevice_platform. - If mureo's Meta tools are unavailable, fall back to the official
meta-ads-officialhosted MCP for its targeting / breakdown surface, and self-apply the guardrail/confirm rules yourself.
- Custom Audiences:
- Performance by segment: For each platform, pull the demographic / placement / device breakdowns the tools support (step 3–4) and compute spend, conversions, CPA, and CVR per segment. Respect sample-size discipline from
../_mureo-learning/SKILL.md— a segment with a handful of clicks is not evidence of "poor CVR"; note thin segments as insufficient data, not as waste. - Mismatch analysis vs Persona: Cross-read the segment table against the Persona and flag three failure shapes:
- Contradicts the Persona: a segment spending meaningfully with poor CVR that the Persona did not call for (e.g. a 55–64 bucket eating budget when the Persona is 25–34) — a candidate exclusion or negative bid.
- Missing what the Persona implies: a high-intent segment the Persona describes that has no targeting or lookalike behind it — a coverage gap.
- Placement waste: a placement with spend and zero (or far-below-average) conversions — classically Audience Network / Search Partners — that is diluting the average.
Recommendations table — each row tied to a Persona/Goal rationale (do not execute yet):
Platform Segment / Placement Current Signal Recommendation Persona/Goal rationale Meta Audience Network on, ¥18k spend 0 conv Flag as hypothesis — validate the exclusion via /experiment (see Allocation & Learning-State Discipline) Persona converts on IG Feed; AN looks like waste, but the row is an allocation outcome Google Mobile +0% modifier CPA 1.8× Desktop −20% device bid Protect Goal CPA Meta (Persona lookalike) none — Create 1% LAL of purchasers Persona = past-buyer profile Recommendation types: exclusions, bid adjustments, lookalike creation, placement pruning. Reference past
action_logoutcomes — if a device bid adjustment was previously REJECTED as no-impact, note that before proposing it again.A breakdown average is never on its own grounds for an exclusion. Where the platform allocates delivery inside the unit automatically (Meta ad-set delivery across audiences/placements; Google Ads Smart Bidding, where manual bid adjustments are ignored except a −100% device opt-out), these rows are outcomes of that allocation, not levers — cutting an expensive-looking row shrinks the optimizer's inventory and can worsen the unit. Present such rows as hypotheses to validate via
/experiment, and act at the level the platform optimizes (a separate ad set, not a row exclusion). See../_mureo-pro-diagnosis/SKILL.md→ Allocation & Learning-State Discipline.- Approval gate before ANY write: Apply the Confirm Before Write Operations rule from
../_mureo-shared/SKILL.md— show current-vs-proposed for every change and get explicit approval. Respect Operation Mode and## Guardrails; a targeting change duringONBOARDING_LEARNING/CREATIVE_TESTINGis discouraged — warn and ask before proceeding. - Execute — only the mutations mureo actually supports; everything else is an honest manual step:
- Google Ads device bid adjustments:
google_ads_bid_adjustments_update(bid_modifier 0.1–10.0; usegoogle_ads_device_targeting_setto toggle a device fully on/off at 0.0). - Meta lookalike creation:
meta_ads_audiences_create_lookalike(source_audience_id, country, ratio 0.01–0.20). - Meta ad-set targeting edits (add an exclusion, narrow a facet, swap an audience):
meta_ads_ad_sets_updatewith atargetingobject — by default it is a safe read-modify-write (supplied keys merge onto the current spec; omitted keys preserved); setreplace_targetingtrue only to replace the whole spec. - Google Ads demographic/audience criterion add/exclude and Meta placement exclusions have no dedicated mureo mutation tool — present these as a manual step in the platform UI (exact segment + action), honestly, rather than referencing a tool that does not exist. Do not fabricate a
*_targeting_updatefor demographics/audiences.
- Google Ads device bid adjustments:
- Record outcome context: For each change executed, append to
action_logviamureo_state_action_log_appendwithmetrics_at_action(the segment'sspend/conversions/cpa/cvr/ reach and theirperiod) andobservation_due14 days out fromserver_now's date (the targeting-change window from../_mureo-learning/SKILL.md), so daily-check's evidence step verifies the change helped. A pure audit with no changes still logs a summary entry (findings + mismatch table), with noobservation_due. 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. Persist the report summary (best-effort): Call
mureo_state_report_setwithreport="audience"and a concisesummaryobject so the read-only dashboard can render this review without re-running you. Follow this convention:generated_at: ISO 8601 timestamp of this run — useserver_nowperiod: the window analysed (e.g."LAST_30_DAYS")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-platform segment counts (targeted / excluded) and the worst-CPA segments vs Persona — the breakdown, not the headline rowflags: notable items (e.g.["meta_audience_network_zero_conv", "google_mobile_cpa_1.8x", "persona_lookalike_missing"])narrative: the verdict (targeting matches Persona / drift found) 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 change 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 — what the segments need, e.g."Exclude 3 loss-making placements — 42% of spend, no conversions". 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 you judged andadgroupsfor ad sets / ad groups / segments; a run that judged neither omitsbreakdownentirely rather 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".stated_values: label + figure chips ONLY ({"label": "…", "value": …}) — the segment figures you reported:{"label": "segments reviewed", "value": 14},{"label": "worst CPA", "value": 18400}. 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.

