# Topic Brief

> Verify a chosen topic against primary sources and turn a pile of links and notes into a one-page brief that later skills can build on. Use for "look into this link", "write this topic up", "research this properly", "check whether this is still open", "what do we actually know about this", or when handed an event, program, product, or announcement URL and asked to sort it out. Produces the input that blog-post and carousel-post consume. Finding a topic in the first place is topic-scout; drafting the actual post is blog-post or carousel-post.

- Skill: `chanuk0/topic-brief` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add chanuk0/topic-brief`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chanuk0/topic-brief/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- Author: chanuk0 (https://skillmd.com/u/chanuk0)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/chanuk0/topic-brief

---


# Topic Brief

Takes the links and notes for one chosen topic, verifies them, and produces **a one-page
brief**. Everything downstream reads this file instead of re-reading the raw links, so the
facts get checked once rather than three times, differently.

This skill does not write posts. If the user wants a post after the brief, hand the brief
path to `blog-post` or `carousel-post`.

## What goes wrong here, and the rule that stops it

**The single most common failure is drift.** You start with a thin row — a name and one
link — start searching to "learn more", and come back with a *different* topic: a
competitor's similar offer, or the same organization's previous round with different terms.
The brief then describes something that does not exist.

Everything in step 1 exists to stop that.

## Procedure

### 1. Set the anchor -- before any searching

Pull these five values out of the source row, link, or notes the user gave you, and write
them down. **The anchor does not change for the rest of this skill.**

| Anchor | Where it comes from | Example |
| --- | --- | --- |
| A1 organization | Topic name, link domain | Acme Bank (`acme.example`) |
| A2 core benefit | Topic name, description | 50 currency units for new signups |
| A3 edition | Event code, notice number, year-month in the URL | `e202608_newsignup` / August 2026 |
| A4 expiry | Description field | Through August 2026 |
| A5 who qualifies | Description field, if present | New customers only |

- No link? Leave A3 empty and anchor on A1, A2, A4.
- **If the row is too thin to anchor** — a name, and nothing else — **do not search. Ask the
  user one question about what this topic is.** Guessing from a name alone returns a
  different topic, and that is the most frequent accident in this skill.

### 2. Sort the links

- **Primary** — the organization's or authority's own domain: official page, public notice,
  regulation, product disclosure. **The only acceptable source for a number or a condition.**
- **Secondary** — blogs, forums, news, video. Records *how you found it*. **Never a source
  for a figure**, even a correct-looking one. Mark anything that looks sponsored or
  affiliate-driven as such.

### 3. Read the primary page

Open it and confirm, at minimum:

- What the benefit is and how much / in what form (cash, credit, points, voucher, access)
- Who qualifies (new customers only? age, status, residency limits?)
- Dates (opens, closes, early-close clause) and when the benefit actually arrives
- What you have to do (sign up only, or additional steps?)

If the fetch returns a title and no body — common on client-rendered pages — **do not give
up.** Reopen with a browser tool and read the rendered text.

Anything you cannot confirm stays literally `[unconfirmed]`. Do not fill it from a blog.

If there is no primary source at all, or the link is dead, go to purpose A below. If you
still can't find one, put **"no primary source -- every figure unverified"** at the top of
the brief and tell the user.

### 4. Search -- only for these three purposes

Search fills the gaps left after reading the primary page. **There is no fourth purpose.**
Aimless "let me learn more" searching is what swaps the topic out.

- **Purpose A -- find the primary page.** When there is no link, the link is dead, or what
  you were given isn't official. You are looking for **one page on A1's own domain**. Found
  it? Go back to step 3 and read it.
- **Purpose B -- fill the `[unconfirmed]` fields.** Payout timing, withdrawal or expiry
  conditions, fine-grained eligibility, whether benefits stack. Look in the organization's
  own FAQ, terms, and press releases — conditions missing from the main page are usually
  there.
- **Purpose C -- check for changes and early closure.** Did the dates, amounts, or terms
  change? Did it close early? **A topic with a deadline always gets one purpose-C pass**,
  no exceptions. Writing a post about something that already ended is the worst outcome
  this pipeline can produce.

**Query rules**

- **Every query contains A1 and A2.** (`acme bank new signup bonus payout conditions`)
- Queries without A1 (`bank signup bonuses`, `best student grants`) are **banned**. They
  return a different topic than the one you were asked about.
- For A and B, restrict to A1's domain first. Drop the restriction only if that returns
  nothing.
- For C, put A3 and A4 in the query (`acme bank signup bonus august 2026 ended early`).
- One or two queries per purpose is enough. Rephrasing the same query repeatedly is not
  new information.
- If web search returns nothing useful — regional pages are often poorly indexed — open a
  search engine in a browser tool, read the results, then open the candidate URL directly.
  The drift test below still applies.

**Drift test -- fail any one of these and the result is discarded**

1. **Organization is not A1** → discard. Competitors running a similar offer are the most
   common contaminant.
2. **Edition or dates don't match A3/A4** → discard. The same organization's previous or
   next round, with different terms, is the second most common. Mixing July's terms into
   an August topic gets every number wrong.
3. **Benefit doesn't match A2** → discard. **Unless it comes from A1's own domain** — then
   it is a purpose-C change: record it under `Changes` and in the risk notes. **The primary
   source wins over the description you were given**, which may be an old note.
4. **Can't tell?** Discard, and leave `[unconfirmed]`. A blank is better than a plausible
   guess; downstream skills know how to handle `[unconfirmed]`.

**Source tier does not change because you found it by searching.** Official domain means
primary; blog, forum, news, or video means secondary, however high it ranked.

**When to search less:** if the primary page fills every field with no `[unconfirmed]`
left, skip A and B, run purpose C once, and stop.

### 5. Write the brief

Follow `references/brief-template.md` exactly. Keep the section order — downstream skills
read specific sections by name.

### 6. Rules that outlast the run

- **Re-verifying an existing brief:** update the checked-on date, add one line per changed
  item under `Changes`, then overwrite. **Never edit quietly.** Someone has to be able to
  trace why a number in a published post no longer matches.
- Figures go in the table only with a primary source in the source column. Where secondary
  and primary disagree, primary wins and the gap is noted as a risk.
- **The search stays inside the anchor.** If something else interesting turns up, it does
  not go in this brief. One queue row equals one brief equals one topic. Mention it in your
  report in one line; if the user wants it, it becomes **its own row**.
- Where the description you were handed conflicts with the primary page, primary wins.
  Record it under `Changes` and **ask** before editing the original row — don't silently
  rewrite someone else's note.
- Topics with a deadline get a countdown in `Handoff`. Timing decides production order.

### 7. Report

In chat, report only: brief path / status / list of fields left `[unconfirmed]` / **one line
on the search** (which purposes ran and what they filled, or why none ran). Add a line if
the given description conflicted with the primary source, and a line if you saw a separate
topic worth its own row.

**Do not paste the brief into chat.** The file is the record.

