---
name: "weekly-content-opportunity-radar"
description: Turn social conversations into validated content opportunities — read Planable Social Listening mentions, find the recurring signals, then check each against SE Ranking organic and AI-search data. Produces up to three scored opportunities (recurring friction, industry question, emerging trend), each with a create/expand/refresh/repurpose/monitor/skip decision, a channel — article, social or both, set by where the citations and conversation are — and a ready-to-execute brief. Use whenever someone asks to run the weekly radar or wants this week's content opportunities, asks what to write or post next, asks to turn social listening or brand mentions into content, mentions an opportunity radar or a social-to-search workflow, asks what people are complaining about that you should cover, wants to check whether a social conversation also shows up in organic or AI search, or wants to fill a calendar from real demand. Also trigger when someone pastes social mentions and asks if the topic is worth writing about.
---

# Weekly Content Opportunity Radar

This skill identifies what people are already saying across social media channels, finds the
recurring patterns inside those conversations, then checks whether each pattern also exists in
organic and AI search before recommending anything.

The sequence is fixed and the order matters. Social tells you what people are talking about. Search
tells you how far that interest travels and whether anyone already owns it. Neither alone justifies
a piece of content — and neither decides, on its own, where the answer should go.

```
Listen (Planable) → identify signals → validate (SE Ranking) → check coverage, owned pages and social
→ score → decide the verb and the channel → brief
```

This file is self-contained. The four appendices at the end hold everything the phases refer to —
signal detection, scoring, the report structure and the brief template. There are no external
reference files to load, and nothing here should be duplicated into one.

## The core discipline

**Tracked keywords are not content ideas.** A keyword is the net that collects conversations. The
signal is the pattern *inside* the collected conversations — a frustration, a question, a shifting
behaviour that nobody configured as a keyword. If the output hands the tracked keyword back to the
user as the opportunity, the run has failed.

**The answer is not always a page.** Social is an input to this skill and it is also a place to act.
Community and video sources — Reddit, YouTube, LinkedIn — carry a large share of the citations that
AI answers are assembled from, so a topic can be worth entering without a blog post being the way in.
When the conversation is live in a thread this week, the honest recommendation is often to show up in
that thread, not to expand a page and wait a quarter to rank. Every opportunity therefore carries two
decisions: the **verb** (create, expand, refresh, repurpose) and the **channel** (article, social, or
both). Routing everything to a URL because the coverage check only looked at URLs is the failure this
principle exists to stop.

**Every number traces to a tool call.** Never estimate mention counts, search volume, or AI
visibility figures. If a layer is unavailable — no AI-search data for the market, listening not
configured, no competitor keywords tracked — write "not available" and cap the score as described in
**Appendix B**. A missing layer is a finding, not a gap to fill with a plausible number.

**Distinct authors, not mention volume, measure strength.** Twelve mentions from two accounts is one
person repeating themselves plus a reply. Three mentions from three unrelated authors in three
separate threads is a pattern. Always report author counts alongside mention counts.

**Three slots, not three findings.** The report has three signal types. If a type has no qualifying
signal this run, say so with the counts that fell short. Two real opportunities and one honest blank
beats three where one is padding — this skill exists to stop content being made for no reason, and
inventing a third opportunity to fill the table is that same failure wearing a report layout.

## Phase 0 — Parameters

Collect these before calling anything. Ask for whatever is missing in one round rather than one at
a time:

| Parameter | Notes |
|---|---|
| Planable workspace | Resolve with `Planable:list_workspaces`; the brand or client whose listening pool you read |
| Brand domain | The site that would publish the content, e.g. `example.com` |
| Competitors | 2–5 domains + brand names, for AI-search and SERP comparison. **Always ask — never pick these yourself.** See below |
| Market | SE Ranking `source` code — lowercase alpha-2, and note SE Ranking uses `uk`, not `gb` |
| Window | 7 days of **available** data, compared with the 7 days before that. Derive it from the data, never from today's date — see below |

If the workspace tracks no listening keywords, stop and say so. There is nothing to listen to, and
the rest of the pipeline would be invention.

**The competitor set is the user's call, and it is a gate.** Do not infer it from the mention feed,
from whoever dominates the category, or from whichever domain is most likely to return data. Who
counts as a competitor is a commercial judgement the user holds and you do not: the loudest vendor in
a market is often one the brand has deliberately decided not to compete with, and measuring against
it produces a gap number that looks alarming and means nothing. If the user hasn't named competitors,
ask before Phase 1 and wait. If they don't know, offer candidates drawn from `DATA_getDomainCompetitors`
on the brand domain plus any competitor names tracked as listening keywords, and let them choose —
proposing a shortlist is fine, adopting one silently is not. Every comparison in the final report
names the competitor set and attributes it to the user.

Some SE Ranking tools referenced below load on demand. If a tool name is not yet available, call
`tool_search` for it rather than guessing at parameter names.

### Connector and data-availability check

- **Planable:** `list_workspaces`. On failure: "The Planable connector isn't responding — please
  reconnect it before we continue."
- **SE Ranking:** `DATA_getSubscription`. On failure: "The SE Ranking connector isn't responding —
  please reconnect it before we continue. Setup guide: https://seranking.com/api/integrations/mcp/"

A response is not the same as a usable plan. Read the payload rather than checking that it arrived:
if the subscription reports an expired, lapsed or trial status, or the remaining units will not
cover a full run, say so now — "search validation limited: the SE Ranking plan reports expired" —
and carry that line into the report. Calls often still succeed on an expired plan while returning
partial data, which is worse than failing outright, because the scores come back looking complete.

Market coverage is the second thing to establish. AI-search data does not exist for every market.
Probe it once with `DATA_getAiSearchOverview` on the brand domain before Phase 3 depends on it. If
the market returns nothing, the AI dimension is capped as described in **Appendix B** and the report
says "AI-search data not available for [market]" instead of scoring around the hole.

Continue once Planable responds and you know which of the search layers you actually have.

## Phase 0.5 — Keyword health gate

Run this before Phase 1, every run. It is the difference between a report that says "nothing
qualified" and a report that says why.

This skill reads whatever keywords the workspace happens to track, and a run is only ever as good as
that set. Three keyword faults produce an empty run that looks identical to a quiet market:

- **Collision.** The keyword is also an everyday word, a ticker, or another entity, so part of the
  feed is about something else. Any product name built from a common noun behaves this way, and the
  collision is specific to that word — the only way to know what a keyword is actually collecting is
  to read a sample of its feed. Collision is a filtering problem first and a disqualifying one only
  at the extreme — see below.
- **Bulk domination.** A broad head term collects thousands of near-duplicate, near-zero-engagement
  posts a day on one platform and buries the handful of real conversations underneath them.
- **Thin authorship.** The keyword is narrow enough to be clean but collects too few distinct people
  to clear any floor.

### The check

The gate needs a keyword list and a window before it can sample anything, so it owns both. Do these
two first, once, and carry the results into Phase 1 rather than repeating the calls:

0a. `Planable:list_keywords(workspaceId)` with the `type` filter set for `brand`, `topic` **and**
   `competitor` — omitting it returns brand and topic only. Record each `keywordId`, `type` and
   `createdAt`.
0b. **Find the sync boundary before choosing any dates.** Call `Planable:get_keyword_metrics` across
   a generous span (30 days or so) per keyword and read the last date that actually carries
   mentions. That date, not today, ends the current window. Phase 1 step 2 holds the full reasoning
   and it applies here in full: a gate run against a window anchored to today samples 3–4 unsynced
   days, under-counts every keyword, and fails clean keywords for thin authorship.

Then, for each tracked keyword, before clustering anything:

1. `Planable:get_keyword_metrics_summary` over the current window — total mentions, platform split,
   engagement.
2. `Planable:list_keyword_mentions` with `limit: 100` and `hideOwnMentions: true`, and read a sample
   of the text rather than the counts alone. A collision is invisible in a count and obvious in
   three posts.

Then judge three things and record them:

| Measure | How to read it | Unusable when |
|---|---|---|
| Collision rate | Share of the sample that is not about the intended entity | Only when the on-entity subset is itself below floor — otherwise filter, don't exclude |
| Bulk share | One platform carrying most mentions at near-zero engagement with near-duplicate text | The bulk platform is most of the volume and the non-bulk pool holds under ~10 posts in the window |
| Distinct authors | Unique authors in the non-bulk pool | Fewer than 5 across the window — but see the note below before calling this a fault |

**Filtering a colliding keyword.** A collision is a reason to filter the feed, not to throw the
keyword away. Most collisions are partial — the off-entity meanings cluster on some platforms while
the real discussion of the product sits on others — so excluding the keyword wholesale discards a
usable pool and, for a competitor keyword, closes the named-competitor form of the friction signal
for no reason. Filter is the default; exclusion is the exception.

1. **Platform first, because it is free.** Split the feed by platform and read a few posts from
   each. The split is usually lopsided, and finding which way it runs costs almost nothing.
   The common pattern is that broad string matching on web and video platforms pulls the off-entity
   meanings while the product discussion sits on discussion platforms — but that is a prior to check
   per keyword, not a rule. A term that collides with a game, a ticker or a place name can invert it
   completely, and a filter applied on the assumption rather than the observation removes the signal
   instead of the noise.
2. **Read the remainder and keep only the on-entity posts.** Platform is a prior, not a verdict —
   confirm by text.
3. **Second pass: drop on-entity but promotional.** Job listings for the vendor, the vendor's own
   employees posting, affiliate and review-farm content are all genuinely about the competitor and
   none of them are signal. On-entity is necessary, not sufficient.
