Skip to content

End the Repair loop when a CI-fix Repair leaves the head unchanged - #104

Merged
JacobStephens2 merged 2 commits into
mainfrom
issue-102
Sep 27, 2026
Merged

JacobStephens2 merged 2 commits into
mainfrom
issue-102

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

When a CI-fix Repair leaves the head unchanged, the Repair loop now ends the Run as a Failed run. It no longer watches the same red commit again until all 5 Repairs are spent. The new ending is called Declined CI fix in CONTEXT.md.

 RepairLoop::run
   loop
     take in Foreign commits (Merge run)
     merge origin/<base>          # conflict → conflict Repair, go round
     push; head = HEAD
+    if head == the head last handed to a CI-fix Repair
+      fail "CI red on <short sha> and the Repair found nothing to fix on the branch"
     watch CI on head
       green/absent → return (or go round on an upstream move)
-      red → CI-fix Repair, go round
+      red → CI-fix Repair, remember head, go round

The check runs after the Base branch has been merged in again. If the Base branch moved while the Repair ran, the head changes, so the Run goes round as before. A Repair that commits also goes round as before. The usual Failed-run handling still applies: a failure commit is pushed, the PR goes back to draft, and the session log printed is the declining Repair's.

The short-sha rule used in ci::watch is now a shared function, ci::short.

Evidence

  • Before (issue Repair loop keeps re-checking the same commit after a CI-fix Repair makes no change #102, cascade#19): 5 Repairs on head 209580e, then repairs exhausted: CI red.
    After: new tests in tests/ci.rs:
    • a_ci_fix_repair_that_makes_no_commit_is_a_failed_run: CI is red and Repair 1 commits nothing. The Run starts exactly 1 Repair and fails with CI red on <sha> and the Repair found nothing to fix on the branch, never repairs exhausted. The session log is repair-1 and the PR is a draft.
    • a_second_ci_fix_repair_that_makes_no_commit_is_a_failed_run: Repair 1 commits, CI is still red, Repair 2 commits nothing. The Run fails after Repair 2, with log repair-2.
    • a_ci_fix_repair_that_makes_no_commit_goes_round_if_the_base_branch_moved: the Repair commits nothing but main moves on. CI is watched on the merge commit and the Run succeeds.
    • Unchanged and still passing: red_ci_is_handed_to_a_ci_fix_repair_whose_fix_turns_it_green and red_ci_after_the_last_repair_is_a_failed_run (repairs exhausted: CI red when every Repair commits).
  • The first two new tests failed before the change. cargo test passes in full, and cargo clippy --all-targets and cargo fmt --check are clean.

Merge Danger

Door: two-way

A Run can now fail sooner. Reverting brings back the old retry-until-exhausted behavior.

Blast Radius: narrow

Only CI-fix Repairs that leave the head unchanged are affected. A Repair that only adds a "CI notes" entry to the PR body now ends the Run straight after it, with the PR in draft.

Unaddressed findings

Standards

  • Possible Primitive Obsession / missing named type for the Declined CI fix error (src/run.rs): skipped. It is a single call site, and failed-run handling is the usual path. PolicyRefusal has a marker type only because it changes that handling.
  • Duplicated message text between declined_ci_fix in tests/ci.rs and src/run.rs: skipped. The repo's tests assert user-visible text literally, for example repairs exhausted: CI red.

Spec

  • A Repair that edits files but doesn't commit is still reported as "found nothing to fix": skipped. The issue defines the trigger as the Repair making no commit, and the Failed-run path commits those edits in the marker commit, so nothing is lost.

Closes #102

🤖 Generated with Claude Code

JacobStephens2 and others added 2 commits September 27, 2026 16:47
A CI-fix Repair that makes no commit leaves CI red on the same head, so
going round again only re-reads the same failure. The Run now fails at
once with a Declined CI fix instead of spending its remaining Repairs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Base branch move that lands while the Repair runs can fix CI on its
own, so the head is compared once the Base branch is merged in again,
not straight after the Repair. Share the short-sha rule with ci::watch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit f95e252 into main Sep 27, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-102 branch September 27, 2026 16:56
@JacobStephens2 JacobStephens2 mentioned this pull request Sep 30, 2026
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.

Repair loop keeps re-checking the same commit after a CI-fix Repair makes no change

1 participant