BlogFindings
AI share of voice: the same 31 answers scored 33.3 percent on one surface and 36.9 on the other
Lantad replayed all 55 answers committed at core/fixtures/tracker-golden/goldens.json through its own shipped extraction pipeline on 26 October 2026, using detectAliasMention, parseJudgeReply and reconcileExtraction from core/src/tracker.ts. 31 of the 55 resolved to a brand mention. Feeding those same 31 into the arithmetic the dashboard uses returns 33.3 percent, because it divides by 93, and feeding them into the arithmetic the presence report uses returns 36.9 percent, because it divides by 84. The numerator is identical. Only the denominator moved, and the function both paths call carries a comment saying one of the two denominators must never be used.
The replay was done on 26 October 2026 against core/fixtures/tracker-golden/goldens.json. Each row carries an answer text, a list of cited URIs, a recorded judge reply and a hand written label. Every row was passed through the shipped functions in the order the production consumer uses them: detectAliasMention for presence, parseJudgeReply for the judge contract, then reconcileExtraction to decide what the run row finally says. Nothing was fetched, no engine was asked anything, no live tracked prompt was run and no database was read. Those 55 answer texts were written by hand to exercise the citation judge, so the mix of brands in them is a property of the test suite rather than a measurement of what assistants emit, and every proportion below describes this file. What does survive the fixture is the arithmetic, because the arithmetic ships and runs on real answers the moment a customer has any. The answers this product stores and the verdicts it draws are visible on what AI says.
In short
- AI share of voice is a ratio with no agreed denominator, and in Lantad's own code two surfaces picked different ones: replaying the 55 committed golden answers on 26 October 2026 gave 33.3 percent on the dashboard arithmetic and 36.9 percent on the presence report arithmetic from an identical numerator of 31.
- The gap is nine entity rows. Of the 62 non-brand entity and answer pairs the dashboard counts, the report counted 53: four were entities outside the tracked roster, and five were roster members the judge listed as recommended entities but not in its competitors field.
- shareOfVoice in core/src/tracker.ts states in its own comment that the denominator is the full auto-detected entity universe and never the tracked competitor roster, because dividing by the roster inflates the brand's share by exactly the entities it is losing to. The presence report in worker/src/reports.ts divides by the roster.
- reportedShareOfVoice in core/src/reports.ts documents itself as counting per mention, so an answer naming a rival three times counts three. Both shipped call paths count per answer instead: over these 55 fixtures the brand numerator is 31 per answer and 36 per mention.
- Nine of the 55 answers contributed nothing to either half, because isMarketVerdict in core/src/tracker.ts admits only the brand, brand_unknown and absent verdicts, and a homonym or a different company sharing the name is excluded by design.
| Surface | Numerator | Denominator | Share | What the denominator holds |
|---|---|---|---|---|
| Dashboard KPI, site/src/lib/tracker.ts | 31 | 93 | 33.3% | Brand answers plus every auto-detected entity answer |
| Presence report, worker/src/reports.ts | 31 | 84 | 36.9% | Brand answers plus tracked roster competitors only |
| Difference | 0 | 9 | 3.6 points | Four off-roster entities and five roster members the judge did not list as competitors |
| Same figures counted per mention | 36 | 98 and 89 | 36.7% and 40.4% | What the reports.ts comment describes but neither path does |
Two denominators shipped in one product
The arithmetic itself is one small function. shareOfVoice in core/src/tracker.ts takes a brand mention count and an all-entity mention count, returns the first over the second, clamps to the range zero to one, and returns null when the denominator is zero or less, on the same unmeasured-is-not-zero rule the other rates follow. The function is unit agnostic. It divides whatever two numbers it is handed, which means it cannot enforce a definition and the definition has to live in its callers.
Its comment states one anyway, in capitals, and the reasoning is sound. The denominator is the full auto-detected entity universe and never the tracked competitor roster, because the roster is a highlight set a customer picked, and dividing by a set the customer picked inflates the brand's share by exactly the entities it is losing to. A rival nobody thought to add is a rival the figure then pretends does not exist.
Two call paths ship. The dashboard KPI in site/src/lib/tracker.ts follows that rule: it sums the brand's daily rollup mentions, takes the entity rollup total, subtracts the brand's own entity row so the brand sits in the denominator exactly once, and divides. The presence report in worker/src/reports.ts calls reportedShareOfVoice, which delegates the arithmetic to the same shareOfVoice and adds a sample floor, and it passes owned mentions over owned plus rival mentions. Its rival figure is the competitor_mentions column of tracker_rollup_daily, and the worker binds that column to the length of the reconciled competitors array, which reconcileExtraction has already scoped to the tracked roster. That is the denominator the comment says must never be used, reached through the function that says so. The public tracked prompts behind both surfaces are listed on tracked prompts, and the per-product differences a buyer is weighing are on compare.
Neither surface is reading the other's number, and in production they also cover different windows, the dashboard over a rolling half window and the report grouped by day and engine. Holding the answer set fixed, as the replay does, isolates the denominator as the only moving part.
Flow: Stored answer to reconcileExtraction; reconcileExtraction (universe) to entities, gated on market verdict; reconcileExtraction (roster) to competitors, scoped to roster; entities, gated on market verdict to Dashboard divides by 93; competitors, scoped to roster to Report divides by 84; Dashboard divides by 93 (33.3%) to shareOfVoice, unit agnostic; Report divides by 84 (36.9%) to shareOfVoice, unit agnostic.
What was replayed on 26 October 2026, and what was not
The population is every row in the committed golden file, which holds 55. Running them through the shipped pipeline produced 31 rows whose final verdict is brand, 14 absent, 2 a different company sharing the name, 1 a homonym, 1 an engine naming the brand only to disclaim knowledge, and 6 with no verdict at all because the judge reply did not parse into the strict contract. Of the 55, 46 passed the market gate and 9 did not. The deduplication the production consumer applies to entity names is a no-op here, because no row in the file names the same entity twice, so the counts in this post match what the rollup would write.
Five limits bound everything above, and the first is the largest. These 55 answers are hand authored test inputs, not captured engine output, and they were written to exercise a judge rather than to be representative. The file is competitor dense by construction, which matters enormously for this particular finding: 58 of the 62 non-brand entity rows belong to names already on the tracked roster, so the fixture is close to the best case for a roster denominator. On a real brand's corpus, where the whole point of auto-detection is that it surfaces rivals nobody listed, the gap this post measures would be expected to be larger, and this file cannot show how much larger. Nothing here estimates that.
Second, one brand is involved, lantad.co and its aliases, so none of this compares vendors. Third, 31 rows is a small base and several cells below are single observations, reported as counts rather than rates. Fourth, nothing here measures stability across repeated runs, which is a separate and larger source of movement: work reported here found that a tracked prompt needed seven runs before its visibility estimate settled, and the question of how many prompts an AI visibility measurement actually needs sits underneath any share figure quoted once. Fifth, this is arithmetic rather than accuracy: the same fixture set was used to audit the neighbouring column, where a word list graded 3 of these 55 answers non-neutral and all three were wrong. The wider programme these sit inside is indexed on research.
| Property of the replay | Value | Why it bounds the finding |
|---|---|---|
| Golden rows replayed | 55 | The whole committed set, not a sample of it |
| Rows resolving to a brand mention | 31 | The numerator of every share figure here |
| Rows passing the market gate | 46 | Only these may contribute entities |
| Non-brand entity and answer pairs | 62 | The dashboard denominator above the brand |
| Of those, names on the tracked roster | 58 | A competitor dense fixture, close to best case for a roster denominator |
| Of those, names off the roster | 4 | Too few to estimate the real-world gap |
| Brands involved | 1 | lantad.co and its aliases only |
| Answers captured from a live engine | 0 | Hand authored test input throughout |
| Repeated runs of any prompt | 0 | Nothing here measures run to run movement |
Where the nine missing entity rows went
The dashboard counted 62 non-brand entity and answer pairs across the file. The report counted 53. Those nine split cleanly into two causes, and they are not the same kind of problem.
Four of the nine are entities that are simply not on the roster. Across the whole file they are four distinct names appearing once each: a search console product, and three names a reader would have to look twice at, Lantern Analytics, LantaData and Lentid. All three are near misses planted in the file to test the fuzzy matcher, each sitting at edit distance two or more from every brand alias, which is itself informative. The auto-detected universe catches whatever the answer recommended; the roster catches only what somebody typed in. That is the inflation the shareOfVoice comment describes, and on this file it is worth four rows.
The other five are more awkward, because they are roster members the report still missed. The report's rival count comes from the reconciled competitors array, which is built from the judge's competitors field and then matched against the roster by a folded name key. The dashboard's universe comes from the judge's recommended entities field. On five answer rows the judge listed a tracked rival among the recommended entities and did not repeat it in the competitors field, so the name entered one denominator and not the other. Nothing is wrong with either field. They answer different questions, one asking what the answer recommended and one asking which rivals it named, and a model answering both will not always agree with itself. The consequence is that the report's denominator is smaller than the roster alone would predict, so its share figure is higher than even the roster rule would give.
Put together: 31 over 93 is 33.3 percent and 31 over 84 is 36.9 percent, a gap of 3.6 points on a fixture built to favour the roster. For a buyer the figure to carry away is not 3.6. It is that a 3.6 point gap existed between two surfaces of one product, from one answer set, with no bug in either query and no disagreement about a single mention. The rivals this corpus happens to name are covered on their own terms under comparisons, and what those vendors actually publish about themselves was read directly in finding that 5 of 7 published a price today. How a composite score hides this sort of choice was opened up on the crawl side, where 972 of 1,419 corpus sites were graded and prose parity took 60.7 percent of every point they lost.
The name verdict gates the numerator and the denominator
Before any division happens, something has to decide what the brand name referred to, and in this pipeline that decision gates both halves of the ratio. Presence is deterministic: an alias list plus edit distance one decides whether the string is in the text, which is a question about characters and needs no model. Identity is the judge's alone, because it is a question about meaning, and a matcher cannot tell a company from an adjective. A mention is the conjunction of the two.
Five verdicts exist in core/src/tracker.ts, and only brand counts as a mention. A different company sharing the name is not one. A common word in another language is not one. An engine naming the brand only to say it does not recognise it is explicitly not one, on the stated reasoning that an engine disclaiming knowledge is the opposite of visibility, so counting it inverts the metric. That narrowing is not theoretical tidying: the literal reading of presence produced a 12.6 percent headline against a truth near one percent, measured here in finding that nineteen counted mentions were about two companies.
The denominator inherits the same gate through a separate function. isMarketVerdict admits only brand, brand_unknown and absent, and the absent case is deliberate: a category answer that never names you is exactly where your rivals are, so it belongs in the universe. A homonym answer and a wrong-company answer do not, because their recommended entities belong to a different market. The comment beside it records what that cost once, a dictionary answer putting three Tagalog words into the live share-of-voice denominator. On this file the gate removed one name, Landa, a real-estate product the engine resolved the brand name to. One is a small number and the mechanism is the point rather than the count. An unclassified run with no verdict is excluded from both halves as well, which is why nine of the 55 contributed nothing. How much of this rests on telling one entity from another is the subject of entity confidence, and the related failure of pointing at the wrong company entirely was counted in finding that most AI citations point at other companies.
-
brand31 rows The only verdict that counts as a mention. Enters both numerator and denominator. -
absent14 rows Name not in the text. No mention, but its entities enter the universe: a category answer is where the rivals are. -
other_entity2 rows A different company sharing the name. No mention, and its entities are refused by the market gate. -
homonym1 row A word rather than an organisation. Refused both ways; a dictionary answer once polluted the live denominator. -
brand_unknown1 row The engine names the brand to disclaim knowledge. Not a mention, but the answer is about this market, so entities count. -
no verdict6 rows Judge reply failed the strict contract. Excluded from both halves rather than scored as a zero.
Lantad
Published .
Every product that measures brand presence in AI answers reports a share figure, and this one does too. A share is a ratio, and a ratio carries no information until you know what sits underneath the line. Two tools can read identical answers, agree on every mention, and still publish numbers that differ by several points, because they disagree about which other names belong in the denominator. That disagreement is invisible from the outside: a dashboard prints a percentage and a reader has no way to recover the set it was divided by. This post opens Lantad's own share arithmetic, replays it over the 55 answers this repository commits as golden fixtures, and reports that two surfaces of this same product divide by different denominators. The measurement framework it sits inside is set out under AI visibility and in the published methodology.
Common questions
What is AI share of voice a share of?
Whatever the vendor divided by, which is not a standard. No search or answer platform publishes a share metric: the Search Analytics API documents clicks, impressions, ctr and position, and Google's AI features guidance names no share figure either. Lantad's dashboard divides brand answers by every auto-detected entity, and over the 55 committed golden answers replayed on 26 October 2026 that gave 31 over 93, or 33.3 percent.
Why would two tools report different share of voice for the same answers?
Because the denominator is a choice. Replaying one answer set through two surfaces of Lantad itself on 26 October 2026 returned 33.3 percent and 36.9 percent from an identical numerator of 31, the difference being nine entity rows: four entities outside the tracked roster and five roster members the judge named as recommended entities but not in its competitors field.
Does dividing by your tracked competitor list inflate the figure?
Yes, and by exactly the rivals you did not think to add. That is the reasoning written into shareOfVoice in core/src/tracker.ts, which states the denominator must be the full auto-detected entity universe and never the tracked roster. On this fixture the inflation was 3.6 points, and the file is competitor dense by construction, with 58 of 62 non-brand entity rows already on the roster, so it is close to the best case rather than a typical one.
What does Lantad report when nothing was measured?
Nothing, rather than zero. shareOfVoice returns null when the denominator is zero or less, and the presence report withholds a share until 12 mentions have accumulated, a floor set in core/src/config.ts. An unclassified answer is excluded from both halves of the ratio, which is why 9 of the 55 golden answers contributed to neither.
See what AI can read on your site
Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.