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

134 lines
5.2 KiB
Markdown

---
status: draft
system: integrations
requirements:
- REQ-INTEGRATIONS-GITHUB-PR-AUTO-FIX-CONFLICTS-001
created: 2026-09-05
owners:
- 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](github-pr-merge-queue-recovery.md).
## Requirement mapping
| Requirement | Design section |
| --- | --- |
| `REQ-INTEGRATIONS-GITHUB-PR-AUTO-FIX-CONFLICTS-001` | [Conflict classification](#conflict-classification), [Checkpoint and prompt](#checkpoint-and-prompt), [Control help](#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.
## Related decisions and designs
- [PR agent notifications](../../../decisions/0051-pr-agent-notifications-extend-task-pr-automation.md)
- [Bind automatic merge attempts to the reviewed head](../../../decisions/2026-08-28-bind-github-auto-merge-attempts-to-reviewed-head.md)
- [Task PR automation design](../../ui/system-design/ci-pr-automation-02.md)
- [GitHub PR Merge Queue Recovery](github-pr-merge-queue-recovery.md)