Auto-dispatch PR conflict resolution from PR poller - #57
Conversation
Summary:
- Fetch GitHub mergeability and base/head metadata during PR review
polling.
- Persist conflict context, dedupe by head/base identity, enforce a
retry cap, and inject conflict instructions into the next prompt.
- Add focused coverage for conflict dispatch, dedupe, escalation,
cleanup, active-run suppression, prompt text, and GitHub parsing.
Rationale:
- Merge conflicts are PR review state, not CI state, so the PR review
poller should hand semantic conflict resolution back to the normal
agent workflow.
- Keeping the conflict key in the existing PR review record avoids a
new store table or config contract while preventing repeated dispatch
loops for the same conflict.
Tests:
- mix test test/symphony_elixir/pr_review_poller_test.exs test/symphony_elixir/github_pull_request_test.exs test/symphony_elixir/core_test.exs:2263
- mix specs.check
- mix lint
- git diff --check
- make all (fails in full app-server tests with {:mcp_socket_open_failed, :eperm}; coverage then misses the 100% threshold)
Summary:
- Remove unreachable non-map fallback clauses from PR conflict helpers.
- Cover PR conflict prompt fallback values for string timestamps and
invalid retry limits.
Rationale:
- Dialyzer can prove PR review conflict helpers only receive maps at these
call sites, so the defensive catch-all clauses were dead code.
- The added prompt assertions exercise fallback branches that CI coverage
previously reported as missed.
Tests:
- mix test test/symphony_elixir/core_test.exs:2268 test/symphony_elixir/pr_review_poller_test.exs test/symphony_elixir/github_pull_request_test.exs
- mix specs.check
- MIX_HOME=/private/tmp/rsm-3739-mix-home HEX_HOME=/private/tmp/rsm-3739-hex-home mix dialyzer --format short
- mix format --check-formatted
- mix lint
- git diff --check
- make all (fails locally: app-server MCP socket setup returns {:mcp_socket_open_failed, :eperm})
Summary: - Let conflict helper functions accept any input shape so Dialyzer no longer reports unreachable fallback clauses. - Cover compact prompt PR conflict instructions and metadata. Rationale: - The PR conflict flow normalizes map-like persisted data at the call sites, so the helper guards were narrower than the inferred types. - Compact prompts share the same conflict section as full prompts and need direct coverage to keep the 100% coverage gate green. Tests: - mix test test/symphony_elixir/pr_review_poller_test.exs test/symphony_elixir/prompt_builder_test.exs test/symphony_elixir/github_pull_request_test.exs test/symphony_elixir/core_test.exs:2263 - mix dialyzer --format short - mix test.coverage - mix specs.check - mix lint - mix format --check-formatted - git diff --check - make all (fails locally: app-server MCP socket setup returns eperm; PromptBuilder reports 100% before coverage fails from those test failures)
|
@copilot resolve the merge conflicts in this pull request |
There was a problem hiding this comment.
Pull request overview
This PR extends Symphony’s PR review polling flow to detect GitHub merge conflicts, persist conflict context (including head/base identity), and auto-dispatch an agent-owned conflict-resolution run by moving the Linear issue back to In Progress while injecting conflict instructions/metadata into the next agent prompt.
Changes:
- Fetch additional PR mergeability + head/base metadata via
gh pr view --json ...and expose it throughGitHub.PullRequest.fetch_activity/2. - Add merge-conflict detection/deduping/escalation logic to
PrReviewPoller, persist conflict context in PR review records, and exposepending_pr_conflict/2for prompt injection. - Inject merge-conflict context/instructions into both full and compact prompts, and wire the injection into
AgentRunner.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
lib/symphony_elixir/pr_review_poller.ex |
Detect merge conflicts from PR activity, store conflict context, dedupe by head/base key, dispatch/escalate, and expose pending_pr_conflict/2. |
lib/symphony_elixir/github/pull_request.ex |
Extend gh pr view fields and normalize mergeability/head/base metadata into activity. |
lib/symphony_elixir/prompt_builder.ex |
Add pr_conflict normalization and append a conflict section (instructions + metadata) to prompts. |
lib/symphony_elixir/agent_runner.ex |
Include pr_conflict in first-turn prompt options and use it in continuation stopping logic. |
test/symphony_elixir/pr_review_poller_test.exs |
Add coverage for conflict dispatch, dedupe, escalation, active-run suppression, and cleanup behavior. |
test/symphony_elixir/github_pull_request_test.exs |
Update expectations for expanded gh pr view --json fields and decoded activity fields. |
test/symphony_elixir/prompt_builder_test.exs |
Assert compact prompt includes conflict instructions and metadata. |
test/symphony_elixir/core_test.exs |
Assert prompt builder injects conflict instructions/metadata and handles partial/missing fields. |
SPEC.md |
Document conflict detection/dispatch behavior in the poller spec. |
docs/configuration.md |
Document merge conflict detection + prompt injection behavior for the PR review poller. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: chihsuan <4344253+chihsuan@users.noreply.github.com>
Co-authored-by: chihsuan <4344253+chihsuan@users.noreply.github.com>
Resolved and pushed in commit |
Summary:
- Add bounded prompt-safety normalization for inline PR conflict fields.
- Apply that normalization before conflict metadata reaches workflow
templates or compact prompt rendering.
- Cover both render paths with malicious and overlong conflict metadata.
Rationale:
- PR conflict metadata can include human-authored titles and branch names.
Sanitizing it before rendering keeps conflict prompts bounded and avoids
confusing control text in untrusted input sections.
Tests:
- mix test test/symphony_elixir/prompt_safety_test.exs test/symphony_elixir/prompt_builder_test.exs test/symphony_elixir/pr_review_poller_test.exs test/symphony_elixir/github_pull_request_test.exs
- mix specs.check
- git diff --check
- MIX_HOME=/private/tmp/symphony-mix-home HEX_HOME=/private/tmp/symphony-hex-home mix dialyzer --format short
- make all (blocked by MCP socket bind returning {:mcp_socket_open_failed,
:eperm}; coverage then fails below the 100% threshold)
Resolved by merging latest
Done — I merged latest |
Summary:
- Add the formatter-required blank line in the GitHub PR activity test.
- Wrap long PR review poller branches and a long AppServer test assertion.
- Replace a one-branch cond with if/else in config schema validation.
Rationale:
- The reviewer-reported format and credo failures blocked the gate.
- The additional small style fixes keep the full lint command green without
changing runtime behavior.
Tests:
- mix format --check-formatted
- mix test test/symphony_elixir/github_pull_request_test.exs test/symphony_elixir/pr_review_poller_test.exs
- mix specs.check
- mix lint
- mix test test/symphony_elixir/app_server_test.exs:1858 failed locally
before the touched assertion with {:mcp_socket_open_failed, :eperm}
Summary:
- Restore the event-specific assert_received pattern for malformed command
completion recovery messages.
- Keep the assertion formatter-friendly without binding the first generic
app-server mailbox message.
Rationale:
- The prior lint rewrite consumed :session_started before the recovery event,
which regressed the test assertion and failed CI.
Tests:
- mix format --check-formatted test/symphony_elixir/app_server_test.exs
- mix lint
- git diff --check -- test/symphony_elixir/app_server_test.exs
- mix test test/symphony_elixir/app_server_test.exs:1858 blocked locally by
{:mcp_socket_open_failed, :eperm}
|
@copilot resolve the merge conflicts in this pull request |
# Conflicts: # test/symphony_elixir/app_server_test.exs Co-authored-by: chihsuan <4344253+chihsuan@users.noreply.github.com>
Resolved in commit |
Context
PR review polling needs to detect merge conflicts and dispatch agents to resolve them semantically.
TL;DR
Dispatch agent-owned PR merge conflict resolution from the review poller.
Summary
Alternatives
Test Plan
make allblocked locally by AF_UNIX socket bind:epermin app-server socket tests.mix format --check-formattedmix lintmix specs.checkmix testprompt safety, prompt builder, PR poller, and GitHub PR testsMIX_HOME=/private/tmp/symphony-mix-home HEX_HOME=/private/tmp/symphony-hex-home mix dialyzer --format shortgit diff --check origin/main..HEAD