Skip to content

Commit 2aea641

Browse files
1.6.43 items 1-3: internal traffic never reaches the read table
ITEM 1 (applied — the accruing one). `record_read` now drops a request carrying INTERNAL_UA_TOKEN BEFORE it reads any field, exactly as `track_visit` has since the internal-traffic contract existed. The hook arrived with the 2.8.0 floor and never learned the rule, so the hub's health sweep, every satellite's link audit and every post-deploy battery have been landing in `reads` — the busiest "vendor" on the board. "Counted nowhere" includes the read table; this repo was holding half its own contract. Keyed on `ua`, checked against the RESOLVED package rather than assumed: EVENT_FIELDS has `ua`, not `user_agent`, and a drop keyed on the wrong name is a silent no-op — this item's own failure mode. tests pin the field name against `_ledger.EVENT_FIELDS` so a rename fails here, not in production. Five tests, both directions, counts PRINTED beside every result because a bare "no rows" is the negative this round learned not to trust: internal probes : reads 1 -> 1 (delta 0 expected) crawler probe : reads 1 -> 2 (delta 1 expected) token neutralised: reads 2 -> 3 (delta 1 expected) That third line is the one that makes the first mean anything. A `delta 0` proves the drop only if the package WOULD have emitted a row for that request; if an internal UA happened not to reach the crawler lane, the assertion would pass while record_read did nothing. So the mutation check neutralises the token, sends the identical probe, and requires the row to appear. It does. ITEM 2 (already-present, verified rather than assumed). (a) relying on item 18's PER-CALL-SITE UA pin, which is green — not the file-scoped form, which this fork already replaced after proving it false-passes when `headers=` sits on an unrelated code path. (c) tests/test_analytics_classifier.py is here as cargo and its three fork-owned seams were diffed against this tracker rather than trusted to a passing run: the row-key set {timestamp, path, device_type, user_agent, ip_address, location} matches what track_visit writes; `flush()` exists; `ANALYTICS_GEO_LOOKUP` is read by the tracker. ITEM 3 (applied). The traps section is ported verbatim per DIVERGENCES 11's sync rule — 176 -> 248 lines, pure addition, no conflicts. Four traps arrive: headless browsers are crawler-lane from dimll 2.9.0; branch-by- timing on a green push (this fork's own measurement, now fleet doctrine); verify the artifact the claim is about; and assert the corpus is non-empty before trusting a negative. Suite 322 -> 327 passed / 1 skipped. Exit codes captured directly rather than through a pipe — `pytest … | tail` reports tail's status, which is how the template seat committed over a red suite an hour after writing the note warning about it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P6tDZymsTt73Z4xFW1M5JX
1 parent 5d6ab80 commit 2aea641

3 files changed

Lines changed: 223 additions & 0 deletions

File tree