4. **Recount on the filtered subset only.** Distinct authors, threads and mentions are recomputed
   from what survived. A floor cleared on the raw feed and failed on the filtered subset was never
   cleared.
5. **Only then consider exclusion.** If the filtered subset is itself below the floor, the keyword
   is unusable for this run — the case where the off-entity meaning is so dominant that filtering
   leaves nothing behind. Say which it was: filtered-and-used, or filtered to nothing and excluded.

**The metrics do not get filtered, and that is the trap.** `get_keyword_metrics` and
`get_keyword_metrics_summary` compute volume and week-over-week movement on the raw polluted feed,
and no filter you apply downstream changes them. So a colliding keyword's mention count and delta
are not competitor signal and must never be reported as one — not in the decision table, not as
trend evidence, not as "mentions of [competitor] rose 30%". Report the filtered counts, label them
as filtered, and give the raw total separately if it is worth showing at all. This also means a
filtered competitor keyword cannot carry the emerging-trend slot on its delta: the trend read for it
is not measurable, for the same reason a backfilled keyword's is not.

**Bulk, in numbers.** Call a platform bulk when it carries roughly 70%+ of the keyword's mentions
*and* its median engagement is near zero *and* the sample shows near-duplicate phrasing. All three,
not one: a keyword that is genuinely most-discussed on one platform is not bulk, and demoting it on
volume alone throws away the pool. Record the percentage and the post counts either way, since that
is the line the report needs.

**Thin authorship is two different findings.** Fewer than 5 distinct authors means the keyword is
broken *or* the brand is small, and those take opposite actions. Before recording it as a fault,
re-sample the keyword over 14 days and then 30. If the author count recovers, the keyword is clean
and the brand is low-volume — carry it to Phase 1 and let the widened-window rule in Phase 2 handle
it, and say in the report which window it was measured over. Only a keyword still thin at 30 days,
or thin because collision or bulk ate the pool, is a keyword to name as unusable. Failing a small
brand's clean keyword set as a setup problem is the same error as returning a silent blank, one
layer earlier.

Then compare each keyword's `createdAt`, recorded in step 0a, to the window end:

- **Created inside the current or prior window (under ~14 days old).** No natively collected prior
  period exists, so no week-over-week comparison is possible. The trend slot is not measurable for
  this keyword — say so rather than computing a number off backfill.
- **Created 14–30 days ago.** The prior window is partly or wholly backfilled. Planable backfills
  roughly 30 days when a keyword is added, so a first-timer can run same-day against real history,
  but backfilled history is thinner than natively collected history. Mark the keyword and treat its
  trend read as provisional; Phase 2 leans that judgement on sustained distinct authors instead of
  the percentage.
- **Older than 30 days.** Normal read.

Say which keywords fell into the first two buckets in the report. A percentage delta computed
against a backfilled first week is the number most likely to be quoted back without its caveat.

### What to do with the verdict

- **All or most keywords usable:** continue to Phase 1. Name any individual failing keyword in the
  report anyway, with the reason and the fix.
- **A keyword collides:** filter it as above, cluster from the on-entity subset, and say so by name
  with both counts, in the form "'[keyword]': [N] raw mentions, [N] on-entity after filtering
  ([what was removed, and from where]), clustered from the [N]". Never let a colliding keyword's raw
  volume or delta enter a count or a trend claim.
- **A keyword is unusable:** exclude it only when filtering leaves it below the floor, or when bulk
  or thin authorship has eaten the pool. Say what it is collecting instead, naming the other meaning
  in the words the posts use — "'[keyword]' is collecting [the other meaning], not [the intended
  entity], and nothing survives the filter".
- **Too little survives to run on:** stop before Phase 1 and return the keyword diagnosis as the
  result. The stop condition is concrete — no usable topic keyword at all, or fewer than two usable
  keywords of any type, or a combined non-bulk pool under ~15 posts from under 5 distinct authors
  **measured at 30 days**, not at 7. Below any of those, Phase 1 cannot produce a cluster and
  running it only converts a fixable setup problem into a blank report. Say which keywords to
  change, to what, and that the run can be repeated as soon as they are.
- **The set is clean and the brand is simply small:** do not stop. A workspace whose keywords all
  pass collision and bulk but whose 7-day pool is thin is the low-volume case, not a broken setup.
  Run Phase 1 on the widened window per the rule in Phase 2, label the window in the report, and say
  plainly that the set is sound. Telling a small brand to fix keywords that are already correct
  sends them to change the one thing that was working.

### The seeding standard

Use this to judge a set and to propose repairs. Offer to audit the tracked keywords against it
before a first run, and reach for it whenever the health gate fails something.

- Roughly 1 brand keyword, 2–5 named competitors, 3–6 narrow topic phrases.
- Competitor keywords use the specific product name, never a word that is also an everyday noun on
  its own. Where the brand name is a common word, pair it with a category term — "[brand] app",
  "[brand] pricing" — or accept that the keyword needs filtering on every run.
- Topic keywords are multi-word phrases describing a situation, not broad heads. "social media
  approval process" collects conversations; "social media marketing" collects bots.
- Expect discussion platforms and forums to carry the signal and one high-volume platform to carry
  the bulk. Which is which varies by category and market, so confirm it in the first run rather than
  assuming it.
- A keyword whose purpose nobody can state is a keyword to drop.

## Phase 1 — Listen

1. Use the keyword list, the `createdAt` values and the window Phase 0.5 already established — they
   are inputs to this phase, not calls to repeat — and drop every keyword the gate marked unusable
   before anything else happens. The `type` filter accepts `brand`, `topic` and `competitor`, and
   omitting it returns brand and topic only, so competitor keywords have to be requested by name or
   they go unread. Competitors are sometimes tracked as topic keywords instead; check both. If no competitor
   keywords exist in either place, the **named-competitor** form of the recurring-friction signal
   cannot be produced from listening data. The slot itself stays open — the category-practice form
   runs off topic keywords — so look for that instead of substituting a different signal type. Say
   in the report which form you found, and note the absent competitor keywords as a configuration
   gap worth closing.
2. **The sync boundary — established in Phase 0.5 step 0b, restated here because everything
   downstream depends on it.** Planable's social listening data refreshes
   on a roughly 7-day cycle, so the most recent days in any range you ask for are usually empty —
   the data simply hasn't landed yet. `Planable:get_keyword_metrics` across a generous span
   (30 days or so) gives the last date that actually carries mentions. That date, not today, is
   the end of the current window. The current window is the 7 days ending there; the prior window is
   the 7 days before that. Cross-check `daysWithData` on `get_keyword_metrics_summary`: if it falls
   well short of the days you asked for, the range is padded with empty days.

   This matters because getting it wrong fabricates a decline. Anchoring to today drags 3–4 unsynced
   days into the current window and none into the prior one, so a flat topic reads as falling and a
   rising one reads as flat — and "mentions down 40%" is exactly the kind of finding that gets acted
   on. Keywords can sync on different days, so set the boundary per keyword rather than assuming one
   date covers the workspace. State the actual window dates and the sync date in the report, and
   never describe the window as "the last 7 days" when it ends several days before today.
3. For every keyword, `Planable:get_keyword_metrics_summary` twice: once for the current window, once
   for the prior window. The delta is what makes "emerging" measurable rather than asserted.

   Compute it on the de-bulked pool, and compare the platform split across both windows before
   reporting any movement at all. A swing driven by the bulk platform is a collection artifact: X
   sweeping into or out of a keyword looks exactly like a topic rising or collapsing, while the
   human conversation underneath has not moved. If the delta is bulk-driven, say so and do not print
   the percentage. A keyword created inside the current or prior window has no true prior period —
   its delta is provisional at best and usually not computable.
4. For anything rising, `Planable:get_keyword_metrics` gives the day-by-day series, which separates a
   steady climb from one viral spike.
5. `Planable:list_keyword_mentions` per keyword with `hideOwnMentions: true` — the premise is
   frustrations described by people who are not you, and your own scheduled posts would otherwise
   pollute the pool. Run it twice per keyword: `sortBy: "engagement"` for what travelled,
   `sortBy: "recency"` for what is happening now. Use `limit: 100` and page with `cursor` when
   `total` exceeds what you have read. `sentiment: "negative"` is a fast route into complaint
   signals; read the neutral pool too, since plenty of real frustration is phrased flatly.
6. **Separate the bulk before you cluster, not after.** Bot- and bulk-dominated platforms inflate
   volume with near-duplicate posts carrying almost no engagement. Identify which platform that is
   from the Phase 0.5 measurement rather than by reputation — it differs by category — then set it
   aside for topic keywords and cluster from the non-bulk pool where the discussion actually lives. De-bulking at scoring
   time is too late: by then the bulk has already decided which mentions got read and inflated the
   author counts everything downstream depends on. State in the report which pool you clustered from
   and what you set aside.

Then read the mention text. Actually read it — the per-platform payload (under `twitter`, `reddit`,
etc.) holds the author, text and url. Cluster by underlying need, not by shared vocabulary. Two
people describing "approvals take forever" and "waiting three days for the client to sign off" are
one signal in two phrasings.

Planable's sentiment labels are a filter for finding candidates, not evidence on their own. What
makes a complaint real is several unconnected people describing the same failure. Quote nothing at
length: paraphrase what people said, and keep any verbatim fragment short and clearly attributed to
the platform it came from.

## Phase 2 — Identify the signals

