Repository navigation
Releases
CiteGEO 0.6.0
Four merges. The last release joined what the product measured to what it
advised. This one is about the product being usable and honest on the screen:
pages that say which page they are, a drawer a keyboard can leave, a report
that had not drawn since the app became a module, and a browser suite that
tests the product that actually ships rather than the one it used to be.
Added
- A tab row for the machine pages. Results and Configuration had no way in.
The only control that reached Results rendered on Results, and nothing reached
Configuration at all. Models and surfaces, Results, Current report and
Configuration now reach each other the way Act's five pages already did. - Asking for a browser by name. The engines route probed for a debuggable
browser on every read, so opening a settings page attached a debugger to
whatever was listening on the local debug port. It reports "Not checked" until
a "Check for a browser" button is pressed.
Changed
- Site marks are stored, not hot linked. The icon service kept each rival's
address, so drawing your own dashboard fetched an image from every competitor
on it and told each one you had looked. The server reads the mark once and
keeps the bytes, capped at 32KB. A record from an older build is read again
rather than drawn. - One primary action per page, and one archive. Pages opened with a warning
and offered several equally weighted buttons. Each now leads with the one
action it is for, and the two separate archives are folded into one. - The run request answers when the run starts. It had waited for the whole
run to finish, so the page sat still while work was already happening. A run
also says how long it has left.
Fixed
- A page named itself after a different page. Trust and Sources both printed
"Answer engine" while loading, on error, and with no answers, and a project
with no answers said it permanently. - A shut drawer kept the keyboard. Five controls inside an
aria-hidden
drawer stayed tabbable and one of them took focus and typing. The shut drawer
isinert, and Escape closes it. - Save project did nothing. The handler looked for an element HTML does not
have, so the request was never sent, the field reverted, and nothing said no. - The current report had not drawn since the app became a module. It read a
global set by a deferred module from a classic block, so its only run was
always too early, and the shell it drew for itself carried the navigation from
before the rail was cut to six destinations. It renders as a page in the
current shell. - One save, said twice. A page that prints a notice in its own live region
no longer also raises a toast with the same sentence. - A retired model is told apart from a refused request, and a key's own
budget is read rather than only the account's credits. - Dark palettes and table floors. Every dark token has a dark value, the
brand column no longer collapses, and a column with nothing in it says "never
named" rather than leaving the cell blank.
Removed
- Fork design notes that were being published with the documentation.
Full changelog: https://github.com/ankit373/citegeo/blob/main/CHANGELOG.md
Image: ghcr.io/ankit373/citegeo:0.6.0
v0.5.0
Fifteen merges since 0.4.0.
The product could already say what was wrong, and could already test whether a change had worked. Nothing joined the two. A draft was written from a measured gap, read, approved, and then forgotten: no field recorded that it went live, so no later run could be read as before or after it.
Both ends joined
A published draft starts the experiment that measures it. The treated arm is read off the evidence the draft already carried, rather than selected a second time by hand. Starting one by hand used to split a single selection down the middle, so which questions were treated depended on the order somebody clicked in. The control is now every question with a baseline the change was not aimed at.
Questions are proposed from what anyone was observed to ask. Search records and the conversation corpus had existed only to score a proposal afterwards. The Search Console pull was discarding five thousand rows after matching them against the questions already chosen, which is circular by construction. Where nothing was observed, the model is told that every question it proposes is its own supposition.
What each page did over time is derived at last. It was always derivable: a citation is recorded against an answer, and an answer carries its run and its date. A run where nothing was cited says nothing about any page and is set aside rather than read as every page losing its citation at once. A page cited once has no pattern to lose and is not called dropped.
The pages that won a question reach the brief that answers it. A citation source kind had been declared since it was written and nothing ever emitted one, so a brief named the rivals that beat you without showing what their pages covered.
Fixed
A visibility score is an index out of a hundred and the memo formatted it as a proportion, so a reading of 1.4 printed as "moved up from -70.0% to 140.0%". The endpoints mixed an overall score with a between-run change and went below nought, which no reading can be. The tests had encoded the same mistake.
Also: a critical alert that fired on a two-answer run naming nobody; twenty-three questions that never named the brand printed in green as agreed; one page cited by five answers printed as five pages disagreeing; a crawler table keyed to the wrong project; fourteen of twenty four assistants never asked.
Full detail in CHANGELOG.md.
CiteGEO 0.4.0
Twenty merges since 0.3.1, and one theme: the distance between a number and a
claim.
Every panel in this release answers something this category reports a figure
for without ever asking. Whether a cited page was used or only listed. Whether
the figure is any good for a brand of this kind. Whether the wording or the day
decided it. Whether the product is right about what it read. And whether the
change you made is what moved the number.
Two of them are the standard protocol of this field arriving here for the first
time: a control arm, and a person checking the classifier.
Measuring what a citation is worth
Uptake, whether a cited page shaped the answer. A citation says a page was
listed. It does not say the answer used it. Measured as vocabulary overlap
between the page and the answer, because exact phrases find nothing on a real
archive: models rewrite rather than copy. Six live runs scored nought on
phrases and 0.48 to 0.67 on terms.
Who gets the credit. The gap between being cited and being named, from the
two halves that were already stored.
What kind of page gets cited. The format and the source of each cited page
against the published shares, so a result says which kind of page is winning
and not only which ones.
How the pages that beat you are built. The one lever here with a causal
test behind it rather than a correlation, and the panel says it is zero sum: in
that audit the credit moved between documents and the total did not rise.
Who supplies these answers. Citation concentration as a curve. A category
where a handful of domains hold most of the citations is a different game from
a long tail, and nothing here said which one you are in.
Reading a figure against something
Against brands like yours. A visibility figure read against what a declared
kind of brand tends to get. Absent until the kind is declared, never inferred,
and the verdict comes off the range rather than the point.
How steady the framing is. Naming had a stability figure. Framing, the more
volatile half of the same score, had none.
What decides whether you appear. The variance share across the question,
the model and the day, asked of your own archive rather than quoted from a
paper.
Phrasing. Holds the day still and varies the wording, the companion to
asking the same question again on another day. Neither says anything alone.
Checking the instrument
The decoy. A name you declare irrelevant, carried through every run beside
the brand. How often the product finds something that is not there is its own
error rate, reported as the upper end rather than as a share.
Check the machine. A random sample of what the classifier decided, put to a
person. Every figure here rests on a model reading what another model wrote,
and until now nothing put a number on that.
Interference. Published work pushes a rewritten document into generated
answers at about a one in two success rate, and the rewrites stay factually
consistent with their originals, so nothing that checks facts catches one. What
is left is shape, compared over reads already stored.
Cause, rather than coincidence
Did your change do anything. A difference in differences against a control
arm. No control concludes nothing, because a number moving after you changed
something is not evidence your change moved it. A band that straddles nought
says nothing was shown, which is not the same as showing nothing happened.
Was it you, or did the model ship. The version the provider says it ran is
stored and reported. Boundaries where presence moved by more than the noise on
either side are named, a provider that only echoes the model back is
unconfirmed rather than steady, and an experiment names a version that changed
inside its window.
Also
Ready to paste. Fixes written from what the site actually shows, one to
twenty a day, default two. The count is a setting rather than somebody else's
constraint. Generation never reaches out and never invents one, and fewer than
asked for says so instead of padding.
Which surfaces this browser can actually drive. Asked before a run rather
than discovered by spending one.
Two measurements had no door. A rewording and a decoy could be measured and
not added. Both can now be created from the panel that reports them.
The image runs on Node 26 and the suite is tested on the version it ships on.
CiteGEO 0.3.1
Two browser surfaces were reporting the wrong thing, and one of them was
reporting it as a measurement.
Both are the same mistake in two places: a condition that is an instruction to
whoever runs this was being recorded as a finding about the surface. In a tool
whose whole claim is that an absence is reported as an absence, that is the
failure that matters most.
Fixed
Copilot answers again. The surface moved to copilot.com, the old host
redirects, and the redirect drops the query string the question was put in, so
every run landed on an empty chat however the browser was signed in.
The question is typed into the composer now. The editor accepts text several
seconds after it appears in the markup, and sending an empty composer still
returns a reply, so the posted question is read back before anything is waited
for. Archiving that reply would have recorded an answer to a question nobody
asked.
Copilot citations come back empty rather than invented. It lists each source
as a title and a domain and keeps the link in a click handler, so no page URL
can be read. Guessing one would have sent the page reader off to fetch a
homepage and report it as the page the model cited.
A ChatGPT sign-in wall is reported as a sign-in wall. The signed-out page
carries one article element, and article was treated as proof a transcript
had rendered, so the wall was reported as a surface that answered nothing.
Referral attribution learnt the new Copilot host, keeping the old one,
because a referral archived before the move is still a Copilot referral. Every
copilot.com arrival had been going uncounted.
Changed
The marketing page states what the product now measures: searching measured
before citation, asking a question more than once, and the range a rate is
consistent with.
Verified
tests 1242 pass 1242 fail 0
9 emitted script blocks parse, 6 stylesheets balanced, 113 doc links resolve
Ten pages opened in a browser against a running server before main moved, and
all four browser surfaces driven against a live browser.
CiteGEO 0.3.0
First release under the CiteGEO name. v0.2.0 is inherited history and
describes a different repository.
This cycle is mostly about the difference between a number and a number you can
act on. Six findings from a read of the published work on generative engine
measurement are answered here, and every panel that reports a figure now also
reports what to do about it.
Measurement
Searching is measured before being cited is. Pr(cited) decomposes into
whether the surface searched at all, and the share cited among those that did.
Counting an answer that never searched beside one that searched and cited nobody
puts two populations under one denominator, and every rate built on it measures
a mixture.
The provider's own account of whether it searched is kept and preferred over
any inference. Only the provider can tell a search that found nothing from a
search that never ran, and that guess was the wider half of the band.
Browser surfaces are told apart by how they ground. An AI overview is
written from the search result it sits on; a chat surface decides per question.
Calling both optional threw the difference away.
Repetitions. A run can ask each question up to ten times, and the answers are
compared pairwise on the sources they cited. Published work puts the day to day
overlap of cited sources near a third, which makes a single pass close to a coin.
A sampling interval on presence. A Wilson interval beside the rate, and a
flag where the range is too wide for the figure to decide anything.
Mentions are checked against the answer the model wrote. Positions are
recounted from the text, and quoted evidence is confirmed to exist in it.
A cited page is counted once however the assistant spelled the URL. Tracking
parameters are dropped and the rest sorted, so one page is one page.
What to do about it
A task listing on the dashboard and the report, ordered by what is holding the
measurement back:
| blocking | no number can be produced at all |
| limiting | a number exists and cannot be trusted or read |
| work | the measurement is sound, this is what it says to do |
Every task carries the observation behind it, and the button lands on the page
that clears it rather than the page being read. Where the product already knows
the cause it gives it, so "find out why 819 answers failed" reads "clear 561
answers lost to the provider returning an error".
Two messages that named the wrong cause are corrected: blocking an AI crawler is
no longer reported as the reason a brand is not cited, because measured across
millions of citations most sites disallowing those agents were cited anyway, and
the citation notice no longer tells somebody to get a provider with web search
when they have one with it switched off.
Also
The score states what it is built to maximise and what it cannot answer. Page
dates are kept on cited sources, so a stored page keeps the date rather than an
age that silently went stale.
Known issue
The Microsoft Copilot browser surface does not answer. copilot.microsoft.com
now redirects to copilot.com/chat, and the redirect drops the query the engine
navigates with, so it lands on an empty chat. The other three browser surfaces
are unaffected.
Verified
tests 1235 pass 1235 fail 0
9 emitted script blocks parse, 6 stylesheets balanced, 113 doc links resolve
Opened in a browser against a running server before main moved: ten pages render
with content, no console errors.