fix(finish): attach the reconcile steer to the out-of-date-with-base merge failure, still non-retryable (#456) #475

Merged
hexajon merged 1 commit from issue-456-madt-finishmerge-masks-real-gitea-merge-errors-as into main 2026-09-09 22:09:47 +00:00
Owner

Summary

Closes #456. The three original asks landed in PR #463 (verbatim surfacing, non-retryable classification, post-5xx landed re-check). This is the one refinement decided on 2026-09-08: the out-of-date-with-base failure keeps its verbatim Gitea body and its non-retryable status, and now also carries the copy-pasteable update-branch-and-remerge block, matching the behind-base 405 path.

Changes:

  • internal/gitea/client_errors.go: new IsMergeOutOfDate predicate, a strict subset of IsMergeNonRetryable (405 plus the "out-of-date with the base branch" body, case-insensitive).
  • internal/service/workflow/merge.go: after the retry loop, an out-of-date lastErr returns merge failed: <verbatim body> followed by ReconcileSteer(prNum, rp). Nothing-to-merge and no-signing-key stay bare. No retry, no auto-update.
  • Tests: TestIsMergeOutOfDate (match set, status gating, subset-of-non-retryable invariant); TestMergeWithRetryNonRetryable_OutOfDate now asserts the steer is present, and the AlreadyIncluded and NoSigningKey tests assert it is absent. The shared helper returns the message so callers can assert on it.
  • docs/architecture/error-handling.md: the non-retryable table and prose describe the steer on the out-of-date row.

Gate: ./scripts/gate.sh full run passes (go-version, build, gofmt, vet, gofix, modtidy, licenses, hook-tests, adr-check, test-race, staticcheck, govulncheck, gosec, modernize, docs-verify, cross-compile, mcp-conformance).

Evidence for the earlier asks, for the record: IsMergeNonRetryable and the verbatim merge failed: %w wrap at internal/service/workflow/merge.go (post-loop), the landed re-check on 5xx inside MergeWithRetry, all pinned by TestMergeWithRetry5xxAlreadyMerged, TestMergeWithRetry5xxNotMergeableSurfacedVerbatim, and the three TestMergeWithRetryNonRetryable_* tests.

Closes #456

## Summary Closes #456. The three original asks landed in PR #463 (verbatim surfacing, non-retryable classification, post-5xx landed re-check). This is the one refinement decided on 2026-09-08: the out-of-date-with-base failure keeps its verbatim Gitea body and its non-retryable status, and now also carries the copy-pasteable update-branch-and-remerge block, matching the behind-base 405 path. Changes: - `internal/gitea/client_errors.go`: new `IsMergeOutOfDate` predicate, a strict subset of `IsMergeNonRetryable` (405 plus the "out-of-date with the base branch" body, case-insensitive). - `internal/service/workflow/merge.go`: after the retry loop, an out-of-date `lastErr` returns `merge failed: <verbatim body>` followed by `ReconcileSteer(prNum, rp)`. Nothing-to-merge and no-signing-key stay bare. No retry, no auto-update. - Tests: `TestIsMergeOutOfDate` (match set, status gating, subset-of-non-retryable invariant); `TestMergeWithRetryNonRetryable_OutOfDate` now asserts the steer is present, and the AlreadyIncluded and NoSigningKey tests assert it is absent. The shared helper returns the message so callers can assert on it. - `docs/architecture/error-handling.md`: the non-retryable table and prose describe the steer on the out-of-date row. Gate: `./scripts/gate.sh` full run passes (go-version, build, gofmt, vet, gofix, modtidy, licenses, hook-tests, adr-check, test-race, staticcheck, govulncheck, gosec, modernize, docs-verify, cross-compile, mcp-conformance). Evidence for the earlier asks, for the record: `IsMergeNonRetryable` and the verbatim `merge failed: %w` wrap at `internal/service/workflow/merge.go` (post-loop), the landed re-check on 5xx inside `MergeWithRetry`, all pinned by `TestMergeWithRetry5xxAlreadyMerged`, `TestMergeWithRetry5xxNotMergeableSurfacedVerbatim`, and the three `TestMergeWithRetryNonRetryable_*` tests. Closes #456
fix(finish): attach the reconcile steer to the out-of-date-with-base merge failure, still non-retryable (#456)
All checks were successful
ci / mcp-conformance (pull_request) Successful in 2m16s
drift / govulncheck (pull_request) Has been skipped
ci / mcp-conformance (push) Successful in 3s
drift / forgejo-smoke (pull_request) Has been skipped
drift / surface-diff (pull_request) Successful in 1m2s
drift / govulncheck (push) Has been skipped
drift / surface-diff (push) Successful in 3s
drift / forgejo-smoke (push) Has been skipped
ci / gate (pull_request) Successful in 30m34s
ci / gate (push) Successful in 17m10s
3b88964597
Closes #456
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea!475
No description provided.