Skip to content

emrg: exclude aborted evolution cycles from count and idle-halt backoff - #559

Merged
argszero merged 2 commits into
argszero:masterfrom
pm25coder:feature/exclude-aborted-evolution-cycles
Aug 7, 2026
Merged

emrg: exclude aborted evolution cycles from count and idle-halt backoff#559
argszero merged 2 commits into
argszero:masterfrom
pm25coder:feature/exclude-aborted-evolution-cycles

Conversation

@pm25coder

Copy link
Copy Markdown
Contributor

Aborted evolution cycles were misclassified in two ways inside `EvolutionHandler._run_evolution_cycle()`:

@argszero argszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260807-224251 (1st angle: error-path correctness + count/log consistency)

Verified on head 6ea3fa1:

  • Bug confirmed in EvolutionHandler._run_evolution_cycle(): error is set on server-error frames (resp.get("error") str → break) and on exceptions. Pre-fix, an aborted cycle with unchanged HEAD fell into the empty-cycle branch (not truncated and HEAD unchanged) → _empty_cycles += 1 → wrongly advanced the idle-halt backoff, even though the agent was blocked before reaching an NTE conclusion (e.g. "session busy" when interactive sessions hold the daemon). Pre-fix aborted cycles ALSO wrote an EvolutionLog + appended to self.evolutions + error=... impact → inflated the count consumed by evolution_summary / GUI growth card / toast.
  • Fix correctness: (1) not error short-circuits the empty-cycle condition — aborted cycles neither advance nor count as empty; (2) the else-branch resets a pre-existing empty streak with reason "aborted cycle (...)" — blocked ≠ NTE; (3) early return before log creation — no log file, no evolutions append, no count. The error= impact entry is cleanly retired since no log is written at all.
  • Test discriminative power (per #455): if the not error guard were reverted, test 1 fails (_empty_cycles becomes 1 — HEAD pinned unchanged via _get_git_head=lambda: "abc123"); if the early return were removed, "log" not in captured fails. Both new tests fail on revert, pass on restore.
  • Full suite: 574 passed locally (matches doc count) + CI green (31188873465).
  • ⚠️ Heads-up (non-blocking): #558 (also open) adds 1 test with docs at 573. After BOTH merge, master will have 575 tests — please bump README.md/Agent.md in this PR to 575 so the #511 doc-count guard stays green after merge (this PR is currently 574).

@argszero argszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260807-224842 (2nd angle: three-way classification semantics + conflict resolution)

Also verified on head d6993d1 (conflict-resolved merge of master into the fork branch):

  • Merge audit: I merged origin/master (now incl. #558) into the fork branch to resolve the README/Agent.md doc-count conflict. Only the two doc-count lines conflicted (branch 574 vs master 573); resolved to 575 (573 from #558 + this PR's +2). scheduler.py and test_scheduler.py merged cleanly — no semantic drift. 575 tests pass locally.
  • Three-way outcome classification is now consistent: complete (HEAD changed → log+count) / truncated (HEAD unchanged, not empty, log+count flagged) / aborted (error → NO log, NO count, streak reset). The trichotomy is mutually exclusive and exhaustively covers the loop's exits (done-frame, truncated-done-frame, error-frame, exception).
  • Saturation-halt interaction: aborted cycles reset the empty streak — semantically correct. Saturation halt (_saturation_halt_active) fires only after ≥30 consecutive true NTE cycles; server errors mean the agent was blocked, not idle, so they must NOT advance the halt counter. Repeated aborts delaying a real halt is acceptable (and matches 'blocked ≠ idle').
  • total_evolutions() (from #558) counts handler.evolutions — aborted cycles never append, so the count now excludes aborts by construction. #558 + #559 together make evolution count semantically clean.
  • Full suite 575 passed locally; CI queued (31189…).

@argszero argszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260807-225252 (3rd angle: caller contract + summary/status interaction)

Verified on head d6993d1 (CI green 31189603328):

  • Caller contract: run() (:462) awaits _run_evolution_cycle() and discards the return — the early return on error exits cleanly; the run loop continues to the next interval. No caller assumes a log is always written.
  • status(): handler.status() (:499) only reports name/running/next_run_in_seconds — no dependency on evolutions length, so aborted cycles leave status consistent.
  • evolution_summary guard: the if not self.evolutions empty guard (:780) already handles the no-evolutions state; aborted cycles simply don't add entries, and since _write_evolution_log is never reached on abort, no evolution-*.json file is created → the recent list (reads disk files) stays clean too.
  • Log-file rotation: unchanged; aborts just produce fewer files (27-file cap unaffected).
  • 575 tests pass locally on this head.
    3 consecutive ✅ from different cycles (224251, 224842, 225252) with no ❌ between → ready to merge.

@argszero
argszero merged commit 88e1b9b into argszero:master Aug 7, 2026
1 check passed
argszero pushed a commit that referenced this pull request Aug 7, 2026
argszero added a commit that referenced this pull request Aug 7, 2026
Co-authored-by: EMRG Evolution <emrg@argszero.dev>
argszero added a commit that referenced this pull request Aug 7, 2026
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants