fix(runner): don't drop iteration 0 in the auto-finalize fallback - #6
Open
Osamaali313 wants to merge 1 commit into
Open
fix(runner): don't drop iteration 0 in the auto-finalize fallback#6Osamaali313 wants to merge 1 commit into
Osamaali313 wants to merge 1 commit into
Conversation
The auto-finalize block in CodexRunner/ClaudeRunner._reader_iter computed
`_parse_iter_n_from_path(p.name) or -1` and then filtered `n >= 0`. Since 0
is falsy, `img_iter0.png` parsed to 0, `0 or -1` became -1, and the next line
discarded it. Iterations are 0-based ("Iterate N = 0..max_iters-1"), so this
silently erased the ordinary first artifact: a run whose only iteration is 0
(a normal early exit, e.g. turn budget exhausted) was reported failed with no
figure.png, and when iter 0 was the floor-passing iteration it could never be
selected for finalize.
Mirror the sibling call sites (codex.py:1113 / claude.py:794), which already
treat only None as the "unparseable" sentinel. Behavior is unchanged for any
run whose lowest iteration is >= 1.
There was a problem hiding this comment.
🟢 Ready to approve
The change is a targeted, correct fix for a confirmed falsy-0 bug and aligns behavior with existing sibling call sites without introducing API or control-flow risk.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Fixes a correctness bug in the runners’ auto-finalize fallback logic where img_iter0.png could be accidentally excluded from consideration due to 0 being falsy in Python. This ensures iteration indices are treated as 0-based consistently when salvaging a run after an early non-zero CLI exit.
Changes:
- Update CodexRunner auto-finalize disk scan to keep parsed iteration indices (including
0) and skip onlyNone. - Update ClaudeRunner auto-finalize disk scan with the same
is not Noneparsing guard for consistency. - Remove the
or -1/>= 0sentinel pattern that incorrectly dropped iteration 0.
File summaries
| File | Description |
|---|---|
| scripts/figcopy_runner/codex.py | Fixes the finalize fallback’s on-disk iteration scan so img_iter0.png is not dropped. |
| scripts/figcopy_runner/claude.py | Applies the same iteration-0-safe parsing pattern to Claude’s finalize fallback. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
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 free
to 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.
What
The auto-finalize fallback in
CodexRunner._reader_iter(scripts/figcopy_runner/codex.py) andClaudeRunner._reader_iter(scripts/figcopy_runner/claude.py) silently drops iteration0:_parse_iter_n_from_pathreturns anintorNone. Theor -1is meant to turn theNonesentinel into-1so the next line can drop it — but0is falsy, soimg_iter0.pngparses to0,0 or -1evaluates to-1, and then >= 0filter discards it.Why it matters
Iterations are 0-based (the loop policy says
Iterate N = 0..{max_iters-1}), soimg_iter0.pngis the ordinary first artifact. This block exists to salvage a run when the CLI exits non-zero mid-loop (e.g. turn budget exhausted). With the bug:disk_iters == []-> auto-finalize is skipped -> the run is reported failed and nofigure.pngis written;_pick_finalize_iternever sees it and a different (possibly worse) iteration ships.The other three callers of the same helper (
codex.py:1113,codex.py:1455,claude.py:794) all correctly useis None— only these two finalize sites useor -1, so it's a self-inconsistency.Fix
Mirror the sibling sites — keep only successfully-parsed indices, treating
None(not0) as the skip sentinel:Applied to both runners. No behavior change for runs whose lowest iteration is
>= 1.The scan lives inline in the
_reader_iterfinalize/exit block (not a standalone function), so it isn't directly unit-testable without driving the full runner — happy to extract it into a small helper with a regression test if you'd prefer.