emrg: invalidate usage anchor on mid-session model/provider switch - #1001
Closed
argszero wants to merge 1 commit into
Closed
emrg: invalidate usage anchor on mid-session model/provider switch#1001argszero wants to merge 1 commit into
argszero wants to merge 1 commit into
Conversation
Fix#1000: _handle_set_model switched llm.config.model but left the per-session usage anchors holding the OLD model's real prompt_tokens. The auto-compact projection (real_anchor + est_delta) then carried a stale tokenizer baseline into the new model's rounds, re-introducing the #946 underestimation (148K est vs 222K real) on the first post-switch round. Now: when the API model actually changes, drop all anchors and mark the drops deliberate (mirror of the post-compact drop) so the fail-LOUD anchor-loss warning does not false-positive; the next round re-anchors from the new provider. +2 tests, Agent.md count 1102->1104.
This was referenced Aug 26, 2026
argszero
commented
Aug 26, 2026
OwnerAuthor
Closing as superseded by #1003 (same fix for issue #1000, submitted ~5 min later by the issue author). Why #1003 wins the consolidation:
Keeping all three duplicates open would split LGTM votes across PRs and force messy Agent.md doc-count conflict resolution on any double merge. #1003 is fully verified (CI double-green, full suite 1105 passed + 1 skipped, import OK) and has my LGTM. Merging #1003 closes #1000. |
argszero
commented
Aug 26, 2026
OwnerAuthor
This was referenced Aug 26, 2026
argszero added a commit
that referenced
this pull request
Aug 26, 2026
…#1004) The doc-count line was a single contention point: python-test PRs bump the python count on line 1 while renderer-test PRs bump the renderer count embedded in the GUI line — any two in-flight PRs conflict on Agent.md (observed 3x this week: #997/#998/#999/#1001/#1002/#1003). Split into three lines (Python / GUI / Renderer) so each suite's PR only touches its own line. Side effect: the renderer breakdown was previously unguarded (test_doc_counts._gui_breakdowns only parses the first (N: ...) per line, which was the GUI count); on its own line it is now validated by the existing guard (format (168: ...) so all parts parse). Co-authored-by: EMRG Evolution <emrg@argszero.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes#1000 — the usage anchor is not invalidated on a mid-session model/provider switch.
Root cause
The auto-compact usage anchor (
emrg/server/daemon.py) is a per-session(real_prompt_tokens, local_estimate)pair, refreshed after every round from the provider's realprompt_tokens. The auto-compact gate projects:so the systematic local-estimator undercount (observed 148K est vs 222K real, #946) never accumulates.
The anchor is deliberately invalidated on auto-compact and manual compact — but not in
_handle_set_model. After a mid-session/modelswitch, the anchor still holds the old model's realprompt_tokens, so the projection carries a stale tokenizer baseline into the new model's rounds — the first post-switch round can underestimate badly and the gate may not fire when it should (the exact #946 failure mode the anchor was built to prevent).Fix
In
_handle_set_model, when the API model actually changes:prompt_tokens.A no-op switch (same API model re-selected) leaves anchors untouched.
Verification
test_model_switch_invalidates_usage_anchor,test_model_switch_same_model_keeps_anchor); all 12 usage-anchor/model-switch tests passemrg --helpOK