5.2 KiB
status, system, requirements, created, owners
| status | system | requirements | created | owners | ||
|---|---|---|---|---|---|---|
| draft | integrations |
|
2026-09-05 |
|
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.