Skip to content

fix(worker): hard-stop reject-artifact patch failures (§60)#445

Merged
SaJaToGu merged 1 commit into
developfrom
codex/returncode-5-hard-stop
Jun 25, 2026
Merged

fix(worker): hard-stop reject-artifact patch failures (§60)#445
SaJaToGu merged 1 commit into
developfrom
codex/returncode-5-hard-stop

Conversation

@SaJaToGu

Copy link
Copy Markdown
Owner

Closes §60 (docs/BACKLOG/open.md).

Bug

workers/execution.py classify_worker_outcome only hardened
against PARTIAL_PATCH_FAILURE_RETURN_CODE = 6 (PR #442 / §57).
It did not generalize to "any nonzero worker-returncode that
produces partial on-disk changes must be a hard stop".

returncode = 5 (reject artifacts in OpenRouterWorker, i.e.
.orig/.rej files left in the working tree after a partial
git apply) still fell through to the generic nonzero_with_changes
branch with failure_class: success. The run then proceeded to
commit + push + open a PR with whatever changes had been partially
applied.

Repro (PR #444)

Issue #390 validation run, 2026-06-26, gpt-4o via
openrouter_direct:

PR #444 was closed + branch ai/fix-issue-390 deleted. Same
symptom as PR #441 / §57, just one returncode class later.

Fix

  • workers/base.py: new shared constant
    PATCH_VALIDATION_FAILED_RETURN_CODE = 5. Reason
    patch_validation_failed documented in the outcome taxonomy.
  • workers/execution.py classify_worker_outcome: new
    branch between partial_patch_failure and changed
    returncode == PATCH_VALIDATION_FAILED_RETURN_CODE
    WorkerOutcome(False, has_changes, "patch_validation_failed").
    Returns before the generic nonzero_with_changes branch.
  • workers/openrouter_worker.py: uses the shared constant
    instead of the magic 5 literal. Doc-string for the
    returncode semantics updated.
  • scripts/solve_issues.py: doc-string for
    run_openrouter_direct_worker returncode semantics updated.

Scope

User-specified scope — targeted fix, no refactor:

In scope: Returncode 5 hard-stop.
Out of scope: the generic nonzero_with_changes semantics
for other workers. nonzero_with_changes may exist intentionally
to let some workers proceed for further review despite nonzero
exit. Do not refactor it without test evidence that it's
safe.

If other nonzero returncodes (e.g. 3 for timeout) need the same
treatment, that is a separate item (potential §60b).

Acceptance test

User-specified reproduction:

returncode=5
git_status=" M scripts/solve_issues.py"WorkerOutcome(should_continue=False, has_changes=True, reason="patch_validation_failed")

Covered by tests/test_worker_execution.py (+1 new test) and
tests/test_worker_adapters.py (+1 new test).

Verification

  • ./.venv/bin/python -m unittest tests.test_worker_execution -v: 22 OK (was 21, +1)
  • ./.venv/bin/python -m unittest tests.test_worker_adapters -v: 96 OK (was 95, +1)
  • ./.venv/bin/python -m unittest tests.test_openrouter_worker -v: 53 OK
  • ./.venv/bin/python -m unittest tests.test_solve_issues -v: 168 OK (no regression)
  • git diff --check develop..HEAD: clean

Diff: 6 files, +39/-5.

@SaJaToGu SaJaToGu merged commit 2549f0f into develop Jun 25, 2026
2 checks passed
@SaJaToGu SaJaToGu deleted the codex/returncode-5-hard-stop branch June 25, 2026 22:16
SaJaToGu pushed a commit that referenced this pull request Jun 25, 2026
- open.md: §60 stubbed out as DONE-via-PR-#445 (squash 2549f0f).
  Cross-references §57 (also done) and the still-valid general
  principle for any future returncode class. Old §60 body
  (Measured/Suggested scope/Checks) trimmed from open.md.
- done.md: full §60 closure entry with bug description, repro
  (PR #444 / Issue #390 / gpt-4o / returncode 5 / reject artifacts),
  fix locations (workers/base.py + workers/execution.py +
  workers/openrouter_worker.py + scripts/solve_issues.py), scope
  discipline (NO refactor of nonzero_with_changes, per User
  directive), verification matrix (22+96+53+168 OK + GitHub CI
  green + user live review 'mergebereit'), and the general
  principle that §57 (returncode 6) and §60 (returncode 5) both
  implement.

Backlog is now: §59 watchlist (parked, Mode-C Threshold ≥3) +
§59-related notes only. §60 closed. All §51-§58 done via earlier
PRs.
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.

1 participant