Produce at most one of each type. Each has an evidence floor — below the floor, the signal does not
qualify:

**Recurring friction (competitor or category practice).** A frustration with an incumbent tool,
vendor, or with the category's standard way of working, appearing across separate conversations.
Floor: 5+ mentions, 3+ distinct authors, 2+ separate threads — the 5/3/2 floor the report cites.
Both forms count equally and neither is a fallback
for the other: record either which competitor failed and how, or which common way of working is
breaking down. The category-practice form needs no competitor keywords at all — it comes out of
topic keywords — so this slot stays available even in a workspace that tracks no competitor names.
The underlying problem is the opportunity; a comparison page is rarely the right answer to it.

**Recurring industry question.** Different people working the same decision, in different words.
Floor: 5+ mentions from 3+ distinct authors asking a materially similar question. Record the
decision they are stuck on, not just the topic area.

**Emerging trend.** A topic, workflow, term or behaviour whose conversation volume is climbing.
Floor: +40% or more between the two windows in `get_keyword_metrics_summary`, **and** 10+ mentions
in the current window, sustained across 3+ days in the daily series, from 3+ distinct authors. The
absolute floor matters more than the percentage — two mentions becoming five is 150% growth and
means nothing. One spike from one account is not a trend.

These three floors are the ones in **Appendix A**, restated. Where a number here and a number there
ever disagree, Appendix A governs and this summary is the thing to correct.

**When the floors cannot be met because the brand is small.** A narrow niche or a low-volume brand
can have a clean keyword set and still produce fewer than 5 distinct authors in seven days. When the
de-bulked distinct-author count across the workspace falls below the floor, widen the window to 14
days — and to 30 if it is still short — for the friction and question signals only. State in the
report which window each signal was measured over.

**The emerging-trend slot does not widen.** It is defined by movement between two comparable 7-day
windows, and a 30-day read of the same data is a different measurement wearing the same label. For a
low-volume brand, or a keyword too young to have a real prior window, report the trend slot as not
measurable in this window with the reason, then judge on distinct authors sustained across days
rather than on a percentage. A provisional trend labelled as provisional is honest; a percentage
computed against a backfilled first week is not, and it is the one number in this report most likely
to be quoted back without its caveat.

## Phase 3 — Validate against search

Social phrasing and search phrasing differ. People vent in the first person and search in the third.
Translate each signal into 2–3 search-language seed terms before querying, and show that translation
in the report — it is the step most likely to be wrong, and a reader who disagrees with the mapping
needs to see it.

**Organic demand**
- `DATA_getRelatedKeywords` and `DATA_getKeywordQuestions` on each seed, to find how the need is
  actually phrased in search. Question keywords map directly onto both headings and AI citations.
- `DATA_getKeywordsMetrics` on the shortlist with `history_trend: true` — volume *and* direction.
  For an emerging signal, direction matters more than absolute volume.
- `DATA_getSerpResults` on the primary query to see who owns the results today and what page type
  wins. A SERP full of vendor comparison pages when people are asking a how-do-I question is a gap;
  a SERP already answering the question well is not.

**AI search**
- `DATA_getAiSearchBrand` to resolve the brand name SE Ranking attributes to the domain, then
  `DATA_getAiSearchPromptsByBrand` or `DATA_getAiSearchPromptsByTarget` for the prompts the brand
  appears in.
- `DATA_getAiSearchOverview` for brand presence, link presence and average position. Its window is a
  fixed monthly one and it ignores date-range arguments, so never describe its output as
  week-over-week movement.
- `DATA_getAiSearchLeaderboard` with the competitor set for share of voice per engine. Citation
  concentration is the useful read: if no domain holds a large share, the topic is open; if one
  does, entering costs more. Name the engines you checked.

**Where the citations come from**

Presence is half the AI read; the other half is which kind of source the engines are pulling from, and
it is what decides the channel later. For each validated signal, read the cited sources on the prompts
the topic appears in and record the split between publisher pages and community or video sources —
Reddit, YouTube, LinkedIn, forums, Q&A sites. Where an SE Ranking project exists for the domain,
`PROJECT_getAirtSourcesSummary` and `PROJECT_listAirtSourceDomains` give that breakdown directly and
`PROJECT_listAirtSourcePages` gives the individual URLs; without a project, read the source lists the
prompt queries return.

This is a finding in its own right, not colour. A topic whose citations come mostly from a subreddit
thread and two YouTube explainers is a topic where publishing a blog post is the slow route and
possibly not the route at all. Record the split as a number — "7 of 10 cited sources are community" —
and carry it into Phase 4, because that is the input the channel decision runs on. If the source
breakdown is unavailable, say so and route on the social evidence alone rather than defaulting to
article.

**Verifying a zero.** A prompt query returning nothing is ambiguous: a genuine absence and a
malformed filter look identical. Confirm it by re-running the identical query against a domain
certain to be cited — a category specialist with heavy topical content. That domain is a **control,
not a competitor**: it exists to prove the query fired, it does not join the competitor set, and its
figure is never reported as the gap the brand should close. Say in the report that the zero was
verified and against what, so nobody reads the control's number as a benchmark. If the control also
returns zero, the filter is the problem — fix it and re-run before concluding anything.

Two things these tools do not do, and must not be implied: AI prompts routinely return `volume: 0`,
which reflects conversational phrasing rather than low value, so never judge a prompt cluster by
search volume. And SE Ranking's AI-search data covers presence and citations, not sentiment — the
only sentiment in this pipeline comes from Planable, about social mentions.

## Phase 4 — Check existing coverage

Coverage has two halves, and checking only the first is what turns every opportunity into a blog
task. Run both.

**Half one — owned pages.**

- `DATA_getDomainKeywords` on the brand domain, filtered to the blog path (`filter_url`) and the seed
  terms (`filter_multi_keyword_included`) — what the site already ranks for.
- `DATA_getDomainKeywords` with `url` on any page that looks like a match, to see what that page
  actually captures versus what the signal needs.
- If Firecrawl or web search is connected, read the candidate page. Ranking for a term and answering
  the question are different things.

**Half two — social and community presence.**

- `Planable:list_posts` on the workspace, and `get_post_metrics` where the topic looks covered — has
  the brand already posted on this, on which platform, and did it travel? Own mentions were hidden
  during listening precisely so they would not inflate demand; here they are the thing being checked.
- Re-read the signal's own threads from Phase 1. Is the brand already in them, is a competitor
  answering in them, or is nobody? An unanswered thread with the brand's exact expertise in it is the
  cheapest opportunity in the report.
- Carry forward the citation-source split from Phase 3: who gets cited on this topic, publishers or
  communities — and check whether any of the brand's own social or community content is among the
  cited sources. Being cited from a Reddit answer the brand wrote is coverage; a topic where the
  brand is cited only from its own blog, on a question the engines answer from communities, is a gap
  the blog cannot close.
- Where the answer already exists as a webinar, support doc or internal thread, note it — that is
  what makes Repurpose available in either channel.

**The verb** comes from half one when the channel is article, and from half two when it is social:

| Situation | Verb |
|---|---|
| Nothing of ours targets this intent, on the channel chosen | **Create** |
| Something targets it but misses the specific need | **Expand** |
| Something covers it and has decayed or gone stale | **Refresh** |
| The answer exists in another format (webinar, doc, thread, page) | **Repurpose** |
| Signal is real but demand or winnability is not there yet | **Monitor** |
| Signal does not survive validation | **Skip** |

**The channel** is a separate decision and it is made on evidence, not habit:

| What the evidence shows | Channel |
|---|---|
| Search demand exists, citations come mostly from publisher pages, the SERP is winnable | **Article** |
| Citations come mostly from community or video sources, or the conversation is live in named threads this window, or search volume is thin while social evidence is strong | **Social** |
| Real search demand *and* live threads — the usual case for a strong signal | **Both**, with the social move first because it can ship this week |
| Neither: demand thin and conversation not live | Monitor, as above |

**The action** is the concrete thing someone does, and the recommendation names it rather than
stopping at the channel. The available actions, on either side:

| Channel | Actions |
|---|---|
| SEO | Create a page · expand an existing page with a named section · refresh what went stale · repurpose an existing asset into a page |
| Social | Publish a LinkedIn post · reply in a named live LinkedIn or Reddit thread · publish a Reddit contribution where the subreddit's rules allow it · record a short video · repurpose an existing asset into any of these |
| Both | One of each, written as two actions with their own owners and dates — never "publish the post and also share it", which is distribution, not a second action |

A Both is not a blog task with social attached. The social action has to stand on its own evidence
and be worth doing if the page never ships; if it does not, the honest answer was Article all along.
Say which action runs first and why — usually social, because a thread reply can ship this week and
a page cannot.

Two rules hold across both halves. Publishing a second page against an intent the site already owns
splits the intent and helps nobody — say so plainly when that is the finding. And a live thread is a
perishable asset: a Social channel recommendation names the threads and goes stale in days, so it is
the one output in this report with an expiry date on it. Say that date.

An article recommendation against a topic whose citations are 70% community is not wrong, but it is
slow, and the report has to say so rather than presenting it as the only move.

## Phase 5 — Score

Score each opportunity out of 20 across five dimensions, 0–4 each, reported in this order:
**social, demand, AI, winnability, fit**. Read **Appendix B** before scoring — it holds the
per-dimension anchors, the band table, the missing-data caps and a worked example, and it is what
makes a 14 this month mean what a 14 meant last month.

Four rules hold even if that file never gets opened:

