Home / Stories / Multi-persona MR review
Story · Review In development

Three reviewers on your MR, and a note on where they disagree.

An engineer opens a merge request (MR) by hand. It bumps the version of a Helm chart (a packaged application) and adds one extra setting. Someone types /review all. Several reviewer personas read the MR in parallel. Each persona uses a different AI model (LLM) and says which one. A final comment counts the verdicts. It also points out the one finding that only one persona caught.

Starts fromAny open MR. Add the assistant as a reviewer, or post a /review comment.
Looks atThe diff, the MR description, and the files around it in the repository.
You getOne comment per persona with its verdict and model. One synthesis comment. A verdict label that you can search.
01 · A human-written MR

Not every change comes from the assistant.

Here an engineer bumps ingress-nginx by one minor version. In the same MR, the engineer turns on allowSnippetAnnotations so one team can add a custom header. The change is only two lines, so it is easy to approve on a Friday.

02 · Ask for a review

Add the assistant as a reviewer, or comment.

Add the assistant to the MR's reviewers list. This runs the default persona once per commit. A /review comment does the same. /review all runs every configured persona. /review premium runs just one.

Only people on the trigger allowlist can start a review by comment. The assistant drops unknown persona names with a warning. The other personas still run.

03 · Personas, in parallel

A stable name in front, a swappable model behind.

Your team learns the personas, not the models. default gives a balanced review. premium is for high-stakes MRs. quick gives a cheap second opinion. Each persona points to an AI model profile in the configuration. When a better model ships, only the pointer changes.

The assistant keys each review on MR, commit and persona, so a persona never reviews the same commit twice. A force-push (a push that rewrites branch history) makes the persona eligible again.

04 · Read more than the diff

Check the claims against the repository.

Each reviewer sees the diff and the MR description. You can also give a reviewer read-only tools. These tools open nearby files, such as the values the chart already sets and the Ingress objects that would use the new setting In development.

Sometimes an approval needs evidence that the reviewer does not have, such as a changelog or a CRD (custom resource definition) schema. The assistant marks that approval contested. It does not pass it on as a clean yes.

05 · One comment per persona

Every header names the persona and the model.

You always know which AI model gave which opinion. Each comment shows a verdict and a quality score. It also shows what the reviewer verified, what worries it, and the commit it reviewed.

Here two personas approve. premium requests changes. The snippet setting lets anyone who can write an Ingress inject NGINX configuration. This is why the chart turns it off by default.

06 · The synthesis

Where they agree, and the finding only one of them made.

When two or more personas run, a synthesis comment tallies the verdicts. It lists shared concerns and highlights unique findings. The assistant does not average away a lone dissent. The dissent is the headline.

07 · A label you can filter on

The worst verdict wins.

The assistant labels the MR review::LGTM, review::NC or review::COMMENT. The label follows the most cautious persona's verdict. A re-review replaces the label, so the MR list always shows the current state.

08 · Assistant MRs get a second reviewer

An independent review with no pipeline context.

The assistant's own reviewer shares its prompts and its blind spots. So an independent reviewer also reads every MR that the assistant opens. This reviewer knows nothing about how the assistant made the MR. It checks that the title matches the diff and that nothing secret leaks. It also checks that the change lands somewhere that is actually deployed.

Its verdict goes on a separate label: xrev::LGTM, xrev::NC (needs changes) or xrev::DNM (do not merge).

!88 · ingress-nginx 4.10.1 → 4.11.2, allow snippets for checkout · by sam
infrastructure/ingress/helmrelease_ingress-nginx.yaml
      chart: ingress-nginx
-     version: 4.10.1
+     version: 4.11.2
  values:
    controller:
+     allowSnippetAnnotations: true
      replicaCount: 3
author: human · 1 file · +2 −1 · pipeline green
!88 · activity
S
sam requested review from gitops-assistant
reviewers: priya, gitops-assistant
P
priya commented
touches the edge for every team, let's get all three on it
/review all
G
gitops-assistant
/review allhead_sha a41c07e · 3 personas, none reviewed yet
defaultQwen3.5-397B
premiumClaude Opus 4.7
quickClaude Haiku 4.5
run in parallel · bounded by max_parallel_reviews · models are examples, set per install
premium · read-only repo tools · 3 calls
→ read_repo_file(infrastructure/ingress/helmrelease_ingress-nginx.yaml)
  controller.config: none · no snippet allow-list
→ list_repo_dir(apps/)
  31 Ingress objects across 9 namespaces
→ read_repo_file(apps/checkout/ingress.yaml)
  configuration-snippet: more_set_headers "X-Frame…"
quick · evidence check
  • diff matches the title
  • 4.10 → 4.11 changelog not available to this persona
  • verdict: approve → marked contested
