<!-- researching-content -->
<!-- One Claude skill, flattened into a single markdown file. -->
<!-- To install: create ~/.claude/skills/researching-content/ and split the FILE blocks below back out. -->
<!-- SKILL.md is everything above the first FILE heading. -->

---
name: researching-content
description: Researches a content topic and returns ranked findings, gaps, and sourced numbers as a markdown list, without writing an outline or a draft. Analyzes the SERP, reads the top four competing pages, records what each page promises and fails to deliver, and optionally pulls AI-citation data when a visibility connector is available. Use when asked to research a topic, find content gaps, check what is ranking, gather data points for an article, size up competitors, or decide whether a topic is worth writing. Do not use when the request is for a brief (use briefing-content) or a draft (use drafting-content).
---

# Researching Content

Returns findings. Writes no outline, no draft, and no file unless asked for one by name.

That boundary is the point. A skill permitted to research and write will write, and the piece then rests on whatever surfaced first instead of on a decision someone made.

## Workflow

Copy this checklist and track progress:

```
Research progress:
- [ ] Step 1: Fix the reader and the question
- [ ] Step 2: Pull and filter the SERP
- [ ] Step 3: Read the top four
- [ ] Step 4: Rank the gaps
- [ ] Step 5: Pull citation data (skip if no connector)
- [ ] Step 6: Return the findings block
```

### Step 1: Fix the reader and the question

Write one line: who reads this, and what problem brings them here.

Ask the user if it is not stated, then continue. Every finding below gets filtered against that line, and an interesting finding that fails the filter gets dropped.

### Step 2: Pull and filter the SERP

Search the primary keyword and take the top 10 organic results.

Drop any result whose domain matches `reference/blocked-domains.md`. Keep the dropped set in a separate list. When a community or video result outranks the vendors, that is a finding about tone, and it belongs in the output.

### Step 3: Read the top four

Fetch each page. Record:

- Word count and format: guide, listicle, comparison, alternatives, how-to, glossary
- Full H2 and H3 outline
- Structural elements carried: tables, FAQ, code blocks, downloads, screenshots, original data
- Author: named person with a title, or brand voice
- Publish and last-updated dates
- The three things it covers best
- **What it says it will cover and does not**

The last field produces most gaps. Pages promise a walkthrough and deliver a summary far more often than they omit a topic outright.

### Step 4: Rank the gaps

A gap qualifies on all three counts:

1. The reader from Step 1 wants it
2. All four top pages are thin on it
3. It can be covered from evidence in hand or obtainable

Write each gap starting with a verb, so it reads as work. "Publish a working file" beats "nobody publishes files."

Rank by how hard a competitor would find it to copy. A gap anyone can fill next week is worth less than one needing data or an artifact you own.

### Step 5: Pull citation data

Skip this step when no AI-visibility connector is configured. Steps 1 to 4 stand on their own.

With a connector, use fully qualified MCP tool names (`ServerName:tool_name`) or the call will fail to resolve. Pull, in this order:

1. The citation category split for the last 90 days
2. Which page types on the owned domain earn citations
3. Which third-party domains get cited on the category's questions

Two failure modes mislead rather than announce themselves:

- **Workspace and account identifiers are typed.** Pass a string where the schema wants an integer and the failure reads like a permissions error.
- **Any tool that sets a current workspace holds session state.** Run those calls in sequence. In parallel, the data returned belongs to whichever call landed last.

An empty account is common and is not an error. Skip it and pick another. Stop sampling once new accounts only confirm ranges already seen.

For benchmark ranges observed across a B2B SaaS portfolio, see `reference/citation-benchmarks.md`.

### Step 6: Return the findings block

Output this in chat. Write nothing to disk unless asked.

```markdown
## Reader
[one line: who, and the problem]

## SERP shape
[dominant format, word-count range, what every page carries]

## Top four
1. [domain] — [format], [words] — best at: [x] — thin on: [y]

## Community and video results
[any that outranked vendors, and what that implies about tone]

## Gaps, ranked by defensibility
1. [verb-first sentence] — defensible because [reason]

## Numbers I can use
- [figure] — [source, linked] — supports [which point]

## Numbers I could not verify
- [figure] — [where it appears] — [why it failed]

## Recommended angle
[two sentences: the gap to lead on, and the format]
```

Keep the unverified list in the output. It stops the same figure getting picked up three articles later.