- **Only qualifying signals get scored.** A cluster below its floor in **Appendix A**
  is not a low-scoring opportunity, it is not an opportunity. It goes to the watch list with its
  actual counts. Never let a low score do the rejecting — a 6/20 in the table reads as "weak
  opportunity" when the honest statement is "this did not qualify".
- **Missing data scores 0 and caps the total.** One dimension missing caps at 14; two or more cap at
  9. Print the uncapped total beside the capped one so the next run can tell which one bound.
- **Bands set posture, not the verb or the channel.** 16–20 act now, 11–15 act scheduled, 6–10
  Monitor, 0–5 Skip. The verb and the channel both come from the Phase 4 coverage check and nothing
  else — a 17/20 against an intent the site already owns is still Expand, and a 17/20 on a topic
  cited mostly from Reddit is still Social. A high total means the topic is worth investment; Phase 4
  says where that investment goes.
- **Score the de-bulked pool.** Bot-heavy platforms inflate mention counts with near-zero engagement,
  and a collection-side change there looks exactly like a topic collapsing. Separate the bulk
  platform out before scoring and say in the report which pool you scored.

Report the per-dimension scores, not just the total. The total is a sorting aid; the dimension that
scored low is what the team actually needs to know.

**Ordering within a band is decided by activity and citations, not by the total.** Two opportunities
that both score 14 are not equally urgent, and keyword volume is the wrong tiebreak. Order them by:

1. **Live conversation.** A signal with named threads still open this window outranks one whose
   threads closed a month ago. Perishable work goes first because it stops being possible.
2. **Citation source mix.** A topic whose citations come mostly from community sources outranks one
   answered from publisher pages, because the entry cost is days rather than a quarter.
3. **Whether we are already present.** A topic where nobody has answered outranks one where the
   brand or a competitor already has.
4. Only then, search volume and difficulty.

Ranking by keyword data alone is what produces a report that is technically correct and three weeks
too late. State the ordering rule that applied when two rows are close, so the reader can disagree
with it.

## Phase 6 — Report

Deliver in chat. No file, no Notion page, unless asked.

The structure is in **Appendix C** — header, decision table, per-opportunity detail, briefs, watch
list, and the tone rule. Follow it exactly rather than reproducing a shortened version here: a
second copy of the structure drifts from the first, and then two parts of this file disagree about
what a report contains.

Five things the appendix will not remind you of, because they are decisions rather than formatting:

- The one-paragraph opener carries what changed against the prior window **and** anything limiting
  confidence in this run — the sync boundary, a keyword too new to have history, a keyword excluded
  by the health gate, a layer that returned nothing.
- When no signal type clears its floor, the report does not stop at three blanks. It commits to one
  of two verdicts: the market was quiet in a well-configured workspace, or the inputs could not
  support a finding. Those are opposite conclusions with opposite next actions, and they render
  identically unless you say which one it is. **Appendix C** has the required block.
- Every row of the decision table keeps its place even when the signal type produced nothing. Name
  the absence in that signal type's own words ("No significant emerging trends detected in this
  window"), never as "no data available" — see **Appendix C** for the three sentences and the
  distinction they protect. Carry the counts that fell short into the same row.
- Every per-opportunity block and every watch item carries at least one real example from the feed —
  one sentence, platform named, link included. Never composed, never invented; if no example exists,
  re-read the feed rather than writing one.
- Per-opportunity detail runs in the order the evidence was built — what people are saying, what
  organic adds, what AI search adds, whether you already cover it on either channel — so the argument
  stays checkable.
- Every acted-on row fills both action columns — a named SEO action, a named social action, or "—"
  where that channel is not the move — and a row with only an SEO action on a community-cited topic
  carries the one clause saying why: "7 of 10 cited sources are community; no thread still open."
  A row that leaves a channel silent will be read as article, which is the default the two columns
  exist to stop being automatic.
- The score line prints all five dimensions, not just the total, and the **Why** is the evidence,
  never the number.

## Phase 7 — Briefs

Every opportunity with a Create, Expand, Refresh or Repurpose decision gets a brief following
**Appendix D** — a writer-ready one for an Article channel, a poster-ready one for a Social channel,
and both for a Both. Monitor and Skip get no brief — write what to watch for instead, in numbers, and
what would move it up a band.

A social brief is not a shortened article brief. It names the platform, the specific threads or
surfaces to enter, who posts, the angle, and what claim the brand can make without it reading as a
pitch into someone else's complaint — see **Appendix D**. It also carries the expiry: a thread reply
that lands three weeks later is a different, worse move than the one being recommended.

The four verbs do not take the same brief. A Create names a new URL and its whole outline; an Expand
names the page being changed and only what to add; a Refresh names what is now wrong; a Repurpose
names the asset being converted and the format it becomes. Writing a Create-shaped brief for an
Expand is the common failure — it reads as a new article and someone builds one, which splits the
intent the coverage check just told you the site owns. **Appendix D** has the shared
spine and the per-verb sections.

The brief carries the evidence forward. A writer who never saw the report should be able to open the
brief and know what problem they are solving, for whom, and what proof to include.

## Handing off

The brief is where this skill stops, and the channel decides where it goes next. For an Article
brief, hand off to whichever brand writing skill is installed — for SE Ranking that is
`se-ranking-blog-writing`. For a Social brief, `planable-smm:draft-post-batch` drafts the posts into
the workspace; a thread reply or a comment is a human action and the brief is the prompt for it, not
something to schedule. `banned-words` applies to anything drafted on either path. A Both routes to
both, social first.

## Failure modes worth watching

- **Reporting the tracked keyword as the signal.** The most common failure. The keyword collected
  the conversation; it is not the finding.
- **Filling all three slots regardless.** Two real opportunities beat three where one is padding.
- **Anchoring the window to today.** Listening data lands on a ~7-day cycle, so the newest days are
  usually empty. Find the last synced day first; counting from today invents a decline.
- **Treating a viral spike as a trend.** Check the daily series and the author spread.
- **Defaulting to a comparison post** every time a recurring friction surfaces. The complaint
  reveals a problem people want solved; solving it usually outranks arguing about it.
- **Routing every opportunity to a blog page.** The coverage check has two halves for a reason. If a
  run produces only Article decisions, check whether half two was actually run or whether the answer
  defaulted because the tooling pointed at URLs.
- **Recommending a thread reply without naming the threads or the date.** A social move that can't be
  executed the same week is a different move from the one that was scored.
- **Blending time windows.** `DATA_getAiSearchOverview` is monthly and fixed, the listening window is
  whatever you chose. Do not merge them into one sentence about "this week".
- **Reading sentiment into AI-search data.** Planable labels sentiment on mentions; SE Ranking does
  not score how a brand is talked about in AI answers, only whether and where it appears.
- **Quietly estimating.** If a layer is missing, name it as missing.
- **Trusting the keyword set.** The run is only as good as what the workspace tracks. Colliding and
  bulk-dominated keywords produce a blank that looks exactly like a quiet market. Gate them in
  Phase 0.5 and name the failures.
- **Returning a blank with no diagnosis.** "Nothing qualified" and "your inputs cannot produce a
  finding" lead to opposite next actions; the report has to say which one this is.
- **Reporting a bulk-driven delta.** A platform sweeping into or out of a keyword is not the topic
  moving.
- **Calling a trend off a young keyword.** Backfilled history has no true prior window. Mark it
  provisional and judge on sustained authors.
- **Confirming the connector responded and stopping there.** An expired plan can return partial data
  that scores like complete data.
- **Running the health gate against today's date.** The gate samples a window, so it inherits the
  sync problem: anchored to today it under-counts every keyword and fails clean ones for thin
  authorship. Find the boundary first, in Phase 0.5.
- **Telling a small brand to fix keywords that are already correct.** Thin authorship on a clean set
  is the low-volume case: widen the window, don't send them to rewrite the one thing that worked.

---

# Appendices


## Appendix A — Signal detection

Read before deciding that anything in the mention feed is a pattern. Governs Phase 2.

Read this before deciding that anything in the mention feed is a pattern. The failure mode of this whole
workflow is calling one loud thread a market signal, writing a piece of content off it, and then having
nobody read it.

### The unit of evidence

Count **distinct authors across distinct threads**, not mentions.

A Reddit post with 60 comments arguing about scheduling tools is **one conversation**. Three separate posts
on three different subreddits raising the same frustration is **three conversations** — and that is the
thing worth writing about. In `list_keyword_mentions`, the per-platform payload carries `author` and `url`;
group by those before counting anything.

Always pass `hideOwnMentions: true`. Own mentions inflate every count and make the brand's own campaign look
like market demand.

---

### Signal 1 — Recurring friction (competitor or category practice)

**Definition:** the same frustration with a competitor product, or with the category's standard way of
working, appears across separate conversations.

**Bar:** ≥5 mentions, ≥3 distinct authors, ≥2 separate threads, inside the window.

**How to find it:**
1. Pull mentions with `sentiment: "negative"` for every topic keyword, plus any keyword that is a competitor
   name.
2. Read the text and group by the *underlying problem*, not the wording. "Their approval flow is a mess",
   "we lost a round of feedback in email again", and "client comments live in four places" are one complaint.
3. Name the complaint in the words people used, not in product language.

**What makes it an opportunity rather than a grievance:** the complaint has to describe a problem the target
can credibly solve or explain. A complaint about a competitor's pricing is not an opportunity unless the
target's answer to it is genuinely different.