.claude/CLAUDE.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,75 @@ they win.
280280
to main, built by Render inside the minute, red in CD at 14:13Z,
281281
served for ~6 minutes. A host whose DIVERGENCES.md posture fence has
282282
no `deploy:` key still watches main — there the trap is the old one.
283+
- Headless browsers are CRAWLER-lane from dash-improve-my-llms 2.9.0
284+
(measured on the wheel, 2026-08-29: `HeadlessChrome/…` and a
285+
Playwright UA classify `lane: crawler, bot_type: monitor,
286+
vendor_key: headless`; 2.8.0 said browser). A host that screenshots
287+
ITSELF for social cards — Playwright, Puppeteer, a headless Chrome
288+
in a job — now receives the crawler document, not the app shell,
289+
unless the screenshot service sends its own non-headless UA. If a
290+
card went blank or textual after a floor bump, look here before
291+
the template. Same class as the two lane traps above: name the UA,
292+
confirm from the body which document answered.
293+
- Which branch Render actually builds can be measured on a GREEN push,
294+
by TIMING, without waiting for a red one (leaflet, 2026-08-31 — the
295+
method, not just its answer). `main == release == wire` at every step
296+
of a promote tells you nothing: both refs hold the same sha, so the
297+
wire cannot separate them, and four promotes across three hosts said
298+
nothing at all. Sample `/healthz` every ~45 s from the moment of the
299+
push and note when the swap lands relative to the PROMOTE, not the
300+
push. leaflet measured build+swap at 2m03s from the promote; had
301+
Render reacted to the push instead, the same 2m03s would have put the
302+
build live ~1m52s earlier than it appeared, and the wire was still
303+
serving the old sha well past that point. That is STRONG EVIDENCE
304+
that Render is building `release` — not proof, since a queued or slow
305+
build could in principle produce the same shape. The canonical
306+
discriminator is unchanged and still owed: the first push that goes
307+
RED on main must leave `release` unmoved and the wire unchanged.
308+
Worth taking on every SECOND promote — it costs one background
309+
sampler and converts "asserted" into "strongly evidenced".
310+
- Verify the artifact the claim is about, and say which one you
311+
measured. Three hosts got this wrong in one round while holding the
312+
rule: a skip link checked in the received HTML lives in the RENDERED
313+
DOM (muicharts, twice inside an hour, having written the rule
314+
itself); a props table absent from the crawler document is a defect
315+
of the site, not of the harness — pannellum moved that assertion onto
316+
the rendered layout and the pin passed for a fortnight over a corpus
317+
serving zero props. WHEN A LANE DISAGREES, THAT IS THE FINDING; never
318+
relocate the assertion to the lane that passes. And an owner-gated
319+
section needs BOTH cookie states to be a measurement at all
320+
(modelviewer: `credentials: 'include'` → 2,962 B with admin hrefs,
321+
`'omit'` → 108 B with none — hidden, not merely styled away).
322+
The error runs BOTH ways and the second one is worse, because it
323+
sends someone hunting a bug that does not exist: `curl https://…/ |
324+
grep -c skip-link` returns **0** on a host where the skip link is
325+
shipped and working (excalidraw, 2026-08-31) — it is a Dash
326+
component in `app.layout`, so React renders it and the served HTML
327+
never contains it. A fork "verifying the skip link on the wire" with
328+
curl reports a missing feature that is present. Anything built by
329+
the layout rather than written into the template is invisible to the
330+
two artifacts curl can reach; assert it through the layout or a real
331+
browser, and say which you used.
332+
- Assert the corpus is NON-EMPTY before trusting any negative, and print
333+
the count beside the result (note 88). A sweep that found nothing and a
334+
sweep that swept nothing produce the same green, and only one of them
335+
is evidence. Measured here 2026-09-01: this repo's `.flake8` excludes
336+
`docs/*/`, so `flake8 docs/` exits 0 with a file in `docs/` containing
337+
`def broken(:` — the linter is not passing that file, it is not reading
338+
it; `py_compile` sees it at once. Same family, same day: a naive
339+
substring count read fenced documentation as defects (this seat), a
340+
file-scoped grep matched prose ABOUT the defect it was hunting
341+
(muicharts, clerkhook), a `git show … && diff` printed "(empty = same)"
342+
on a comparison that never ran (llms), and `pytest … | tail -2 && git
343+
commit` committed over a red suite because a pipeline's exit status is
344+
the LAST command's (this seat, one hour after writing the note above).
345+
Capture the exit code; count what you swept; say both.
346+
- And the same family one turn later, worth keeping because it nearly
347+
shipped a wrong fact into a spec: extracting a package constant with
348+
`re.search(r"EVENT_FIELDS = \((.*?)\)", src, re.S)` truncated at a `)`
349+
inside a COMMENT in the middle of the tuple, printed eight of sixteen
350+
fields, and reported `'ua' present: False` — confidently, with a
351+
number beside it. Caught only because eight looked too few. When you
352+
parse a language construct out of source with a regex, check the count
353+
against something independent (the file, `python -c "from … import X;
354+
print(len(X))"`, the CHANGELOG) before you believe a negative.

