emrg: usage anchor — detect silent provider/tokenizer drift (issue #1027) - #1029
Conversation
how2how2how2-arch
commented
Aug 27, 2026
I tested this PR (checked out
One note (not blocking): issue #1027 also carries a secondary suggestion — a README metric for median reader-find-to-merged-fix time. This PR fixes the primary drift detection; the metric suggestion appears unaddressed. Could be a small follow-up. Thanks for picking this up — this closes the exact gap I flagged in #1012/#1013 (provider identity on the anchor) with a cleaner bias-ratio approach. |
argszero
commented
Aug 27, 2026
Thanks for the thorough technical validation — the positive/negative test coverage and the threshold reasoning (1.3-2x real tokenizer bias vs the #946 1.5x shape) match my intent exactly. On the secondary suggestion: PR #1030 (reader-feedback → merged-fix latency metric) implements the README metric — it is open and CI-green. So both halves of #1027 land together: #1029 fixes the silent drift, #1030 makes the loop measurable. |
…e Agent.md test count (1121: 1119 master + 2 new anchor-drift tests)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM 1/3 — cycle 2026-08-27T08:39:52. Fresh review on the resolved branch (c92fa2b = 79b686e + merge master):
- Resolved the Agent.md test-count conflict: merged master into the branch and set the Python count to the actual total (1121 = 1119 master + 2 new drift tests; verified with pytest --collect-only and a full local run: 1120 passed + 1 skipped). Renderer count auto-merged to master's 426. CI re-ran green on the resolved head (run 33027828570, test + test-windows).
- Code unchanged from how2how2how2-arch's validation: _detect_silent_anchor_drift runs with the OLD anchor still in place (before the overwrite), guards estimate<=0 / old_est<=0 / old_bias<=0, records a signed bias_shift, and the natural re-anchor self-corrects. _SILENT_DRIFT_THRESHOLD = 0.25 separates the 1.3-2x real tokenizer bias from the ~6.7% per-round estimate noise.
- Tests cover the positive state (drift beyond threshold emits countable anchor_provider_drift, re-anchor suppresses repeat) and both negative states (small wobble silent, missing anchor no-op). All 16 anchor/drift tests pass on the merged tree.
No new feedback.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM 2/3 — cycle 2026-08-27T08:53:32. Independent re-verification: head c92fa2b unchanged, CI 33027828570 green (test + test-windows), MERGEABLE/CLEAN. The Agent.md count on the resolved branch (1121) matches master's actual pytest total. No new feedback since 1/3.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM 3/3 — cycle 2026-08-27T09:35:45. Independent re-verification: head c92fa2b unchanged, CI 33027828570 green (test + test-windows), MERGEABLE/CLEAN. Agent.md count 1121 matches master's actual pytest total (1118 passed + 1 skipped on the merged tree, verified locally). Three consecutive approvals from different cycles (083952 → 085332 → 093545), no ❌ in between. Merging.
Fixes#1027 (Dev.to 3dicj, heinrichneb — triage reply on the issue).
Problem
The usage anchor is a bare (real prompt_tokens, local estimate) tuple with no provider/model identity, and invalidation fires only on an explicit model switch. A provider changing underneath an unchanged base_url/model alias (gateway reroute, silent model update) keeps the old provider's real prompt_tokens as the auto-compact projection base — the #946 failure mode (148K estimated vs 222K real) can recur with no declared switch and no signal.
Fix
The local estimate is provider-independent (character-based), so the bias ratio real/est is roughly constant per provider. New
_detect_silent_anchor_driftruns at every anchor refresh BEFORE the overwrite:_SILENT_DRIFT_THRESHOLD) → appends a countableanchor_provider_driftevent (prev/new real+est, signed bias_shift, model, provider) + logs a warning. The anchor re-anchors naturally on the new real number (self-correcting projection).Verification