**Validation seeds:** turn the complaint into the query someone would type when they act on it — usually
`[competitor] alternative`, `how to [do the thing that broke]`, `[competitor] vs [target]`.

---

### Signal 2 — Recurring industry question

**Definition:** different people raise versions of the same problem or decision, phrased as a question.

**Bar:** ≥5 mentions, ≥3 distinct authors, and the mentions read as questions or requests for help
("how do you…", "does anyone…", "what's the best way to…", "is it worth…").

**How to find it:**
1. Pull mentions across topic keywords sorted by `relevance`, then again by `engagement`.
2. Extract every interrogative. Cluster near-duplicates — "how often should we post on LinkedIn" and "what's
   a realistic LinkedIn cadence" are the same question.
3. Note which platform each cluster lives on. A question dominant on Reddit and absent on LinkedIn usually
   means the honest answer isn't being published anywhere.

**Why this signal is the most reliable of the three:** a question people ask out loud almost always has a
search-volume twin, so it validates cleanly in step 4 of the main process. `DATA_getKeywordQuestions` on the
cluster's core noun is the fastest confirmation.

---

### Signal 3 — Emerging trend

**Definition:** discussion around a topic, workflow, term, or behaviour is growing.

**Bar:** ≥40% growth week-over-week across ≥2 weeks, **and** ≥10 mentions in the most recent week.

The absolute floor matters more than the percentage. Two mentions becoming five is 150% growth and means
nothing. Percentages on small bases are the most common way this analysis embarrasses itself.

**How to find it:**
1. Use `get_keyword_metrics` for the daily series and aggregate into weeks.
2. For **topic** keywords, only compare week-over-week — they resync every 7 days, so a day-level spike is
   frequently a sync artefact rather than a real surge. Brand keywords resync every 24 hours and can be read
   at day level.
3. Check `daysWithData` from `get_keyword_metrics_summary`. If the window has large gaps, the series is not
   a trend line — say so and fall back to reading the mentions themselves.
4. Confirm the rise is topical, not incidental: read the mentions from the growth period. A spike caused by
   one viral post, a news event, or an unrelated collision with the keyword string is not an emerging trend.

**Validation is different for this signal.** A genuinely emerging topic often has *low* search volume and
*rising* direction — that combination is the opportunity, because the SERP hasn't consolidated yet. Read
`DATA_getRelatedKeywords` for direction and `DATA_getSerpResults` for whether anyone has claimed the term.
If the first page is thin, off-topic, or all forum threads, that is the signal to move early.

---

### Clustering method

For all three signals:

1. Strip the keyword itself out of the text — everyone in the feed used it, so it carries no information.
2. Group by the problem, question, or behaviour, not by shared vocabulary.
3. Keep the cluster's own name in the market's words. The phrase people repeat is often the exact term to
   target in the content.
4. Discard clusters that are off-brand no matter how large. A high-volume conversation the brand has no
   standing in is not an opportunity, and putting it in the report trains people to ignore the report.
5. Keep 2–3 verbatim quotes per surviving cluster, each with platform and URL.

---

### Ambiguity and false positives

- **Keyword collisions.** A brand or topic keyword that is also a common phrase will pull in unrelated posts.
  Filter them out per Phase 0.5 — by platform first, then by reading — and recount authors and threads on
  what survives. Do not drop the keyword unless the filtered subset is itself below floor, and do not let
  its raw volume or delta stand as evidence for anything: those are computed on the unfiltered feed.
- **Bot and promo noise.** Repeated near-identical posts from different accounts are usually promotional, not
  organic discussion. Exclude them and say how many you excluded.
- **One author, many platforms.** The same person cross-posting counts once.
- **Sentiment is a sorting aid.** AI-classified sentiment is useful for finding complaints quickly; it is not
  precise enough to headline. Never report a sentiment percentage as the finding.

---

### Worked example

**Raw feed (topic keyword "content approval", 30 days, own mentions hidden):** 47 mentions, 31 distinct
authors, 19 threads. Sentiment skew negative.

**Cluster A — "approvals live in too many places"**: 11 mentions, 8 authors, 6 threads, across Reddit and
LinkedIn. Clears the complaint bar.
→ Seeds: `content approval workflow`, `client feedback process`, `[competitor] approval`.
→ Organic: `content approval workflow` has demand and the target doesn't rank; two competitors do.
→ AI search: the topic appears in prompts where two competitors are cited and the target isn't — **missing**.
→ **Create.** Both checks positive.

**Cluster B — "how many rounds of revisions is normal"**: 6 mentions, 5 authors, 4 threads, all Reddit.
Clears the question bar.
→ `DATA_getKeywordQuestions` returns three related questions with low but real volume; no vendor owns the
SERP, which is all forum threads.
→ **Create.** Organic check positive, and the SERP is unclaimed.

**Cluster C — "AI-generated first drafts in approval chains"**: 4 mentions, 3 authors, week-over-week
movement from 1 to 4.
→ Fails the emerging-trend floor: 4 mentions in the latest week is under 10, and 300% growth on a base of 1
is noise.
→ **Monitor.** Report it as a watch item with the actual numbers shown, so nobody mistakes it for a finding.


## Appendix B — Scoring

The rubric, the bands and the missing-data caps. Governs Phase 5.

Read this before scoring anything. The point of a fixed rubric is that a 14 in March means the same
thing as a 14 in September, to a different person, on a different brand. A score that gets re-derived
from vibes each run is worse than no score, because it looks comparable and isn't.

Five dimensions, 0–4 each, 20 total. Report every dimension separately in the order the report
template uses: **social, demand, AI, winnability, fit**.

---

### Before you score: the entry gate

Scoring is for signals that already cleared their evidence floor in **Appendix A**. A cluster
below the floor is not a low-scoring opportunity — it is not an opportunity, and it goes to the watch
list with its actual counts. Do not score it and let a low number do the rejecting; a 6/20 in the
table reads as "weak opportunity" when the honest statement is "this did not qualify".

Score the **de-bulked** counts. Bot-dominated platforms (usually Twitter/X, sometimes web) inflate
mention volume with near-zero engagement and can swamp the real conversation in both directions —
a platform-level collection change looks exactly like a topic collapsing. The separation happens at
the read step in Phase 1, not here: if you have arrived at scoring with a pool you never de-bulked,
go back and re-cluster rather than adjusting the number down to compensate. Say in the report which
pool you scored.

---

### 1. Social (0–4) — how strong is the conversation

Counts distinct authors across distinct threads, not mentions.

| Score | Anchor |
|---|---|
| 0 | Below floor. Should not be here — see entry gate. |
| 1 | Meets floor on a technicality: exactly 3 authors, exactly 2 threads, one platform. |
| 2 | Meets floor comfortably: 3–4 authors across 3+ threads. |
| 3 | 5+ authors across 4+ threads, or 4+ authors across 2+ platforms. |
| 4 | 6+ authors across 6+ threads, unprompted, with independent phrasings of the same need. |

Single-platform clusters cap at 3 unless the platform concentration is itself the finding (a question
alive on Reddit and absent everywhere else usually means nobody has published the honest answer).
Note it either way.

### 2. Demand (0–4) — does the need exist in search

Volume **and** direction. For a signal typed as emerging, direction outweighs absolute volume; for a
complaint or question, volume carries more weight.

| Score | Anchor |
|---|---|
| 0 | No seed term returns data, or every term is 0/mo. |
| 1 | Cluster under ~250/mo **and** declining 25%+ over the 12-month trend. |
| 2 | Cluster under ~250/mo, flat or mildly declining; or higher volume with a weak trend. |
| 3 | 250–1,000/mo and stable, or under 250/mo and clearly rising. |
| 4 | 1,000+/mo stable, or any volume rising 40%+ with a commercial signal (CPC above category median). |

Two traps. **Never score an AI-prompt cluster on search volume** — prompts routinely return 0 because
people phrase them conversationally, and that says nothing about value. And **a dead question layer is
a demand finding, not a neutral**: if `getKeywordQuestions` returns only legacy or off-topic results,
the need is expressed as a tool/product query rather than a question, which caps how much of it can be
captured through question-shaped content or AI citation. Drop a point and say so.

### 3. AI (0–4) — is there room in AI search

Presence and citation only. SE Ranking does not score how a brand is talked about in AI answers, and
Planable-style sentiment never enters this dimension.

| Score | Anchor |
|---|---|
| 0 | Not assessed this run, or no AI-search data for the market. Triggers a cap — see below. |
| 1 | Topic is saturated: one domain holds a dominant citation share and the brand is nowhere near it on any engine. |
| 2 | Brand present but middling across engines, no single engine shows a clear addressable gap. |
| 3 | A specific, measurable gap on a named engine — brand competitive on some engines and badly behind on one. |
| 4 | Topic is open: no domain holds a large share, citations are unconsolidated, brand can enter cheaply. |

A 3 is the most actionable score here and the most common for an established brand. Name the engines
checked. An aggregate share-of-voice number hides the actionable part — always read per-engine before
scoring, because leading on one engine while trailing 10:1 on another is a different brief from being
uniformly mid.

**Record the source mix beside the score.** The number answers whether there is room; the mix answers
how you get in. A gap on a topic whose citations are mostly community pages is a gap a post or a
thread reply can close in days, and one whose citations are mostly publisher pages is a gap that
needs a page and a quarter. Same score, different channel, and the score alone will not tell the
reader which — so write it as "AI 3 (7 of 10 cited sources community)".

