Count the audience by what a visit did, not by a fingerprint - #244
Conversation
Two corrections to the visitor report, both mine, both found by running it after #238 emptied the wall. THE WARNING FIRED ON EVERY RUN. It cross-checked the crawler fingerprint against Accept-Language and complained when the two disagreed, which held only while one fleet dominated both signals. The morning the snapshot crawler left, the numbers became 773 against 592 and then 62 against 1 -- a permanent warning, which is how a warning turns into a line people skip. It now asks something the data can always answer: are more visitors touching only the gallery than reading the site? `open wall only` is by construction the population the fingerprint did NOT catch -- the classifier takes the impossible ones first -- so a crawl that has changed its viewport lands there whatever else it changed, and no guess about the next fingerprint is needed. Yesterday that reads 661 against 289 and says so. In the ninety minutes after the deploy, 13 against 154, silent. AND THE AUDIENCE WAS OVERSTATED. Every real browser sends Accept-Language. With the wall crawler gone, what was left on /ru and /zh became visible: 62 of 154 visitors sending none, every one reporting an 800px viewport and no browser token. They reach a page outside the wall, so they were counted as readers -- a third of the number this whole report exists to produce. They now have a line of their own, subtracted from readers, and their pages are out of the per-reader list. A line rather than a silent drop, because a few privacy setups do strip the header and this is the report where someone can judge that and add them back. The same rule the wall split follows: an ambiguous population gets named, never a share of "people". Yesterday re-reads as 289 readers and 106 unattributable, where it used to say 395 readers.
PR Summary by QodoClassify audience by visit behavior instead of crawler fingerprints
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1.
|
visitors() defaulted language to "-" when no al= field was present, and the new reader split then read that as "this client omitted Accept-Language" -- taking the visitor, and every page they read, out of the audience. A day's log spans both formats whenever a log-format change lands, and rows written before al= existed carry no field at all, so the report would have quietly shrunk the audience on exactly the day someone went looking at it. Absent and empty are now different things: only a field that is present and empty says anything about the client. It changes no number today -- the beacon went live after al= did, so every beacon row in the current logs carries the field, and yesterday still reads 289 readers and 106 unattributable. It is a guard for the archived logs and for the next format change.
|
Real, and it would have been invisible in the direction that matters: quietly shrinking the audience, on exactly the day someone goes looking at a log that spans a format change.
Checked against yesterday's log, which does span both formats: 289 readers and 106 unattributable, unchanged. The beacon went live after The regression test adds a pre-rollout row ending at 753 runs, 3,336 assertions, 0 failures. |
Two corrections to the visitor report in
deploy/audience-report.sh, both mine, both found by running it after #238 emptied the wall.The warning fired on every run
It cross-checked the crawler fingerprint against Accept-Language and complained when the two disagreed. That held only while one fleet dominated both signals. The morning the snapshot crawler left, it became 773 against 592, then 62 against 1 — a permanent warning, which is how a warning turns into a line people skip.
It now asks something the data can always answer: are more visitors touching only the gallery than reading the site?
open wall onlyis by construction the population the fingerprint did not catch — the classifier takes the impossible ones first — so a crawl that has changed its viewport lands there whatever else it changed, and no guess about the next fingerprint is needed.And the audience was overstated
Every real browser sends Accept-Language. With the wall crawler gone, what was left on
/ruand/zhbecame visible: 62 of 154 visitors sending none, every one reporting an 800px viewport and no browser token. They reach a page outside the wall, so they were counted as readers — a third of the number this report exists to produce.They now have a line of their own, subtracted from readers, and their pages are out of the per-reader list. A line rather than a silent drop, because a few privacy setups do strip the header and this is the report where someone can judge that and add them back. Same rule the wall split follows: an ambiguous population gets named, never a share of "people".
The same script over three windows
Yesterday re-reads as 289 readers and 106 unattributable, where it used to say 395 readers.
Tests
The drift test is replaced by one that adds four wall-only visitors reporting a viewport a real machine has — so the fingerprint cannot see them, which is the point — and asserts the warning names them. Plus a test that the fixture raises no warning, and one that a reader-shaped visit with no Accept-Language is counted on its own line and keeps its page out of the reader list.
752 runs, 3,331 assertions, 0 failures. No rubocop offences in the changed file.