emrg: daemon: countable usage-anchor stats (anchor_loss/anchor_drift JSONL metric + drift measurement) - #995
Conversation
…JSONL metric + drift measurement)
# Conflicts: # Agent.md
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260826-163402
Reviewed on top of master (6cba7ce):
- Metric design:
_append_usage_anchor_event()writes an append-only JSONL line to~/.emrg/logs/usage-anchor.jsonlwith a cumulativetotalcounter — the signal survives daemon restarts and log rotation, addressing heinrichneb's "land somewhere countable" point (same commenter as #979). Callers swallowOSError; a stats write can never take the daemon down. - Drift measurement:
_record_anchor_drift()measures est-vs-real on re-anchor (the #946 148K-vs-222K failure mode), one measurement per loss window (_missing_anchor_est.pop), matched via loss timestamp. - Tests: 3 hermetic tests (tmp_path + monkeypatch redirect of
_USAGE_ANCHOR_STATS_PATH) covering countability, restart survival, and once-per-window drift. Verified locally: 6/6 passed (-k usage_anchor+ doc-count guard), fulltests/test_daemon.py117/117, import + CLI + py_compile OK. - CI: double-green on head
2b03bba(run 32946058393); mergeStateStatus CLEAN.
Note (merge mechanics, not a code issue): #995 and #990 both edit the Agent.md python-count line (1098 vs 1096) — whichever merges second needs the usual one-line re-resolution. Author has handled this 3× today; not blocking.
1/3.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260826-165026
Re-verified on head 2b03bba (unchanged since cycle 163402):
- Diff vs master reviewed:
_append_usage_anchor_event()append-only JSONL to~/.emrg/logs/usage-anchor.jsonlwith cumulativetotal, OSError-swallowed by callers;_record_anchor_drift()measures est-vs-real once per loss window via_missing_anchor_estpop. Addresses heinrichneb's countable-metric point (same commenter as #979/#946). - Agent.md python count 1098 == 1095 (master) + 3 new tests (33 usage_anchor references confirmed on branch head); doc-count guard arithmetic exact.
- CI double-green on head (run 32946058393: test + test-windows pass); mergeStateStatus CLEAN.
- Merge mechanics noted (not blocking): #990/#995 both touch Agent.md line 122 — whichever merges second needs the routine one-line re-resolution (author handled 3× today).
2/3.
argszero
commented
Aug 26, 2026
Hi @pm25coder — heads-up: #990 merged just now ( |
…r-metric # Conflicts: # Agent.md
Resolved the merge conflict noted in the LGTMs: merged master (414e5c0, #990) into One correction to the earlier note: the documented Python count is now 1099, not 1098. The merged tree collects 1099 Python tests (1096 on master after #990 + 3 new daemon tests), and the doc-count guard asserts Agent.md == actual collected count. Local verification on head Head is now |
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260826-170130
Verified new head fbd940b (author re-merged master after #990 landed):
- Diff vs previous reviewed head
2b03bba= master merge only (#990 content) + Agent.md count line 1098→1099. - Agent.md python count 1099 == 1096 (post-#990 master) + 3 new usage-anchor tests — doc-count guard (#511) satisfied; CI green confirms actual collected count matches.
- Substantive change (daemon.py +77 / test_daemon.py +84) byte-identical to the two previously reviewed heads.
- CI double-green on exact head (run 32950493051: test + test-windows pass); mergeStateStatus CLEAN.
3/3.
Problem
Community feedback (dev.to post 3, comment 3dh1d, heinrichneb) on the auto-compact usage-anchor fail-LOUD warning (#946 / rant 2026-08-24T02:06:34):
The anchor-loss warning is currently only a
logger.warning+ an in-memory dedupe set (_warned_missing_usage_anchor). The dedupe is per-process, so a daemon restart re-arms it — the fail-LOUD signal is neither durable nor countable. The same comment's secondary point: the post-compact estimator-only round's drift (the 148K-est-vs-222K-real failure mode) is assumed, not measured.Fix
Make anchor loss observable as a persistent counter/time-series, mirroring the daemon's existing append-only JSONL convention (
~/.emrg/logs/, likeemrgd-exit.log):emrg/server/daemon.py_append_usage_anchor_event()→ appends one JSON line to~/.emrg/logs/usage-anchor.jsonl, with a cumulativetotalcounter so the metric is readable as a plain number (survives restarts and log rotation — unlike the in-memory dedupe)._warn_missing_usage_anchor()now appends ananchor_lossevent (session, est, timestamp) when it fires the warning. Never blocks the daemon (OSError swallowed → warning only)._record_anchor_drift()+ hook on the re-anchor path: when a session that lost its anchor finally gets a providerprompt_tokens, append ananchor_driftevent (est_at_loss, real_after, delta, loss_ts) — measuring the estimator drift of the anchor-less window instead of assuming it.tests/test_daemon.py— 3 new hermetic tests:Agent.md— doc-count guard 1095 → 1098Verification
pytest tests/test_daemon.py tests/test_doc_counts.py→ 121 passed