!88 · discussion
G
✅ Review — persona: default — model: qwen3.5-397b — approve
Quality 84/100 · chart name unchanged, replicaCount preserved.
G
❌ Review — persona: premium — model: claude-opus-4-7 — request_changes
Quality 91/100 · allowSnippetAnnotations is cluster-wide: any namespace that can create an Ingress can inject NGINX config. Only checkout needs a header; use a controller.addHeaders entry or scope it with an admission policy.
G
✅ Review — persona: quick — model: claude-haiku-4-5 — approve
Quality 78/100 · ⚠ contested: approved without changelog evidence for 4.10 → 4.11.
🧭 Review synthesis across personas: default, premium, quick
approve
2
request changes
1
shared concerns
0
read alongside the individual persona comments above
Merge requests · label = review::NC
  • !88 ingress-nginx 4.10.1 → 4.11.2, allow snippets for checkout review::NC
  • !85 cert-manager: raise renewBefore to 30d review::LGTM
  • !83 split monitoring values per environment review::COMMENT
worst persona verdict wins: request_changes › comment › approve
!88 · after force-push b92e310
-     allowSnippetAnnotations: true
+     addHeaders: { X-Frame-Options: DENY }
/review premium  →  approve · label replaced: review::LGTM
Bot MRgitops-ai/…
Independent reviewerdiff + repo only
Verdict labelxrev::…
independent review · no pipeline context
  • title matches the diff scope
  • no credentials or tokens in the diff leak check
  • target file is reconciled by a Kustomization placement
  • no same-file MR already open siblings
xrev::LGTMxrev::NCxrev::DNM

The review thread you get.

Illustrative. The comment headers, the synthesis and the label scopes follow the format the reviewer writes. The model names are examples. Each installation sets its own.

Open

ingress-nginx 4.10.1 → 4.11.2, allow snippets for checkout

from sam/ingress-nginx-4.11 into main · 1 file · +2 −1 · reviewers: priya, gitops-assistant
review::NC
premiumdefaultquickSynthesis
❌ Review — persona: premium — model: claude-opus-4-7 — request_changes

Quality: 91/100

The version bump is fine on its own. The second change is not scoped to what the MR description asks for.

✅ Verified
  • chart name and source unchanged
  • replicaCount and existing values preserved byte-identical
  • 4.11.x is a minor line. No values renames touch this release
⚠️ Concerns
  • controller.allowSnippetAnnotations: true applies to every Ingress in the cluster (31 objects, 9 namespaces). Any team that can write an Ingress can then inject NGINX configuration. The chart defaults this to off for that reason.
  • The need in the description is one response header for checkout. controller.addHeaders (or a per-host header ConfigMap) covers it without enabling snippets.

Generated by the GitOps Assistant reviewer · head_sha a41c07e

✅ Review — persona: default — model: qwen3.5-397b — approve

Quality: 84/100

✅ Verified
  • chart name unchanged
  • spec.values preserved apart from the one added key
⚠️ Concerns
  • Snippet annotations widen what Ingress authors can configure. Confirm this is intended.

Generated by the GitOps Assistant reviewer · head_sha a41c07e

✅ Review — persona: quick — model: claude-haiku-4-5 — approve

Quality: 78/100

LGTM: minor chart bump, one values addition.

Generated by the GitOps Assistant reviewer · head_sha a41c07e

🧭 Review synthesis across personas: default, premium, quick

2/3 personas approve. premium requests changes. Shared concern: none that all three raised. default noted the snippet setting but did not block on it.

Unique finding: premium showed that the snippet setting is cluster-wide, but the need is one header for one service. It also named a narrower alternative. The operator should resolve this before merging.

quick's approval is marked contested because it lacked changelog evidence.

Synthesis produced by the GitOps Assistant reviewer. Read alongside the individual persona comments.

S
sam pushed b92e310

Fair, switched to addHeaders. /review premium

G
✅ Review — persona: premium — model: claude-opus-4-7 — approve head_sha b92e310

Snippets stay disabled. The controller sets the header globally, which matches the stated need. The label is now review::LGTM.

What keeps it honest.

A reviewer that agrees with everything is worse than none. These are the rules that keep the verdicts meaningful.

The model is always namedEvery comment header names the persona and the AI model. The assistant stores both with the review, so you can compare personas over time.
Dissent is shown, not averagedThe synthesis highlights findings that only one persona made. The verdict label takes the most cautious verdict.
Approvals without evidence are flaggedThe assistant marks an approval contested when it needed a changelog or CRD schema that it did not have. So a missing check cannot pass as a clean yes.
Once per commitEach persona reviews a given commit once. A re-review runs after a push or on explicit request. It replaces the label.
Comment triggers are allowlistedOnly listed users can start a review by comment. Anyone else's /review is ignored.
It reviews, it does not mergeThe reviewer posts comments and a label. It never merges, and pushing fixes to your branch is off.

Where this stands.

Live
  • Independent second review of every bot MR, with xrev::LGTM / NC / DNM labels
In development
  • On-demand review by reviewer assignment or /review comment (built, not yet enabled in production)
  • Parallel personas with model-named headers and the synthesis comment
  • review:: verdict labels and contested-approval marking
  • Read-only repository tools for the reviewer
  • review <MR> from Slack
Roadmap
  • Label triggers such as reviewer:all
  • One GitLab user per persona, so each shows in the reviewers sidebar
  • Small fixes pushed to the branch by the default persona
← Previous storySlack commands