**Verifying a zero.** Before scoring a 0 or 1 off an empty result, re-run the identical query against a
control domain certain to be cited. The control proves the query fired; it is not a competitor and its
figure is never reported as the gap to close. If the control also returns zero, the filter is broken —
fix and re-run before scoring.

### 4. Winnability (0–4) — can this brand actually take the position

| Score | Anchor |
|---|---|
| 0 | Locked: high difficulty, incumbents with far greater authority, no angle. |
| 1 | Hard: difficulty well above the brand's typical ranking band, SERP owned by stronger domains. |
| 2 | Position already held. Gains come from defending or extending rather than new capture. |
| 3 | Low difficulty (roughly under 25) and no entrenched owner, or a SERP that mismatches the intent. |
| 4 | Open: thin SERP, forum threads or off-topic results on page one, and the brand has topical authority. |

The 2 is counter-intuitive and deliberate. Already ranking #1–#3 is a *good* outcome and a *low*
winnability score, because there is little new ground to take — which is exactly why the decision comes
out as Expand or Refresh rather than Create. A reader who sees winnability 2 next to fit 4 should
understand immediately that the work is deepening an owned page, not building another one.

**Score the channel you are recommending.** These anchors read the SERP, which is the right lens for an
Article decision and the wrong one for a Social decision. For a Social channel, winnability asks
whether the brand can credibly enter the conversation: an open thread with no vendor answering and a
question the product genuinely solves is a 4 regardless of keyword difficulty; a thread where a
competitor's team is already answering well, or where a vendor reply would read as an ad, is a 1. Say
which lens you used. A topic that is locked in search and open in a thread is the exact case the
channel decision exists for, and scoring it once through the SERP lens hides that.

### 5. Fit (0–4) — can the brand credibly answer it

| Score | Anchor |
|---|---|
| 0 | Off-brand. Discard regardless of size — putting it in the report trains people to ignore the report. |
| 1 | Adjacent to the audience but not to the product. The brand has no standing to give this advice. |
| 2 | Relevant to the audience, product connection needs work to be honest. |
| 3 | Clear product connection; the brand's answer is genuinely different from the category's. |
| 4 | Dead centre of what the product does. The complaint describes the problem the product exists to solve. |

Audience overlap is not fit. A topic every one of the brand's customers cares about can still be a 1 if
answering it well requires expertise the brand does not have.

---

### Missing data caps

A missing layer is a finding, not a gap to fill with a plausible number. Score the dimension 0, write
"not available" or "not assessed" in the report, and apply the cap:

| Condition | Cap on total |
|---|---|
| One dimension scored 0 for missing data | 14 |
| Two or more dimensions scored 0 for missing data | 9 (Monitor ceiling) |
| AI-search data unavailable for the market entirely | 14, and say so in the header |
| Competitor set not supplied by the user | Do not score at all — the competitor set is a gate |

The one-missing-layer cap of 14 exists so a blind layer can never produce a top-band "act now". If the
cap binds, state the uncapped total alongside it so the next run can tell whether the cap or the
evidence was the constraint.

---

### Bands → posture, not verb

The band decides **whether and how urgently to act**. It never decides the verb.

| Total | Posture |
|---|---|
| 16–20 | Act this cycle. Brief it now. |
| 11–15 | Act, scheduled. Brief it, queue behind anything in the band above. |
| 6–10 | Monitor. No brief — write what to watch and what would move it up. |
| 0–5 | Skip. Record it so the next run doesn't re-surface it. |

The verb — **Create / Expand / Refresh / Repurpose** — comes from the Phase 4 coverage check and
nothing else. A 17/20 against an intent the site already owns is still Expand, not Create; publishing
a second page against an owned intent splits it and helps nobody, however high the score. If the band
says act and coverage says covered, the score is telling you the topic is worth investment and the
coverage check is telling you where that investment goes.

Monitor and Skip get no brief. Write the trigger that would change the decision, in numbers
("re-check when the 12-month trend flattens for two consecutive months"), not in adjectives.

---

### Worked example

From a September 2026 run on Planable, US market, competitor set supplied by the user.

**Signal A — social teams running with no coordination system (recurring friction, category practice)**
6 mentions / 5 authors / 5 threads across Reddit and LinkedIn → **social 3**. Core terms 50–90/mo,
flat-to-declining, and the question layer returned only legacy SharePoint results → **demand 2**.
Brand led two engines on brand presence but sat ~10:1 behind the category leader on AI Overview — a
specific named-engine gap → **AI 3**. Site already ranked #1–#3 across the commercial cluster →
**winnability 2**. The complaint describes the exact problem the product solves → **fit 4**.

**14/20 → band 11–15, act scheduled.** Coverage check returned "covered well" → verb is **Expand**.
Low winnability beside high fit is the whole story: strengthen two existing pages, add no new URL.

**Signal B — how to start an agency and find first clients (industry question)**
8 mentions / 7 authors / 7 threads, single platform → **social 4**. 140/mo and −56% over 12 months →
**demand 1**. Not assessed this run → **AI 0**, cap 14 applies but does not bind. Difficulty 7 →
**winnability 3**. Collaboration tool, not a business-development advisor → **fit 1**.

**9/20 → band 6–10, Monitor.** No brief. This is the case the two-layer check exists to catch: the
loudest social signal of the run sitting on top of search demand that has more than halved.


## Appendix C — Report template

The output structure. Governs Phase 6.

Use this structure exactly. A reader should be able to scan the table, understand what the team should make
and why, and only then read the detail if they want to challenge it.

---

### 1. Header

```
# Weekly Content Opportunity Radar — [Workspace] — [start date] to [end date]

Keywords analysed: [brand keyword] (brand), [topic keywords] (topic), [competitor keywords] (competitor)
Market: [country] · Domain: [domain] · Competitors: [list, attributed to the user]
Window: [start]–[end], compared with [prior start]–[prior end]. Last synced [date]
Mentions reviewed: [N] across [M] platforms, own mentions excluded
Pool clustered: [non-bulk platforms read], [bulk platform] set aside ([N] mentions, [N]% of volume)
Keyword health: [N] of [N] keywords usable · filtered: [keyword] ([N] raw → [N] on-entity, [what was removed]) · excluded: [keyword] ([reason]) · provisional: [keyword] (created [date])
```

Competitor keywords get their own slot in that first line even when the answer is "none tracked",
because their absence is what closes the named-competitor form of the friction signal and it should
not have to be inferred from a line that isn't there.

If any keyword returned no data, list it here as analysed-but-empty. A reader must be able to tell the
difference between "we looked and found nothing" and "we didn't look".

Add one line for anything the Phase 0.5 health gate filtered or excluded, with the reason, in the
form "filtered: '[keyword]' ([N] raw → [N] on-entity, [what was removed])" or "excluded: '[keyword]'
([the other meaning it collects], nothing survives the filter)" — and one for any keyword too young
to carry a prior window. Filtered and excluded are different states and the reader
needs to see which happened: one narrowed the pool, the other closed a signal form.
The reader needs to know the pool was narrowed and on what grounds, because that is usually the
single most actionable thing in a thin run.

---

### 2. Decision table

One row per signal type. Keep the column order — it walks the reader through the chain of evidence in the
order it was gathered.

| Signal | Topic | Social evidence | Organic opportunity | AI-search opportunity | SEO action | Social action |
|---|---|---|---|---|---|---|
| Recurring friction | [topic] | [N] mentions across [N] conversations | [N] searches, [±N%] trend | Appears in [N%] of prompts, [N] of [N] sources community | Expand /blog/[page]: add [section] | Reply in [N] live threads [links], by [date] |
| Industry question | [topic] | [N] questions from [N] authors | [N] searches, [±N%] trend | Brand visible in [N%] of answers | Create /[slug] | — |
| Emerging trend | [topic] | Mentions up [N%] | Growing demand, [N] searches | [N] competitors already visible | Monitor | Monitor |

Rules for filling it:

- Every number is a number you pulled. Unknown stays "unknown"; zero stays "0".
- The AI-search column reports presence and citation only, never sentiment. Where the citation source
  mix was readable, it belongs in this column too — it is the evidence the action columns run on.
- The two action columns are what replaced the single Decision column, because one column forced a
  choice between channels that a strong signal does not have to make. Each cell holds a named action —
  the verb plus the specific page, slug, thread or format — or "—" when that channel is not the move,
  or "Monitor"/"Skip" on rows that get neither. Never leave either cell blank: blank reads as
  oversight, "—" reads as a decision, and only one of those is true.
- A row with both cells filled is a Both. State in the reason line under the table which action runs
  first and the date the social one expires. A row with only the SEO cell filled on a topic whose
  citations are mostly community needs one clause saying why — that is the case most likely to be a
  default rather than a decision.
- A colliding keyword's raw mention count and week-over-week delta never appear in the Social
  evidence column. Those metrics are computed on the unfiltered feed. Report the filtered counts and
  mark them filtered.
- If a signal type produced nothing above its floor, keep the row and name the absence **in that signal
  type's own words**. Use the matching sentence:
  - Recurring friction → "No recurring friction detected in this window"
  - Industry question → "No recurring industry questions detected in this window"
  - Emerging trend → "No significant emerging trends detected in this window"

  Never fill that cell with "no data available", "N/A", "none", a dash or a blank. Those say the layer
  could not be read; the sentences above say the layer *was* read and held nothing above the bar. A
  reader has to be able to tell those two apart, because they lead to opposite next actions. Reserve
  "not available" for a layer that genuinely could not be queried, and name which layer and why.

  The sentence alone does not say whether the market was quiet or the inputs were unusable. When
  every row is one of these sentences, §2b below is required and carries that verdict.
