Files
kandev/docs/specs/integrations/system-design/github-pr-auto-fix-conflicts.md
T
2026-09-06 11:36:16 +01:00

5.2 KiB

status, system, requirements, created, owners
status system requirements created owners
draft integrations
REQ-INTEGRATIONS-GITHUB-PR-AUTO-FIX-CONFLICTS-001
2026-09-05
Kandev

GitHub PR Auto-Fix Conflicts System Design

Purpose and boundaries

The integration system owns GitHub mergeability state and auto-fix signal classification. This design adds ordinary merge conflicts to the existing per-PR auto-fix evaluator.

The design reuses the current poller, prompt renderer, session dispatcher, round limit, and automation controls. Merge-queue removal behavior remains in GitHub PR Merge Queue Recovery.

Requirement mapping

Requirement Design section
REQ-INTEGRATIONS-GITHUB-PR-AUTO-FIX-CONFLICTS-001 Conflict classification, Checkpoint and prompt, Control help

Components and responsibilities

TaskPR.MergeableState carries the normalized GitHub mergeability state from the latest lightweight pull-request sync.

handleTaskPRCIAutoFix in apps/backend/internal/orchestrator/event_handlers_github_ci_automation.go combines full feedback with pull-request state. It then builds the actionable delta and current checkpoint.

The existing auto-fix dispatcher owns session selection, direct delivery, durable queueing, coalescing, and round accounting. This change does not add a second dispatch path.

Conflict classification

The evaluator classifies only normalized dirty mergeability as an ordinary merge conflict. It does not classify blocked, behind, draft, unknown, or an empty state as a conflict.

The existing settled-check gate applies before conflict evaluation. This gate keeps one auto-fix round focused on the final check, review, and conflict snapshot.

Checkpoint and prompt

ciAutomationCheckpoint adds an optional conflict item. The item contains:

  • normalized mergeability state.
  • head commit.
  • head branch.
  • base branch.

The JSON field is additive. Existing checkpoint rows decode with no conflict item, so the change needs no database migration.

The current checkpoint contains one conflict item while the pull request is dirty. The delta contains that item when no identical item exists in the previous checkpoint.

An authoritative non-conflict observation removes the item during the existing prompt-free checkpoint refresh. An empty or unknown state preserves the prior item because GitHub can report these states during recomputation. A later dirty observation is actionable after an authoritative clear. A changed head commit or base branch also creates a new snapshot while the state remains dirty.

When {{pr.feedback}} is present, ciAutomationRenderSnapshot adds a merge conflict section. It names the sanitized head and base branches and the head commit. The saved prompt remains hidden system context.

Queue-removal compatibility

The same evaluator can include an ordinary conflict item and a queue-removal item in one delta. The dispatcher sends one combined round for that evaluation.

For failed-check queue removals, current-head ownership requires both a matching durable last_queue_attempt_head_sha and a non-empty last_merge_signature written by an attempted or adopted queue entry. A passive removal-only baseline does not prove which pull-request head produced the removal, so it cannot start an auto-fix round. The removal event ID remains the deduplication identity, and same-head automatic requeue protection remains unchanged.

Control help

PRCIAutomationControls keeps the existing switch label and responsive surfaces. English and translated help state that auto-fix handles these inputs:

  • settled failed checks.
  • review comments.
  • ordinary merge conflicts.
  • actionable merge-queue removals.

The existing desktop popover and mobile drawer use the same localized copy. No layout, navigation, touch target, or scroll behavior changes.

Failure and recovery

  • If mergeability is unknown, Kandev preserves prior conflict checkpoint state and waits for a later authoritative state.
  • If checks are unsettled, Kandev waits and does not use a round.
  • If prompt delivery fails, the existing per-PR error and retry behavior apply.
  • If a conflict clears, the checkpoint refresh is prompt-free.
  • If Kandev restarts, the persisted JSON checkpoint preserves deduplication.

Security

Branch names and commit identities are untrusted provider data. Snapshot rendering uses the existing field sanitizer and sysprompt.Wrap boundary.

The change does not expand GitHub write permissions. The agent uses its current task and repository permissions to repair the branch.

Observability

Existing CI automation logs identify the task, repository, pull request, and dispatch result. Focused tests cover conflict classification, checkpoint transitions, queue-removal eligibility, and prompt rendering.