feat(chat): flag a conflicted pull request on its session chip - #3760
Conversation
A session-list chip showed a green check whenever the PR's checks passed, including on a branch that conflicts with the base and cannot merge — so the chip read "ready" on work that needs a rebase. The merge pair the chip needed was already on the wire: the chip-status cache projects `mergeable` / `mergeStateStatus` and the slot serializer spreads the whole entry, owner-gated exactly like `ci`. Only the render ignored it. Replace the three independent CI conditionals with one `chipStatusGlyph` decision so the precedence is stated once: a failed rollup, then a conflict, then pending, then passed. A conflict therefore replaces a passing or pending glyph but never masks a failure, and stays suppressed on a terminal PR where the providers stop answering the merge pair at all.
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Design Review (Fable 5) — 🟡 CONCERNSAdvisory design-level review of Design-Verdict: CONCERNS Sound single-precedence design, but GitLab Watch
Suggestions
[DESIGN-REVIEWED] 40b841d |
UX Review (Fable 5) — 🟡 CONCERNSAdvisory UX-level review of UX-Verdict: CONCERNS A red 10px triangle carries the whole message, but nothing visible ever says "merge conflicts" — hover explains the click, not the glyph. Watch
Suggestions
[UX-REVIEWED] 40b841d |
First Principles Review (Fable 5) — 🟡 CONCERNSAdvisory premise-level review of First-Principles-Verdict: CONCERNS The chip fix is cause-level and earns its place, but it ships a fourth spelling of "is this PR conflicted", and the panel it borrows its label from disagrees with it. What this change shipsIntent: stop a session-list PR chip from reading "ready" on a branch that cannot merge — a FIX to a misleading signal.
Watch
[FIRST-PRINCIPLES-REVIEWED] 40b841d |
Opus 4.8 Review — ✅ no blocking findingsReviewed Review detailsI've independently verified the key claims. The core logic is sound:
The committed No findings. [OPUS-REVIEWED] 40b841d Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
iamwhatever
left a comment
There was a problem hiding this comment.
Tier 1 auto-approve: cosmetic-UI (7 files). Criteria: no conflict, no requested changes, no security surface, AI reviewers green. Category: adds a visual conflict indicator on the PR session chip — purely presentational change.
…otdev#3760) A session-list chip showed a green check whenever the PR's checks passed, including on a branch that conflicts with the base and cannot merge — so the chip read "ready" on work that needs a rebase. The merge pair the chip needed was already on the wire: the chip-status cache projects `mergeable` / `mergeStateStatus` and the slot serializer spreads the whole entry, owner-gated exactly like `ci`. Only the render ignored it. Replace the three independent CI conditionals with one `chipStatusGlyph` decision so the precedence is stated once: a failed rollup, then a conflict, then pending, then passed. A conflict therefore replaces a passing or pending glyph but never masks a failure, and stays suppressed on a terminal PR where the providers stop answering the merge pair at all. Co-authored-by: Nick Bowers <nrb@amazon.com>
Open PR relationship auditThis is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion. Relationship findings
No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit. |
Problem
A session-list pull-request chip shows a green check whenever the PR's checks
pass — including on a branch that conflicts with its base and cannot merge. The
chip reads "ready" on work that needs a rebase.
Why it matters
The chip is the session list's only at-a-glance answer to "where is this PR?".
A green check there is read as "nothing to do", so a conflicted branch is
invisible until someone opens the PR and finds it unmergeable. The signal is
worst exactly when it matters most: a long-running session accumulates chips, and
the conflicted one looks identical to the landed-and-waiting ones.
Fix (symptoms -> root cause -> change)
Symptom: ✓ on an unmergeable PR.
Root cause: the chip only ever consulted
link.ci. The merge answer wasalready on the wire and ignored — the chip-status cache projects
mergeable/mergeStateStatus(_record_merge_state), the slot serializer spreads the wholeentry into
source_links, andChatSidebar's ownSlottype already declaredboth fields. Only the render never read them.
Change: replace the three independent
&&conditionals with onechipStatusGlyph()decision, so the precedence is stated once instead of beingan emergent property of guard order:
A conflict therefore replaces a passing or pending glyph but never masks a
failure — with both blockers live, the worse outcome is the one worth surfacing.
Two deliberate exclusions.
mergeStateStatus: 'blocked'is not treated as aconflict: on a repo with required reviews it is the normal state of every open PR,
so flagging it would decorate the whole session list and mean nothing. And
behindis left alone because such a branch still merges.The conflict test is
mergeable === 'conflicting' || mergeStateStatus === 'dirty'rather than one field, because
_record_merge_statesettles the two fieldsindependently — a poll can land
dirtywhilemergeableis stillunknown—and GitLab's
conflictnormalizes into both.The glyph reuses the panel's existing
components.pullRequestPanel.merge_conflictskey rather than adding a
pages.chatSidebarone, so the chip and the panel'sconflict banner cannot word the same pull request differently in any of the 12
shipped locales. No catalog changes.
Owner-gating is inherited unchanged: the merge pair reaches owner clients only,
exactly like
ci, so an embed or app-token client renders precisely what it didbefore.
Tests
14 cases added to
ChatSidebar.sourceLinkChip.test.tsx, all asserting renderedaria-labels:can express a conflict (both fields,
mergeablealone,mergeStateStatusalone)blockedbranch, abehindbranch, and a payload with no merge fields (the non-owner shape)
mergedandclosedchipsInverting the precedence order in
chipStatusGlyphfails 4 of them, so they pinthe behaviour rather than passing vacuously.
Manual verification
Captured through a new Playwright harness,
website/scripts/capture-sidebar-chip-conflict.mjs, which drives the real builtSPA with fixture slots and asserts all six chips'
aria-labels before itexits — it cannot ship a screenshot of the old rendering. Both themes.
Screenshots
Chip rows in dark and light. Row 1: #843 passes its checks and conflicts (⚠),
#844 differs only in being mergeable (✓), #845 is pending. Row 2 is the
precedence: #846 carries both blockers and shows the failure, #847 conflicts
while pending, #848 is merged so the merge pair is moot.
Full sidebar context
no linked issue: raised directly as a feature request in a dashboard session, not filed first.