- Put the counts that fell short in the Social evidence column of that same row: "4 mentions / 3 authors /
  2 threads — below the 5/3/2 floor", or "+15% week-over-week, floor is +40%". The sentence says what you
  did not find; the counts say how close it came, and that is what makes the next run faster.
- Write "this week" only when the window really is a week. If it ends on a sync boundary days before
  today, say "in this window" or give the actual dates — the same rule that governs every other date
  claim in the report.
- Add a one-line reason under the table for each Monitor or Skip. A decision nobody can audit gets ignored.

---

### 2b. When nothing cleared the floor

Three "no X detected" rows are a legitimate outcome, but on their own they are unreadable: they look
the same whether the market was quiet or the keyword set could never have produced a finding.
Whenever every row is a blank, a short diagnosis goes directly under the table, and it commits to one
of two verdicts.

**Verdict 1 — the inputs could not support a finding.** Use it when the health gate flagged
collisions, bulk domination or thin authorship, when competitor keywords are absent or too new to
compare against, or when the surviving pool was too small to cluster. Name each failing keyword,
what it is actually collecting, and the specific change. Close by saying the run can be repeated as
soon as the set changes — this is not a come-back-next-week result, and reading it as one wastes a
week.

**Verdict 2 — the market was quiet.** Use it only when the keyword set passed the health gate, the
non-bulk pool was read in full, and the clusters genuinely fell short. Give the near-misses with
their counts. This is the one that means come back next window.

Both verdicts state the window dates, the pool that was clustered, and which layers were skipped.
Phases 3 and 4 do not run on sub-floor clusters — validating something that did not qualify
manufactures rigor the evidence cannot support — so say that plainly rather than leaving those
columns looking unfinished.

Never let a blank run end without one of these two verdicts. A reader who gets three blanks and no
diagnosis concludes the tool found nothing, when the likeliest cause is a keyword set that could be
fixed in ten minutes.

**A partial blank needs the same treatment, one row at a time.** One or two empty rows in an
otherwise full report are the easier failure to miss, and the reader draws the same wrong conclusion
about that signal type. Whenever a row is blank *and* the health gate flagged something that feeds
it, add a clause to that row's reason line naming the connection — "no named-competitor friction:
the only competitor keyword was excluded as a collision, so this form had nothing to read" — rather
than leaving the row looking like a market finding. A row that is blank with a clean set
underneath it needs no clause; say nothing and let the sentence stand.

---

### 3. Per-opportunity detail

Repeat this block for each row, in table order. Five sub-headings, in this order — they mirror how the
evidence was built, so the argument stays checkable, and the last two are what keep the channel decision
visible rather than implied.

**Every block must carry at least one real example from the mention feed.** One sentence is enough. It
goes under "What people are saying", with the platform named and the link included, and it has to be
something a person actually posted in the window — either a short verbatim fragment or a close
paraphrase of one specific post, not a composite of several. Counts tell a reader the pattern is real;
one line of someone describing the problem in their own words is what makes it land and what lets them
judge the clustering for themselves. A block with no example reads as an assertion.

Prefer the example that shows the need most plainly over the one with the highest engagement — the
loudest post is often the least representative. Two or three per cluster is the ceiling, and the
quoting rules below still apply.

If a cluster has no example you can point to, do not write one. Fabricating or composing a quote
invalidates the whole report. Treat it as a signal the cluster may not be real, and re-read the feed
before keeping it.

```
### [Signal type]: [topic, in the market's own words]

**What people are saying**
The recurring pain point, question, or trend as it appears in the conversations. [N] mentions from [N]
authors across [N] threads on [platforms], [date range]. Sentiment skew if relevant.

> "[short verbatim quote — REQUIRED, at least one]" — [platform], [link]
> "[short verbatim quote — optional second]" — [platform], [link]

**What organic search adds**
Related queries and their volume, direction of demand, difficulty, and who owns the SERP today. Whether the
target already ranks for anything in the cluster — and if so, which page.

**What AI search adds**
Prompt coverage for the topic, whether the brand and competitors are cited, which engines, and whether the
cluster is owned / contested / missing. The citation source mix — how many of the cited sources are
publisher pages and how many are community or video — with the number.

**What we already have, on both channels**
Which of our pages targets this intent and what it captures. Whether we have posted on this, where, and
whether it travelled. Whether we are already in the threads the signal came from, or whether a competitor
is, or nobody.

**What to do, and where**
The recommended angle in one sentence, the channel, and why that channel rather than the other. For a
Social channel, name the threads or surfaces and the date by which the move stops being timely.
```

---

### 4. Content brief (Create, Expand, Refresh and Repurpose rows)

The field list and the per-decision guidance live in **Appendix D**. They are deliberately not
reproduced here — a second copy drifts from the first within a release or two, and then two parts of
this file disagree about what a brief contains.

One brief per Create, Expand, Refresh or Repurpose row, in table order. Monitor and Skip rows get a
watch item in section 5 instead.

The last line matters. A brief that carries its evidence survives the handoff to whoever writes it; one that
doesn't turns back into an opinion the moment it leaves the room.

---

### 5. Watch list

