Applies `ruff format` to the accumulated formatting debt on this branch.
Formatting-only — no behavioral changes. Required for CI/lint's format
gate (`nox -s format -- --check`), which the branch was failing on 288
tracked files that drifted from ruff's canonical style.
In-progress WIP files are intentionally excluded so this commit stays a
clean formatting-only diff.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The first post-commit fix only handled merge-error-* strings and
missed that build_train's single-PR failure reasons flow straight
into terminal_state via _release. Four were unmapped (no-head-ref,
rev-parse-fetched-head-failed, rebase-timeout,
push-failed-force-lease-mismatch) — same stranding bug class.
- _resolve_bridge_event no longer returns None. Any unrecognised
terminal_state falls back to merge_retry_exhausted (-> STUCK):
operator-visible and recoverable beats silently orphaned in MERGING.
The three static build_train reasons are mapped explicitly; the
catch-all logs loudly so an unanticipated state is still visible.
- merge-error-* routing refined: 404 -> merge_external_action
(reconcile via PR state), 422 -> merge_base_conflict (CONFLICT_-
RESOLVING re-rebases) instead of blanket STUCK.
- Hard-crash reaper: merge_drive is a singleton and run_one_cycle is
serial, so any workflow in MERGING at cycle start is the residue of
a crashed prior cycle. run_one_cycle now reclaims them via
merge_interrupted (MERGING -> APPROVED) before picking candidates.
Adds bridge.list_merging_workflows.
- run_one_cycle warns if a claimed PR is absent from
pr_terminal_states instead of silently using the aggregate.
3309 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The trial-5 merge-pipeline split could strand workflows in MERGING
forever on its main paths. The controller has no MERGING handler
(merge_drive owns it), so any terminal_state that maps to no event
leaves the workflow orphaned. Three such holes, all caught by the
post-commit multi-perspective review:
1. merge_train emits "merge-error-{403,5xx,...}" for any non-2xx/409
Forgejo merge POST — none were mapped. Added _resolve_bridge_event:
403 -> branch_protection_blocked, all else -> retry_exhausted (STUCK).
2. run_one_cycle applied one shared outcome.terminal_state to every
claimed PR. A bisected train returns "bisected" (unmapped) so all
PRs stranded; a mixed train could tell a merged PR merge_base_conflict.
CycleOutcome now carries pr_terminal_states and events emit per-PR.
3. Graceful shutdown mid-merge ("stopped") was unmapped. Added the
merge_interrupted event (MERGING -> APPROVED) so the workflow
returns to the handoff state for clean re-pickup.
Also fixes a stale comment in _controller_db_bridge.py (merge_base_conflict
routes to CONFLICT_RESOLVING, not IMPLEMENTING) and adds a drift-guard
test cross-checking the bridge's transition map against the canonical
state machine — that drift is what produced the stale comment.
3304 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
T5-1 reviewer feedback rendered full-body to the implementer
T5-4/9 implementer dispute path — dispute-at-any-tier with per-tier cap,
OPERATOR_ATTENTION state on stalemate, pr-review-worker-dispute agent
T5-5 reviewer BLOCKING ISSUE EVIDENCE RULE + 5-step validation
T5-7 merge step split into a singleton process — impl/review masters write
APPROVED and stop; merge_drive owns APPROVED -> MERGING -> MERGED
T5-10 merge process is fully deterministic; base conflicts bounce to the
controller's CONFLICT_RESOLVING (LLM); conflict_drive sidecar retired
T5-11 implementer fast success path — verified-clean outcome so a no-op
after conflict resolution doesn't force busywork
T5-12 conflict-resolver permissions fixed across all paths (/tmp/** glob)
T5-13 conflict-resolver PR-intent prehydration (title/body/comments)
Adds tools/_controller_db_bridge.py so merge_drive reads the controller DB
directly (Option B), plus APPROVED + OPERATOR_ATTENTION states, the
dispute/verified-clean events, and the V1 contract fields backing them.
Reviewer model: baseline -> sonnet, dispute -> opus.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>