## Verification loop

Before returning, check each line:

1. Every gap traces to a page that was actually fetched
2. Every figure carries a source URL, or sits in the unverified list
3. Every finding speaks to the reader from Step 1

If any check fails, return to the step that produced the line and correct it.

## Test it

Three scenarios worth running:

1. A keyword where community results dominate the SERP. The output should flag tone as a finding.
2. A keyword with no connector configured. The output should still rank gaps from the SERP alone.
3. A request phrased as "write me an outline for X". The skill should return findings and decline the outline.

## What still needs a person

Which gap is worth a week. That depends on what can be proved, who the reader is, and what the site can rank for. Treat any tool claiming to make that call with suspicion.


---

## FILE: `researching-content/reference/blocked-domains.md`

Save this block at `~/.claude/skills/researching-content/reference/blocked-domains.md`

```markdown
# Blocked Domains

## Contents
- Why the filter exists
- The list
- Situational additions
- Matching rule

## Why the filter exists

Competitors get read to learn what page structure the SERP rewards. A discussion thread at position two is not a structure that can be copied into a layout, and counting it distorts every average calculated: word count, heading depth, format mix.

So it leaves the structural set and stays in the brief as a finding. Where community or video results own the top of a SERP, that says something about the tone the page needs, and that belongs in the intent section.

## The list

**Discussion and Q&A**
```
reddit.com
quora.com
stackoverflow.com
stackexchange.com
news.ycombinator.com
```

**Social and professional networks**
```
x.com
twitter.com
linkedin.com
facebook.com
instagram.com
tiktok.com
pinterest.com
threads.net
```

**Video**
```
youtube.com
vimeo.com
```

**Free-publish platforms**
```
medium.com
substack.com
slideshare.net
dev.to
hashnode.dev
```

**Marketplaces and review aggregators**
```
amazon.com
ebay.com
walmart.com
g2.com
capterra.com
trustradius.com
getapp.com
softwareadvice.com
```

Review aggregators are the judgment call. On a "best tools" query they are the competition and stay in. On a how-to or definitional query they are noise. Decide per brief and record which way it went.

## Situational additions

Add per brief when a domain clearly is not a ranking competitor for the query:

- Wikipedia, on anything non-definitional
- GitHub, on anything not developer-facing
- Government and standards bodies, where they rank as the source rather than a competing page
- The client's own domain, when the job is a refresh instead of a new page

## Matching rule

Lower-case the URL, match on substring, drop on any hit.

Substring matching catches subdomains and country variants (`uk.linkedin.com`, `old.reddit.com`) without a separate entry for each.
```


---

## FILE: `researching-content/reference/citation-benchmarks.md`

Save this block at `~/.claude/skills/researching-content/reference/citation-benchmarks.md`

```markdown
# Citation Benchmarks

## Contents
- Coverage and limits
- Category split
- Community source order
- Owned formats that earn citations
- How to use these

## Coverage and limits

Aggregate ranges across a B2B SaaS client portfolio, 90-day windows, never a single account. Accounts under 500 citations in a 90-day window are excluded, because small samples swing far enough to widen every band without adding signal.

Do not carry these into a category outside B2B SaaS.

## Category split

| Who earns the citation | Share of all citations |
|---|---|
| Sources that never mention the brand | 53% to 86% |
| A competitor | 4% to 20% |
| Independent media, analysts, vertical review sites | 0.7% to 19% |
| Community and video sources | 2% to 11% |
| The brand's own pages | 1% to 12% |
| Roundups that mention without citing | 0.2% to 5% |

The first row sets the ceiling on visibility work more often than any competitor does. When the owned share sits at the low end, writing more pages is rarely the whole answer.

## Community source order

Holds almost everywhere in B2B SaaS, in this order:

1. Reddit
2. YouTube
3. LinkedIn
4. Medium
5. Quora

Facebook, GitHub, and Stack Overflow appear and are category-dependent.

## Owned formats that earn citations

Five formats repeat across categories:

1. Category listicles
2. Alternatives and comparison pages
3. Explainers that define a category
4. Integration pages
5. Product announcements

## How to use these

Compare a fresh 90-day pull against the bands above. A pull that sits outside a band is either a genuine outlier worth investigating or a sign the query set is wrong. Check the query set first.

When a category returns the brand absent from most answers, the work is finding the questions it is missing from and covering those in the formats above.
```