lib/analytics_tracker.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,27 @@ def record_read(self, event):
396396
it appends; the flush does the disk work.
397397
398398
``client_ip`` is dropped unless ``ANALYTICS_KEEP_CLIENT_IP=1``.
399+
400+
INTERNAL TRAFFIC IS DROPPED FIRST, before any field is read (1.6.43
401+
item 1). The network's internal-traffic contract says a request
402+
carrying ``INTERNAL_UA_TOKEN`` is counted NOWHERE, and "nowhere"
403+
includes this table — ``track_visit`` has honoured that since the
404+
contract existed, and this hook, added with the 2.8.0 floor, never
405+
learned it. Until this fix the hub's health sweep, every satellite's
406+
link audit and every post-deploy battery landed in ``reads`` and were
407+
the busiest "vendor" on the board.
408+
409+
Keyed on ``ua``: ``EVENT_FIELDS`` has ``ua``, NOT ``user_agent``, and
410+
a drop keyed on the wrong name is a silent no-op — which is this
411+
item's own failure mode, so the name is checked against the resolved
412+
package rather than assumed (tests/test_internal_traffic.py).
399413
"""
400414
if not isinstance(event, dict):
401415
return
416+
from lib.constants import INTERNAL_UA_TOKEN
417+
418+
if INTERNAL_UA_TOKEN in (event.get("ua") or "").lower():
419+
return
402420
row = {k: event.get(k) for k in EVENT_FIELDS}
403421
if not KEEP_CLIENT_IP:
404422
row.pop("client_ip", None)

tests/test_internal_traffic.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,139 @@ def test_real_traffic_is_still_counted(client):
164164
assert after["bot_hits"] == before["bot_hits"] + 1
165165

166166

167+
# ------------------------------------------------------- the READ table -----
168+
#
169+
# "Counted nowhere" includes the `reads` table (1.6.43 item 1). Everything
170+
# above this point tests `visits`, which `track_visit` has guarded since the
171+
# internal-traffic contract existed. `record_read` — the `on_document_read`
172+
# hook the 2.8.0 floor added — never learned the rule, so until this round the
173+
# hub's health sweep, every satellite's link audit and every post-deploy
174+
# battery landed in `reads` and were the busiest "vendor" on the board.
175+
176+
177+
def _ledger_reads():
178+
tracker.flush()
179+
try:
180+
with open(analytics_path()) as f:
181+
return json.load(f).get("reads", [])
182+
except FileNotFoundError:
183+
return []
184+
185+
186+
def test_the_drop_keys_on_the_field_the_package_actually_sends():
187+
"""This item's own failure mode, guarded.
188+
189+
The drop reads `event["ua"]`. `EVENT_FIELDS` has `ua`, NOT `user_agent` —
190+
a drop keyed on the wrong name is a silent no-op that passes every
191+
"no rows" assertion below by dropping nothing and being asked nothing.
192+
Checked against the RESOLVED package rather than a literal, so a rename
193+
between versions fails here rather than in production.
194+
"""
195+
import importlib.metadata as md
196+
197+
from dash_improve_my_llms import _ledger
198+
199+
from pathlib import Path
200+
201+
assert "ua" in _ledger.EVENT_FIELDS, (
202+
f"the package resolved here ({md.version('dash-improve-my-llms')}) has "
203+
f"no `ua` field: {_ledger.EVENT_FIELDS}"
204+
)
205+
tracker_src = (Path(__file__).resolve().parent.parent
206+
/ "lib" / "analytics_tracker.py").read_text()
207+
body = tracker_src.split("def record_read")[1].split("def _enqueue")[0]
208+
assert 'event.get("ua")' in body, "record_read does not key the drop on `ua`"
209+
assert "INTERNAL_UA_TOKEN" in body, "record_read never checks the token"
210+
211+
212+
def test_an_internal_probe_writes_no_read_row(client, capsys):
213+
"""One probe carrying the token -> ZERO read rows, count PRINTED.
214+
215+
A bare "no rows" is the negative this round learned not to trust, so the
216+
count goes next to the result and the positive control below proves the
217+
pin cannot pass by dropping everything.
218+
"""
219+
before = len(_ledger_reads())
220+
client.get("/llms.txt", user_agent=internal_ua("network-smoke"))
221+
client.get("/llms.txt", user_agent=f"{CRAWLER_UA} {INTERNAL_UA}")
222+
after = len(_ledger_reads())
223+
with capsys.disabled():
224+
print(f"\n internal probes: reads {before} -> {after} (delta 0 expected)")
225+
assert after == before, (
226+
f"internal traffic reached the read table: {after - before} row(s)"
227+
)
228+
229+
230+
def test_a_real_crawler_probe_writes_exactly_one_read_row(client, capsys):
231+
"""The positive control, in the same file as the negative.
232+
233+
A `record_read` that returned unconditionally would satisfy the test
234+
above; this is what stops that passing.
235+
"""
236+
before = len(_ledger_reads())
237+
client.get("/llms.txt", user_agent=CRAWLER_UA)
238+
after = len(_ledger_reads())
239+
with capsys.disabled():
240+
print(f" crawler probe : reads {before} -> {after} (delta 1 expected)")
241+
assert after == before + 1, (
242+
f"expected exactly one read row, got {after - before}"
243+
)
244+
245+
246+
def test_the_zero_above_is_the_drop_working_not_the_probe_being_silent(
247+
client, monkeypatch, capsys
248+
):
249+
"""MUTATION CHECK, and the reason this file has one.
250+
251+
`delta 0` proves the drop only if the package WOULD have emitted a row
252+
for that request. If an internal UA happened not to reach the crawler
253+
lane, the assertion above would pass while `record_read` did nothing —
254+
the vacuous negative this round has now produced three times.
255+
256+
So: neutralise the token, send the identical probe, and require the row
257+
to appear. If it does, the zero above was the drop.
258+
"""
259+
from lib import constants
260+
261+
monkeypatch.setattr(constants, "INTERNAL_UA_TOKEN", "\x00-never-matches")
262+
before = len(_ledger_reads())
263+
client.get("/llms.txt", user_agent=internal_ua("network-smoke"))
264+
after = len(_ledger_reads())
265+
with capsys.disabled():
266+
print(f" token neutralised: reads {before} -> {after} (delta 1 expected)")
267+
assert after == before + 1, (
268+
"with the token neutralised the identical probe STILL wrote no row — "
269+
"so the zero in the test above says nothing about the drop"
270+
)
271+
272+
273+
def test_internal_reads_never_reach_the_rollups_vendor_block(client):
274+
"""The number the hub actually charts.
275+
276+
`vendors[]` and `reads` in the daily rollup are built from this table, so
277+
a token-carrying probe must not appear as a vendor row either.
278+
"""
279+
from lib.traffic_rollup import daily_rollup, load_reads
280+
281+
# Scoped to the rows THIS test causes. The mutation check above
282+
# deliberately writes one internal row (with the token neutralised) to
283+
# prove the drop is load-bearing, so a whole-table assertion here would
284+
# fail on another test's intentional fixture rather than on a defect.
285+
before = len(_ledger_reads())
286+
for _ in range(3):
287+
client.get("/llms.txt", user_agent=internal_ua("link-audit"))
288+
tracker.flush()
289+
new_rows = load_reads(str(analytics_path()))[before:]
290+
internal = [r for r in new_rows
291+
if INTERNAL_UA_TOKEN in (r.get("ua") or "").lower()]
292+
assert internal == [], f"{len(internal)} internal row(s) in the read table"
293+
assert new_rows == [], f"3 internal probes wrote {len(new_rows)} row(s)"
294+
295+
payload = daily_rollup("leaflet", datetime.now().date()) or {}
296+
for v in payload.get("vendors", []):
297+
assert INTERNAL_UA_TOKEN not in str(v.get("key") or "").lower()
298+
299+
167300
# ----------------------------------------------------------------- outbound --
168301

169302

0 commit comments

Comments
 (0)