Phase 2: Create Conflict Resolver Foundational Flow
## Overview Create a foundational flow that autonomously resolves merge request conflicts — analyzing conflicted files, presenting a resolution plan, and (after user approval) editing files, committing, and pushing resolved changes. ## Key Behavior Change ⚠️ **This is NOT a guidance/advisory flow** — it **performs the actual conflict resolution**: - Analyzes conflicts - Determines resolution strategy - **Asks user for approval** - **Edits files to remove conflict markers** - **Creates commit with resolved changes** - **Pushes to source branch** - Reports results to user ### Open question: Agent or Flow? The original description proposed a foundational **chat agent**, but after investigating the codebase and [our glossary](https://docs.gitlab.com/ee/development/ai_features/glossary.md), a foundational **flow** appears to be the better fit: | Criteria | Chat Agent | Flow | Conflict Resolver needs | |----------|-----------|------|------------------------| | Interaction | Conversational, open-ended | Triggered, structured sequence | Structured: analyze → plan → approve → execute | | Execution | Advisory/generative | Autonomous with pre-approved privileges | Autonomous (edit files, commit, push) | | Closest analog | Pipeline Builder (advises on CI config) | `developer/v1` (edits files, commits, creates MRs) | Same as `developer/v1` | | Privileges | Defined per-tool in catalog | Explicit `pre_approved_agent_privileges` | Needs `READ_WRITE_FILES`, `USE_GIT`, `READ_WRITE_GITLAB` | | Entry point | Duo Chat | Button/trigger/event | Button on MR page (per UX discussion on #588530) | **Recommendation:** Follow the `developer/v1` pattern as a foundational flow. The UX can still surface this via a button that opens a progress view — flows don't require a chat interface. If there are reasons to prefer a chat agent (e.g., the team wants iterative back-and-forth during resolution), we should discuss before implementation. ## Tasks ### 1. Register the foundational flow Add entry to `ee/app/models/ai/catalog/foundational_flow.rb`: ```ruby { foundational_flow_reference: "resolve_merge_conflicts/v1", display_name: s_("FoundationalFlow|Resolve Merge Conflicts"), description: s_("FoundationalFlow|Automatically resolve merge request conflicts."), feature_maturity: "experimental", avatar: "gitlab-duo-flow.png", pre_approved_agent_privileges: [ ::Ai::DuoWorkflows::Workflow::AgentPrivileges::READ_WRITE_FILES, ::Ai::DuoWorkflows::Workflow::AgentPrivileges::READ_ONLY_GITLAB, ::Ai::DuoWorkflows::Workflow::AgentPrivileges::READ_WRITE_GITLAB, ::Ai::DuoWorkflows::Workflow::AgentPrivileges::USE_GIT, ::Ai::DuoWorkflows::Workflow::AgentPrivileges::RUN_MCP_TOOLS ], environment: "web", triggers: [] } ``` ### 2. Create AI Catalog item + version Create the flow definition in the AI Catalog with: **Tools** (by actual ID from `built_in_tool_definitions.rb`): | ID | Tool | Purpose | |----|------|---------| | 20 | `get_merge_request` | Fetch MR metadata (source/target branch, status) | | 89 | `get_merge_request_conflicts` | Get raw conflict markers per file | | 39 | `read_file` | Read full file content for context beyond conflict markers | | 10 | `edit_file` | Apply conflict resolutions | | 3 | `run_git_command` | Stage, commit, push resolved files | | 1 | `gitlab_blob_search` | Search codebase for broader context when resolving | | 24 | `grep` | Search for usages/patterns to inform resolution decisions | | 9 | `create_merge_request_note` | Post resolution summary as MR comment | ### 3. System prompt requirements The prompt MUST instruct the agent to: **1. Analyze & Plan:** - Fetch conflicts using `get_merge_request_conflicts` - For each conflicted file, optionally use `read_file` to get broader context or `grep`/`gitlab_blob_search` to understand how conflicted code is used elsewhere - Determine resolution strategy per file - Assess confidence level per file **2. Get User Approval:** - Present clear resolution plan with per-file summary - Explain what will be changed and why - Show confidence level (high/medium/low) - Flag files it can't confidently resolve (binary files, complex logic conflicts) for manual review - **Wait for explicit approval** before executing **3. Execute Autonomously:** - Use `edit_file` to apply resolutions to each conflicting file - Remove conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) - Apply chosen resolution - Stage changes **4. Commit & Push:** - Use `run_git_command` to create commit with descriptive message - Push to source branch - Handle errors gracefully (push failures, branch protection, etc.) **5. Report Results:** - Post summary via `create_merge_request_note` - Confirm successful resolution with commit SHA - If any issues occurred, report them and provide rollback guidance (e.g., `git revert <sha>`) ### 4. Feature flag - Create `config/feature_flags/development/resolve_merge_conflicts_flow.yml` - Gate the flow behind this flag (defaults to disabled) ### 5. Specs - Flow registration in `foundational_flow.rb` (validate attributes, privileges) - Feature flag gating - Follow patterns from existing flow specs (e.g., `resolve_sast_vulnerability/v1`) ## What the MCP tool returns For context — `get_merge_request_conflicts` (tool ID **89**, built in Phase 1) returns plain text: ``` # File: app/models/user.rb <<<<<<< source_branch def admin? role == 'admin' end ======= def admin? is_admin == true end >>>>>>> target_branch ``` No structured metadata, no line numbers, no conflict type classification. The agent needs to parse and reason about this raw output. Binary files and files over 200 KB are not supported. ## Expected flow ``` 1. User clicks "Resolve with AI" on MR page 2. Flow is triggered → agent fetches conflict data 3. Agent analyzes 3 conflicted files: - app/models/user.rb: Combine OAuth + 2FA methods (High confidence ✅) - config/routes.rb: Keep both route sets (High confidence ✅) - spec/models/user_spec.rb: Merge test suites (Medium confidence ⚠️) 4. Agent presents resolution plan → waits for user approval 5. User approves 6. Agent executes: ✅ Edited app/models/user.rb ✅ Edited config/routes.rb ✅ Edited spec/models/user_spec.rb ✅ Created commit abc1234 ✅ Pushed to feature/oauth 7. Agent posts summary comment on MR ``` ## Testing checklist - [ ] Flow can be triggered and resolves simple text conflicts - [ ] Agent **actually edits files** (not just suggests) - [ ] Agent **creates commits** with descriptive messages - [ ] Agent **pushes to branch** successfully - [ ] Agent requests user approval before executing - [ ] Agent handles push failures gracefully - [ ] Agent respects branch protection rules - [ ] Agent correctly flags unresolvable conflicts (binary, too complex) - [ ] Error handling works (MR not found, no conflicts, permission denied) ## Safety considerations - ✅ Get explicit user approval before executing - ✅ Show what will be changed before execution - ✅ Handle push failures gracefully - ✅ Respect branch protection rules - ✅ Never force push - ✅ Provide rollback guidance if resolution was wrong - ✅ Log all actions for audit trail ## Acceptance criteria - [ ] Flow registered in `foundational_flow.rb` with correct privileges - [ ] AI Catalog item created with system prompt and tool configuration - [ ] System prompt emphasizes **autonomous execution with approval** - [ ] Feature flag created and defaults to disabled - [ ] Flow successfully resolves simple text conflicts end-to-end - [ ] Specs pass ## Errata from original description The original description (LLM-generated) had several inaccuracies: - Said to register as foundational chat agent in `foundational_chat_agents_definitions.rb` — execution pattern matches a foundational flow instead - Said agent ID 5, but that's already `pipeline_builder` - Said tool ID 88 for `get_merge_request_conflicts` — actual ID is **89** (88 is `run_glql_query`) Related to &20688
issue