emrg: fix evolution count always 0 — aggregate scheduler handler logs - #558
Conversation
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260807-223327 (1st angle: bug confirmation + fix correctness)
Verified on head 256ee56:
- Bug confirmed: daemon.py:161
self.evolutions = []is NEVER appended (legacy from pre-scheduler BackgroundThread design #95); the scheduler handlers own the real per-cycle logs (scheduler.py:131 per-handler evolutions, appended at :708). Soevolution_count=len(self.evolutions)was permanently 0 in production, and evolution_summary count too. - Fix correctness: _evolution_count() aggregates via scheduler.total_evolutions() (sum over handlers), falls back to len(self.evolutions) only when the scheduler is unavailable (test harnesses) — correct single-source-of-truth direction.
- Test discriminative power (per #455, ran it): changed sum(...) to len(first handler) → test FAILS (multi-handler aggregation case); restored → passes. Covers 0/2/3 counts, multi-handler.
- Doc counts synced (572→573); 573 tests pass locally + CI green (31188220443).
256ee56 to
aeb71f9
Compare
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260807-223711 (2nd angle: rebase audit + aggregation regression surface)
Verified on head aeb71f9 (rebase of 256ee56 onto master 374c98b):
- Rebase audit:
git diff 256ee56d aeb71f9 --statshows only #556's master content (main.js/package-lock/components.css/main.py/evolution_prompt.md/tests) — the PR's own 5 files (daemon.py, scheduler.py, test_scheduler.py, README.md, Agent.md) are byte-identical, 45 insertions unchanged. Pure rebase, no content drift. - Aggregation regression surface: TaskScheduler._handlers is typed
list[EvolutionHandler](scheduler.py:812) and ALL task types (evolution/paper/open-source/promote) resolve to EvolutionHandler (HANDLERS map :805-808) — every handler initializesself.evolutions: list[EvolutionLog] = [](:131), sototal_evolutions()can never AttributeError on a non-evolution handler._evolution_count()adds try/except + isinstance(int) guard + legacylen(self.evolutions)fallback — defensive even against mocked/partial schedulers. - count/recent consistency:
evolution_summaryrecentreads ~/.emrg/logs/evolution-*.json from disk (daemon.py:1167), count now comes from the scheduler — both sources live post-fix, no count>0 with recent=[] mismatch. - Empty-state: fresh daemon restart resets both scheduler handler lists and self.evolutions → count 0, consistent with uptime-scoped semantics.
- Full suite: 573 passed locally + import check OK; mergeable CLEAN, CI green (31188377359).
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260807-224251 (3rd angle: production-impact confirmation)
Head aeb71f9 unchanged since cycle 223711 (rebase audit confirmed byte-identical to 256ee56). This fix resolves a real production bug: evolution count was permanently 0 in /version pong + evolution_summary because self.evolutions was never appended (legacy #95). After this merge, count = scheduler handler aggregations — and #559 (aborted-cycle exclusion) will keep that count free of error-inflation. Mergeable CLEAN, CI green (31188377359), 574→ wait — 573 tests verified locally. 3 consecutive ✅ from different cycles with no ❌ between → ready to merge.
…unt fixes (#553-#561) (#562) Version bump 0.2.11 → 0.2.12 across all 7 version sources (pyproject.toml / emrg/__init__.py / gui/package.json / gui/package-lock.json / uv.lock / build-runtime.sh / make-installer.sh). Release for rant 发布新版本 (2026-08-07T23:54:46) — ships 9 commits accumulated since v0.2.11: - #553 Windows TUI Unicode input via ReadConsoleInputW - #554 GUI interleaved text/tool message order - #556 rant UX (daemon-authoritative timestamp + GUI textarea + UTF-8 log) - #558 evolution count always 0 fix - #559 exclude aborted evolution cycles from count and idle-halt backoff - #557/#560/#561 quick-ref entries All 575 tests green.
Fix the evolution counter being permanently 0 in production.