AI citation tracking
- Read profile: keywords.targets (the query set), competitors, site url,
and the optional
citations: {engines: [...]} key (see Engine set
below).
- For each query (cap 20 per run; rotate through the set across runs),
ask each engine in the engine set that is actually reachable from this
session. Sources in order of preference: an authorized AI-search
connector; the search-data adapter's AI-visibility read, when its
tools are present in this session (the search-data slot, ADR-0009 in
the repo; the known adapter is OpenSEO - see
$CLAUDE_PLUGIN_ROOT/docs/connectors.md - licensed data, and every
line carrying it names the adapter as its source); WebSearch with
engine-targeted queries; plain WebSearch otherwise. Never scrape
engines through automation that violates their ToS.
- Record per query: engine | our domain mentioned? | cited (linked)? |
position (only when cited - the ordinal below) | sentiment (only when
mentioned - the label plus its evidence quote, below) | competitors
mentioned | answer summary (<=30 words).
- Metrics: mention rate, citation rate, share of voice vs competitors
(mentions of us / mentions of anyone tracked).
- Persist to runs/YYYYMMDD-citations/ + append one signal line with the
headline movement vs the previous run (diff the last runs/ folder).
- New citation appearing or disappearing on a money query -> P1 signal.
- When
runs/<date>-ai-baseline/REPORT.md exists in the brain (written by
/organic-os:setup's AI-visibility baseline step), compare this run's
headline numbers against it and report movement, not just this run's
absolutes - see Baseline comparison below for what movement now covers.
Position within the answer
When the brand IS cited, record where it sits in the answer. One of four
ordinal values, best to worst:
lead-answer - the answer's opening or primary recommendation is
built on the brand; a reader who stops after the first paragraph has
seen it.
supporting-mention - the brand is named with substance in the body
of the answer, as one of the inputs the answer actually uses.
listed-among-others - the brand appears only inside a list or
comparison of alternatives, with nothing said about it specifically.
footnote-link - the brand appears only as a cited source link; the
answer text itself never names it.
An uncited mention gets no position value - position describes where a
citation sits, and recording one without a citation would overstate the
result.
Sentiment of the mention
When the brand is mentioned, judge the sentiment of that mention from the
answer text: positive, neutral, or mixed-negative. Every sentiment
label MUST carry the exact quoted phrase from the answer that justifies
it - never a bare label without the quote. The quote is the evidence and
the check: anyone reading the report can re-judge the call from the same
words. If no phrase in the answer supports a judgment either way, the
label is neutral with the brand's surrounding sentence as the quote.
Baseline comparison and movement
The per-query table in this run's REPORT.md carries the position and
sentiment columns from step 3. The baseline REPORT.md format extends the
same way, additively: new baselines written from now on include both
columns; old baselines without them compare on presence only, and the
movement section states that plainly ("baseline predates
position/sentiment fields - movement reported on presence only").
Movement reporting covers three layers, deepest available first:
- Presence: cited or not, mentioned or not, vs the baseline or the
previous run.
- Position: when both runs have position values, report the shift by
name - "cited, and moved from listed-among-others to lead answer".
- Sentiment: when both runs have sentiment values and the label changed,
report it with the new evidence quote attached - "sentiment shifted
from neutral to mixed-negative; quote attached".
Honesty rules
- This method samples, it does not measure. A run covers the queries it
checked on the engines it could reach, nothing more - never let a
report imply broader coverage than that.
- Every REPORT.md lists which engines were actually reachable from the
session that ran it, and which configured engines were not.
- Sentiment is a judgment call and is labeled as such in the report; the
recorded quote is the check on that judgment.
- Position and sentiment are recorded only from answer text actually
read this run - never inferred, never carried forward from a previous
run.
Engine set (BYO, no tiers)
The default engine set, canonical here (see docs/INFORMATION-MAP.md in
the repo): ChatGPT, Perplexity, Google AI Overviews, Gemini, Microsoft
Copilot.
The set is profile-configurable via the additive
citations: {engines: [...]} key in site-profile.yaml (absence means
the default set; schema_version stays 1 - documented in
site-repo-contract.md). Each listed engine is checked only if it is
reachable from the session running the tracker - an unreachable engine
is listed as unreachable in the report, never silently skipped and never
guessed at. Users add engines the same way: one more list entry, checked
through the same connector-or-WebSearch path under the same ToS rule.
No tiers, no per-engine pricing - commercial AI-visibility tools sell
extra engines, per-answer position, and sentiment as paid add-on tiers;
here they are the same skill reading the user's own reachable surfaces,
inside ADR-0006's no-scraping rule (docs/adr/0006 in the repo).
1---2name: hoo-citation-tracker3description: Use to measure AI answer-engine visibility - "are we cited by ChatGPT/Perplexity", "AI share of voice", /organic-os:citations, or the weekly routine's citation step.4---56# AI citation tracking781. Read profile: keywords.targets (the query set), competitors, site url,9 and the optional `citations: {engines: [...]}` key (see Engine set10 below).112. For each query (cap 20 per run; rotate through the set across runs),12 ask each engine in the engine set that is actually reachable from this13 session. Sources in order of preference: an authorized AI-search14 connector; the search-data adapter's AI-visibility read, when its15 tools are present in this session (the search-data slot, ADR-0009 in16 the repo; the known adapter is OpenSEO - see17 `$CLAUDE_PLUGIN_ROOT/docs/connectors.md` - licensed data, and every18 line carrying it names the adapter as its source); WebSearch with19 engine-targeted queries; plain WebSearch otherwise. Never scrape20 engines through automation that violates their ToS.213. Record per query: engine | our domain mentioned? | cited (linked)? |22 position (only when cited - the ordinal below) | sentiment (only when23 mentioned - the label plus its evidence quote, below) | competitors24 mentioned | answer summary (<=30 words).254. Metrics: mention rate, citation rate, share of voice vs competitors26 (mentions of us / mentions of anyone tracked).275. Persist to runs/YYYYMMDD-citations/ + append one signal line with the28 headline movement vs the previous run (diff the last runs/ folder).296. New citation appearing or disappearing on a money query -> P1 signal.307. When `runs/<date>-ai-baseline/REPORT.md` exists in the brain (written by31 `/organic-os:setup`'s AI-visibility baseline step), compare this run's32 headline numbers against it and report movement, not just this run's33 absolutes - see Baseline comparison below for what movement now covers.3435## Position within the answer3637When the brand IS cited, record where it sits in the answer. One of four38ordinal values, best to worst:3940- `lead-answer` - the answer's opening or primary recommendation is41 built on the brand; a reader who stops after the first paragraph has42 seen it.43- `supporting-mention` - the brand is named with substance in the body44 of the answer, as one of the inputs the answer actually uses.45- `listed-among-others` - the brand appears only inside a list or46 comparison of alternatives, with nothing said about it specifically.47- `footnote-link` - the brand appears only as a cited source link; the48 answer text itself never names it.4950An uncited mention gets no position value - position describes where a51citation sits, and recording one without a citation would overstate the52result.5354## Sentiment of the mention5556When the brand is mentioned, judge the sentiment of that mention from the57answer text: `positive`, `neutral`, or `mixed-negative`. Every sentiment58label MUST carry the exact quoted phrase from the answer that justifies59it - never a bare label without the quote. The quote is the evidence and60the check: anyone reading the report can re-judge the call from the same61words. If no phrase in the answer supports a judgment either way, the62label is `neutral` with the brand's surrounding sentence as the quote.6364## Baseline comparison and movement6566The per-query table in this run's REPORT.md carries the position and67sentiment columns from step 3. The baseline REPORT.md format extends the68same way, additively: new baselines written from now on include both69columns; old baselines without them compare on presence only, and the70movement section states that plainly ("baseline predates71position/sentiment fields - movement reported on presence only").7273Movement reporting covers three layers, deepest available first:7475- Presence: cited or not, mentioned or not, vs the baseline or the76 previous run.77- Position: when both runs have position values, report the shift by78 name - "cited, and moved from listed-among-others to lead answer".79- Sentiment: when both runs have sentiment values and the label changed,80 report it with the new evidence quote attached - "sentiment shifted81 from neutral to mixed-negative; quote attached".8283## Honesty rules8485- This method samples, it does not measure. A run covers the queries it86 checked on the engines it could reach, nothing more - never let a87 report imply broader coverage than that.88- Every REPORT.md lists which engines were actually reachable from the89 session that ran it, and which configured engines were not.90- Sentiment is a judgment call and is labeled as such in the report; the91 recorded quote is the check on that judgment.92- Position and sentiment are recorded only from answer text actually93 read this run - never inferred, never carried forward from a previous94 run.9596## Engine set (BYO, no tiers)9798The default engine set, canonical here (see docs/INFORMATION-MAP.md in99the repo): ChatGPT, Perplexity, Google AI Overviews, Gemini, Microsoft100Copilot.101102The set is profile-configurable via the additive103`citations: {engines: [...]}` key in site-profile.yaml (absence means104the default set; `schema_version` stays 1 - documented in105site-repo-contract.md). Each listed engine is checked only if it is106reachable from the session running the tracker - an unreachable engine107is listed as unreachable in the report, never silently skipped and never108guessed at. Users add engines the same way: one more list entry, checked109through the same connector-or-WebSearch path under the same ToS rule.110No tiers, no per-engine pricing - commercial AI-visibility tools sell111extra engines, per-answer position, and sentiment as paid add-on tiers;112here they are the same skill reading the user's own reachable surfaces,113inside ADR-0006's no-scraping rule (docs/adr/0006 in the repo).