ADR-005: Automated Conflict Management Strategy
Status
Accepted - 2025-10-01
Context
Merge conflicts between upstream and the fork's own modifications are inevitable. The system needs to detect them automatically, keep conflicted code away from main, make the conflict visible to the team, and let resolution happen without blocking other development.
Resolving conflicts directly on main destabilizes it; ignoring them lets the fork drift from upstream.
Decision
- Conflict Detection: The cascade detects merge conflicts when merging
fork_upstreamintofork_integration. - Isolation: Conflicts are resolved on
fork_integration, never onmain. - Issue Creation: Each conflict opens a GitHub issue listing the conflicted files and the steps to resolve them.
- Manual Resolution: A human resolves the conflict directly on
fork_integrationand pushes. No conflict is resolved automatically. - Escalation: Conflicts open longer than 48 hours are escalated with a separate issue and label.
- Documentation: The issue records when the conflict occurred and how it was resolved.
Alternatives Considered
1. Automatic Conflict Resolution
No manual intervention, but risks incorrect resolutions and silent data loss. Rejected.
2. Conflict Resolution on Main Branch
Simpler, but destabilizes main and blocks other development while conflicts are open. Rejected.
3. Feature Branch per Conflict
Complete isolation per conflict, but branch proliferation and tracking overhead. Rejected.
4. Manual Conflict Detection
Human judgment in detection, but inconsistent and slow. Rejected.
Consequences
Every conflict needs a human, so upstream integration waits on resolution. In exchange, main never receives conflicted code and every resolution is recorded on an issue.
Implementation Details
Where Detection Happens
The strategy is implemented in cascade.yml (job cascade-to-integration) together with the Cascade Monitor Pattern (ADR-019) and the Human-Required Label Strategy (ADR-020):
sync.ymlopens a PR from async/upstream-*branch tofork_upstream.- After that PR merges, a human triggers
cascade.yml.cascade-monitor.ymldispatches it as a safety net if nobody does. - The cascade merges
fork_upstreamintofork_integration. If git reports unmerged paths, the step lists the conflicted files, opens an issue titled🚨 Cascade Conflicts: Manual Resolution Requiredwith labelsconflict,cascade-blocked,high-priority,human-required, moves the tracking issue fromcascade-activetocascade-blocked, and stops. - The developer resolves the conflicts on
fork_integrationlocally, commits, and pushes. - Once the
human-requiredlabel is removed,cascade-monitor.ymlre-dispatches the cascade, which continues to validation and the production PR. check-stale-conflictsin bothcascade.ymlandcascade-monitor.ymllooks forconflict,cascade-blockeditems older than 48 hours, opens an escalation issue labeledescalation,high-priority,cascade-escalated,human-required, and comments on the original.
Labels (ADR-020)
human-required: manual intervention neededconflict: the issue typecascade-blocked: the pipeline is blockedhigh-priority: urgencycascade-escalated: the 48-hour SLA was exceeded