Anything that cleared the recurrence bar but failed validation, with the numbers that made it a Monitor and
what would change the decision ("re-check when weekly mentions clear 10" / "re-check if a vendor publishes
on it"). This section is what makes the next run faster than this one.

Watch items carry one example too — a single sentence with the platform and link. Next run needs to
recognise the same conversation when it sees it again, and a topic label alone will not do that. The
exception is a watch item that exists because a layer could not be measured rather than because a
cluster fell short; say that plainly instead.

---

### Tone

Write it flat. No adjectives doing work that numbers should do, no "significant" or "strong" signals —
give the count and let the reader judge. The report's only job is to end an argument about what to create,
and it does that by being checkable, not persuasive.


## Appendix D — Brief template

Writer-ready brief fields and per-decision guidance. Governs Phase 7.

Every opportunity with a **Create, Expand, Refresh or Repurpose** decision gets a brief. Monitor and
Skip do not — write the watch trigger instead, in numbers.

There are two brief shapes, chosen by the channel Phase 4 decided: the article brief below, and the
social brief after it. A **Both** decision gets one of each, social first, because the social move can
ship this week and the article cannot.

The brief is where this skill stops and someone else's work starts. The test: a writer who never saw
the report should be able to open the brief alone and know what problem they are solving, for whom,
and what proof to include. If the brief only makes sense to someone who sat through the analysis, it
will turn back into an opinion the moment it leaves the room.

---

### The fields

Use all of them. A field with nothing in it is information — write "none found" rather than deleting
the line, so the writer knows it was checked.

```
#### Brief: [working title]

- **Decision:** [Create / Expand / Refresh / Repurpose]
- **Channel:** Article
- **Target URL:** [the new URL's intended slug, or the exact existing URL being changed]
- **Format:** [article / comparison / guide / social series / landing page section]
- **Primary query:** [query] — [volume], [difficulty], [CPC if commercially relevant]
- **Supporting queries:** [3–6 related and question keywords, each with volume]
- **Audience and moment:** [who is asking this and what they are trying to decide, in the
  situation that sends them looking — not a persona label]
- **The question the piece must answer in the first 100 words:** [one sentence]
- **Sections to cover:** [outline, drawn from the questions people actually asked]
- **What competitors already say — and what they leave out:** [the gap this piece fills, naming
  the competitor set the user supplied]
- **Proof to include:** [the social evidence, the search data, and any product detail that belongs]
- **AI-search notes:** [the prompts this should become citable for, and the claims to state
  plainly so they survive being quoted out of context]
- **Internal links:** [existing pages that should point at this, or that this should update]
- **Source evidence:** [links to the mentions and the SE Ranking calls behind the brief]
```

---

### What changes per decision

The fields stay the same; what fills them does not. Getting this wrong is how an Expand brief
accidentally becomes a second page against an intent the site already owns.

All four verbs exist on both channels. A Social Expand adds to a thread the brand is already in; a
Social Refresh re-answers a question whose old answer has gone stale; a Social Repurpose turns a
webinar section into the reply the thread needs. Read the verb notes below for what each one means,
then execute them in the shape of the channel's brief.

**Create.** No page targets this intent. Target URL is a proposed slug. Sections come from the
question clusters in the mention feed, not from the competitor outline — if the outline mirrors the
incumbent's, the piece has no reason to outrank it.

**Expand.** A page targets the intent but misses the specific need. Target URL is the **existing**
page, named exactly. Split "Sections to cover" into what stays and what gets added, and say which
rankings must not regress — a writer who does not know the page ranks #2 for its head term will
happily rewrite the section holding that position. Name the gap between how the page is written and
how people in the feed describe the problem; that mismatch is usually the whole brief.

**Refresh.** A page covers the intent and has decayed or gone stale. Lead with what specifically
went stale — figures, screenshots, a named tool that changed, a claim that is no longer true — and
the position history. Refresh is not a rewrite; if the brief reads like a rewrite, the decision was
probably Create or Expand.

**Repurpose.** The answer already exists in another format — a webinar, a support doc, a thread.
Name the source asset and where it lives. The brief's job is the translation: what carries over, what
has to be re-reported because a spoken aside will not survive as a written claim, and what the new
format adds that the original could not.

---

### Writing the fields well

**Audience and moment.** "Social media managers" is not a moment. "Someone who has just lost a round
of client feedback in a chat thread and is trying to name what is broken" is. The moment is what
determines the first 100 words, and it comes from the mention text — use the situation people
described, not a demographic.

**Primary query.** One query. If two are competing for the slot, the cluster is probably two briefs.
Carry the volume and difficulty from the validation step; do not re-estimate from memory.

**Supporting queries.** Prefer question keywords where they exist — they map directly onto both
headings and AI citations. Where the question layer came back empty, say so here rather than padding
with related terms, because it tells the writer the piece has to earn citations structurally rather
than by answering a question people type.

**Proof to include.** Three kinds, and label which is which: what people said (at least one real
example, one sentence is enough, with platform and link), what the search data showed (with the
figure), and what the product can legitimately claim. The first kind is required — a brief that
reaches the writer with no line of anyone describing the problem gives them nothing to write the
first 100 words from. Do not let the third quietly become the first — a brief that leads with product
capability produces a page nobody searched for.

**AI-search notes.** Write the claims as standalone sentences that survive extraction with no
surrounding context, because that is how they get quoted. Name the engine the gap was measured on
and the figure, so the writer knows whether they are defending a lead or closing a deficit.

**Source evidence.** Links, not descriptions. This is the field that makes the brief auditable six
weeks later when someone asks why the piece exists.

---

### The social brief

For a **Social** channel. Same evidence, different execution, and it is not a shortened article brief —
an article brief hands someone a topic, a social brief hands someone a conversation that is already
happening and a place to stand in it.

```
#### Social brief: [working title]

- **Decision:** [Create / Expand / Refresh / Repurpose]
- **Channel:** Social
- **Platform and surface:** [LinkedIn / Reddit r/x / YouTube / X] — and for a reply, the exact
  threads, with links
- **Format:** [original post / reply in an existing thread / short video / carousel / comment]
- **Live until:** [the date after which these threads are stale and this brief should be re-scored]
- **Who posts:** [brand account, or a named person — a reply from a company account and one from a
  practitioner land differently and the choice is part of the brief]
- **The conversation as it stands:** [what people are saying, who has answered already, what is
  still unanswered — one short paragraph]
- **Key message:** [the one sentence this has to land, written as it would be posted]
- **Angle:** [what we add that nobody in the thread has said yet, and the tone that fits the room]
- **The claim we can honestly make:** [the product point, if any, and the form it can take without
  reading as a pitch into someone else's complaint — often "none, answer the question"]
- **What we must not say:** [the claim that would be true of the product but wrong in this room]
- **Supporting evidence:** [the data point, study or example that earns the reply]
- **AI-citation note:** [the standalone sentence worth stating plainly, because community posts on
  this topic are what the engines are citing — see the source mix in the report]
- **Follow-on:** [whether this should also become an article, and the brief it pairs with]
- **Source evidence:** [links to the threads and to the citation-source read behind the channel call]
```

Two fields carry most of the weight. **"The claim we can honestly make"** is what stops a reply
becoming an ad in a thread of people complaining — often the right answer is that there is no claim
and the move is to answer the question. And **"Live until"** is what makes the brief auditable: a
thread reply recommended in this report and posted a month later is a different action from the one
that was scored, and nobody will notice unless the date is written down.

---

### Quoting

Paraphrase. Keep any verbatim fragment short and attributed to the platform it came from, and keep
two or three per cluster at most. A brief padded with long quotes from other people's posts is a
liability, not evidence.

The floor matters as much as the ceiling: at least one per cluster, never zero, and never invented.
One sentence carries it. If the only way to illustrate a cluster is to stitch several posts into a
sentence nobody wrote, the cluster is not ready to report.

---

### Monitor and Skip: the watch item

No brief. Write this instead, and put it in section 5 of the report:

```
- **[Topic]** — [decision], [score]/20. [The count or trend that fell short, with the number.]
  Re-check when: [numeric trigger or observable event]
  Would become [verb] if: [the condition that changes the decision]
```

The trigger has to be a number or an event someone could notice — "re-check when the 12-month trend
flattens for two consecutive months", "re-check if a vendor publishes against it", "re-check when
weekly mentions clear 10 from 5+ authors". Never an adjective. "Monitor for growing interest" is
unusable next run, and next run is the entire reason the watch item exists.

A watch item is also where a signal that failed on one layer gets its reason recorded. Six weeks
later the useful fact is not that it scored 9 — it is that social was strong and demand was falling.

---

### Worked example — an Expand

From one brand's run, abridged; the real brief carries the full evidence block. The domains, pages
and figures here are that run's, not defaults — read the shape of the brief, not the content.

```
#### Brief: what it costs when approvals live in DMs

- Decision: Expand
- Target URL: /blog/social-media-approval-process/ and /blog/approval-software/
  — edits to existing pages, not a new page
- Format: article expansion
- Primary query: social media approval tool — 50/mo, difficulty 11, CPC $12.67
  (/blog/approval-software/ currently #2 for the adjacent "content approval software")
- Audience and moment: someone who has just lost a round of client feedback in a chat thread,
  or a manager watching one person absorb nine accounts across three platforms. Not yet
  shopping for a tool — trying to name what is broken.
- Sections — what stays: the tool comparison and feature tables holding current rankings.
  What gets added: the symptom language from the feed (tasks sent via chat, no documented
  process, scope landing on one person); where feedback gets lost between client, account
  manager and creator; what to hand a new manager in week one.
- Must not regress: the #1 positions on the "social media collaboration tool" cluster.
- Supporting queries: content approval process (50), approval workflow software (320, #9),
  social media approval workflow (10). Question layer came back empty — only legacy SharePoint
  and Liferay results — so this has to earn citations structurally, not by answering a question
  people type.
- AI-search notes: brand leads Perplexity and Gemini on brand presence but sits roughly 10:1
  behind the category leader on Google AI Overview (445 vs 4,240). State claims standalone so
  they survive extraction.
- Source evidence: r/marketing 1w4abs9, r/DigitalMarketing 1w7rm5b, three LinkedIn threads;
  getKeywordsMetrics / getKeywordQuestions / getDomainKeywords / getAiSearchLeaderboard.
```

Note what the shape prevented. The score was 14/20 with fit 4 — high enough that a Create-shaped
brief would have looked justified, and would have produced a second page against an intent the site
already ranks #1–#3 for.

---

### Worked example — a Both

The case the two action columns exist for: an SEO action and a social action on one signal, each
worth doing on its own, with the social one first because it expires. Again, one brand's run — the
competitor, the page and the platforms are illustrative.

**The signal.** Competitor approval-seat pricing — several unconnected people working out that
per-seat billing makes their reviewers the expensive part of the tool. Live in two LinkedIn threads
and one r/socialmedia thread this window. Coverage check, half one: `/blog/[competitor]-alternatives/`
already ranks #2 for its head term and says nothing about approval-only seats. Half two: the brand
has never posted on pricing arithmetic, nobody in the threads has laid it out, and the citation read
came back 7 of 10 community sources.

**SEO action — Expand `/blog/[competitor]-alternatives/`.** Add one section on what approval-only seats
cost across the pricing models, using the three team shapes people described in the feed. Do not
restructure the page: the comparison tables hold the #2 position. This captures the demand once it
consolidates in search, and it will not land this month.

**Social action — reply in the three live threads, by [date].** Full brief below. This is where the
demand is visible right now and where the engines are pulling citations from on this topic.

**Why both, and why social first.** Expanding the page alone answers the question in the place the
question is not currently being asked, and waits a quarter to rank on a page that already ranks.
Replying alone leaves nothing standing once the threads scroll away. The page is the durable asset;
the threads are the perishable one, so the perishable one runs first.

```
#### Social brief: what an approval seat actually costs you

- Decision: Create
- Channel: Social (paired with the Expand above; social runs first)
- Platform and surface: two LinkedIn threads and one r/socialmedia thread where people are
  pricing approval seats right now [links]
- Format: reply in an existing thread — not an original post. The audience is already
  assembled and a standalone post would be talking past it.
- Live until: [10 days from the window end] — after that these threads are cold and this
  gets re-scored
- Who posts: a named practitioner, not the brand account. The threads are people comparing
  bills; a company reply reads as a sales pitch and gets downvoted.
- The conversation as it stands: several unconnected people working out that per-seat
  pricing makes their reviewers the expensive part of the tool. Nobody has laid out the
  arithmetic. One competitor's team is in one of the threads, answering narrowly.
- Key message: reviewers are usually the cheapest people to add and the most expensive
  seats to buy, and which of those you get is set by the pricing model, not the headline price.
- Angle: do the arithmetic publicly for the three team shapes people keep describing. Flat,
  numerate, no product framing until the end.
- The claim we can honestly make: that reviewers do not need paid seats in every model —
  stated once, at the end, as a fact about the category rather than a pitch.
- What we must not say: anything comparative about the competitor's billing that we have
  not verified from their own pricing page this month.
- Supporting evidence: the per-shape costings, each from a published pricing page, dated.
- AI-citation note: state the per-shape cost conclusions as standalone sentences. The
  citation read on this topic was 7 of 10 community sources, which is the whole reason
  this runs before the page.
- Follow-on: the Expand above, briefed separately.
- Source evidence: [thread links]; getAiSearchPromptsByTarget, getAirtSourcesSummary,
  getDomainKeywords on /blog/[competitor]-alternatives/.
```

Note what the two columns prevented. A single-decision table would have recorded this as "Expand
`/blog/[competitor]-alternatives/`" and been defensible — the page exists, the intent matches, the
verb is right. It would also have missed the only action available this week, on a topic whose
citations the engines are taking from exactly the threads nobody replied in.

